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);
83 /* return number of variable where lies result
84 * pref_var < 0 => no preference
87 evaluate(struct tree* t, int pref_var, struct list* where)
91 if (t->st == ST_LEAF) {
93 } else if (t->st == ST_OP) {
95 left = evaluate(t->pt.op.left, -1, where);
96 right = evaluate(t->pt.op.right, -1, where);
97 switch (t->pt.op.op) {
103 ins.u.cat.res = pref_var;
105 ins.u.cat.res = current_varcode++;;
106 new_instr(ins, where);
107 return ins.u.cat.res;
110 die("evaluate: got to default");
113 die("evaluate: I can evaluate only expressions but I got %d",
118 do_ass(struct tree* t, struct list* where)
122 var_l = t->pt.ass.left->pt.leaf.n;
123 var_r = evaluate(t->pt.ass.right, -1, where);
128 new_instr(ins, where);
133 eval_cond(struct tree *t, int pref_var, struct list* where)
137 if (t->pt.cond.type == JUST_BOOL) {
138 if (t->pt.cond.left->st == ST_LEAF)
139 return t->pt.cond.left->pt.leaf.n;
140 if (t->pt.cond.left->st == ST_OP)
141 return evaluate(t->pt.cond.left, -1, where);
143 die("eval_cond: %d cannot be JUST_BOOL\n",
144 t->pt.cond.left->st);
146 if (t->pt.cond.type == OP_REL) {
147 left = evaluate(t->pt.cond.left, -1, where);
148 right = evaluate(t->pt.cond.right, -1, where);
150 switch (t->pt.cond.op) {
156 ins.u.gt.res = pref_var;
158 ins.u.gt.res = current_varcode++;;
159 new_instr(ins, where);
162 /* fixme: do more of them */
164 die("eval_cond: unknown relation op %c\n",
172 do_if(struct tree *t, struct list* where)
175 struct code ins, nop, jmp;
176 struct list* if_branch = xmalloc(sizeof(struct list));
177 struct list* else_branch = xmalloc(sizeof(struct list));
179 list_init(if_branch);
180 list_init(else_branch);
184 c = eval_cond(t->pt.tif.c, -1, where);
186 compile(t->pt.tif.i, if_branch);
187 compile(t->pt.tif.i, else_branch);
188 new_instr(nop, if_branch);
189 new_instr(nop, else_branch);
190 jmp.u.jump.target = list_last(else_branch);
191 new_instr(jmp, if_branch);
193 ins.opcode = JUMP_UNLESS;
194 ins.u.jump_unless.cond = c;
195 ins.u.jump_unless.target = list_last(if_branch);
196 new_instr(ins, where);
197 list_cat(where, if_branch);
198 list_cat(where, else_branch);
205 reset_temp_var_count(void)
207 current_varcode = temp_varcode_start;
211 compile(struct tree* t, struct list* where)
220 reset_temp_var_count();
221 compile(t->pt.block.head, where);
222 compile(t->pt.block.tail, where);
230 evaluate(t, -1, where); //emit warning?
236 eval_cond(t, -1, where); // warn?
238 die("compile: got to default");
247 LIST_FOREACH(p, &input_code) {
250 printf("SET %d %d\n", p->u.set.l, p->u.set.r);
253 printf("CAT %d %d %d\n", p->u.cat.l,
254 p->u.cat.r, p->u.cat.res);
257 printf("JUMP %d\n", (int) p->u.jump.target);
260 printf("JUMP_UNLESS %d %d\n", p->u.jump_unless.cond,(int) p->u.jump_unless.target);
263 printf("GT %d %d %d\n", p->u.gt.l, p->u.gt.r, p->u.gt.res);
269 printf("not implemented, opcode: %d\n",