From 7a57309be67a71012bcde51ccc47197ac1291e5a Mon Sep 17 00:00:00 2001 From: Anicka Bernathova Date: Wed, 15 Jul 2009 14:01:08 +0200 Subject: [PATCH] nearly finish conditions, just more operators are missing --- code.c | 65 +++++++++++++++++++++++++++++++++++++++++----------------- umpf.h | 10 +++------ 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/code.c b/code.c index de0ed89..4f665e1 100644 --- a/code.c +++ b/code.c @@ -97,14 +97,14 @@ evaluate(struct tree* t, int pref_var, struct list* where) switch (t->pt.op.op) { case '.': ins.opcode = CAT; - ins.u.cat.l = left; - ins.u.cat.r = right; + ins.u.tpop.l = left; + ins.u.tpop.r = right; if (pref_var >= 0) - ins.u.cat.res = pref_var; + ins.u.tpop.res = pref_var; else - ins.u.cat.res = current_varcode++;; + ins.u.tpop.res = current_varcode++;; new_instr(ins, where); - return ins.u.cat.res; + return ins.u.tpop.res; break; default: die("evaluate: got to default"); @@ -130,9 +130,25 @@ do_ass(struct tree* t, struct list* where) } static int -eval_cond(struct tree *t, int pref_var, struct list* where) +new_cond_instr(int opcode, int left, int right, int pref_var, + struct list* where) { struct code ins; + + ins.opcode = opcode; + ins.u.tpop.l = left; + ins.u.tpop.r = right; + if (pref_var >= 0) + ins.u.tpop.res = pref_var; + else + ins.u.tpop.res = current_varcode++;; + new_instr(ins, where); + return ins.u.tpop.res; +} + +static int +eval_cond(struct tree *t, int pref_var, struct list* where) +{ int left, right; if (t->pt.cond.type == JUST_BOOL) { if (t->pt.cond.left->st == ST_LEAF) @@ -149,16 +165,9 @@ eval_cond(struct tree *t, int pref_var, struct list* where) switch (t->pt.cond.op) { case '>': - ins.opcode = GT; - ins.u.gt.l = left; - ins.u.gt.r = right; - if (pref_var >= 0) - ins.u.gt.res = pref_var; - else - ins.u.gt.res = current_varcode++;; - new_instr(ins, where); - return ins.u.gt.res; - break; + return new_cond_instr(GT, left, + right, pref_var, where); + break; /* fixme: do more of them */ default: die("eval_cond: unknown relation op %c\n", @@ -166,6 +175,21 @@ eval_cond(struct tree *t, int pref_var, struct list* where) } } + if (t->pt.cond.type == OP_BOOL) { + left = eval_cond(t->pt.cond.left, -1, where); + right = eval_cond(t->pt.cond.right, -1, where); + switch (t->pt.cond.op) { + case '&': + return new_cond_instr(AND, left, + right, pref_var, where); + break; + default: + die("eval_cond: unknown boolean op %c\n", + t->pt.cond.op); + } + } + + die("eval_cond: unknown condition type"); } static void @@ -250,8 +274,8 @@ print_code(void) 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); + printf("CAT %d %d %d\n", p->u.tpop.l, + p->u.tpop.r, p->u.tpop.res); break; case JUMP: printf("JUMP %d\n", (int) p->u.jump.target); @@ -260,7 +284,10 @@ print_code(void) printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target); break; case GT: - printf("GT %d %d %d\n", p->u.gt.l, p->u.gt.r, p->u.gt.res); + printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); + break; + case AND: + printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res); break; case NOP: puts("NOP"); diff --git a/umpf.h b/umpf.h index b5b7df8..ff83a93 100644 --- a/umpf.h +++ b/umpf.h @@ -128,7 +128,8 @@ struct code { CALL_EXT, NOP, CAT, - GT + GT, + AND } opcode; union { @@ -151,14 +152,9 @@ struct code { int l; int r; int res; /* result */ - } cat; + } tpop; struct { } nop; - struct { - int l; - int r; - int res; /* result */ - } gt; } u; }; -- 2.39.2