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++);
35 /* return var struct or NULL if not found */
37 get_var_struct(char* name, struct list* hash)
42 n = get_bucket_number(name);
43 int nocase = isupper(*name);
44 LIST_FOREACH(p, hash + n)
45 if (!(nocase ? strcasecmp : strcmp)(p->name,name))
52 find_var(char* name, struct list* hash)
57 n = get_bucket_number(name);
58 int nocase = isupper(*name);
59 LIST_FOREACH(p, hash + n)
60 if (!(nocase ? strcasecmp : strcmp)(p->name,name))
63 p = xmalloc(sizeof(struct variable));
64 p->name = xstrdup(name);
65 p->varcode = current_varcode++;
66 list_add_last(hash+n, &p->car);
74 if (cur_const_n >= cur_const_s) {
76 const_tab = xrealloc(const_tab, cur_const_s);
79 const_tab[cur_const_n] = c;
81 return -cur_const_n++;
85 new_instr(struct code c, struct list* where)
87 struct code* p = xmalloc(sizeof(struct code));
90 list_add_last(where, &p->car);
92 list_add_last(&input_code, &p->car);
96 new_3par_instr(int opcode, int left, int right, int pref_var,
103 ins.u.tpop.r = right;
105 ins.u.tpop.res = pref_var;
107 ins.u.tpop.res = current_varcode++;;
108 new_instr(ins, where);
109 return ins.u.tpop.res;
112 /* return number of variable where lies result
113 * pref_var < 0 => no preference
116 evaluate(struct tree* t, int pref_var, struct list* where)
118 if (t->st == ST_LEAF) {
122 left = evaluate(t->pt.op.left, -1, where);
123 right = evaluate(t->pt.op.right, -1, where);
124 switch (t->pt.op.op) {
126 return new_3par_instr(OPC_CAT, left,
127 right, pref_var, where);
130 return new_3par_instr(OPC_PLUS, left,
131 right, pref_var, where);
134 return new_3par_instr(OPC_MINUS, left,
135 right, pref_var, where);
138 return new_3par_instr(OPC_MUL, left,
139 right, pref_var, where);
142 return new_3par_instr(OPC_DIV, left,
143 right, pref_var, where);
146 die("evaluate: Never can get here :)");
150 do_ass(struct tree* t, struct list* where)
154 var_l = t->pt.ass.left->pt.leaf.n;
155 var_r = evaluate(t->pt.ass.right, -1, where);
157 ins.opcode = OPC_SET;
160 new_instr(ins, where);
165 eval_cond(struct tree *t, int pref_var, struct list* where)
168 if (t->pt.cond.type == JUST_BOOL) {
169 if (t->pt.cond.left->st == ST_LEAF)
170 return t->pt.cond.left->pt.leaf.n;
171 if (t->pt.cond.left->st == ST_OP)
172 return evaluate(t->pt.cond.left, -1, where);
174 die("eval_cond: %d cannot be JUST_BOOL\n",
175 t->pt.cond.left->st);
177 if (t->pt.cond.type == OP_REL) {
178 left = evaluate(t->pt.cond.left, -1, where);
179 right = evaluate(t->pt.cond.right, -1, where);
181 switch (t->pt.cond.op) {
183 return new_3par_instr (OPC_GT, left,
184 right, pref_var, where);
187 return new_3par_instr (OPC_LT, left,
188 right, pref_var, where);
191 return new_3par_instr (OPC_LE, left,
192 right, pref_var, where);
195 return new_3par_instr (OPC_GE, left,
196 right, pref_var, where);
199 return new_3par_instr (OPC_NRE, left,
200 right, pref_var, where);
203 return new_3par_instr (OPC_RE, left,
204 right, pref_var, where);
207 return new_3par_instr (OPC_EQ, left,
208 right, pref_var, where);
211 return new_3par_instr (OPC_NEQ, left,
212 right, pref_var, where);
214 /* fixme: do more of them */
216 die("eval_cond: unknown relation op %c\n",
221 if (t->pt.cond.type == OP_BOOL) {
224 left = eval_cond(t->pt.cond.left, -1, where);
225 if (t->pt.cond.op != '!') /* ! is unary */
226 right = eval_cond(t->pt.cond.right, -1, where);
227 switch (t->pt.cond.op) {
229 return new_3par_instr (OPC_AND, left,
230 right, pref_var, where);
233 return new_3par_instr (OPC_OR, left,
234 right, pref_var, where);
237 return new_3par_instr (OPC_XOR, left,
238 right, pref_var, where);
241 ins.opcode = OPC_NOT;
242 ins.u.dpop.par = left;
244 ins.u.dpop.res = pref_var;
246 ins.u.dpop.res = current_varcode++;;
247 new_instr(ins, where);
248 return ins.u.dpop.res;
251 die("eval_cond: unknown boolean op %c\n",
256 die("eval_cond: unknown condition type");
260 do_if(struct tree *t, struct list* where)
263 struct code ins, nop, jmp;
264 struct list* if_branch = xmalloc(sizeof(struct list));
265 struct list* else_branch = xmalloc(sizeof(struct list));
267 list_init(if_branch);
268 list_init(else_branch);
269 nop.opcode = OPC_NOP;
270 jmp.opcode = OPC_JUMP;
272 c = eval_cond(t->pt.tif.c, -1, where);
274 compile(t->pt.tif.i, if_branch);
275 compile(t->pt.tif.i, else_branch);
276 new_instr(nop, if_branch);
277 new_instr(nop, else_branch);
278 jmp.u.jump.target = list_last(else_branch);
279 new_instr(jmp, if_branch);
281 ins.opcode = OPC_JUMP_UNLESS;
282 ins.u.jump_unless.cond = c;
283 ins.u.jump_unless.target = list_last(if_branch);
284 new_instr(ins, where);
285 list_cat(where, if_branch);
286 list_cat(where, else_branch);
293 do_arrow(struct tree* t, struct list* where)
299 if (t->pt.arrow.left == K_COPY)
300 ins.u.arrow.copy = 1;
302 ins.u.arrow.copy = 0;
303 switch (t->pt.arrow.right) {
305 ins.opcode = OPC_DELIVER;
308 ins.opcode = OPC_PIPE;
311 ins.opcode = OPC_MAIL;
314 ins.opcode = OPC_DISCARD;
317 ins.opcode = OPC_FILTER;
320 die("do_arrow: This cannot happen ;-)");
323 if (t->pt.arrow.right != K_DISCARD) {
324 v = evaluate(t->pt.arrow.s, -1, where);
325 ins.u.arrow.what = v;
328 new_instr(ins, where);
332 reset_temp_var_count(void)
334 if (current_varcode > max_varcode)
335 max_varcode = current_varcode;
336 current_varcode = temp_varcode_start;
340 compile(struct tree* t, struct list* where)
349 reset_temp_var_count();
350 compile(t->pt.block.head, where);
351 compile(t->pt.block.tail, where);
355 case ST_LEAF: //warn?
361 evaluate(t, -1, where); //emit warning?
367 eval_cond(t, -1, where); // warn?
372 die("compile: got to default, type: %d", t->st);
381 LIST_FOREACH(p, &input_code) {
384 printf("SET %d %d\n", p->u.set.l, p->u.set.r);
387 printf("CAT %d %d %d\n", p->u.tpop.l,
388 p->u.tpop.r, p->u.tpop.res);
391 printf("JUMP %d\n", (int) p->u.jump.target);
393 case OPC_JUMP_UNLESS:
394 printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target);
397 printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
400 printf("LT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
403 printf("LE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
406 printf("GE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
409 printf("RE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
412 printf("NRE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
415 printf("NEQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
418 printf("EQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
421 printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
424 printf("OR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
427 printf("XOR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
430 printf("PLUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
433 printf("MINUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
436 printf("MUL %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
439 printf("DIV %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
442 printf("NOT %d %d\n", p->u.dpop.par, p->u.dpop.res);
448 printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
451 printf("FILTER %d %d\n", p->u.arrow.what, p->u.arrow.copy);
454 printf("DELIVER %d %d\n", p->u.arrow.what, p->u.arrow.copy);
457 printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);
463 printf("not implemented, opcode: %d\n",