list_add_last(&input_code, &p->car);
}
+static int
+new_3par_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;
+}
+
/* return number of variable where lies result
* pref_var < 0 => no preference
*/
static int
evaluate(struct tree* t, int pref_var, struct list* where)
{
- struct code ins;
-
if (t->st == ST_LEAF) {
return t->pt.leaf.n;
} else if (t->st == ST_OP) {
right = evaluate(t->pt.op.right, -1, where);
switch (t->pt.op.op) {
case '.':
- ins.opcode = CAT;
- 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;
+ return new_3par_instr(OPC_CAT, left,
+ right, pref_var, where);
break;
default:
die("evaluate: got to default");
var_l = t->pt.ass.left->pt.leaf.n;
var_r = evaluate(t->pt.ass.right, -1, where);
- ins.opcode = SET;
+ ins.opcode = OPC_SET;
ins.u.set.l = var_l;
ins.u.set.r = var_r;
new_instr(ins, where);
}
-static int
-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)
{
switch (t->pt.cond.op) {
case '>':
- return new_cond_instr(GT, left,
+ return new_3par_instr (OPC_GT, left,
+ right, pref_var, where);
+ break;
+ case '<':
+ return new_3par_instr (OPC_LT, left,
+ right, pref_var, where);
+ break;
+ case CC('<','='):
+ return new_3par_instr (OPC_LE, left,
+ right, pref_var, where);
+ break;
+ case CC('>','='):
+ return new_3par_instr (OPC_GE, left,
+ right, pref_var, where);
+ break;
+ case CC('!','~'):
+ return new_3par_instr (OPC_NRE, left,
+ right, pref_var, where);
+ break;
+ case CC('~','~'):
+ return new_3par_instr (OPC_RE, left,
+ right, pref_var, where);
+ break;
+ case CC('=','='):
+ return new_3par_instr (OPC_EQ, left,
+ right, pref_var, where);
+ break;
+ case CC('!','='):
+ return new_3par_instr (OPC_NEQ, left,
right, pref_var, where);
break;
/* fixme: do more of them */
}
}
if (t->pt.cond.type == OP_BOOL) {
+ struct code ins;
+
left = eval_cond(t->pt.cond.left, -1, where);
- right = eval_cond(t->pt.cond.right, -1, where);
+ if (t->pt.cond.op != '!') /* ! is unary */
+ right = eval_cond(t->pt.cond.right, -1, where);
switch (t->pt.cond.op) {
case '&':
- return new_cond_instr(AND, left,
+ return new_3par_instr (OPC_AND, left,
right, pref_var, where);
break;
+ case '|':
+ return new_3par_instr (OPC_OR, left,
+ right, pref_var, where);
+ break;
+ case '^':
+ return new_3par_instr (OPC_XOR, left,
+ right, pref_var, where);
+ break;
+ case '!':
+ ins.opcode = OPC_NOT;
+ ins.u.dpop.par = left;
+ if (pref_var >= 0)
+ ins.u.dpop.res = pref_var;
+ else
+ ins.u.dpop.res = current_varcode++;;
+ new_instr(ins, where);
+ return ins.u.dpop.res;
+ break;
default:
die("eval_cond: unknown boolean op %c\n",
t->pt.cond.op);
list_init(if_branch);
list_init(else_branch);
- nop.opcode = NOP;
- jmp.opcode = JUMP;
+ nop.opcode = OPC_NOP;
+ jmp.opcode = OPC_JUMP;
c = eval_cond(t->pt.tif.c, -1, where);
jmp.u.jump.target = list_last(else_branch);
new_instr(jmp, if_branch);
- ins.opcode = JUMP_UNLESS;
+ ins.opcode = OPC_JUMP_UNLESS;
ins.u.jump_unless.cond = c;
ins.u.jump_unless.target = list_last(if_branch);
new_instr(ins, where);
ins.u.arrow.copy = 0;
switch (t->pt.arrow.right) {
case K_EMPTY:
- ins.opcode = STORE;
+ ins.opcode = OPC_STORE;
break;
case K_PIPE:
- ins.opcode = PIPE;
+ ins.opcode = OPC_PIPE;
break;
case K_MAIL:
- ins.opcode = MAIL;
+ ins.opcode = OPC_MAIL;
break;
case K_DISCARD:
- ins.opcode = DISCARD;
+ ins.opcode = OPC_DISCARD;
break;
default:
die("do_arrow: This cannot happen ;-)");
LIST_FOREACH(p, &input_code) {
switch (p->opcode) {
- case SET:
+ case OPC_SET:
printf("SET %d %d\n", p->u.set.l, p->u.set.r);
break;
- case CAT:
+ case OPC_CAT:
printf("CAT %d %d %d\n", p->u.tpop.l,
p->u.tpop.r, p->u.tpop.res);
break;
- case JUMP:
+ case OPC_JUMP:
printf("JUMP %d\n", (int) p->u.jump.target);
break;
- case JUMP_UNLESS:
+ case OPC_JUMP_UNLESS:
printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target);
break;
- case GT:
+ case OPC_GT:
printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
break;
- case AND:
+ case OPC_AND:
printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
break;
- case NOP:
+ case OPC_NOP:
puts("NOP");
break;
- case PIPE:
+ case OPC_PIPE:
printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
break;
- case STORE:
+ case OPC_STORE:
printf("STORE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
break;
- case MAIL:
+ case OPC_MAIL:
printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);
break;
- case DISCARD:
+ case OPC_DISCARD:
puts("DISCARD");
break;
default: