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)
@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 $@
@echo " OX $^"
@ox $^
-%.c: %.bfe chelper.h
+%.c: %.bfe chelper.h tree.h
@echo " IBURG $<"
@bfe < $< | iburg > $@
@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
#include <stdlib.h>
#include <string.h>
#include "symtable.h"
+ #include "chelper.h"
+ #include "tree.h"
%}
%start Input
@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");
@}
;
METHOD IDENT '(' Parms ')' Statseq END
@{
@i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0);
+ @gen @revorder(1) func_header(@IDENT.name@);
@}
;
/* 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);
@}
|
@{
@i @Statement.sin@ = @Statseq.0.s@;
@i @Statseq.1.s@ = @Statement.sout@;
+ @gen burm_label(@Statement.node@); burm_reduce(@Statement.node@, 1);
@}
|
statinout()
xxputsin(@Lexpr.s@,)
xxputsin(@Expr.s@,)
+ @i @Statement.node@ = TREENULL;
@}
| VAR IDENT ASSIGN Expr
* > 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
statinout()
xxputsin(@Expr.s@,)
xxputsin(@Statseq.s@,)
+ @i @Statement.node@ = TREENULL;
@}
| IF Expr THEN Statseq ELSE Statseq END
xxputsin(@Expr.s@,)
xxputsin(@Statseq.0.s@,)
xxputsin(@Statseq.1.s@,)
+ @i @Statement.node@ = TREENULL;
@}
| WHILE Expr DO Statseq END
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
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:
--- /dev/null
+#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