diff options
| author | Marc Vertes <mvertes@free.fr> | 2023-11-20 19:28:31 +0100 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2023-11-20 19:28:31 +0100 |
| commit | ae58deb5da1fa2ae5e461783ce592a9b962da778 (patch) | |
| tree | de1d3bf4ce4ceea9c7386d191aecb6801b407ca0 | |
| parent | 6a0490257bf235d011004bc303306f617ac6ea31 (diff) | |
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.
| -rw-r--r-- | parser/compiler.go | 6 | ||||
| -rw-r--r-- | parser/expr.go | 2 | ||||
| -rw-r--r-- | parser/interpreter_test.go | 7 | ||||
| -rw-r--r-- | 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: "<nil>"}, + //{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() } |
