lua: generic for-in; ipairs/pairs/next; arity-tolerant fns +9 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-04-24 18:23:50 +00:00
parent e224fb2db0
commit 0934c4bd28
5 changed files with 313 additions and 42 deletions

View File

@@ -534,50 +534,73 @@
(let
((body (parse-block)))
(begin (consume! "keyword" "end") (list (quote lua-do) body))))))
(define
parse-for
(fn
()
(define parse-for-num-rest
(fn (name)
(begin
(consume! "op" "=")
(let ((start (parse-expr)))
(begin
(consume! "op" ",")
(let ((stop (parse-expr)) (step nil))
(begin
(when (at-op? ",")
(begin
(advance-tok!)
(set! step (parse-expr))))
(consume! "keyword" "do")
(let ((body (parse-block)))
(begin
(consume! "keyword" "end")
(list (quote lua-for-num) name start stop step body))))))))))
(define parse-for-in-names
(fn (names)
(cond
((at-op? ",")
(begin
(advance-tok!)
(let ((nt (peek-tok)))
(begin
(when (not (= (lua-tok-type nt) "ident"))
(error "lua-parse: expected name after , in for"))
(let ((nm (lua-tok-value nt)))
(begin
(advance-tok!)
(parse-for-in-names (append names (list nm)))))))))
(else names))))
(define parse-for-in-exps
(fn (exps)
(cond
((at-op? ",")
(begin
(advance-tok!)
(parse-for-in-exps (append exps (list (parse-expr))))))
(else exps))))
(define parse-for-in-rest
(fn (names)
(begin
(consume! "keyword" "in")
(let ((exps (parse-for-in-exps (list (parse-expr)))))
(begin
(consume! "keyword" "do")
(let ((body (parse-block)))
(begin
(consume! "keyword" "end")
(list (quote lua-for-in) names exps body))))))))
(define parse-for
(fn ()
(begin
(consume! "keyword" "for")
(let
((t (peek-tok)))
(let ((t (peek-tok)))
(begin
(when
(not (= (lua-tok-type t) "ident"))
(when (not (= (lua-tok-type t) "ident"))
(error "lua-parse: expected name in for"))
(let
((name (lua-tok-value t)))
(let ((name (lua-tok-value t)))
(begin
(advance-tok!)
(when
(not (at-op? "="))
(error "lua-parse: only numeric for supported"))
(consume! "op" "=")
(let
((start (parse-expr)))
(begin
(consume! "op" ",")
(let
((stop (parse-expr)) (step nil))
(begin
(when
(at-op? ",")
(begin
(advance-tok!)
(set! step (parse-expr))))
(consume! "keyword" "do")
(let
((body (parse-block)))
(begin
(consume! "keyword" "end")
(list
(quote lua-for-num)
name
start
stop
step
body))))))))))))))
(cond
((at-op? "=") (parse-for-num-rest name))
(else
(parse-for-in-rest (parse-for-in-names (list name))))))))))))
(define
parse-funcname
(fn