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) {
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: Never can get here :)");
135 do_ass(struct tree* t, struct list* where)
139 var_l = t->pt.ass.left->pt.leaf.n;
140 var_r = evaluate(t->pt.ass.right, -1, where);
142 ins.opcode = OPC_SET;
145 new_instr(ins, where);
150 eval_cond(struct tree *t, int pref_var, struct list* where)
153 if (t->pt.cond.type == JUST_BOOL) {
154 if (t->pt.cond.left->st == ST_LEAF)
155 return t->pt.cond.left->pt.leaf.n;
156 if (t->pt.cond.left->st == ST_OP)
157 return evaluate(t->pt.cond.left, -1, where);
159 die("eval_cond: %d cannot be JUST_BOOL\n",
160 t->pt.cond.left->st);
162 if (t->pt.cond.type == OP_REL) {
163 left = evaluate(t->pt.cond.left, -1, where);
164 right = evaluate(t->pt.cond.right, -1, where);
166 switch (t->pt.cond.op) {
168 return new_3par_instr (OPC_GT, left,
169 right, pref_var, where);
172 return new_3par_instr (OPC_LT, left,
173 right, pref_var, where);
176 return new_3par_instr (OPC_LE, left,
177 right, pref_var, where);
180 return new_3par_instr (OPC_GE, left,
181 right, pref_var, where);
184 return new_3par_instr (OPC_NRE, left,
185 right, pref_var, where);
188 return new_3par_instr (OPC_RE, left,
189 right, pref_var, where);
192 return new_3par_instr (OPC_EQ, left,
193 right, pref_var, where);
196 return new_3par_instr (OPC_NEQ, left,
197 right, pref_var, where);
199 /* fixme: do more of them */
201 die("eval_cond: unknown relation op %c\n",
206 if (t->pt.cond.type == OP_BOOL) {
209 left = eval_cond(t->pt.cond.left, -1, where);
210 if (t->pt.cond.op != '!') /* ! is unary */
211 right = eval_cond(t->pt.cond.right, -1, where);
212 switch (t->pt.cond.op) {
214 return new_3par_instr (OPC_AND, left,
215 right, pref_var, where);
218 return new_3par_instr (OPC_OR, left,
219 right, pref_var, where);
222 return new_3par_instr (OPC_XOR, left,
223 right, pref_var, where);
226 ins.opcode = OPC_NOT;
227 ins.u.dpop.par = left;
229 ins.u.dpop.res = pref_var;
231 ins.u.dpop.res = current_varcode++;;
232 new_instr(ins, where);
233 return ins.u.dpop.res;
236 die("eval_cond: unknown boolean op %c\n",
241 die("eval_cond: unknown condition type");
245 do_if(struct tree *t, struct list* where)
248 struct code ins, nop, jmp;
249 struct list* if_branch = xmalloc(sizeof(struct list));
250 struct list* else_branch = xmalloc(sizeof(struct list));
252 list_init(if_branch);
253 list_init(else_branch);
254 nop.opcode = OPC_NOP;
255 jmp.opcode = OPC_JUMP;
257 c = eval_cond(t->pt.tif.c, -1, where);
259 compile(t->pt.tif.i, if_branch);
260 compile(t->pt.tif.i, else_branch);
261 new_instr(nop, if_branch);
262 new_instr(nop, else_branch);
263 jmp.u.jump.target = list_last(else_branch);
264 new_instr(jmp, if_branch);
266 ins.opcode = OPC_JUMP_UNLESS;
267 ins.u.jump_unless.cond = c;
268 ins.u.jump_unless.target = list_last(if_branch);
269 new_instr(ins, where);
270 list_cat(where, if_branch);
271 list_cat(where, else_branch);
278 do_arrow(struct tree* t, struct list* where)
284 if (t->pt.arrow.left == K_COPY)
285 ins.u.arrow.copy = 1;
287 ins.u.arrow.copy = 0;
288 switch (t->pt.arrow.right) {
290 ins.opcode = OPC_DELIVER;
293 ins.opcode = OPC_PIPE;
296 ins.opcode = OPC_MAIL;
299 ins.opcode = OPC_DISCARD;
302 die("do_arrow: This cannot happen ;-)");
305 if (t->pt.arrow.right != K_DISCARD) {
306 v = evaluate(t->pt.arrow.s, -1, where);
307 ins.u.arrow.what = v;
310 new_instr(ins, where);
314 reset_temp_var_count(void)
316 current_varcode = temp_varcode_start;
320 compile(struct tree* t, struct list* where)
329 reset_temp_var_count();
330 compile(t->pt.block.head, where);
331 compile(t->pt.block.tail, where);
335 case ST_LEAF: //warn?
341 evaluate(t, -1, where); //emit warning?
347 eval_cond(t, -1, where); // warn?
352 die("compile: got to default, type: %d", t->st);
361 LIST_FOREACH(p, &input_code) {
364 printf("SET %d %d\n", p->u.set.l, p->u.set.r);
367 printf("CAT %d %d %d\n", p->u.tpop.l,
368 p->u.tpop.r, p->u.tpop.res);
371 printf("JUMP %d\n", (int) p->u.jump.target);
373 case OPC_JUMP_UNLESS:
374 printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target);
377 printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
380 printf("LT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
383 printf("LE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
386 printf("GE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
389 printf("RE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
392 printf("NRE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
395 printf("NEQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
398 printf("EQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
401 printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
404 printf("OR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
407 printf("XOR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
410 printf("PLUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
413 printf("MINUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
416 printf("MUL %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
419 printf("DIV %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
422 printf("NOT %d %d\n", p->u.dpop.par, p->u.dpop.res);
428 printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
431 printf("DELIVER %d %d\n", p->u.arrow.what, p->u.arrow.copy);
434 printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);
440 printf("not implemented, opcode: %d\n",