compiler: allow to omit struct field names in literals

This commit is contained in:
Evgenii Stratonikov 2020-06-24 19:33:58 +03:00
parent 5a615d8178
commit 6ddaed3927
2 changed files with 24 additions and 0 deletions

View file

@ -1253,12 +1253,25 @@ func (c *codegen) convertStruct(lit *ast.CompositeLit) {
emit.Int(c.prog.BinWriter, int64(strct.NumFields()))
emit.Opcode(c.prog.BinWriter, opcode.NEWSTRUCT)
keyedLit := len(lit.Elts) > 0
if keyedLit {
_, ok := lit.Elts[0].(*ast.KeyValueExpr)
keyedLit = keyedLit && ok
}
// We need to locally store all the fields, even if they are not initialized.
// We will initialize all fields to their "zero" value.
for i := 0; i < strct.NumFields(); i++ {
sField := strct.Field(i)
fieldAdded := false
if !keyedLit {
emit.Opcode(c.prog.BinWriter, opcode.DUP)
emit.Int(c.prog.BinWriter, int64(i))
ast.Walk(c, lit.Elts[i])
emit.Opcode(c.prog.BinWriter, opcode.SETITEM)
continue
}
// Fields initialized by the program.
for _, field := range lit.Elts {
f := field.(*ast.KeyValueExpr)

View file

@ -394,6 +394,17 @@ var structTestCases = []testCase{
}`,
big.NewInt(42),
},
{
"omit field names",
`package foo
type pair struct { a, b int }
func Main() int {
p := pair{1, 2}
x := p.a * 10
return x + p.b
}`,
big.NewInt(12),
},
}
func TestStructs(t *testing.T) {