From 6ddaed39279fb06f6409a2f7a4a467d84c3cba96 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 24 Jun 2020 19:33:58 +0300 Subject: [PATCH] compiler: allow to omit struct field names in literals --- pkg/compiler/codegen.go | 13 +++++++++++++ pkg/compiler/struct_test.go | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 7093acae3..7866fe5e7 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -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) diff --git a/pkg/compiler/struct_test.go b/pkg/compiler/struct_test.go index b11b55ac0..945273d28 100644 --- a/pkg/compiler/struct_test.go +++ b/pkg/compiler/struct_test.go @@ -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) {