diff options
| author | Marc Vertes <mvertes@free.fr> | 2026-01-21 19:26:42 +0100 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2026-01-21 19:26:42 +0100 |
| commit | c922c797204069f42a7abf88500c5708f68a8e43 (patch) | |
| tree | a0379dc6f6992f0ba077b028dfd4b031dd674d98 /parser/parse.go | |
| parent | ee9397bc031dc33e4f735b3331643bbf60a0d17a (diff) | |
feat: add support for range clause and iterators
- vm: added Pull, Next and Stop instructions, to implement iterators
- lang: add Range, Next and Stop tokens
- parser: handle range clause. Still naive and incomplete.
- comp: generate iterator instructions from range clause.
Work in progress. Only initial support for slices. Many more tests
and combinations needed, but the main pattern is there now.
Diffstat (limited to 'parser/parse.go')
| -rw-r--r-- | parser/parse.go | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/parser/parse.go b/parser/parse.go index 46b1724..67d8657 100644 --- a/parser/parse.go +++ b/parser/parse.go @@ -193,25 +193,33 @@ func (p *Parser) parseGoto(in Tokens) (out Tokens, err error) { func (p *Parser) parseFor(in Tokens) (out Tokens, err error) { // TODO: detect invalid code. + var init, cond, post, body, final Tokens fc := strconv.Itoa(p.labelCount[p.scope]) p.labelCount[p.scope]++ - var init, cond, post, body Tokens + breakLabel, continueLabel := p.breakLabel, p.continueLabel + p.pushScope("for" + fc) + p.breakLabel, p.continueLabel = p.scope+"e", p.scope+"b" + defer func() { + p.breakLabel, p.continueLabel = breakLabel, continueLabel + p.popScope() + }() pre := in[1 : len(in)-1].Split(lang.Semicolon) switch len(pre) { case 1: - cond = pre[0] + if in.Index(lang.Range) >= 0 { + init = pre[0] + // cond = Tokens{{Tok: lang.Next, Str: p.scope + "c"}} + // final = Tokens{{Tok: lang.Stop, Str: p.scope + "f"}} + cond = Tokens{{Tok: lang.Next}} + final = Tokens{{Tok: lang.Stop}} + } else { + cond = pre[0] + } case 3: init, cond, post = pre[0], pre[1], pre[2] default: return nil, ErrFor } - breakLabel, continueLabel := p.breakLabel, p.continueLabel - p.pushScope("for" + fc) - p.breakLabel, p.continueLabel = p.scope+"e", p.scope+"b" - defer func() { - p.breakLabel, p.continueLabel = breakLabel, continueLabel - p.popScope() - }() if len(init) > 0 { if init, err = p.parseStmt(init); err != nil { return nil, err @@ -239,6 +247,7 @@ func (p *Parser) parseFor(in Tokens) (out Tokens, err error) { out = append(out, scanner.Token{Tok: lang.Goto, Str: p.scope + "b"}, scanner.Token{Tok: lang.Label, Str: p.scope + "e"}) + out = append(out, final...) return out, err } |
