diff options
Diffstat (limited to 'codegen')
| -rw-r--r-- | codegen/codegen.go | 8 | ||||
| -rw-r--r-- | codegen/codegen_test.go | 13 |
2 files changed, 14 insertions, 7 deletions
diff --git a/codegen/codegen.go b/codegen/codegen.go index 048b20f..d7702cd 100644 --- a/codegen/codegen.go +++ b/codegen/codegen.go @@ -41,8 +41,7 @@ func (c *Compiler) CodeGen(node *parser.Node) (err error) { switch n.Kind { case parser.FuncDecl: fname := n.Child[0].Content() - i := c.Emit(n, vm1.Enter) - c.AddSym(i, scope+fname, false) + c.AddSym(len(c.Code), scope+fname, false) scope = pushScope(scope, fname) frameNode = append(frameNode, n) fnote = notes[n] @@ -124,7 +123,8 @@ func (c *Compiler) CodeGen(node *parser.Node) (err error) { } case parser.ReturnStmt: - c.Emit(n, vm1.Return, int64(len(n.Child))) + fun := frameNode[len(frameNode)-1] + c.Emit(n, vm1.Return, int64(len(n.Child)), int64(len(fun.Child[1].Child))) case parser.StmtBloc: nd.ipend = len(c.Code) @@ -144,7 +144,7 @@ func (c *Compiler) CodeGen(node *parser.Node) (err error) { // TODO: Fix this temporary hack to compute an entry point if c.Entry < 0 && len(scope) == 0 && n.Kind != parser.FuncDecl { c.Entry = len(c.Code) - 1 - if c.Code[c.Entry][1] == vm1.Return { + if c.Entry >= 0 && len(c.Code) > c.Entry && c.Code[c.Entry][1] == vm1.Return { c.Entry++ } } diff --git a/codegen/codegen_test.go b/codegen/codegen_test.go index d2f8033..7262ddc 100644 --- a/codegen/codegen_test.go +++ b/codegen/codegen_test.go @@ -16,7 +16,7 @@ func TestCodeGen(t *testing.T) { test := test t.Run("", func(t *testing.T) { c := New() - c.AddSym(fmt.Println, "println") + c.AddSym(fmt.Println, "println", false) n := &parser.Node{} var err error if n.Child, err = golang.GoParser.Parse(test.src); err != nil { @@ -31,6 +31,9 @@ func TestCodeGen(t *testing.T) { } t.Log("data:", c.Data) t.Log("code:", vm1.Disassemble(c.Code)) + if s := vm1.Disassemble(c.Code); s != test.asm { + t.Errorf("got error %#v, want error %#v", s, test.asm) + } }) } } @@ -45,7 +48,11 @@ var tests = []struct { asm: "Dup 0\nDup 1\nCallX 1\n", }, { // #02 src: `a := 2; println(a)`, - asm: "Push 2\nAssign 1\nDup 0\nDup 1\nCallX 1", + asm: "Push 2\nAssign 1\nDup 0\nDup 1\nCallX 1\n", }, { // #03 src: `a := 2; if a < 3 {println(a)}; println("bye")`, -}} + asm: "Push 2\nAssign 1\nDup 1\nPush 3\nLower\nJumpFalse 4\nDup 0\nDup 1\nCallX 1\nDup 0\nDup 2\nCallX 1\n", +}, { // #04 + src: "func add(a int, b int) int { return a + b }", + asm: "Fdup -2\nFdup -3\nAdd\nReturn 1 2\n", +}, {}} |
