Skip to content

Commit

Permalink
added linenoise for line editing, a few bug fixes, cleaned up measure…
Browse files Browse the repository at this point in the history
…ment code
  • Loading branch information
HackerFoo committed May 5, 2013
1 parent ed211ca commit 24c6b85
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 37 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,3 +3,4 @@ _darcs
/rt
/rt.h
/.gdbinit
/.pegc_history
3 changes: 3 additions & 0 deletions .gitmodules
@@ -0,0 +1,3 @@
[submodule "linenoise"]
path = linenoise
url = git://github.com/antirez/linenoise.git
20 changes: 18 additions & 2 deletions Makefile
@@ -1,5 +1,21 @@
rt: rt.c rt.h rt_types.h
gcc -falign-functions=16 -Wall -g rt.c -o rt
CC=gcc
CFLAGS=-falign-functions=16 -Wall -g

.PHONY: all
all: rt

rt.o: rt.c rt.h rt_types.h
$(CC) $(CFLAGS) -c rt.c

linenoise/linenoise.o: linenoise/linenoise.c linenoise/linenoise.c
$(CC) $(CFLASGS) -c linenoise/linenoise.c -o linenoise/linenoise.o

rt: rt.o linenoise/linenoise.o
$(CC) $(CFLAGS) rt.o linenoise/linenoise.o -o rt

rt.h: rt.c
makeheaders rt.c

.PHONY: clean
clean:
rm -f *.o linenoise/*.o rt.h rt
1 change: 1 addition & 0 deletions linenoise
Submodule linenoise added at 27a3b4
145 changes: 111 additions & 34 deletions rt.c
Expand Up @@ -23,16 +23,15 @@
#include <assert.h>
#include <time.h>
#include "rt_types.h"
#include "linenoise/linenoise.h"
#include "rt.h"

// make sure &cells > 255
cell_t cells[1<<16];
cell_t *cells_ptr;
uint8_t alt_cnt = 0;
unsigned int reduce_cnt = 0;
unsigned int alloc_cnt = 0;
int current_alloc_cnt = 0;
unsigned int max_alloc_cnt = 0;

measure_t measure, saved_measure;

// #define CHECK_CYCLE

Expand Down Expand Up @@ -141,7 +140,7 @@ bool reduce(cell_t *c) {
if(c) {
assert(is_closure(c) &&
closure_is_ready(c));
reduce_cnt++;
measure.reduce_cnt++;
return c->func(c);
} else return false;
}
Expand Down Expand Up @@ -188,9 +187,6 @@ void cells_init() {
cells_ptr = &cells[0];
assert(check_cycle());
alt_cnt = 0;
reduce_cnt = 0;
current_alloc_cnt = 0;
max_alloc_cnt = 0;
}

void cell_alloc(cell_t *c) {
Expand All @@ -202,9 +198,9 @@ void cell_alloc(cell_t *c) {
if(cells_ptr == c) cells_next();
prev->next = next;
next->prev = prev;
alloc_cnt++;
if(++current_alloc_cnt > max_alloc_cnt)
max_alloc_cnt = current_alloc_cnt;
measure.alloc_cnt++;
if(++measure.current_alloc_cnt > measure.max_alloc_cnt)
measure.max_alloc_cnt = measure.current_alloc_cnt;
assert(check_cycle());
}

Expand Down Expand Up @@ -261,7 +257,7 @@ void closure_shrink(cell_t *c, int s) {
c[size-1].next = cells_ptr;
cells_ptr->prev = &c[size-1];
assert(check_cycle());
current_alloc_cnt -= size - s;
measure.current_alloc_cnt -= size - s;
}
}

Expand All @@ -271,7 +267,7 @@ void closure_free(cell_t *c) {

bool func_reduced(cell_t *c) {
assert(is_closure(c));
reduce_cnt--;
measure.reduce_cnt--;
return c->type != T_FAIL;
}

Expand Down Expand Up @@ -1185,6 +1181,29 @@ void (*tests[])(void) = {
test16
};

void measure_start() {
bzero(&measure, sizeof(measure));
measure.start = clock();
}

void measure_stop() {
memcpy(&saved_measure, &measure, sizeof(measure));
saved_measure.stop = clock();
}

void measure_display() {
double time = (saved_measure.stop - saved_measure.start) /
(double)CLOCKS_PER_SEC;
printf("time : %.3e sec\n", time);
printf("allocated : %d bytes\n",
saved_measure.alloc_cnt * (int)sizeof(cell_t));
printf("working set : %d bytes\n",
saved_measure.max_alloc_cnt * (int)sizeof(cell_t));
printf("reductions : %d",
saved_measure.reduce_cnt);

}

int main(int argc, char *argv[]) {
unsigned int test_number;
if(argc != 2) return -1;
Expand All @@ -1195,45 +1214,92 @@ int main(int argc, char *argv[]) {
"(( test %-3d ))"
"_________________________________\n", i);
cells_init();
measure_start();
tests[i]();
measure_stop();
check_free();
}
} else if(strcmp("eval", argv[1]) == 0) {
char s[1024];
bzero(s, sizeof(s));
if(fgets(s, sizeof(s), stdin)) {
cells_init();
eval(s, sizeof(s));
check_free();
}
run_eval();
} else {
test_number = atoi(argv[1]);
if(test_number >= LENGTH(tests)) return -2;
cells_init();
//alloc_test();
measure_start();
tests[test_number]();
measure_stop();
check_free();
}
printf("allocated %d bytes\n", alloc_cnt * (int)sizeof(cell_t));
printf("max %d bytes\n", max_alloc_cnt * (int)sizeof(cell_t));
printf("performed %d reduction%s\n", reduce_cnt, reduce_cnt > 1 ? "s" : "");
measure_display();
return 0;
}

void *lookup(void *table, unsigned int width, unsigned int rows, char *key) {
#define HISTORY_FILE ".pegc_history"
void run_eval() {
char *line;
linenoiseSetCompletionCallback(completion);
linenoiseHistoryLoad(HISTORY_FILE);
while((line = linenoise(": "))) {
if(line[0] == '\0') {
free(line);
break;
}
if(strcmp(line, ":m") == 0) {
measure_display();
} else {
linenoiseHistoryAdd(line);
cells_init();
measure_start();
eval(line, strlen(line));
measure_stop();
check_free();
}
free(line);
}
linenoiseHistorySave(HISTORY_FILE);
}

void completion(const char *buf, linenoiseCompletions *lc) {
int n = strlen(buf);
char comp[n+sizeof_field(word_entry_t, name)];
char *insert = comp + n;
strncpy(comp, buf, sizeof(comp));
char *tok = rtok(comp, insert);
int tok_len = strnlen(tok, sizeof_field(word_entry_t, name));
if(!tok) return;
word_entry_t *e = lookup_word(tok);
if(e) {
/* add completions */
do {
if(strnlen(e->name, sizeof_field(word_entry_t, name)) >
tok_len) {

strncpy(tok, e->name, sizeof(e->name));
linenoiseAddCompletion(lc, comp);
}
e++;
} while(strncmp(e->name, tok, tok_len) == 0);
}
}

