compiler: support nested struct reading

This commit is contained in:
Evgenii Stratonikov 2020-05-20 11:05:01 +03:00
parent c751472852
commit 1e40f9dac0
2 changed files with 20 additions and 9 deletions

View file

@ -753,17 +753,14 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor {
return nil return nil
case *ast.SelectorExpr: case *ast.SelectorExpr:
switch t := n.X.(type) { strct, ok := c.typeOf(n.X).Underlying().(*types.Struct)
case *ast.Ident: if !ok {
if strct, ok := c.typeOf(t).Underlying().(*types.Struct); ok { c.prog.Err = fmt.Errorf("selectors are supported only on structs")
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")
return nil return nil
} }
ast.Walk(c, n.X) // load the struct
i := indexOfStruct(strct, n.Sel.Name)
c.emitLoadField(i) // load the field
return nil return nil
case *ast.UnaryExpr: case *ast.UnaryExpr:

View file

@ -338,6 +338,20 @@ var structTestCases = []testCase{
}`, }`,
big.NewInt(2), 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) { func TestStructs(t *testing.T) {