summaryrefslogtreecommitdiff
path: root/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'codegen')
-rw-r--r--codegen/codegen.go8
-rw-r--r--codegen/codegen_test.go13
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",
+}, {}}