From 00cd63b47c0c32be821f80e006ed08ce57020e15 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Thu, 24 Aug 2023 09:32:36 +0200 Subject: vm1: improve function calling (#6) The "Enter" instruction has been removed and the frame pointer is now saved by the "Call" instruction. The "Return" instruction now takes the number of function input parameters as the second operand. It's used to return the output values at the correct place in the caller frame, no matter the number of input parameters. The tests and the code generator have been updated accordingly. --- codegen/codegen.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'codegen/codegen.go') 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++ } } -- cgit v1.2.3