summaryrefslogtreecommitdiff
path: root/parser
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2023-11-20 19:28:31 +0100
committerMarc Vertes <mvertes@free.fr>2023-11-20 19:28:31 +0100
commitae58deb5da1fa2ae5e461783ce592a9b962da778 (patch)
treede1d3bf4ce4ceea9c7386d191aecb6801b407ca0 /parser
parent6a0490257bf235d011004bc303306f617ac6ea31 (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.
Diffstat (limited to 'parser')
-rw-r--r--parser/compiler.go6
-rw-r--r--parser/expr.go2
-rw-r--r--parser/interpreter_test.go7
-rw-r--r--parser/type.go9
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()
}