From ae58deb5da1fa2ae5e461783ce592a9b962da778 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Mon, 20 Nov 2023 19:28:31 +0100 Subject: parser: add pointer support (work in progress) This is incomplete because the scalar variables are not addressable right now. To be addressable they must be represented as reflect values, not interfaces. --- parser/compiler.go | 6 ++++++ parser/expr.go | 2 +- parser/interpreter_test.go | 7 +++++++ parser/type.go | 9 ++++++++- 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/parser/compiler.go b/parser/compiler.go index bdf801b..36aa9d8 100644 --- a/parser/compiler.go +++ b/parser/compiler.go @@ -87,6 +87,12 @@ func (c *Compiler) Codegen(tokens Tokens) (err error) { case lang.Plus: // Nothing to do. + case lang.Address: + emit(int64(t.Pos), vm.Address) + + case lang.Deref: + emit(int64(t.Pos), vm.Deref) + case lang.Index: emit(int64(t.Pos), vm.Index) diff --git a/parser/expr.go b/parser/expr.go index 207f38b..806fd75 100644 --- a/parser/expr.go +++ b/parser/expr.go @@ -42,7 +42,7 @@ func (p *Parser) ParseExpr(in Tokens) (out Tokens, err error) { case lang.Int, lang.String: out = append(out, t) vl++ - case lang.Define, lang.Add, lang.Sub, lang.Assign, lang.Equal, lang.Greater, lang.Less, lang.Mul, lang.Land, lang.Lor, lang.Shl, lang.Shr, lang.Not: + case lang.Define, lang.Add, lang.Sub, lang.Assign, lang.Equal, lang.Greater, lang.Less, lang.Mul, lang.Land, lang.Lor, lang.Shl, lang.Shr, lang.Not, lang.And: if i == 0 || in[i-1].Id.IsOperator() { // An operator preceded by an operator or no token is unary. t.Id = lang.UnaryOp[t.Id] diff --git a/parser/interpreter_test.go b/parser/interpreter_test.go index db9b916..9555475 100644 --- a/parser/interpreter_test.go +++ b/parser/interpreter_test.go @@ -192,6 +192,13 @@ func TestArray(t *testing.T) { }) } +func TestPointer(t *testing.T) { + run(t, []etest{ + {src: "var a *int; a", res: ""}, + //{src: "var a int = 2; var b *int = &a; b", res: "2"}, + }) +} + func TestStruct(t *testing.T) { run(t, []etest{ {src: "type T struct {a string; b, c int}; var t T; t", res: "{ 0 0}"}, diff --git a/parser/type.go b/parser/type.go index 573ae6f..31af1e3 100644 --- a/parser/type.go +++ b/parser/type.go @@ -51,6 +51,13 @@ func (p *Parser) ParseTypeExpr(in Tokens) (typ reflect.Type, err error) { } return reflect.SliceOf(typ), nil + case lang.Mul: + typ, err := p.ParseTypeExpr(in[1:]) + if err != nil { + return nil, err + } + return reflect.PointerTo(typ), nil + case lang.Func: // Get argument and return token positions depending on function pattern: // method with receiver, named function or anonymous closure. @@ -165,7 +172,7 @@ func (p *Parser) parseParamTypes(in Tokens, flag typeFlag) (types []reflect.Type func (p *Parser) addSymVar(index int, name string, typ reflect.Type, flag typeFlag, local bool) { var zv any = reflect.New(typ).Elem() switch typ.Kind() { - case reflect.Struct, reflect.Array, reflect.Slice: + case reflect.Struct, reflect.Array, reflect.Slice, reflect.Pointer: default: zv = zv.(reflect.Value).Interface() } -- cgit v1.2.3