From 79bf606e8b7d140aa1468154bb747636bd75eb00 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Fri, 23 Apr 2010 08:58:13 +0200 Subject: [PATCH] codea: codegeruest wird generiert :) eingabe: $ cat ~/test/codea/lewurm_01.0 > method f(x) > return x; > end; $ make all && ./codea < ~/test/codea/lewurm_01.0 > new_node: 1 (O_RETURN) > .text > .globl f > .type f, @function > f: > ret --- codea/Makefile | 9 ++-- codea/chelper.c | 1 + codea/code.bfe | 24 +++++++++++ codea/parser.y | 106 +++++++++++++++++++++++++++++++++++++++++++--- codea/scanner.lex | 4 +- codea/symtable.c | 6 ++- codea/symtable.h | 5 ++- codea/tree.c | 23 ++++++++++ codea/tree.h | 44 +++++++++++++++++++ 9 files changed, 207 insertions(+), 15 deletions(-) create mode 100644 codea/tree.c create mode 100644 codea/tree.h diff --git a/codea/Makefile b/codea/Makefile index 2b0df7d..a7c5036 100644 --- a/codea/Makefile +++ b/codea/Makefile @@ -1,7 +1,7 @@ SHELL := bash NAME := codea CFLAGS := -ansi -pedantic -D_GNU_SOURCE -OBJS := scanner.o parser.o symtable.o code.o chelper.o +OBJS := scanner.o parser.o symtable.o code.o chelper.o tree.o all: $(NAME) @@ -14,11 +14,11 @@ scanner.c: oxout.l @flex -o$@ $< #dirty deps ;) -%.o: %.c parser.h symtable.h chelper.h +%.o: %.c parser.h symtable.h chelper.h tree.h @echo " CC $<" @gcc -c $(CFLAGS) $< #-Wall -parser.c: oxout.y chelper.h +parser.c: oxout.y chelper.h tree.h @echo " YACC $<" @yacc -t -v -d $< -o $@ @@ -28,7 +28,7 @@ oxout.y oxout.l: parser.y scanner.lex @echo " OX $^" @ox $^ -%.c: %.bfe chelper.h +%.c: %.bfe chelper.h tree.h @echo " IBURG $<" @bfe < $< | iburg > $@ @@ -40,6 +40,7 @@ clean: @echo " CC callingconvention.c" @gcc -c -fomit-frame-pointer -fno-defer-pop testit/callingconvention.c -o testit/callingconvention.o @./testit/test + @rm testcodeaout*.s a.out 2test: /usr/ftp/pub/ublu/test/$(NAME)/test 2>&1 diff --git a/codea/chelper.c b/codea/chelper.c index c590232..8f9185c 100644 --- a/codea/chelper.c +++ b/codea/chelper.c @@ -1,6 +1,7 @@ #include #include #include "chelper.h" +#include "tree.h" void func_header(char *s) { diff --git a/codea/code.bfe b/codea/code.bfe index e69de29..0d4661b 100644 --- a/codea/code.bfe +++ b/codea/code.bfe @@ -0,0 +1,24 @@ +%{ +#define BFEHAX + +#include +#include +#include +#include "tree.h" +#include "chelper.h" + +%} + +%start begin +%term O_RETURN=1 + +%% + +begin: ret +ret: O_RETURN # 1 # ret(); + +%% + +/* vim: filetype=c + */ + diff --git a/codea/parser.y b/codea/parser.y index dbd4e24..9e2d284 100644 --- a/codea/parser.y +++ b/codea/parser.y @@ -3,6 +3,8 @@ #include #include #include "symtable.h" + #include "chelper.h" + #include "tree.h" %} %start Input @@ -20,18 +22,24 @@ @end @autoinh s +@autosyn node + @attributes { char *name; } IDENT +@attributes { long val; } NUM @attributes { struct symbol *f; } FeldID Parms Structdef Program -@attributes { struct symbol *s; } Methoddef Statseq Lexpr Expr Minusterm Multerm Orterm Term Exprs Feld -@attributes { struct symbol *sin; struct symbol *sout; } Statement +@attributes { struct symbol *s; } Methoddef Statseq Exprs +@attributes { struct symbol *s; struct treenode *node; } Lexpr Expr Minusterm Multerm Orterm Term Feld +@attributes { struct symbol *sin; struct symbol *sout; struct treenode *node; } Statement @traversal @postorder c +@traversal @postorder gen %% Input: Program @{ @i @Program.f@ = tab_new(); + @gen @revorder(1) printf("\t.text\n"); @} ; @@ -53,6 +61,7 @@ Methoddef: METHOD IDENT '(' Parms ')' Statseq END @{ @i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0); + @gen @revorder(1) func_header(@IDENT.name@); @} ; @@ -67,7 +76,7 @@ Parms: /* lokale Vars werden in Statement in die tabelle eingefuegt */ IDENT Parms @{ - @i @Parms.0.f@ = tab_add_symbol(@Parms.1.f@, @IDENT.name@, S_VAR, 1); + @i @Parms.0.f@ = tab_add_symbol(@Parms.1.f@, @IDENT.name@, S_PARM, 1); @} | @@ -93,6 +102,7 @@ Statseq: @{ @i @Statement.sin@ = @Statseq.0.s@; @i @Statseq.1.s@ = @Statement.sout@; + @gen burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1); @} | @@ -104,6 +114,7 @@ Statement: statinout() xxputsin(@Lexpr.s@,) xxputsin(@Expr.s@,) + @i @Statement.node@ = TREENULL; @} | VAR IDENT ASSIGN Expr @@ -112,12 +123,14 @@ Statement: * > var x := x - 1; */ @i @Statement.sout@ = tab_add_symbol(tab_clone(@Statement.sin@), @IDENT.name@, S_VAR, 1); xxputsin(@Expr.s@,) + @i @Statement.node@ = TREENULL; @} | Expr @{ statinout() xxputsin(@Expr.s@,) + @i @Statement.node@ = TREENULL; @} | IF Expr THEN Statseq END @@ -125,6 +138,7 @@ Statement: statinout() xxputsin(@Expr.s@,) xxputsin(@Statseq.s@,) + @i @Statement.node@ = TREENULL; @} | IF Expr THEN Statseq ELSE Statseq END @@ -133,6 +147,7 @@ Statement: xxputsin(@Expr.s@,) xxputsin(@Statseq.0.s@,) xxputsin(@Statseq.1.s@,) + @i @Statement.node@ = TREENULL; @} | WHILE Expr DO Statseq END @@ -140,19 +155,22 @@ Statement: statinout() xxputsin(@Expr.s@,) xxputsin(@Statseq.s@,) + @i @Statement.node@ = TREENULL; @} | RETURN Expr @{ statinout() xxputsin(@Expr.s@,) + @i @Statement.node@ = new_node(O_RETURN, @Expr.node@, TREENULL); @} ; Lexpr: IDENT @{ - @c check(@Lexpr.s@, @IDENT.name@, S_VAR); + @i @Lexpr.node@ = TREENULL; + @c check(@Lexpr.s@, @IDENT.name@, S_VAR|S_PARM); @} | Feld @@ -161,47 +179,125 @@ Lexpr: Feld: Term '.' IDENT @{ @c check(@Feld.s@, @IDENT.name@, S_FIELD); + @i @Feld.node@ = TREENULL; @} ; Expr: Term + @{ + @i @Expr.node@ = TREENULL; + @} + | NOT Term + @{ + @i @Expr.node@ = TREENULL; + @} + | Term Minusterm + @{ + @i @Expr.node@ = TREENULL; + @} + | Term Multerm + @{ + @i @Expr.node@ = TREENULL; + @} + | Term Orterm + @{ + @i @Expr.node@ = TREENULL; + @} + | Term '<' Term + @{ + @i @Expr.node@ = TREENULL; + @} + | Term '=' Term + @{ + @i @Expr.node@ = TREENULL; + @} ; Minusterm: '-' Term Minusterm + @{ + @i @Minusterm.node@ = TREENULL; + @} + | '-' Term + @{ + @i @Minusterm.node@ = TREENULL; + @} ; Multerm: '*' Term Multerm + @{ + @i @Multerm.node@ = TREENULL; + @} + | '*' Term + @{ + @i @Multerm.node@ = TREENULL; + @} ; Orterm: OR Term Orterm + @{ + @i @Orterm.node@ = TREENULL; + @} | OR Term + @{ + @i @Orterm.node@ = TREENULL; + @} + ; Term: '(' Expr ')' + @{ + @i @Term.node@ = TREENULL; + @} + | NUM + @{ + @i @Term.node@ = TREENULL; + @} + | '-' NUM + @{ + @i @Term.node@ = TREENULL; + @} + | THIS + @{ + @i @Term.node@ = TREENULL; + @} + | IDENT @{ - @c check(@Term.s@, @IDENT.name@, S_VAR); + @c check(@Term.s@, @IDENT.name@, S_VAR|S_PARM); + @i @Term.node@ = TREENULL; @} | Feld + @{ + @i @Term.node@ = TREENULL; + @} + | IDENT '(' Exprs ')' + @{ + @i @Term.node@ = TREENULL; + @} + | Term '.' IDENT '(' Exprs ')' + @{ + @i @Term.node@ = TREENULL; + @} + ; Exprs: diff --git a/codea/scanner.lex b/codea/scanner.lex index c104d0f..92f6df7 100644 --- a/codea/scanner.lex +++ b/codea/scanner.lex @@ -42,8 +42,8 @@ this return(THIS); {IDENTIFIER} return(IDENT); @{ @IDENT.name@ = strdup(yytext); @} -{NUMBER_DEC} return(NUM); -{NUMBER_HEX} return(NUM); +{NUMBER_DEC} return(NUM); @{ @NUM.val@ = strtol(yytext, (char **)NULL, 10); @} +{NUMBER_HEX} return(NUM); @{ @NUM.val@ = strtol(yytext, (char **)NULL, 16); @} \:= return(ASSIGN); \; return(';'); diff --git a/codea/symtable.c b/codea/symtable.c index 850c1b0..a889a1e 100755 --- a/codea/symtable.c +++ b/codea/symtable.c @@ -3,7 +3,9 @@ #include #include "symtable.h" +#if 0 #define DD +#endif struct symbol *tab_new(void) { @@ -68,7 +70,7 @@ struct symbol *tab_lookup(struct symbol *tab, char *ident, short type) } do { - if((elm->type == type) && (strcmp(elm->ident, ident) == 0)) { + if((elm->type & type) && (strcmp(elm->ident, ident) == 0)) { return elm; } elm = elm->next; @@ -123,7 +125,7 @@ void check(struct symbol *tab, char *ident, short type) printf("check: tab(%08X), ident(%s), type(%i), elm(%08X)\n", tab, ident, type, elm); #endif - if(type == S_VAR) { + if(type & (S_VAR | S_PARM)) { elm = tab_lookup(tab, ident, type); if(elm != SYMNULL) { return; diff --git a/codea/symtable.h b/codea/symtable.h index df7fa5a..6b29561 100755 --- a/codea/symtable.h +++ b/codea/symtable.h @@ -1,8 +1,9 @@ #ifndef SYMTABLE_H #define SYMTABLE_H -#define S_FIELD 0 -#define S_VAR 1 +#define S_FIELD (1<<0) +#define S_VAR (1<<1) +#define S_PARM (1<<2) #define SYMNULL (struct symbol *)NULL diff --git a/codea/tree.c b/codea/tree.c new file mode 100644 index 0000000..55798f7 --- /dev/null +++ b/codea/tree.c @@ -0,0 +1,23 @@ +#include +#include +#include "tree.h" + +#if 0 +#define DDTREE +#endif + +struct treenode *new_node(int op, struct treenode *l, struct treenode *r) +{ + struct treenode *new = (TREECAST) malloc(TREESIZE); + +#if DDTREE + printf("new_node: %i (%s)\n", op, o_names[op]); +#endif + + new->kids[0] = l; + new->kids[1] = r; + new->op = op; + new->name = (char *)NULL; + return new; +} + diff --git a/codea/tree.h b/codea/tree.h new file mode 100644 index 0000000..152b7c1 --- /dev/null +++ b/codea/tree.h @@ -0,0 +1,44 @@ +#ifndef __TREE_H +#define __TREE_H + +#define TREENULL (struct treenode *)NULL +#define TREESIZE (sizeof(struct treenode)) +#define TREECAST struct treenode * + +#ifndef BFEHAX +typedef struct burm_state *STATEPTR_TYPE; +#endif + +enum { + O_RETURN=1 +}; + +static char o_names[100][100] = { + "", + "O_RETURN" +}; + +struct treenode { + int op; + struct treenode *kids[2]; + STATEPTR_TYPE label; + char *name; + long val; + char *reg; + struct treenode *parent; + int skip; + int param_index; +}; + +typedef struct treenode *treenodep; + +#define NODEPTR_TYPE treenodep +#define OP_LABEL(p) ((p)->op) +#define LEFT_CHILD(p) ((p)->kids[0]) +#define RIGHT_CHILD(p) ((p)->kids[1]) +#define STATE_LABEL(p) ((p)->label) +#define PANIC printf + +struct treenode *new_node(int op, struct treenode *l, struct treenode *r); + +#endif -- 2.25.1