diff options
| author | Marc Vertes <mvertes@free.fr> | 2023-11-17 16:45:58 +0100 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2023-11-17 16:45:58 +0100 |
| commit | ee21c324ce8c41b589e5a39e5715223ffd154315 (patch) | |
| tree | 9dfe692c787ceb65d85f3a9e04524759fab31200 /parser/expr.go | |
| parent | a79e558d825c5b777c95c5e098b01391ee36781e (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.go | 16 |
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] |
