5 #include "symbol_table.h"
11 /* TODO failed test case: func f(a) if not (a=0 or a=1) then return 0; end; end; */
15 %token FUNC END STRUCT VAR IF THEN ELSE WHILE DO RETURN OR NOT
16 %token ID NUM ASSIGN GREATER
18 @autoinh symbols stack_offset all_pars if_in jump_true jump_false
19 @autosyn node defined_vars immediate if_out
21 @attributes { char *name; } ID
22 @attributes { long value; } NUM
23 @attributes { struct symbol_t *fields; struct symbol_t *symbols; int if_in; } Program
24 @attributes { struct symbol_t *fields; } Structdef
25 @attributes { struct symbol_t *fields; int offset; } Ids
26 @attributes { struct symbol_t *pars; int num_pars; int all_pars; } Pars
27 @attributes { struct symbol_t *symbols; int defined_vars; int if_in; int if_out; } Funcdef
28 @attributes { struct symbol_t *symbols; int defined_vars; int stack_offset; treenode *node; int if_in; int if_out; } Stats
29 @attributes { struct symbol_t *symbols; treenode *node; int immediate; } Expr Term Plusterm Malterm
30 @attributes { struct symbol_t *symbols; treenode *node; } Call Lexpr Field Exprs
31 @attributes { struct symbol_t *symbols; treenode *node; char *jump_true; char *jump_false; int negated; int if_in; int if_out; int negated2; int top_level; } Bool Orterm Subbool Bterm
32 @attributes { struct symbol_t *in_symbols; struct symbol_t *out_symbols; treenode *node; int defined_vars; int stack_offset; int if_in; int if_out; } Stat
33 @attributes { struct symbol_t *symbols; treenode *node; int defined_vars; int stack_offset; int if_in; int if_out; int if_nr; } Blubb
35 @traversal @postorder check
36 @traversal @preorder reg
37 @traversal @preorder codegen
43 @i @Program.symbols@ = @Program.fields@;
44 @i @Program.if_in@ = 0;
46 @codegen printf("\t.text\n");
51 Program: Funcdef ';' Program
53 @i @Program.fields@ = @Program.1.fields@;
54 @i @Program.1.if_in@ = @Funcdef.if_out@;
57 | Structdef ';' Program
59 @i @Program.fields@ = table_merge(@Structdef.fields@, @Program.1.fields@, 1);
60 @i @Program.1.symbols@ = @Program.0.symbols@;
64 @{ @i @Program.fields@ = new_table(); @}
68 Funcdef: FUNC ID '(' Pars ')' Stats END
70 @i @Stats.symbols@ = table_merge(@Funcdef.symbols@, @Pars.pars@, 0);
71 @i @Stats.stack_offset@ = 0;
72 @i @Pars.all_pars@ = @Pars.num_pars@;
74 @codegen function_header(@ID.name@, @Funcdef.defined_vars@);
77 | FUNC ID '(' ')' Stats END
79 @i @Stats.symbols@ = table_merge(@Funcdef.symbols@, new_table(), 0);
80 @i @Stats.stack_offset@ = 0;
82 @codegen function_header(@ID.name@, @Funcdef.defined_vars@);
87 Structdef: STRUCT Ids END
89 @i @Structdef.fields@ = @Ids.fields@;
97 @i @Ids.fields@ = table_add_symbol(@Ids.1.fields@, @ID.name@, SYMBOL_TYPE_FIELD, 1, @Ids.offset@);
98 @i @Ids.1.offset@ = @Ids.offset@ + 1;
102 @{ @i @Ids.fields@ = new_table(); @}
108 @i @Pars.pars@ = table_add_param(@Pars.1.pars@, @ID.name@, @Pars.num_pars@);
109 @i @Pars.num_pars@ = @Pars.1.num_pars@ + 1;
114 @i @Pars.pars@ = table_add_param(new_table(), @ID.name@, 1);
115 @i @Pars.num_pars@ = 1;
120 Stats: Stat ';' Stats
122 @i @Stat.in_symbols@ = @Stats.symbols@;
123 @i @Stats.1.symbols@ = @Stat.out_symbols@;
124 @i @Stats.defined_vars@ = @Stat.defined_vars@ + @Stats.1.defined_vars@;
125 @i @Stats.1.stack_offset@ = @Stats.stack_offset@ + @Stat.defined_vars@ * 8;
126 @i @Stats.node@ = new_node(OP_Stats, @Stat.node@, @Stats.1.node@);
127 @i @Stat.if_in@ = @Stats.if_in@;
128 @i @Stats.1.if_in@ = @Stat.if_out@;
129 @i @Stats.if_out@ = @Stats.1.if_out@;
134 @i @Stats.node@ = new_leaf(OP_Empty); /* TODO */
135 @i @Stats.defined_vars@ = 0;
136 @i @Stats.if_out@ = @Stats.if_in@;
141 Stat: VAR ID ASSIGN Expr /* Nodes necessary for IF, DO, ... ? */
143 @i @Stat.out_symbols@ = table_add_symbol(clone_table(@Stat.in_symbols@), @ID.name@, SYMBOL_TYPE_VAR, 0, @Stat.stack_offset@);
144 @i @Expr.symbols@ = @Stat.in_symbols@;
145 @i @Stat.node@ = new_node(OP_Assign, new_named_leaf_value(OP_ID, @ID.name@, @Stat.stack_offset@, -1), @Expr.node@);
146 @i @Stat.defined_vars@ = 1;
147 @i @Stat.if_out@ = @Stat.if_in@;
149 @reg @Expr.node@->reg = get_next_reg((char *)NULL, 0); @Stat.node@->reg = @Expr.node@->reg;
151 @codegen /* write_tree(@Stat.node@, 0); */ burm_label(@Stat.node@); burm_reduce(@Stat.node@, 1);
156 @i @Stat.out_symbols@ = @Stat.in_symbols@;
157 @i @Lexpr.symbols@ = @Stat.in_symbols@;
158 @i @Expr.symbols@ = @Stat.in_symbols@;
159 @i @Stat.node@ = new_node(OP_Assign, @Lexpr.node@, @Expr.node@);
160 @i @Stat.defined_vars@ = 0;
161 @i @Stat.if_out@ = @Stat.if_in@;
163 @reg @Lexpr.node@->reg = get_next_reg((char *)NULL, 0); @Expr.node@->reg = get_next_reg(@Lexpr.node@->reg, 0); @Stat.node@->reg = @Expr.node@->reg;
165 @codegen /* write_tree(@Stat.node@, 0); */ burm_label(@Stat.node@); burm_reduce(@Stat.node@, 1);
168 | IF Bool THEN Stats END
170 @i @Bool.symbols@ = @Stat.in_symbols@;
171 @i @Stats.symbols@ = @Stat.in_symbols@;
172 @i @Stat.out_symbols@ = @Stat.in_symbols@;
173 @i @Stat.node@ = new_node(OP_If, @Bool.node@, @Stats.node@);
174 @i @Bool.if_in@ = @Stat.if_in@ + 1;
175 @i @Stats.if_in@ = @Bool.if_out@;
176 @i @Stat.if_out@ = @Stats.if_out@;
177 @e Bool.jump_true : Stats.if_in; @Bool.jump_true@ = malloc(100); sprintf(@Bool.jump_true@, "if_then%i", @Stats.if_in@);
178 @e Bool.jump_false : Stats.if_in; @Bool.jump_false@ = malloc(100); sprintf(@Bool.jump_false@, "if_end%i", @Stats.if_in@);
180 @reg @Bool.node@->reg = get_next_reg((char *)NULL, 0);
182 @codegen /* write_tree(@Bool.node@, 0); burm_label(@Bool.node@); burm_reduce(@Bool.node@, 1); printf("\ttest %s1, %%%s\n\tjz if_end%i\n", imm_prefix, @Bool.node@->reg, @Stats.if_in@); */
183 @codegen @revorder(1) printf("if_end%i:\n", @Stats.if_in@);
186 | IF Bool THEN Stats Blubb END
188 @i @Bool.symbols@ = @Stat.in_symbols@;
189 @i @Blubb.symbols@ = @Stat.in_symbols@;
190 @i @Stat.out_symbols@ = @Stat.in_symbols@;
191 @i @Stats.symbols@ = @Stat.in_symbols@;
192 @i @Stat.node@ = new_node(OP_Ifstats, @Stats.node@, @Blubb.node@);
193 @i @Stat.defined_vars@ = @Stats.defined_vars@ + @Blubb.defined_vars@;
194 @i @Bool.if_in@ = @Stat.if_in@ + 1;
195 @i @Stats.if_in@ = @Bool.if_out@;
196 @i @Blubb.if_in@ = @Stats.if_out@;
197 @i @Stat.if_out@ = @Blubb.if_out@;
198 @i @Blubb.if_nr@ = @Stats.if_in@;
199 @e Bool.jump_true : Stats.if_in; @Bool.jump_true@ = malloc(100); sprintf(@Bool.jump_true@, "if_then%i", @Stats.if_in@);
200 @e Bool.jump_false : Stats.if_in; @Bool.jump_false@ = malloc(100); sprintf(@Bool.jump_false@, "if_else%i", @Stats.if_in@);
202 @reg @Bool.node@->reg = get_next_reg((char *)NULL, 0);
204 @codegen /* write_tree(@Bool.node@, 0); burm_label(@Bool.node@); burm_reduce(@Bool.node@, 1); printf("\ttest %s1, %%%s\n\tjz if_else%i\n", imm_prefix, @Bool.node@->reg, @Stats.if_in@); */
205 @codegen @revorder(1) printf("if_end%i:\n", @Stats.if_in@);
208 | WHILE Bool DO Stats END
210 @i @Bool.symbols@ = @Stat.in_symbols@;
211 @i @Stats.symbols@ = @Stat.in_symbols@;
212 @i @Stat.out_symbols@ = @Stat.in_symbols@;
213 @i @Stat.node@ = new_node(OP_While, @Bool.node@, @Stats.node@);
214 @i @Bool.if_in@ = @Stat.if_in@ + 1;
215 @i @Stats.if_in@ = @Bool.if_out@;
216 @i @Stat.if_out@ = @Stats.if_out@;
217 @e Bool.jump_true : Stats.if_in; @Bool.jump_true@ = malloc(100); sprintf(@Bool.jump_true@, "do_enter%i", @Stats.if_in@);
218 @e Bool.jump_false : Stats.if_in; @Bool.jump_false@ = malloc(100); sprintf(@Bool.jump_false@, "do_end%i", @Stats.if_in@);
220 @reg @Bool.node@->reg = get_next_reg((char *)NULL, 0);
222 @codegen printf("do_start%i:\n", @Stats.if_in@); /* write_tree(@Bool.node@, 0); burm_label(@Bool.node@); burm_reduce(@Bool.node@, 1); printf("\ttest %s1, %%%s\n\tjz do_end%i\n", imm_prefix, @Bool.node@->reg, @Stats.if_in@); */
223 @codegen @revorder(1) printf("\tjmp do_start%i\ndo_end%i:\n", @Stats.if_in@, @Stats.if_in@);
228 @i @Call.symbols@ = @Stat.in_symbols@;
229 @i @Stat.out_symbols@ = @Stat.in_symbols@;
230 @i @Stat.node@ = (treenode *)NULL;
231 @i @Stat.defined_vars@ = 0;
232 @i @Stat.if_out@ = @Stat.if_in@;
237 @i @Expr.symbols@ = @Stat.in_symbols@;
238 @i @Stat.out_symbols@ = @Stat.in_symbols@;
239 @i @Stat.node@ = new_node(OP_Return, @Expr.node@, (treenode *)NULL);
240 @i @Stat.defined_vars@ = 0;
241 @i @Stat.if_out@ = @Stat.if_in@;
243 @reg @Stat.node@->reg = get_next_reg((char *)NULL, 0); @Expr.node@->reg = @Stat.node@->reg;
245 @codegen /* write_tree(@Stat.node@, 0); */ burm_label(@Stat.node@); burm_reduce(@Stat.node@, 1);
252 @codegen printf("\tjmp if_end%i\nif_else%i:\n", @Blubb.if_nr@, @Blubb.if_nr@);
257 @i @Lexpr.node@ = new_named_leaf_value(OP_ID, @ID.name@, (table_lookup(@Lexpr.symbols@, @ID.name@)==NULL) ? 0 : table_lookup(@Lexpr.symbols@, @ID.name@)->stack_offset, (table_lookup(@Lexpr.symbols@, @ID.name@)==NULL) ? 0 : table_lookup(@Lexpr.symbols@, @ID.name@)->param_index);
259 @check check_variable(@Lexpr.symbols@, @ID.name@);
267 @i @Expr.node@ = new_node(OP_Negation, @Term.node@, (treenode *)NULL);
269 @reg @Term.node@->reg = @Expr.node@->reg;
273 @{ @reg @Term.node@->reg = @Expr.node@->reg; @}
277 @i @Expr.node@ = new_node(OP_Addition, @Plusterm.node@, @Term.node@);
278 @i @Expr.immediate@ = @Term.immediate@ && @Plusterm.immediate@;
280 @reg if(!@Plusterm.immediate@) { @Plusterm.node@->reg = @Expr.node@->reg; @Term.node@->reg = get_next_reg(@Plusterm.node@->reg, @Expr.node@->skip_reg); @Plusterm.node@->skip_reg = 1; } else { @Term.node@->reg = @Expr.node@->reg; @Plusterm.node@->reg = get_next_reg(@Term.node@->reg, @Expr.node@->skip_reg); }
285 @i @Expr.node@ = new_node(OP_Multiplication, @Malterm.node@, @Term.node@);
286 @i @Expr.immediate@ = @Term.immediate@ && @Malterm.immediate@;
288 @reg if(!@Malterm.immediate@) { @Malterm.node@->reg = @Expr.node@->reg; @Term.node@->reg = get_next_reg(@Malterm.node@->reg, @Expr.node@->skip_reg); @Malterm.node@->skip_reg = 1; } else { @Term.node@-> reg = @Expr.node@->reg; @Malterm.node@->reg = get_next_reg(@Term.node@->reg, @Expr.node@->skip_reg); }
293 Plusterm: '+' Term Plusterm
295 @i @Plusterm.node@ = new_node(OP_Addition, @Plusterm.1.node@, @Term.node@);
296 @i @Plusterm.immediate@ = @Term.immediate@ && @Plusterm.1.immediate@;
298 @reg @Plusterm.1.node@->reg = @Plusterm.node@->reg; @Term.node@->reg = get_next_reg(@Plusterm.1.node@->reg, @Plusterm.node@->skip_reg);
302 @{ @reg @Term.node@->reg = @Plusterm.node@->reg; @}
306 Malterm: '*' Term Malterm
308 @i @Malterm.node@ = new_node(OP_Multiplication, @Malterm.1.node@, @Term.node@);
309 @i @Malterm.immediate@ = @Term.immediate@ && @Malterm.1.immediate@;
311 @reg @Malterm.1.node@->reg = @Malterm.node@->reg; @Term.node@->reg = get_next_reg(@Malterm.1.node@->reg, @Malterm.node@->skip_reg);
315 @{ @reg @Term.node@->reg = @Malterm.node@->reg; @}
320 @{ @reg @Expr.node@->reg = @Term.node@->reg; @}
324 @i @Term.node@ = new_named_leaf_value(OP_ID, @ID.name@, (table_lookup(@Term.symbols@, @ID.name@)==NULL) ? 0 : table_lookup(@Term.symbols@, @ID.name@)->stack_offset, (table_lookup(@Term.symbols@, @ID.name@)==NULL) ? 0 : table_lookup(@Term.symbols@, @ID.name@)->param_index);
325 @i @Term.immediate@ = 0;
327 @check check_variable(@Term.symbols@, @ID.name@);
332 @i @Term.node@ = new_number_leaf(@NUM.value@);
333 @i @Term.immediate@ = 1;
337 @{ @i @Term.immediate@ = 0; @}
341 @i @Term.immediate@ = 0;
343 @reg @Field.node@->reg = @Term.node@->reg;
348 /* TODO replace by Bool -> Subbool */
351 @i @Bool.negated@ = 0;
352 @i @Bool.negated2@ = 0;
353 @i @Bterm.negated@ = 0;
354 @i @Bterm.negated2@ = 0;
355 @i @Bool.top_level@ = 1;
356 @i @Bterm.top_level@ = 1;
358 @codegen @revorder(1) if(@Bterm.node@->op!=OP_Disjunction) { printf("\tjmp %s # foo1\n", @Bool.jump_false@); } printf("%s:\n", @Bool.jump_true@); /* printf("\tjmp %s\n%s:\n", @Bool.jump_false@, @Bool.jump_true@); */
363 @i @Bool.node@ = new_node(OP_Disjunction, @Bterm.node@, @Orterm.node@);
364 @i @Bool.negated@ = 0;
365 @i @Bool.negated2@ = 0;
366 @i @Bterm.negated@ = 0;
367 @i @Orterm.negated@ = 0;
368 @i @Bterm.negated2@ = 0;
369 @i @Orterm.negated2@ = 0;
370 @e Bterm.jump_true : Bool.negated Bool.jump_true Bool.if_in; if(!@Bool.negated@) { @Bterm.jump_true@ = malloc(100); sprintf(@Bterm.jump_true@, "bool_true%i", @Bool.if_in@); } else { @Bterm.jump_true@ = @Bool.jump_true@; }
371 @i @Orterm.jump_true@ = @Bterm.jump_true@;
372 @e Bterm.jump_false : Bool.negated Bool.jump_false Bool.if_in; if(@Bool.negated@) { @Bterm.jump_false@ = malloc(100); sprintf(@Bterm.jump_false@, "bool_false%i", @Bool.if_in@); } else { @Bterm.jump_false@ = @Bool.jump_false@; }
373 @i @Orterm.jump_false@ = @Bterm.jump_false@;
374 @i @Bterm.if_in@ = @Bool.if_in@ + 1;
375 @i @Orterm.if_in@ = @Bterm.if_out@;
376 @i @Bool.if_out@ = @Orterm.if_out@;
377 @i @Bterm.top_level@ = 0;
378 @i @Orterm.top_level@ = 0;
379 @i @Bool.top_level@ = 1;
381 @reg @Bterm.node@->reg = @Bool.node@->reg; @Orterm.node@->reg = @Bool.node@->reg;
383 @codegen @revorder(1) printf("\tjmp %s # foo2\n", @Bool.jump_false@); printf(@Bool.negated@ ? "bool_false%i:\n" : "bool_true%i:\n", @Bool.if_in@); printf("%s:\n", @Bool.jump_true@); /* printf("\tjmp %s\n%s:\n", @Bool.jump_false@, @Bool.jump_true@); */
388 @i @Bool.node@ = new_node(OP_Not, @Bterm.node@, (treenode *)NULL);
389 @i @Bterm.jump_true@ = @Bool.jump_true@;
390 @i @Bool.negated@ = 0;
391 @i @Bool.negated2@ = 0;
392 @i @Bterm.negated@ = 1;
393 @i @Bterm.negated2@ = 1;
394 @i @Bterm.top_level@ = 0;
395 @i @Bool.top_level@ = 1;
397 @reg @Bterm.node@-> reg = @Bool.node@->reg;
399 @codegen @revorder(1) if(@Bterm.node@->op!=OP_Not) { printf("\tjmp %s # foo3\n", @Bool.jump_false@); } printf("%s:\n", @Bool.jump_true@); /* printf("\tjmp %s\nnot_break%i:\n\tjmp %s\n%s:\n", @Bool.jump_true@, 0, @Bool.jump_false@, @Bool.jump_true@); */
406 @i @Bterm.negated@ = @Subbool.negated@;
407 @i @Bterm.negated2@ = @Subbool.negated2@;
408 @i @Bterm.top_level@ = @Subbool.top_level@;
409 @codegen @revorder(1) /* printf("\tjmp %s\n%s:\n", @Subbool.jump_false@, @Subbool.jump_true@); */
414 @i @Subbool.node@ = new_node(OP_Disjunction, @Bterm.node@, @Orterm.node@);
415 @i @Bterm.negated@ = @Subbool.negated@;
416 @i @Orterm.negated@ = @Subbool.negated@;
417 @i @Bterm.negated2@ = 0;
418 @i @Orterm.negated2@ = 0;
419 @e Bterm.jump_true : Subbool.negated Subbool.negated2 Subbool.jump_true Subbool.if_in; if(!@Subbool.negated@ && @Subbool.negated2@) { @Bterm.jump_true@ = malloc(100); sprintf(@Bterm.jump_true@, "bool_true%i", @Subbool.if_in@); } else { @Bterm.jump_true@ = @Subbool.jump_true@; }
420 @i @Orterm.jump_true@ = @Bterm.jump_true@;
421 @e Bterm.jump_false : Subbool.negated Subbool.negated2 Subbool.jump_false Subbool.if_in; if(@Subbool.negated@ && @Subbool.negated2@) { @Bterm.jump_false@ = malloc(100); sprintf(@Bterm.jump_false@, "bool_false%i", @Subbool.if_in@); } else { @Bterm.jump_false@ = @Subbool.jump_false@; }
422 @i @Orterm.jump_false@ = @Bterm.jump_false@;
423 @i @Bterm.if_in@ = @Subbool.if_in@ + 1;
424 @i @Orterm.if_in@ = @Bterm.if_out@;
425 @i @Subbool.if_out@ = @Orterm.if_out@;
426 @i @Bterm.top_level@ = 0;
427 @i @Orterm.top_level@ = 0;
428 @reg @Bterm.node@->reg = @Subbool.node@->reg; @Orterm.node@->reg = @Subbool.node@->reg;
430 @codegen @revorder(1) /* TODO output if on top level */ if(@Subbool.negated2@ || @Subbool.top_level@) { printf("\tjmp %s # foo4\n", @Subbool.negated2@ ? @Subbool.jump_true@ : @Subbool.jump_false@); } printf(!@Subbool.negated@ ? "bool_true%i:\n" : "bool_false%i:\n", @Subbool.if_in@); /* printf("\tjmp %s\n# %s:\n", @Subbool.jump_true@, @Subbool.jump_true@); */
435 @i @Subbool.node@ = new_node(OP_Not, @Bterm.node@, (treenode *)NULL);
436 @i @Bterm.jump_true@ = @Subbool.jump_true@;
437 @i @Bterm.negated@ = 1 - @Subbool.negated@;
438 @i @Bterm.negated2@ = 1 - @Subbool.negated2@;
439 @i @Bterm.top_level@ = 0;
441 @reg @Bterm.node@-> reg = @Subbool.node@->reg; /* printf("%s, %s\n", @Bterm.jump_true@, @Subbool.jump_false@); */
443 @codegen @revorder(1) printf("# !!\n"); if(@Subbool.negated2@ || @Subbool.top_level@) { printf("\tjmp %s # foo9\n", @Subbool.negated2@ ? @Subbool.jump_false@ : @Subbool.jump_false@); } /* printf("\tjmp %s\nnot_break%i:\n", @Subbool.negated@ ? @Bterm.jump_true@ : @Subbool.jump_false@, 0); printf("\tjmp %s\n%s:\n", @Subbool.jump_false@, @Subbool.jump_true@); */
449 Orterm: OR Bterm Orterm
451 @i @Orterm.node@ = new_node(OP_Disjunction, @Bterm.node@, @Orterm.1.node@);
452 @i @Bterm.negated@ = @Orterm.negated@;
453 @i @Orterm.1.negated@ = @Orterm.negated@;
454 @i @Bterm.negated2@ = 0;
455 @i @Orterm.1.negated2@ = 0;
456 @i @Orterm.1.if_in@ = @Bterm.if_out@;
457 @i @Orterm.if_out@ = @Orterm.1.if_out@;
458 @i @Bterm.top_level@ = 0;
459 @i @Orterm.1.top_level@ = 0;
461 @reg @Bterm.node@->reg = @Orterm.node@->reg; @Orterm.1.node@->reg = @Orterm.node@->reg;
466 @i @Bterm.negated@ = @Orterm.negated@;
467 @i @Bterm.negated2@ = @Orterm.negated2@;
468 @i @Bterm.top_level@ = 0;
473 Bterm: Term GREATER Term
475 @i @Bterm.node@ = new_node(OP_Greater, @Term.node@, @Term.1.node@);
476 @i @Bterm.if_out@ = @Bterm.if_in@;
478 @reg @Term.node@->reg = @Bterm.node@->reg; @Term.1.node@->reg = get_next_reg(@Bterm.node@->reg, 0);
480 @codegen /* write_tree(@Term.node@, 0); */ burm_label(@Term.node@); burm_reduce(@Term.node@, 1); /* write_tree(@Term.1.node@, 0); */ burm_label(@Term.1.node@); burm_reduce(@Term.1.node@, 1); printf(@Bterm.negated2@ ? "\tcmp %%%s, %%%s\n\tjs %s # %s %s %i %i\n" : "\tcmp %%%s, %%%s\n\tjns %s # %s %s %i %i\n", @Term.1.node@->reg, @Term.node@->reg, ((@Bterm.negated2@ ^ @Bterm.negated@)) ? @Bterm.jump_false@ : @Bterm.jump_true@, @Bterm.jump_true@, @Bterm.jump_false@, @Bterm.negated2@, @Bterm.negated@);
485 @i @Bterm.node@ = new_node(OP_Equal, @Term.node@, @Term.1.node@);
486 @i @Bterm.if_out@ = @Bterm.if_in@;
488 @reg @Term.node@->reg = @Bterm.node@->reg; @Term.1.node@->reg = get_next_reg(@Bterm.node@->reg, 0);
490 @codegen /* write_tree(@Term.node@, 0); */ burm_label(@Term.node@); burm_reduce(@Term.node@, 1); /* write_tree(@Term.1.node@, 0); */ burm_label(@Term.1.node@); burm_reduce(@Term.1.node@, 1); printf(@Bterm.negated2@ ? "\tcmp %%%s, %%%s\n\tjnz %s # %s %s %i %i\n" : "\tcmp %%%s, %%%s\n\tjz %s # %s %s %i %i\n", @Term.node@->reg, @Term.1.node@->reg, ((@Bterm.negated2@ ^ @Bterm.negated@)) ? @Bterm.jump_false@ : @Bterm.jump_true@, @Bterm.jump_true@, @Bterm.jump_false@, @Bterm.negated2@, @Bterm.negated@);
495 @i @Subbool.negated@ = @Bterm.negated@;
496 @i @Subbool.negated2@ = @Bterm.negated2@;
497 @i @Subbool.top_level@ = @Bterm.top_level@;
504 @i @Field.node@ = new_node_value(OP_Field, @Term.node@, new_named_leaf(OP_ID, @ID.name@), table_lookup(@Field.symbols@, @ID.name@)==(struct symbol_t *)NULL ? 0 : table_lookup(@Field.symbols@, @ID.name@)->stack_offset, -1);
506 @check check_field(@Field.symbols@, @ID.name@);
508 @reg @Term.node@->reg = @Field.node@->reg; @Field.node@->kids[1]->reg = get_next_reg(@Field.node@->reg, 0);
513 Call: ID '(' Exprs ')'
514 @{ @i @Call.node@ = new_node(OP_Call, new_named_leaf(OP_ID, @ID.name@), @Exprs.node@); @}
517 @{ @i @Call.node@ = new_node(OP_Call, new_named_leaf(OP_ID, @ID.name@), NULL); @}
523 @{ @i @Exprs.node@ = new_node(OP_Exprs, @Exprs.1.node@, @Expr.node@); @}
532 int yyerror(char *error_text) {
533 fprintf(stderr,"Line %i: %s\n",yylineno, error_text);
537 int main(int argc, char **argv) {