compiler: support calling function literals

This commit is contained in:
Evgenii Stratonikov 2020-08-19 17:31:02 +03:00
parent b4bcd23c0f
commit d73f3cd24c
2 changed files with 19 additions and 0 deletions

View file

@ -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:

View file

@ -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))
}