From d54c60ded3ac2e805ea23137d37f02daf873535c Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Sun, 2 Aug 2020 14:56:47 +0300 Subject: [PATCH] compiler: support pointer dereferencing for structs Signed-off-by: Evgenii Stratonikov --- pkg/compiler/codegen.go | 10 ++++++++++ pkg/compiler/pointer_test.go | 12 ++++++++++++ 2 files changed, 22 insertions(+) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 2691ff35e..ad4a07029 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -610,6 +610,16 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { c.emitLoadConst(c.typeAndValueOf(n)) return nil + case *ast.StarExpr: + _, ok := c.getStruct(c.typeOf(n.X)) + if !ok { + c.prog.Err = errors.New("dereferencing is only supported on structs") + return nil + } + ast.Walk(c, n.X) + c.emitConvert(stackitem.StructT) + return nil + case *ast.Ident: if tv := c.typeAndValueOf(n); tv.Value != nil { c.emitLoadConst(tv) diff --git a/pkg/compiler/pointer_test.go b/pkg/compiler/pointer_test.go index 090101056..7b9e8c2dd 100644 --- a/pkg/compiler/pointer_test.go +++ b/pkg/compiler/pointer_test.go @@ -16,3 +16,15 @@ func TestAddressOfLiteral(t *testing.T) { func setA(s *Foo, a int) { s.A = a }` eval(t, src, big.NewInt(3)) } + +func TestPointerDereference(t *testing.T) { + src := `package foo + type Foo struct { A int } + func Main() int { + f := &Foo{A: 4} + setA(*f, 3) + return f.A + } + func setA(s Foo, a int) { s.A = a }` + eval(t, src, big.NewInt(4)) +}