From: Bernhard Urban Date: Wed, 5 May 2010 21:52:54 +0000 (+0200) Subject: codea: feldzugriffe X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=uebersetzerbau-ss10.git;a=commitdiff_plain;h=a643bd86b35650367d7db70901c12a35e05d8f61 codea: feldzugriffe --- diff --git a/codea/code.bfe b/codea/code.bfe index fd78dd2..c366fbf 100644 --- a/codea/code.bfe +++ b/codea/code.bfe @@ -95,7 +95,7 @@ void gen_eqless_ie(struct treenode *bnode, char *op) %} %start begin -%term O_RET=1 O_NOT=2 O_SUB=3 O_MUL=4 O_OR=5 O_LESS=6 O_EQ=7 O_ID=8 O_ADD=9 O_NUM=10 +%term O_RET=1 O_NOT=2 O_SUB=3 O_MUL=4 O_OR=5 O_LESS=6 O_EQ=7 O_ID=8 O_ADD=9 O_NUM=10 O_FIELD=11 %% @@ -127,6 +127,8 @@ expr: O_EQ(expr,expr) # 5 # gen_eqless_ee(bnode, "e"); expr: O_EQ(expr,imm) # 5 # gen_eqless_ei(bnode, "e"); expr: O_EQ(imm,expr) # 5 # gen_eqless_ie(bnode, "e"); +expr: O_FIELD(exprno) # 1 # KIDREG2PARM(0); printf("\tmovq %li(%%%s), %%%s\n", bnode->soffset * 8, KID_REG(0), BN_REG); + exprno: O_ID # 0 # /* brauchen wir nicht 'zwischenlagern', weil nur gelesen wird */ exprno: expr diff --git a/codea/parser.y b/codea/parser.y index a6bb1d3..fa8d988 100644 --- a/codea/parser.y +++ b/codea/parser.y @@ -43,8 +43,8 @@ @attributes { struct symbol *f; int soffset; int offsetcount; } FeldID Structdef @attributes { struct symbol *s; } Methoddef @attributes { struct symbol *s; int gparamges; } Statseq Exprs -@attributes { struct symbol *s; int gparamges; struct treenode *node; int exprcount; } Expr Minusterm Term Multerm Orterm -@attributes { struct symbol *s; int gparamges; struct treenode *node; } Lexpr Feld +@attributes { struct symbol *s; int gparamges; struct treenode *node; int exprcount; } 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; } Statement @traversal @postorder c @@ -204,6 +204,8 @@ Lexpr: @{ @i @Lexpr.node@ = TREENULL; @c check(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM); + /* this.feldname */ + /* TODO fuer zuweisungen ... (codeb?) */ @} | Feld @@ -212,7 +214,10 @@ Lexpr: Feld: Term '.' IDENT @{ @c check(@Feld.s@, @IDENT.name@, S_FIELD); - @i @Feld.node@ = TREENULL; + @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, @Feld.exprcount@); + + @i @Feld.exprcount@ = @Term.exprcount@; fprintf(stderr, "(Feld)- Term.IDENT\n"); + @reg @Term.node@->reg = @Feld.node@->reg; @} ; @@ -376,13 +381,27 @@ Term: | IDENT @{ @c check(@Term.s@, @IDENT.name@, S_VAR|S_PARM); + @i @Term.exprcount@ = 0; fprintf(stderr, "(Term)- IDENT\n"); - @i @Term.node@ = new_param(O_ID, @IDENT.name@, TREENULL, TREENULL, tab_lookup(@Term.s@, @IDENT.name@, S_PARM) == SYMNULL ? -1 : tab_lookup(@Term.s@, @IDENT.name@, S_PARM)->param_index, @Term.exprcount@); + @i { + @Term.node@ = TREENULL; + if(tab_lookup(@Term.s@, @IDENT.name@, S_VAR|S_PARM) == SYMNULL) { + /* es handelt sich um ein feldzugriff auf this */ + @Term.node@ = new_field(@IDENT.name@, new_param(O_ID, strdup("this"), TREENULL, TREENULL, 0, @Term.exprcount@), TREENULL, tab_lookup(@Term.s@, @IDENT.name@, S_FIELD) == SYMNULL ? -1 : tab_lookup(@Term.s@, @IDENT.name@, S_FIELD)->soffset, @Term.exprcount@); + } else { /* param oder var */ + @Term.node@ = new_param(O_ID, @IDENT.name@, TREENULL, TREENULL, tab_lookup(@Term.s@, @IDENT.name@, S_PARM) == SYMNULL ? -1 : tab_lookup(@Term.s@, @IDENT.name@, S_PARM)->param_index, @Term.exprcount@); + } + } + + @reg if(tab_lookup(@Term.s@, @IDENT.name@, S_VAR|S_PARM) == SYMNULL) { + /* TODO: kein schoener hack? */ + @Term.node@->kids[0]->reg = @Term.node@->reg; + } @} | Feld @{ - @i @Term.node@ = TREENULL; + @i @Term.node@ = @Feld.node@; /*TODO*/@i @Term.exprcount@ = 0; @} diff --git a/codea/tree.c b/codea/tree.c index 9ee0b47..7e7c715 100644 --- a/codea/tree.c +++ b/codea/tree.c @@ -47,6 +47,18 @@ struct treenode *new_param(int op, char *name, struct treenode *l, struct treeno return new; } +struct treenode *new_field(char *name, struct treenode *l, struct treenode *r, int soffset, int exprcount) +{ + struct treenode *new = new_node(O_FIELD, l, r, exprcount); + +#ifdef DDTREE + fprintf(stderr, "new_field: %i (soffset)\n", soffset); +#endif + new->soffset = soffset; + new->name = name; + return new; +} + struct treenode *new_number(long val, int exprcount) { struct treenode *new = _new_plain(O_NUM); diff --git a/codea/tree.h b/codea/tree.h index 7e8beb5..b824d15 100644 --- a/codea/tree.h +++ b/codea/tree.h @@ -19,7 +19,8 @@ enum { O_EQ, O_ID, O_ADD, - O_NUM + O_NUM, + O_FIELD }; static char *o_names[] = { @@ -33,7 +34,8 @@ static char *o_names[] = { "O_EQ", "O_ID", "O_ADD", - "O_NUM" + "O_NUM", + "O_FIELD" }; struct treenode { @@ -47,6 +49,7 @@ struct treenode { int skip; int param_index; int exprcount; + int soffset; }; typedef struct treenode *treenodep; @@ -61,6 +64,7 @@ typedef struct treenode *treenodep; struct treenode *new_node(int op, struct treenode *l, struct treenode *r, int exprcount); struct treenode *new_number(long val, int exprcount); struct treenode *new_param(int op, char *name, struct treenode *l, struct treenode *r, int param_index, int exprcount); +struct treenode *new_field(char *name, struct treenode *l, struct treenode *r, int soffset, int exprcount); void write_tree(struct treenode *node, int ident); #endif