X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=codeb%2Fparser.y;h=39cc35dbe86ea521fc84c18bcccc679ba47ae200;hb=7b8df533cad8c9a84e4da9b60f26b5109daef638;hp=6c956447d4d44e7eddb93014a8957005c5a0b227;hpb=e8d204f6cc7958e2d9711aa34bb879261b663431;p=uebersetzerbau-ss10.git diff --git a/codeb/parser.y b/codeb/parser.y index 6c95644..39cc35d 100644 --- a/codeb/parser.y +++ b/codeb/parser.y @@ -23,6 +23,10 @@ * geht nicht, weil verschachtelte macros deaktiviert sind */ @end +@macro lblcountinout() + @i @Statement.lblcnt_out@ = @Statement.lblcnt_in@; +@end + /* beschreibung der attribute * s: symboltabelle * f: symboltabelle fuer quirks mit structur und parameter @@ -41,11 +45,12 @@ @attributes { struct symbol *f; } Program Structdef; @attributes { struct symbol *f; int offsetcount; } FeldID @attributes { struct symbol *s; } Methoddef -@attributes { struct symbol *s; int gparamges; } Statseq Exprs +@attributes { struct symbol *s; int gparamges; } Exprs +@attributes { struct symbol *s; int gparamges; int lblcnt_in; int lblcnt_out; } Statseq +@attributes { struct symbol *s; int gparamges; int lblcnt_in; int lblcnt_out; int reallblcnt; } Elsestat @attributes { struct symbol *s; int gparamges; struct treenode *node; short imm; } Expr Minusterm Multerm Orterm Feld Term @attributes { struct symbol *s; int gparamges; struct treenode *node; } Lexpr -@attributes { struct symbol *sin; int gparamges; struct symbol *sout; struct -treenode *node; int vars; } Statement +@attributes { struct symbol *sin; int gparamges; struct symbol *sout; struct treenode *node; int vars; int lblcnt_in; int lblcnt_out; } Statement @traversal @postorder c @traversal @preorder reg @@ -80,6 +85,7 @@ Methoddef: @i @Parms.parms@ = 1; @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0); @i @Statseq.gparamges@ = @Parms.paramges@; + @i @Statseq.lblcnt_in@ = 0; @gen func_header(@IDENT.name@); @} ; @@ -125,21 +131,34 @@ Statseq: Statement ';' Statseq @{ @i @Statement.sin@ = @Statseq.0.s@; + @i @Statement.lblcnt_in@ = @Statseq.0.lblcnt_in@; + @i @Statseq.1.s@ = @Statement.sout@; + @i @Statseq.1.lblcnt_in@ = @Statement.lblcnt_out@; @i @Statseq.1.gparamges@ = @Statseq.0.gparamges@ + @Statement.vars@; + + @i @Statseq.0.lblcnt_out@ = @Statseq.1.lblcnt_out@; @} | + @{ + @i @Statseq.0.lblcnt_out@ = @Statseq.0.lblcnt_in@; + @} ; Statement: Lexpr ASSIGN Expr @{ statinout() + lblcountinout() xxputsin(@Lexpr.s@,) xxputsin(@Expr.s@,) - @i @Statement.node@ = TREENULL; + @i @Statement.node@ = new_node(O_ASSIGN, @Expr.node@, @Lexpr.node@); @i @Statement.vars@ = 0; + @reg @Statement.node@->reg = @Expr.node@->reg = next_reg((char *)NULL, @Expr.gparamges@); + @reg @Lexpr.node@->reg = next_reg(@Expr.node@->reg, @Expr.gparamges@); + + @gen write_tree(@Statement.node@, 0); burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1); @} | VAR IDENT ASSIGN Expr @@ -147,10 +166,11 @@ Statement: /* tab_clone ist hier noetig, vgl. folgendes statement * > var x := x - 1; */ @i @Statement.sout@ = tab_add_symbol(tab_clone(@Statement.sin@), @IDENT.name@, S_VAR, 1, @Statement.gparamges@, -1); + lblcountinout() xxputsin(@Expr.s@,) - @i @Statement.vars@ = 1; - @i @Statement.node@ = new_node(O_ASSIGN, new_param(O_ID, @IDENT.name@, TREENULL, TREENULL, @Statement.gparamges@), @Expr.node@); + @i @Statement.node@ = new_node(O_ASSIGN, @Expr.node@, new_param(O_ID, @IDENT.name@, TREENULL, TREENULL, @Statement.gparamges@)); + @i @Statement.vars@ = 1; @reg @Statement.node@->reg = @Expr.node@->reg = next_reg((char *)NULL, @Expr.gparamges@); @gen write_tree(@Statement.node@, 0); burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1); @@ -159,6 +179,7 @@ Statement: | Expr @{ statinout() + lblcountinout() xxputsin(@Expr.s@,) @i @Statement.node@ = TREENULL; @i @Statement.vars@ = 0; @@ -167,35 +188,78 @@ Statement: | IF Expr THEN Statseq END @{ statinout() + @i @Statseq.lblcnt_in@ = @Statement.lblcnt_in@ + 1; + @i @Statement.lblcnt_out@ = @Statseq.lblcnt_out@; xxputsin(@Expr.s@,) xxputsin(@Statseq.s@,) - @i @Statement.node@ = TREENULL; + + @i @Statement.node@ = new_node(O_IF, @Expr.node@, TREENULL); @i @Statement.vars@ = 0; + + @reg @Statement.node@->reg = @Expr.node@->reg = next_reg((char *)NULL, @Expr.gparamges@); + @gen { + printf(".%s_ifstart_%d:\n", get_func_name(), @Statement.lblcnt_in@); + write_tree(@Statement.node@, 0); burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1); + /* TODO: kann ich mir das test wirklich wegan and davor sparen? */ + printf("\tjz .%s_ifend_%d\n", get_func_name(), @Statement.lblcnt_in@); + } + @gen @revorder(1) printf(".%s_ifend_%d:\n", get_func_name(), @Statement.lblcnt_in@); @} - | IF Expr THEN Statseq ELSE Statseq END + | IF Expr THEN Statseq Elsestat END @{ statinout() + @i @Statseq.0.lblcnt_in@ = @Statement.lblcnt_in@ + 1; + @i @Elsestat.lblcnt_in@ = @Statseq.lblcnt_out@; + @i @Statement.lblcnt_out@ = @Elsestat.lblcnt_out@; + + /* im Elsestat muss noch ein label numeriert werden */ + @i @Elsestat.reallblcnt@ = @Statement.lblcnt_in@; + xxputsin(@Expr.s@,) xxputsin(@Statseq.0.s@,) - xxputsin(@Statseq.1.s@,) - @i @Statement.node@ = TREENULL; + xxputsin(@Elsestat.s@,) + + @i @Statement.node@ = new_node(O_IF, @Expr.node@, TREENULL); @i @Statement.vars@ = 0; + + @reg @Statement.node@->reg = @Expr.node@->reg = next_reg((char *)NULL, @Expr.gparamges@); + @gen { + printf(".%s_ifstart_%d:\n", get_func_name(), @Statement.lblcnt_in@); + write_tree(@Statement.node@, 0); burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1); + /* TODO: kann ich mir das test wirklich wegan and davor sparen? */ + printf("\tjz .%s_ifelse_%d\n", get_func_name(), @Statement.lblcnt_in@); + } + @gen @revorder(1) printf(".%s_ifend_%d:\n", get_func_name(), @Statement.lblcnt_in@); @} | WHILE Expr DO Statseq END @{ statinout() + @i @Statseq.lblcnt_in@ = @Statement.lblcnt_in@ + 1; + @i @Statement.lblcnt_out@ = @Statseq.lblcnt_out@; xxputsin(@Expr.s@,) xxputsin(@Statseq.s@,) - @i @Statement.node@ = TREENULL; + + @i @Statement.node@ = new_node(O_IF, @Expr.node@, TREENULL); @i @Statement.vars@ = 0; + + @reg @Statement.node@->reg = @Expr.node@->reg = next_reg((char *)NULL, @Expr.gparamges@); + @gen { + printf(".%s_whilestart_%d:\n", get_func_name(), @Statement.lblcnt_in@); + write_tree(@Statement.node@, 0); burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1); + /* TODO: kann ich mir das test wirklich wegan and davor sparen? */ + printf("\tjz .%s_whileend_%d\n", get_func_name(), @Statement.lblcnt_in@); + } + @gen @revorder(1) printf("\tjmp .%s_whilestart_%d\n.%s_whileend_%d:\n", get_func_name(), @Statement.lblcnt_in@, get_func_name(), @Statement.lblcnt_in@); @} | RETURN Expr @{ statinout() + lblcountinout() xxputsin(@Expr.s@,) + @i @Statement.vars@ = 0; @i @Statement.node@ = new_node(O_RET, @Expr.node@, TREENULL); @reg @Statement.node@->reg = @Expr.node@->reg = next_reg((char *)NULL, @Expr.gparamges@); @@ -204,13 +268,36 @@ Statement: @} ; +Elsestat: + ELSE Statseq + @{ + @i @Statseq.lblcnt_in@ = @Elsestat.lblcnt_in@; + @i @Elsestat.lblcnt_out@ = @Statseq.lblcnt_out@; + + @gen printf("\tjmp .%s_ifend_%d\n.%s_ifelse_%d:\n", get_func_name(), @Elsestat.reallblcnt@, get_func_name(), @Elsestat.reallblcnt@); + @} + Lexpr: IDENT @{ - @i @Lexpr.node@ = TREENULL; @c check(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM); - /* this.feldname */ - /* TODO fuer zuweisungen ... (codeb?) */ + + /* TODO: selbe Code wie bei Term/IDENT -- schoener machen! */ + @i { + @Lexpr.node@ = TREENULL; + if(tab_lookup(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM) == SYMNULL) { + /* es handelt sich um ein feldzugriff auf this */ + @Lexpr.node@ = new_field(@IDENT.name@, new_param(O_ID, strdup("this"), TREENULL, TREENULL, 0), TREENULL, tab_lookup(@Lexpr.s@, @IDENT.name@, S_FIELD) == SYMNULL ? -1 : tab_lookup(@Lexpr.s@, @IDENT.name@, S_FIELD)->soffset); + } else { /* param oder var */ + int tmp = tab_lookup(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM) == SYMNULL ? -1 : tab_lookup(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM)->param_index; + @Lexpr.node@ = new_param(O_ID, @IDENT.name@, TREENULL, TREENULL, tmp); + } + } + + @reg if(tab_lookup(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM) == SYMNULL) { + /* TODO: kein schoener hack? */ + @Lexpr.node@->kids[0]->reg = @Lexpr.node@->reg; + } @} | Feld @@ -221,7 +308,7 @@ Feld: Term '.' IDENT @c check(@Feld.s@, @IDENT.name@, S_FIELD); @i @Feld.node@ = new_field(@IDENT.name@, @Term.node@, TREENULL, tab_lookup(@Feld.s@, @IDENT.name@, S_FIELD) == SYMNULL ? -1 : tab_lookup(@Feld.s@, @IDENT.name@, S_FIELD)->soffset); - @reg @Term.node@->reg = @Feld.node@->reg; + @reg @Term.node@->reg = next_reg(@Feld.node@->reg, @Term.gparamges@); @} ; @@ -233,9 +320,9 @@ Expr: | NOT Term @{ - @i @Expr.node@ = new_node(O_EQ, @Term.node@, new_node(O_NULL, TREENULL, TREENULL)); + @i @Expr.node@ = new_node(O_BOOL, new_node(O_EQ, @Term.node@, new_node(O_NULL, TREENULL, TREENULL)), TREENULL); - @reg @Term.node@->reg = @Expr.node@->reg; + @reg @Term.node@->reg = @Expr.node@->kids[0]->reg = @Expr.node@->reg; @} | Term Minusterm @@ -283,22 +370,22 @@ Expr: | Term '<' Term @{ - @i @Expr.node@ = new_node(O_LESS, @Term.0.node@, @Term.1.node@); + @i @Expr.node@ = new_node(O_BOOL, new_node(O_LESS, @Term.0.node@, @Term.1.node@), TREENULL); @i @Expr.imm@ = @Term.0.imm@ && @Term.0.imm@; @reg { - @Term.0.node@->reg = @Expr.node@->reg; + @Term.0.node@->reg = @Expr.node@->kids[0]->reg = @Expr.node@->reg; @Term.1.node@->reg = next_reg(@Term.0.node@->reg, @Expr.gparamges@); } @} | Term '=' Term @{ - @i @Expr.node@ = new_node(O_EQ, @Term.0.node@, @Term.1.node@); + @i @Expr.node@ = new_node(O_BOOL, new_node(O_EQ, @Term.0.node@, @Term.1.node@), TREENULL); @i @Expr.imm@ = @Term.0.imm@ && @Term.0.imm@; @reg { - @Term.0.node@->reg = @Expr.node@->reg; + @Term.0.node@->reg = @Expr.node@->kids[0]->reg = @Expr.node@->reg; @Term.1.node@->reg = next_reg(@Term.0.node@->reg, @Expr.gparamges@); } @} @@ -406,7 +493,6 @@ Term: @Term.node@ = new_field(@IDENT.name@, new_param(O_ID, strdup("this"), TREENULL, TREENULL, 0), TREENULL, tab_lookup(@Term.s@, @IDENT.name@, S_FIELD) == SYMNULL ? -1 : tab_lookup(@Term.s@, @IDENT.name@, S_FIELD)->soffset); } else { /* param oder var */ int tmp = tab_lookup(@Term.s@, @IDENT.name@, S_VAR|S_PARM) == SYMNULL ? -1 : tab_lookup(@Term.s@, @IDENT.name@, S_VAR|S_PARM)->param_index; - fprintf(stderr, "WTF: %d\n", tmp); @Term.node@ = new_param(O_ID, @IDENT.name@, TREENULL, TREENULL, tmp); } }