X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=code.c;h=932bb9ab5d8766c3a43f508a43b5add5b27825ab;hb=8628def3891660a2ebfce358dc65cf6b0f0a92d1;hp=070f7831615d86c5bb3f75c7f434a35e1f6997cd;hpb=0dc94edb85ce7d4f6972a5a2339e7500a9a30dbe;p=umpf.git diff --git a/code.c b/code.c index 070f783..932bb9a 100644 --- a/code.c +++ b/code.c @@ -5,9 +5,6 @@ #include "umpf.h" -#define HASHSIZE 103 -#define MAGIC 19 - struct list* new_var_hash(void) { @@ -21,7 +18,7 @@ new_var_hash(void) return res; } -static int +int get_bucket_number(char* name) { unsigned int n = 0; @@ -35,22 +32,36 @@ get_bucket_number(char* name) return n; } -/* if not found, variable with value "" is created */ +/* return var struct or NULL if not found */ +struct variable* +get_var_struct(char* name, enum var_type type, struct list* hash) +{ + int n; + struct variable *p; + + n = get_bucket_number(name); + LIST_FOREACH(p, hash + n) + if (!strcasecmp(p->name, name) && p->type == type) + return p; + + return NULL; +} + int -find_var(char* name, struct list* hash) +find_var(char* name, enum var_type type, struct list* hash) { int n; struct variable *p; n = get_bucket_number(name); - int nocase = isupper(*name); LIST_FOREACH(p, hash + n) - if (!(nocase ? strcasecmp : strcmp)(p->name,name)) + if (!strcasecmp(p->name, name) && p->type == type) return p->varcode; p = xmalloc(sizeof(struct variable)); p->name = xstrdup(name); p->varcode = current_varcode++; + p->type = type; list_add_last(hash+n, &p->car); return p->varcode; @@ -105,21 +116,33 @@ evaluate(struct tree* t, int pref_var, struct list* where) { 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, where); - right = evaluate(t->pt.op.right, -1, where); - switch (t->pt.op.op) { - case '.': - return new_3par_instr(OPC_CAT, left, - right, pref_var, where); - break; - default: - die("evaluate: got to default"); - } - } else - die("evaluate: I can evaluate only expressions but I got %d", - t->st); + } + int left, right; + left = evaluate(t->pt.op.left, -1, where); + right = evaluate(t->pt.op.right, -1, where); + switch (t->pt.op.op) { + case '.': + return new_3par_instr(OPC_CAT, left, + right, pref_var, where); + break; + case '+': + return new_3par_instr(OPC_PLUS, left, + right, pref_var, where); + break; + case '-': + return new_3par_instr(OPC_MINUS, left, + right, pref_var, where); + break; + case '*': + return new_3par_instr(OPC_MUL, left, + right, pref_var, where); + break; + case '/': + return new_3par_instr(OPC_DIV, left, + right, pref_var, where); + break; + } + die("evaluate: Never can get here :)"); } static void @@ -278,7 +301,7 @@ do_arrow(struct tree* t, struct list* where) ins.u.arrow.copy = 0; switch (t->pt.arrow.right) { case K_EMPTY: - ins.opcode = OPC_STORE; + ins.opcode = OPC_DELIVER; break; case K_PIPE: ins.opcode = OPC_PIPE; @@ -289,6 +312,9 @@ do_arrow(struct tree* t, struct list* where) case K_DISCARD: ins.opcode = OPC_DISCARD; break; + case K_FILTER: + ins.opcode = OPC_FILTER; + break; default: die("do_arrow: This cannot happen ;-)"); } @@ -304,6 +330,8 @@ do_arrow(struct tree* t, struct list* where) static void reset_temp_var_count(void) { + if (current_varcode > max_varcode) + max_varcode = current_varcode; current_varcode = temp_varcode_start; } @@ -367,17 +395,62 @@ print_code(void) case OPC_GT: printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); break; + case OPC_LT: + printf("LT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_LE: + printf("LE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_GE: + printf("GE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_RE: + printf("RE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_NRE: + printf("NRE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_NEQ: + printf("NEQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_EQ: + printf("EQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; case OPC_AND: printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); break; + case OPC_OR: + printf("OR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_XOR: + printf("XOR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_PLUS: + printf("PLUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_MINUS: + printf("MINUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_MUL: + printf("MUL %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_DIV: + printf("DIV %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case OPC_NOT: + printf("NOT %d %d\n", p->u.dpop.par, p->u.dpop.res); + break; case OPC_NOP: puts("NOP"); break; case OPC_PIPE: printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy); break; - case OPC_STORE: - printf("STORE %d %d\n", p->u.arrow.what, p->u.arrow.copy); + case OPC_FILTER: + printf("FILTER %d %d\n", p->u.arrow.what, p->u.arrow.copy); + break; + case OPC_DELIVER: + printf("DELIVER %d %d\n", p->u.arrow.what, p->u.arrow.copy); break; case OPC_MAIL: printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);