From c922c797204069f42a7abf88500c5708f68a8e43 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Wed, 21 Jan 2026 19:26:42 +0100 Subject: 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. --- parser/parse.go | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'parser/parse.go') 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 } -- cgit v1.2.3