mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-22 19:29:39 +00:00
compiler: allow to declare variables of struct type
Previously, struct variables were initialize with VM's nil value which is of primitive type. Thus SETITEM used for struct's field updating wasn't working.
This commit is contained in:
parent
6baed7a010
commit
3cbd138b67
3 changed files with 43 additions and 0 deletions
|
@ -203,6 +203,19 @@ func isByte(t types.Type) bool {
|
|||
return ok && e.Kind() == types.Byte
|
||||
}
|
||||
|
||||
func (c *codegen) isStructType(t ast.Expr) (int, bool) {
|
||||
switch s := t.(type) {
|
||||
case *ast.StructType:
|
||||
return s.Fields.NumFields(), true
|
||||
case *ast.Ident:
|
||||
st, ok := c.typeInfo.Types[s].Type.Underlying().(*types.Struct)
|
||||
if ok {
|
||||
return st.NumFields(), true
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func isByteArray(lit *ast.CompositeLit, tInfo *types.Info) bool {
|
||||
if len(lit.Elts) == 0 {
|
||||
if typ, ok := lit.Type.(*ast.ArrayType); ok {
|
||||
|
|
|
@ -287,6 +287,11 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
|
|||
emit.Opcode(c.prog.BinWriter, opcode.NEWARRAY)
|
||||
l := c.scope.newLocal(t.Names[0].Name)
|
||||
c.emitStoreLocal(l)
|
||||
} else if n, ok := c.isStructType(t.Type); ok {
|
||||
emit.Int(c.prog.BinWriter, int64(n))
|
||||
emit.Opcode(c.prog.BinWriter, opcode.NEWSTRUCT)
|
||||
l := c.scope.newLocal(t.Names[0].Name)
|
||||
c.emitStoreLocal(l)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -302,6 +302,31 @@ var structTestCases = []testCase{
|
|||
`,
|
||||
big.NewInt(14),
|
||||
},
|
||||
{
|
||||
"declare struct literal",
|
||||
`package foo
|
||||
func Main() int {
|
||||
var x struct {
|
||||
a int
|
||||
}
|
||||
x.a = 2
|
||||
return x.a
|
||||
}`,
|
||||
big.NewInt(2),
|
||||
},
|
||||
{
|
||||
"declare struct type",
|
||||
`package foo
|
||||
type withA struct {
|
||||
a int
|
||||
}
|
||||
func Main() int {
|
||||
var x withA
|
||||
x.a = 2
|
||||
return x.a
|
||||
}`,
|
||||
big.NewInt(2),
|
||||
},
|
||||
}
|
||||
|
||||
func TestStructs(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue