From d73f3cd24cd1b965f83d250b68d6bc0d9cc80637 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 19 Aug 2020 17:31:02 +0300 Subject: [PATCH] compiler: support calling function literals --- pkg/compiler/codegen.go | 6 ++++++ pkg/compiler/lambda_test.go | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 4b7c3f2d2..90f4d62c9 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -708,6 +708,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { numArgs = len(n.Args) isBuiltin bool isFunc bool + isLiteral bool ) switch fun := n.Fun.(type) { @@ -746,6 +747,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { ast.Walk(c, n.Args[0]) c.emitConvert(stackitem.BufferT) return nil + case *ast.FuncLit: + isLiteral = true } c.saveSequencePoint(n) @@ -798,6 +801,9 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { c.emitLoadVar("", name) emit.Opcode(c.prog.BinWriter, opcode.CALLA) } + case isLiteral: + ast.Walk(c, n.Fun) + emit.Opcode(c.prog.BinWriter, opcode.CALLA) case isSyscall(f): c.convertSyscall(n, f.pkg.Name(), f.name) default: diff --git a/pkg/compiler/lambda_test.go b/pkg/compiler/lambda_test.go index d9ab32613..f3e7132a7 100644 --- a/pkg/compiler/lambda_test.go +++ b/pkg/compiler/lambda_test.go @@ -13,3 +13,16 @@ func TestFuncLiteral(t *testing.T) { }` eval(t, src, big.NewInt(5)) } + +func TestCallInPlace(t *testing.T) { + src := `package foo + var a int = 1 + func Main() int { + func() { + a += 10 + }() + a += 100 + return a + }` + eval(t, src, big.NewInt(111)) +}