From: Anicka Bernathova Date: Tue, 14 Jul 2009 16:31:46 +0000 (+0200) Subject: compile SET and CAT X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=cb47d077417b11b8bd79562045e9b9f6511e03d3;p=umpf.git compile SET and CAT --- diff --git a/code.c b/code.c index 7aff3de..af23489 100644 --- a/code.c +++ b/code.c @@ -7,9 +7,8 @@ #define HASHSIZE 103 #define MAGIC 19 -#define BUFSIZE 1024 -static struct list* +struct list* new_var_hash(void) { struct list* res; @@ -37,7 +36,7 @@ get_bucket_number(char* name) } /* if not found, variable with value "" is created */ -static int +int find_var(char* name, struct list* hash) { int n; @@ -53,19 +52,11 @@ find_var(char* name, struct list* hash) p->name = xstrdup(name); p->varcode = current_varcode++; list_add_last(hash+n, &p->car); - return p->varcode; -} -void -init(void) -{ - list_init(&input_code); - var_hash = new_var_hash(); - const_tab = xmalloc(BUFSIZE); - cur_const_s = BUFSIZE; + return p->varcode; } -static int +int store_const(char* c) { if (cur_const_n >= cur_const_s) { @@ -86,23 +77,59 @@ new_instr(struct code c) list_add_last(&input_code, &p->car); } +/* return number of variable where lies result + * pref_var < 0 => no preference + */ +static int +evaluate(struct tree* t, int pref_var) +{ + struct code ins; + + if (t->st == ST_LEAF) { + return t->pt.leaf.n; + } else if (t->st == ST_OP) { + int left, right; + left = evaluate(t->pt.op.left, -1); + right = evaluate(t->pt.op.right, -1); + switch (t->pt.op.op) { + case '.': + ins.opcode = CAT; + ins.u.cat.l = left; + ins.u.cat.r = right; + if (pref_var >= 0) + ins.u.cat.res = pref_var; + else + ins.u.cat.res = current_varcode++;; + new_instr(ins); + return ins.u.cat.res; + break; + default: + die("evaluate: got to default"); + } + } else + die("evaluate: I can evaluate only expressions but I got %d", + t->st); +} + static void do_ass(struct tree* t) { int var_l, var_r; struct code ins; - var_l = find_var(t->pt.ass.left->pt.leaf.value, var_hash); + var_l = t->pt.ass.left->pt.leaf.n; + var_r = evaluate(t->pt.ass.right, -1); + + ins.opcode = SET; + ins.u.set.l = var_l; + ins.u.set.r = var_r; + new_instr(ins); - if (t->st == ST_LEAF) { - if (t->pt.leaf.type == L_VAR) - var_r = find_var(t->pt.leaf.value, var_hash); - else - var_r = store_const(t->pt.leaf.value); - ins.opcode = SET; - ins.u.set.l = var_l; - ins.u.set.r = var_r; - new_instr(ins); - } +} + +static void +reset_temp_var_count(void) +{ + current_varcode = temp_varcode_start; } void @@ -112,6 +139,7 @@ compile(struct tree* t) return; switch(t->st) { case ST_BLOCK: + reset_temp_var_count(); compile(t->pt.block.head); compile(t->pt.block.tail); break; @@ -120,13 +148,30 @@ compile(struct tree* t) case ST_ASS: do_ass(t); break; + case ST_OP: + break; default: die("compile: got to default"); } } void -print_code(struct tree* t) +print_code(void) { - + struct code* p; + + LIST_FOREACH(p, &input_code) { + switch (p->opcode) { + case SET: + printf("SET %d %d\n", p->u.set.l, p->u.set.r); + break; + case CAT: + printf("CAT %d %d %d\n", p->u.cat.l, + p->u.cat.r, p->u.cat.res); + break; + default: + printf("not implemented, opcode: %d\n", + p->opcode); + } + } } diff --git a/cond.y b/cond.y index 6ae17e8..b5e4bf6 100644 --- a/cond.y +++ b/cond.y @@ -147,7 +147,7 @@ ass: $$->pt.ass.left = tree_malloc(ST_LEAF); $$->pt.ass.left->pt.leaf.type = L_VAR; $$->pt.ass.left->pt.leaf.value = $1; - + $$->pt.ass.left->pt.leaf.n = find_var($1, var_hash); $$->pt.ass.right = $3; } ; @@ -156,11 +156,13 @@ leaves: VAR { $$ = tree_malloc(ST_LEAF); $$->pt.leaf.type = L_VAR; $$->pt.leaf.value = $1; + $$->pt.leaf.n = find_var($1, var_hash); } | CONST { $$ = tree_malloc(ST_LEAF); $$->pt.leaf.type = L_CONST; $$->pt.leaf.value = $1; + $$->pt.leaf.n = store_const($1); } ; diff --git a/umpf.c b/umpf.c index bb8ca58..f868775 100644 --- a/umpf.c +++ b/umpf.c @@ -3,6 +3,16 @@ #include "umpf.h" +void +init(void) +{ + list_init(&input_code); + var_hash = new_var_hash(); + const_tab = xmalloc(BUFSIZE); + cur_const_n = 1; + cur_const_s = BUFSIZE; +} + int main(int argc, char** argv) { @@ -19,17 +29,17 @@ main(int argc, char** argv) save_gids(); read_conf(argv[1]); - + init(); // yydebug=1; res = yyparse (); if (res) return res; - init(); + temp_varcode_start = current_varcode; compile(input_tree); - print_code(input_tree); + print_code(); // var_hash = new_var_hash(); // current_headers = make_hlist(); diff --git a/umpf.h b/umpf.h index a2d4576..2da7f00 100644 --- a/umpf.h +++ b/umpf.h @@ -48,6 +48,7 @@ struct tree { L_CONST, } type; char* value; + int n; } leaf; struct { @@ -114,7 +115,7 @@ int open_mailbox(char* path, int is_default_mailbox); char* cat(char* l, char* r); /* code.c */ - +#define BUFSIZE 1024 struct code { struct node car; enum { @@ -124,7 +125,8 @@ struct code { JUMP_UNLESS, DELIVER, CALL_EXT, - NOP + NOP, + CAT } opcode; union { @@ -132,6 +134,15 @@ struct code { int l; int r; } set; + + struct { + int l; + int r; + int res; /* result */ + } cat; + + struct { + } nop; } u; }; @@ -144,10 +155,15 @@ struct variable { struct list input_code; struct list* var_hash; int current_varcode; +int temp_varcode_start; char** var_tab; char** const_tab; -int cur_const_n, cur_const_s; +int cur_const_n; +int cur_const_s; void init(void); void compile(struct tree* t); -void print_code(struct tree* t); +int find_var(char* name, struct list* hash); +int store_const(char* c); +struct list* new_var_hash(void); +void print_code(void);