summaryrefslogtreecommitdiff
path: root/parser/expr.go
diff options
context:
space:
mode:
authorMarc Vertes <mvertes@free.fr>2023-11-17 16:45:58 +0100
committerMarc Vertes <mvertes@free.fr>2023-11-17 16:45:58 +0100
commitee21c324ce8c41b589e5a39e5715223ffd154315 (patch)
tree9dfe692c787ceb65d85f3a9e04524759fab31200 /parser/expr.go
parenta79e558d825c5b777c95c5e098b01391ee36781e (diff)
parser: support selector expression to get / set struct fields
The structures are reresented by reflect values. New instructions `Field` and `Vassign` have been added to the VM to assign reflect values and access struct fields.
Diffstat (limited to 'parser/expr.go')
-rw-r--r--parser/expr.go16
1 files changed, 14 insertions, 2 deletions
diff --git a/parser/expr.go b/parser/expr.go
index 2cd19c6..c2d5eeb 100644
--- a/parser/expr.go
+++ b/parser/expr.go
@@ -10,8 +10,9 @@ import (
func (p *Parser) ParseExpr(in Tokens) (out Tokens, err error) {
log.Println("ParseExpr in:", in)
- var ops Tokens
+ var ops, selectors Tokens
var vl int
+ var selectorId string
//
// Process tokens from last to first, the goal is to reorder the tokens in
// a stack machine processing order, so it can be directly interpreted.
@@ -21,8 +22,11 @@ func (p *Parser) ParseExpr(in Tokens) (out Tokens, err error) {
// temporary assumptions: binary operators, returning 1 value
switch t.Id {
case lang.Ident:
+ if i > 0 && in[i-1].Id == lang.Period {
+ selectorId = t.Str
+ continue
+ }
// resolve symbol if not a selector rhs.
- // TODO: test for selector expr.
_, sc, ok := p.getSym(t.Str, p.scope)
if ok {
if sc != "" {
@@ -31,6 +35,10 @@ func (p *Parser) ParseExpr(in Tokens) (out Tokens, err error) {
}
out = append(out, t)
vl++
+ case lang.Period:
+ t.Str += selectorId
+ selectors = append(Tokens{t}, selectors...)
+ continue
case lang.Int, lang.String:
out = append(out, t)
vl++
@@ -64,6 +72,10 @@ func (p *Parser) ParseExpr(in Tokens) (out Tokens, err error) {
}
ops = append(ops, scanner.Token{Str: "call", Id: lang.Call, Pos: t.Pos})
}
+ if len(selectors) > 0 {
+ out = append(out, selectors...)
+ selectors = nil
+ }
if lops, lout := len(ops), len(out); lops > 0 && vl > lops {
op := ops[lops-1]
ops = ops[:lops-1]