From 1e40f9dac055b4a399e6b2810b027635bb8ee8ba Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 20 May 2020 11:05:01 +0300 Subject: [PATCH] compiler: support nested struct reading --- pkg/compiler/codegen.go | 15 ++++++--------- pkg/compiler/struct_test.go | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 9dadbeff9..e5a558ce4 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -753,17 +753,14 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { return nil case *ast.SelectorExpr: - switch t := n.X.(type) { - case *ast.Ident: - if strct, ok := c.typeOf(t).Underlying().(*types.Struct); ok { - c.emitLoadVar(t.Name) // load the struct - i := indexOfStruct(strct, n.Sel.Name) - c.emitLoadField(i) // load the field - } - default: - c.prog.Err = fmt.Errorf("nested selectors not supported yet") + strct, ok := c.typeOf(n.X).Underlying().(*types.Struct) + if !ok { + c.prog.Err = fmt.Errorf("selectors are supported only on structs") return nil } + ast.Walk(c, n.X) // load the struct + i := indexOfStruct(strct, n.Sel.Name) + c.emitLoadField(i) // load the field return nil case *ast.UnaryExpr: diff --git a/pkg/compiler/struct_test.go b/pkg/compiler/struct_test.go index f50390899..cffb8c335 100644 --- a/pkg/compiler/struct_test.go +++ b/pkg/compiler/struct_test.go @@ -338,6 +338,20 @@ var structTestCases = []testCase{ }`, big.NewInt(2), }, + { + "nested selectors (simple read)", + `package foo + type S1 struct { x, y S2 } + type S2 struct { a, b int } + func Main() int { + var s1 S1 + var s2 S2 + s2.a = 3 + s1.y = s2 + return s1.y.a + }`, + big.NewInt(3), + }, } func TestStructs(t *testing.T) {