From 88baba94a917221ffd6b4f15304ac560e7f2a6a8 Mon Sep 17 00:00:00 2001 From: Asami Doi Date: Tue, 27 Aug 2019 14:14:15 +0900 Subject: [PATCH] Success running a fibonacci function! --- codegen.go | 5 +++++ parse.go | 43 ++++++++++++++++++++++++++++++++++++------- test.sh | 3 +++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/codegen.go b/codegen.go index abfe63c..b142360 100644 --- a/codegen.go +++ b/codegen.go @@ -179,6 +179,11 @@ func codegen(prog Program) { fmt.Printf(" mov rbp, rsp\n") fmt.Printf(" sub rsp, %d\n", f.stackSize) + // Push parameters to the stack. + for i, p := range f.params { + fmt.Printf(" mov [rbp-%d], %s\n", p.offset, argreg[i]) + } + // Emit code. for _, s := range f.stmts { gen(s) diff --git a/parse.go b/parse.go index 6e7751e..7993cf2 100644 --- a/parse.go +++ b/parse.go @@ -4,7 +4,7 @@ import ( "fmt" ) -var locals []Var +var tmpLocals []Var var varOffset int = 8 type Expr interface { @@ -21,8 +21,9 @@ type Program struct { type Function struct { name string - stmts []Stmt + params []Var locals []Var + stmts []Stmt stackSize int } @@ -90,7 +91,7 @@ func (For) isStmt() {} func (Empty) isStmt() {} func findVar(tok Token) *Var { - for _, v := range locals { + for _, v := range tmpLocals { if v.name == tok.str { return &v } @@ -138,8 +139,10 @@ func program() Program { func function() Function { // Initialize for one function. name := "" + params := make([]Var, 0) + varOffset = 8 - locals = make([]Var, 0) + tmpLocals = make([]Var, 0) if consume("func") { tok := consumeIdent() @@ -147,8 +150,10 @@ func function() Function { panic("Expect an identifier after 'func' keyword.") } name = tok.str - // No sigunatures for now. + //fmt.Println("================") + //fmt.Println(tokens) assert("(") + params = funcParams() assert(")") } @@ -156,7 +161,7 @@ func function() Function { for len(tokens) > 0 && !next("func") { stmts = append(stmts, stmt()) } - return Function{name, stmts, locals, len(locals) * 8} + return Function{name, params, tmpLocals, stmts, len(tmpLocals) * 8} } func stmt() Stmt { @@ -353,7 +358,7 @@ func primary() Expr { if varp == nil { varp = &Var{tok.str, varOffset} varOffset += 8 - locals = append(locals, *varp) + tmpLocals = append(tmpLocals, *varp) } return *varp } @@ -378,6 +383,30 @@ func funcArgs() []Expr { return args } +func funcParams() []Var { + params := make([]Var, 0) + if next(")") { + return params + } + + for { + tok := consumeIdent() + if tok == nil { + panic("Expect an identifier inside function parameters.") + } + + v := Var{tok.str, varOffset} + varOffset += 8 + tmpLocals = append(tmpLocals, v) + params = append(params, v) + + if !consume(",") { + break + } + } + return params +} + func printNodes(funcs []Function) { for i, f := range funcs { fmt.Println("[Function]:", i, f.name) diff --git a/test.sh b/test.sh index 20ca7be..be3d9a6 100755 --- a/test.sh +++ b/test.sh @@ -117,5 +117,8 @@ assert 2 'func main() { return sub(5, 3); }' assert 21 'func main() { return add6(1,2,3,4,5,6); }' assert 32 'func main() { return ret32(); } func ret32() { return 32; }' +assert 7 'func main() { return add2(3,4); } func add2(x,y) { return x+y; }' +assert 1 'func main() { return sub2(4,3); } func sub2(x,y) { return x-y; }' +assert 55 'func main() { return fib(9); } func fib(x) { if x<=1 { return 1; } return fib(x-1) + fib(x-2); }' echo OK