compiler: emit default values in a generic way

This commit is contained in:
Evgenii Stratonikov 2020-05-19 16:57:42 +03:00
parent 2cc58c3c9e
commit 582469028b

View file

@ -216,13 +216,9 @@ func (c *codegen) emitStoreVar(name string) {
} }
} }
func (c *codegen) emitDefault(n ast.Expr) { func (c *codegen) emitDefault(t types.Type) {
tv, ok := c.typeInfo.Types[n] switch t := t.Underlying().(type) {
if !ok { case *types.Basic:
c.prog.Err = errors.New("invalid type")
return
}
if t, ok := tv.Type.(*types.Basic); ok {
info := t.Info() info := t.Info()
switch { switch {
case info&types.IsInteger != 0: case info&types.IsInteger != 0:
@ -234,10 +230,17 @@ func (c *codegen) emitDefault(n ast.Expr) {
default: default:
emit.Opcode(c.prog.BinWriter, opcode.PUSHNULL) emit.Opcode(c.prog.BinWriter, opcode.PUSHNULL)
} }
return case *types.Slice:
if isCompoundSlice(t) {
emit.Opcode(c.prog.BinWriter, opcode.NEWARRAY0)
} }
case *types.Struct:
emit.Int(c.prog.BinWriter, int64(t.NumFields()))
emit.Opcode(c.prog.BinWriter, opcode.NEWSTRUCT)
default:
emit.Opcode(c.prog.BinWriter, opcode.PUSHNULL) emit.Opcode(c.prog.BinWriter, opcode.PUSHNULL)
} }
}
// convertGlobals traverses the AST and only converts global declarations. // convertGlobals traverses the AST and only converts global declarations.
// If we call this in convertFuncDecl then it will load all global variables // If we call this in convertFuncDecl then it will load all global variables
@ -363,14 +366,8 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
for i := range t.Names { for i := range t.Names {
if len(t.Values) != 0 { if len(t.Values) != 0 {
ast.Walk(c, t.Values[i]) ast.Walk(c, t.Values[i])
} else if typ := c.typeOf(t.Type); isCompoundSlice(typ) {
emit.Opcode(c.prog.BinWriter, opcode.PUSH0)
emit.Opcode(c.prog.BinWriter, opcode.NEWARRAY)
} else if s, ok := typ.Underlying().(*types.Struct); ok {
emit.Int(c.prog.BinWriter, int64(s.NumFields()))
emit.Opcode(c.prog.BinWriter, opcode.NEWSTRUCT)
} else { } else {
c.emitDefault(t.Type) c.emitDefault(c.typeOf(t.Type))
} }
c.emitStoreVar(t.Names[i].Name) c.emitStoreVar(t.Names[i].Name)
} }