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 /* if not found, variable with value "" is created */
37 find_var(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))
48 p = xmalloc(sizeof(struct variable));
49 p->name = xstrdup(name);
50 p->varcode = current_varcode++;
51 list_add_last(hash+n, &p->car);
59 if (cur_const_n >= cur_const_s) {
61 const_tab = xrealloc(const_tab, cur_const_s);
64 const_tab[cur_const_n] = c;
66 return -cur_const_n++;
70 new_instr(struct code c, struct list* where)
72 struct code* p = xmalloc(sizeof(struct code));
75 list_add_last(where, &p->car);
77 list_add_last(&input_code, &p->car);
81 new_3par_instr(int opcode, int left, int right, int pref_var,
90 ins.u.tpop.res = pref_var;
92 ins.u.tpop.res = current_varcode++;;
93 new_instr(ins, where);
94 return ins.u.tpop.res;
97 /* return number of variable where lies result
98 * pref_var < 0 => no preference
101 evaluate(struct tree* t, int pref_var, struct list* where)
103 if (t->st == ST_LEAF) {
105 } else if (t->st == ST_OP) {
107 left = evaluate(t->pt.op.left, -1, where);
108 right = evaluate(t->pt.op.right, -1, where);
109 switch (t->pt.op.op) {
111 return new_3par_instr(OPC_CAT, left,
112 right, pref_var, where);
115 return new_3par_instr(OPC_PLUS, left,
116 right, pref_var, where);
119 return new_3par_instr(OPC_MINUS, left,
120 right, pref_var, where);
123 return new_3par_instr(OPC_MUL, left,
124 right, pref_var, where);
127 return new_3par_instr(OPC_DIV, left,
128 right, pref_var, where);
131 die("evaluate: got to default");
134 die("evaluate: I can evaluate only expressions but I got %d",
139 do_ass(struct tree* t, struct list* where)
143 var_l = t->pt.ass.left->pt.leaf.n;
144 var_r = evaluate(t->pt.ass.right, -1, where);
146 ins.opcode = OPC_SET;
149 new_instr(ins, where);
154 eval_cond(struct tree *t, int pref_var, struct list* where)
157 if (t->pt.cond.type == JUST_BOOL) {
158 if (t->pt.cond.left->st == ST_LEAF)
159 return t->pt.cond.left->pt.leaf.n;
160 if (t->pt.cond.left->st == ST_OP)
161 return evaluate(t->pt.cond.left, -1, where);
163 die("eval_cond: %d cannot be JUST_BOOL\n",
164 t->pt.cond.left->st);
166 if (t->pt.cond.type == OP_REL) {
167 left = evaluate(t->pt.cond.left, -1, where);
168 right = evaluate(t->pt.cond.right, -1, where);
170 switch (t->pt.cond.op) {
172 return new_3par_instr (OPC_GT, left,
173 right, pref_var, where);
176 return new_3par_instr (OPC_LT, left,
177 right, pref_var, where);
180 return new_3par_instr (OPC_LE, left,
181 right, pref_var, where);
184 return new_3par_instr (OPC_GE, left,
185 right, pref_var, where);
188 return new_3par_instr (OPC_NRE, left,
189 right, pref_var, where);
192 return new_3par_instr (OPC_RE, left,
193 right, pref_var, where);
196 return new_3par_instr (OPC_EQ, left,
197 right, pref_var, where);
200 return new_3par_instr (OPC_NEQ, left,
201 right, pref_var, where);
203 /* fixme: do more of them */
205 die("eval_cond: unknown relation op %c\n",
210 if (t->pt.cond.type == OP_BOOL) {
213 left = eval_cond(t->pt.cond.left, -1, where);
214 if (t->pt.cond.op != '!') /* ! is unary */
215 right = eval_cond(t->pt.cond.right, -1, where);
216 switch (t->pt.cond.op) {
218 return new_3par_instr (OPC_AND, left,
219 right, pref_var, where);
222 return new_3par_instr (OPC_OR, left,
223 right, pref_var, where);
226 return new_3par_instr (OPC_XOR, left,
227 right, pref_var, where);
230 ins.opcode = OPC_NOT;
231 ins.u.dpop.par = left;
233 ins.u.dpop.res = pref_var;
235 ins.u.dpop.res = current_varcode++;;
236 new_instr(ins, where);
237 return ins.u.dpop.res;
240 die("eval_cond: unknown boolean op %c\n",
245 die("eval_cond: unknown condition type");
249 do_if(struct tree *t, struct list* where)
252 struct code ins, nop, jmp;
253 struct list* if_branch = xmalloc(sizeof(struct list));
254 struct list* else_branch = xmalloc(sizeof(struct list));
256 list_init(if_branch);
257 list_init(else_branch);
258 nop.opcode = OPC_NOP;
259 jmp.opcode = OPC_JUMP;
261 c = eval_cond(t->pt.tif.c, -1, where);
263 compile(t->pt.tif.i, if_branch);
264 compile(t->pt.tif.i, else_branch);
265 new_instr(nop, if_branch);
266 new_instr(nop, else_branch);
267 jmp.u.jump.target = list_last(else_branch);
268 new_instr(jmp, if_branch);
270 ins.opcode = OPC_JUMP_UNLESS;
271 ins.u.jump_unless.cond = c;
272 ins.u.jump_unless.target = list_last(if_branch);
273 new_instr(ins, where);
274 list_cat(where, if_branch);
275 list_cat(where, else_branch);
282 do_arrow(struct tree* t, struct list* where)
288 if (t->pt.arrow.left == K_COPY)
289 ins.u.arrow.copy = 1;
291 ins.u.arrow.copy = 0;
292 switch (t->pt.arrow.right) {
294 ins.opcode = OPC_DELIVER;
297 ins.opcode = OPC_PIPE;
300 ins.opcode = OPC_MAIL;
303 ins.opcode = OPC_DISCARD;
306 die("do_arrow: This cannot happen ;-)");
309 if (t->pt.arrow.right != K_DISCARD) {
310 v = evaluate(t->pt.arrow.s, -1, where);
311 ins.u.arrow.what = v;
314 new_instr(ins, where);
318 reset_temp_var_count(void)
320 current_varcode = temp_varcode_start;
324 compile(struct tree* t, struct list* where)
333 reset_temp_var_count();
334 compile(t->pt.block.head, where);
335 compile(t->pt.block.tail, where);
339 case ST_LEAF: //warn?
345 evaluate(t, -1, where); //emit warning?
351 eval_cond(t, -1, where); // warn?
356 die("compile: got to default, type: %d", t->st);
365 LIST_FOREACH(p, &input_code) {
368 printf("SET %d %d\n", p->u.set.l, p->u.set.r);
371 printf("CAT %d %d %d\n", p->u.tpop.l,
372 p->u.tpop.r, p->u.tpop.res);
375 printf("JUMP %d\n", (int) p->u.jump.target);
377 case OPC_JUMP_UNLESS:
378 printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target);
381 printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
384 printf("LT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
387 printf("LE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
390 printf("GE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
393 printf("RE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
396 printf("NRE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
399 printf("NEQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
402 printf("EQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
405 printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
408 printf("OR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
411 printf("XOR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
414 printf("PLUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
417 printf("MINUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
420 printf("MUL %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
423 printf("DIV %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
426 printf("NOT %d %d\n", p->u.dpop.par, p->u.dpop.res);
432 printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
435 printf("DELIVER %d %d\n", p->u.arrow.what, p->u.arrow.copy);
438 printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);
444 printf("not implemented, opcode: %d\n",