Merge pull request #1101 from nspcc-dev/feature/convert
Support type conversions
This commit is contained in:
commit
9ca87855a6
3 changed files with 86 additions and 3 deletions
|
@ -708,6 +708,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
name string
|
||||
numArgs = len(n.Args)
|
||||
isBuiltin bool
|
||||
isFunc bool
|
||||
)
|
||||
|
||||
switch fun := n.Fun.(type) {
|
||||
|
@ -717,6 +718,10 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
if !ok && !isBuiltin {
|
||||
name = fun.Name
|
||||
}
|
||||
// distinguish lambda invocations from type conversions
|
||||
if fun.Obj != nil && fun.Obj.Kind == ast.Var {
|
||||
isFunc = true
|
||||
}
|
||||
case *ast.SelectorExpr:
|
||||
// If this is a method call we need to walk the AST to load the struct locally.
|
||||
// Otherwise this is a function call from a imported package and we can call it
|
||||
|
@ -763,9 +768,15 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
// We can be sure builtins are of type *ast.Ident.
|
||||
c.convertBuiltin(n)
|
||||
case name != "":
|
||||
// Function was not found thus is can be only an invocation of func-typed variable.
|
||||
c.emitLoadVar(name)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.CALLA)
|
||||
// Function was not found thus is can be only an invocation of func-typed variable or type conversion.
|
||||
// We care only about string conversions because all others are effectively no-op in NeoVM.
|
||||
// E.g. one cannot write `bool(int(a))`, only `int32(int(a))`.
|
||||
if isString(c.typeOf(n.Fun)) {
|
||||
c.emitConvert(stackitem.ByteArrayT)
|
||||
} else if isFunc {
|
||||
c.emitLoadVar(name)
|
||||
emit.Opcode(c.prog.BinWriter, opcode.CALLA)
|
||||
}
|
||||
case isSyscall(f):
|
||||
c.convertSyscall(n, f.selector.Name, f.name)
|
||||
default:
|
||||
|
@ -987,6 +998,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
// not the assertion type.
|
||||
case *ast.TypeAssertExpr:
|
||||
ast.Walk(c, n.X)
|
||||
typ := toNeoType(c.typeOf(n.Type))
|
||||
emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)})
|
||||
return nil
|
||||
}
|
||||
return c
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue