17 res = xmalloc (HASHSIZE * sizeof(struct list));
18 for (i = 0; i < HASHSIZE; i++)
25 get_bucket_number(char* name)
28 unsigned char* p = name;
31 n = n * MAGIC + toupper(*p++);
38 /* if not found, variable with value "" is created */
40 find_var(char* name, struct list* hash)
45 n = get_bucket_number(name);
46 int nocase = isupper(*name);
47 LIST_FOREACH(p, hash + n)
48 if (!(nocase ? strcasecmp : strcmp)(p->name,name))
51 p = xmalloc(sizeof(struct variable));
52 p->name = xstrdup(name);
53 p->varcode = current_varcode++;
54 list_add_last(hash+n, &p->car);
62 if (cur_const_n >= cur_const_s) {
64 const_tab = xrealloc(const_tab, cur_const_s);
67 const_tab[cur_const_n] = c;
69 return -cur_const_n++;
73 new_instr(struct code c, struct list* where)
75 struct code* p = xmalloc(sizeof(struct code));
78 list_add_last(where, &p->car);
80 list_add_last(&input_code, &p->car);
84 new_3par_instr(int opcode, int left, int right, int pref_var,
93 ins.u.tpop.res = pref_var;
95 ins.u.tpop.res = current_varcode++;;
96 new_instr(ins, where);
97 return ins.u.tpop.res;
100 /* return number of variable where lies result
101 * pref_var < 0 => no preference
104 evaluate(struct tree* t, int pref_var, struct list* where)
106 if (t->st == ST_LEAF) {
108 } else if (t->st == ST_OP) {
110 left = evaluate(t->pt.op.left, -1, where);
111 right = evaluate(t->pt.op.right, -1, where);
112 switch (t->pt.op.op) {
114 return new_3par_instr(OPC_CAT, left,
115 right, pref_var, where);
118 return new_3par_instr(OPC_PLUS, left,
119 right, pref_var, where);
122 return new_3par_instr(OPC_MINUS, left,
123 right, pref_var, where);
126 return new_3par_instr(OPC_MUL, left,
127 right, pref_var, where);
130 return new_3par_instr(OPC_DIV, left,
131 right, pref_var, where);
134 die("evaluate: got to default");
137 die("evaluate: I can evaluate only expressions but I got %d",
142 do_ass(struct tree* t, struct list* where)
146 var_l = t->pt.ass.left->pt.leaf.n;
147 var_r = evaluate(t->pt.ass.right, -1, where);
149 ins.opcode = OPC_SET;
152 new_instr(ins, where);
157 eval_cond(struct tree *t, int pref_var, struct list* where)
160 if (t->pt.cond.type == JUST_BOOL) {
161 if (t->pt.cond.left->st == ST_LEAF)
162 return t->pt.cond.left->pt.leaf.n;
163 if (t->pt.cond.left->st == ST_OP)
164 return evaluate(t->pt.cond.left, -1, where);
166 die("eval_cond: %d cannot be JUST_BOOL\n",
167 t->pt.cond.left->st);
169 if (t->pt.cond.type == OP_REL) {
170 left = evaluate(t->pt.cond.left, -1, where);
171 right = evaluate(t->pt.cond.right, -1, where);
173 switch (t->pt.cond.op) {
175 return new_3par_instr (OPC_GT, left,
176 right, pref_var, where);
179 return new_3par_instr (OPC_LT, left,
180 right, pref_var, where);
183 return new_3par_instr (OPC_LE, left,
184 right, pref_var, where);
187 return new_3par_instr (OPC_GE, left,
188 right, pref_var, where);
191 return new_3par_instr (OPC_NRE, left,
192 right, pref_var, where);
195 return new_3par_instr (OPC_RE, left,
196 right, pref_var, where);
199 return new_3par_instr (OPC_EQ, left,
200 right, pref_var, where);
203 return new_3par_instr (OPC_NEQ, left,
204 right, pref_var, where);
206 /* fixme: do more of them */
208 die("eval_cond: unknown relation op %c\n",
213 if (t->pt.cond.type == OP_BOOL) {
216 left = eval_cond(t->pt.cond.left, -1, where);
217 if (t->pt.cond.op != '!') /* ! is unary */
218 right = eval_cond(t->pt.cond.right, -1, where);
219 switch (t->pt.cond.op) {
221 return new_3par_instr (OPC_AND, left,
222 right, pref_var, where);
225 return new_3par_instr (OPC_OR, left,
226 right, pref_var, where);
229 return new_3par_instr (OPC_XOR, left,
230 right, pref_var, where);
233 ins.opcode = OPC_NOT;
234 ins.u.dpop.par = left;
236 ins.u.dpop.res = pref_var;
238 ins.u.dpop.res = current_varcode++;;
239 new_instr(ins, where);
240 return ins.u.dpop.res;
243 die("eval_cond: unknown boolean op %c\n",
248 die("eval_cond: unknown condition type");
252 do_if(struct tree *t, struct list* where)
255 struct code ins, nop, jmp;
256 struct list* if_branch = xmalloc(sizeof(struct list));
257 struct list* else_branch = xmalloc(sizeof(struct list));
259 list_init(if_branch);
260 list_init(else_branch);
261 nop.opcode = OPC_NOP;
262 jmp.opcode = OPC_JUMP;
264 c = eval_cond(t->pt.tif.c, -1, where);
266 compile(t->pt.tif.i, if_branch);
267 compile(t->pt.tif.i, else_branch);
268 new_instr(nop, if_branch);
269 new_instr(nop, else_branch);
270 jmp.u.jump.target = list_last(else_branch);
271 new_instr(jmp, if_branch);
273 ins.opcode = OPC_JUMP_UNLESS;
274 ins.u.jump_unless.cond = c;
275 ins.u.jump_unless.target = list_last(if_branch);
276 new_instr(ins, where);
277 list_cat(where, if_branch);
278 list_cat(where, else_branch);
285 do_arrow(struct tree* t, struct list* where)
291 if (t->pt.arrow.left == K_COPY)
292 ins.u.arrow.copy = 1;
294 ins.u.arrow.copy = 0;
295 switch (t->pt.arrow.right) {
297 ins.opcode = OPC_STORE;
300 ins.opcode = OPC_PIPE;
303 ins.opcode = OPC_MAIL;
306 ins.opcode = OPC_DISCARD;
309 die("do_arrow: This cannot happen ;-)");
312 if (t->pt.arrow.right != K_DISCARD) {
313 v = evaluate(t->pt.arrow.s, -1, where);
314 ins.u.arrow.what = v;
317 new_instr(ins, where);
321 reset_temp_var_count(void)
323 current_varcode = temp_varcode_start;
327 compile(struct tree* t, struct list* where)
336 reset_temp_var_count();
337 compile(t->pt.block.head, where);
338 compile(t->pt.block.tail, where);
342 case ST_LEAF: //warn?
348 evaluate(t, -1, where); //emit warning?
354 eval_cond(t, -1, where); // warn?
359 die("compile: got to default, type: %d", t->st);
368 LIST_FOREACH(p, &input_code) {
371 printf("SET %d %d\n", p->u.set.l, p->u.set.r);
374 printf("CAT %d %d %d\n", p->u.tpop.l,
375 p->u.tpop.r, p->u.tpop.res);
378 printf("JUMP %d\n", (int) p->u.jump.target);
380 case OPC_JUMP_UNLESS:
381 printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target);
384 printf("GT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
387 printf("LT %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
390 printf("LE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
393 printf("GE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
396 printf("RE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
399 printf("NRE %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
402 printf("NEQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
405 printf("EQ %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
408 printf("AND %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
411 printf("OR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
414 printf("XOR %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
417 printf("PLUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
420 printf("MINUS %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
423 printf("MUL %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
426 printf("DIV %d %d %d\n", p->u.tpop.l, p->u.tpop.r, p->u.tpop.res);
429 printf("NOT %d %d\n", p->u.dpop.par, p->u.dpop.res);
435 printf("PIPE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
438 printf("STORE %d %d\n", p->u.arrow.what, p->u.arrow.copy);
441 printf("MAIL %d %d\n", p->u.arrow.what, p->u.arrow.copy);
447 printf("not implemented, opcode: %d\n",