void *lookup(void *table, unsigned int width, unsigned int rows, const char *key) {
unsigned int low = 0, high = rows, pivot;
int c;
void *entry;
void *entry, *ret = 0;
int key_length = strnlen(key, width);
while(high > low) {
pivot = low + ((high - low) >> 1);
entry = table + width * pivot;
c = strncmp(key, entry, key_length);
if(c == 0) return entry;
if(c < 0) high = pivot;
if(c == 0) {
/* keep looking for a lower key */
ret = entry;
high = pivot;
} else if(c < 0) high = pivot;
else low = pivot + 1;
}
return 0;
return ret;
}

bool is_num(char *str) {
Expand All @@ -1253,6 +1319,14 @@ word_entry_t word_table[] = {
{"|", func_alt, 2, 1}
};

word_entry_t *lookup_word(const char *w) {
return
lookup(word_table,
WIDTH(word_table),
LENGTH(word_table),
w);
}

cell_t *word(char *w) {
unsigned int in, out;
return word_parse(w, &in, &out);
Expand All @@ -1267,11 +1341,11 @@ cell_t *word_parse(char *w,
*in = 0;
*out = 1;
} else {
word_entry_t *e =
lookup(word_table,
WIDTH(word_table),
LENGTH(word_table),
w);
word_entry_t *e = lookup_word(w);
/* disallow partial matches */
if(strnlen(w, sizeof_field(word_entry_t, name)) !=
strnlen(e->name, sizeof_field(word_entry_t, name)))
return NULL;
if(!e) return NULL;
c = func(e->func, e->in);
if(e->func == func_alt)
Expand Down Expand Up @@ -1353,13 +1427,16 @@ void eval(char *str, int n) {
p++;
}
cell_t *c = build(str, &p);
if(!c) return;
if(!closure_is_ready(c))
printf("incomplete expression\n");
else {
clock_t start = clock();
//clock_t start = clock();
show_eval(c);
/*
double time = (clock() - start) /
(double)CLOCKS_PER_SEC;
printf("%.3e sec\n", time);
*/
}
}
12 changes: 11 additions & 1 deletion rt_types.h
Expand Up @@ -41,7 +41,7 @@ struct __attribute__((packed)) cell {
};

typedef struct word_entry_t {
char name[16];
char name[64];
reduce_t *func;
unsigned int in, out;
} word_entry_t;
Expand All @@ -61,4 +61,14 @@ typedef enum char_class_t {
CC_SYMBOL
} char_class_t;

#define sizeof_field(s, f) sizeof(((s *)0)->f)

typedef struct measure_t {
unsigned int reduce_cnt, alloc_cnt, max_alloc_cnt;
signed int current_alloc_cnt;
clock_t start, stop;
} measure_t;

#define zero(a) bzero((a), sizeof(a))

#endif

0 comments on commit 24c6b85

Please sign in to comment.