14 res = xmalloc (HASHSIZE * sizeof(struct list));
15 for (i = 0; i < HASHSIZE; i++)
22 get_bucket_number(char* name)
25 unsigned char* p = name;
28 n = n * MAGIC + toupper(*p++);
36 find_var(char* name, struct list* hash)
41 n = get_bucket_number(name);
42 int nocase = isupper(*name);
43 LIST_FOREACH(p, hash + n)
44 if (!(nocase ? strcasecmp : strcmp)(p->name,name))
47 p = xmalloc(sizeof(struct variable));
48 p->name = xstrdup(name);
49 p->varcode = current_varcode++;
50 list_add_last(hash+n, &p->car);
58 if (cur_const_n >= cur_const_s) {
60 const_tab = xrealloc(const_tab, cur_const_s);
63 const_tab[cur_const_n] = c;
65 return -cur_const_n++;
69 new_instr(struct code c, struct list* where)
71 struct code* p = xmalloc(sizeof(struct code));
74 list_add_last(where, &p->car);
76 list_add_last(&input_code, &p->car);
80 new_3par_instr(int opcode, int left, int right, int pref_var,
89 ins.u.tpop.res = pref_var;
91 ins.u.tpop.res = current_varcode++;;
92 new_instr(ins, where);
93 return ins.u.tpop.res;
96 /* return number of variable where lies result
97 * pref_var < 0 => no preference
100 evaluate(struct tree* t, int pref_var, struct list* where)
102 if (t->st == ST_LEAF) {
106 left = evaluate(t->pt.op.left, -1, where);
107 right = evaluate(t->pt.op.right, -1, where);
108 switch (t->pt.op.op) {
110 return new_3par_instr(OPC_CAT, left,
111 right, pref_var, where);
114 return new_3par_instr(OPC_PLUS, left,
115 right, pref_var, where);
118 return new_3par_instr(OPC_MINUS, left,
119 right, pref_var, where);
122 return new_3par_instr(OPC_MUL, left,
123 right, pref_var, where);
126 return new_3par_instr(OPC_DIV, left,
127 right, pref_var, where);
130 die("evaluate: Never can get here :)");
134 do_ass(struct tree* t, struct list* where)
138 var_l = t->pt.ass.left->pt.leaf.n;
139 var_r = evaluate(t->pt.ass.right, -1, where);
141 ins.opcode = OPC_SET;
144 new_instr(ins, where);
149 eval_cond(struct tree *t, int pref_var, struct list* where)
152 if (t->pt.cond.type == JUST_BOOL) {
153 if (t->pt.cond.left->st == ST_LEAF)
154 return t->pt.cond.left->pt.leaf.n;
155 if (t->pt.cond.left->st == ST_OP)
156 return evaluate(t->pt.cond.left, -1, where);
158 die("eval_cond: %d cannot be JUST_BOOL\n",
159 t->pt.cond.left->st);
161 if (t->pt.cond.type == OP_REL) {
162 left = evaluate(t->pt.cond.left, -1, where);
163 right = evaluate(t->pt.cond.right, -1, where);
165 switch (t->pt.cond.op) {
167 return new_3par_instr (OPC_GT, left,
168 right, pref_var, where);
171 return new_3par_instr (OPC_LT, left,
172 right, pref_var, where);
175 return new_3par_instr (OPC_LE, left,
176 right, pref_var, where);
179 return new_3par_instr (OPC_GE, left,
180 right, pref_var, where);
183 return new_3par_instr (OPC_NRE, left,
184 right, pref_var, where);
187 return new_3par_instr (OPC_RE, left,
188 right, pref_var, where);
191 return new_3par_instr (OPC_EQ, left,
192 right, pref_var, where);
195 return new_3par_instr (OPC_NEQ, left,
196 right, pref_var, where);
198 /* fixme: do more of them */
200 die("eval_cond: unknown relation op %c\n",
205 if (t->pt.cond.type == OP_BOOL) {
208 left = eval_cond(t->pt.cond.left, -1, where);
209 if (t->pt.cond.op != '!') /* ! is unary */
210 right = eval_cond(t->pt.cond.right, -1, where);
211 switch (t->pt.cond.op) {
213 return new_3par_instr (OPC_AND, left,
214 right, pref_var, where);
217 return new_3par_instr (OPC_OR, left,
218 right, pref_var, where);
221 return new_3par_instr (OPC_XOR, left,
222 right, pref_var, where);
225 ins.opcode = OPC_NOT;
226 ins.u.dpop.par = left;
228 ins.u.dpop.res = pref_var;
230 ins.u.dpop.res = current_varcode++;;
231 new_instr(ins, where);
232 return ins.u.dpop.res;
235 die("eval_cond: unknown boolean op %c\n",
240 die("eval_cond: unknown condition type");
244 do_if(struct tree *t, struct list* where)
247 struct code ins, nop, jmp;
248 struct list* if_branch = xmalloc(sizeof(struct list));
249 struct list* else_branch = xmalloc(sizeof(struct list));
251 list_init(if_branch);
252 list_init(else_branch);
253 nop.opcode = OPC_NOP;
254 jmp.opcode = OPC_JUMP;
256 c = eval_cond(t->pt.tif.c, -1, where);
258 compile(t->pt.tif.i, if_branch);
259 compile(t->pt.tif.i, else_branch);
260 new_instr(nop, if_branch);
261 new_instr(nop, else_branch);
262 jmp.u.jump.target = list_last(else_branch);
263 new_instr(jmp, if_branch);
265 ins.opcode = OPC_JUMP_UNLESS;
266 ins.u.jump_unless.cond = c;
267 ins.u.jump_unless.target = list_last(if_branch);
268 new_instr(ins, where);
269 list_cat(where, if_branch);
270 list_cat(where, else_branch);
277 do_arrow(struct tree* t, struct list* where)
283 if (t->pt.arrow.left == K_COPY)
284 ins.u.arrow.copy = 1;
286 ins.u.arrow.copy = 0;
287 switch (t->pt.arrow.right) {
289 ins.opcode = OPC_DELIVER;
292 ins.opcode = OPC_PIPE;
295 ins.opcode = OPC_MAIL;
298 ins.opcode = OPC_DISCARD;
301 die("do_arrow: This cannot happen ;-)");
304 if (t->pt.arrow.right != K_DISCARD) {
305 v = evaluate(t->pt.arrow.s, -1, where);
306 ins.u.arrow.what = v;
309 new_instr(ins, where);
313 reset_temp_var_count(void)
315 if (current_varcode > max_varcode)
316 max_varcode = current_varcode;
317 current_varcode = temp_varcode_start;
321 compile(struct tree* t, struct list* where)
330 reset_temp_var_count();
331 compile(t->pt.block.head, where);
332 compile(t->pt.block.tail, where);
336 case ST_LEAF: //warn?
342 evaluate(t, -1, where); //emit warning?
348 eval_cond(t, -1, where); // warn?
353 die("compile: got to default, type: %d", t->st);
362 LIST_FOREACH(p, &input_code) {
365 printf("SET %d %d\n", p->u.set.l, p->u.set.r);
368 printf("CAT %d %d %d\n", p->u.tpop.l,
369 p->u.tpop.r, p->u.tpop.res);
372 printf("JUMP %d\n", (int) p->u.jump.target);
374 case OPC_JUMP_UNLESS:
375 printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target);
378 printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
381 printf("LT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
384 printf("LE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
387 printf("GE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
390 printf("RE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
393 printf("NRE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
396 printf("NEQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
399 printf("EQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
402 printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
405 printf("OR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
408 printf("XOR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
411 printf("PLUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
414 printf("MINUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
417 printf("MUL %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
420 printf("DIV %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
423 printf("NOT %d %d\n", p->u.dpop.par, p->u.dpop.res);
429 printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
432 printf("DELIVER %d %d\n", p->u.arrow.what, p->u.arrow.copy);
435 printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);
441 printf("not implemented, opcode: %d\n",