lua: multi-return + unpack at call sites (+10 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
This commit is contained in:
@@ -169,3 +169,49 @@
|
||||
(if (= t nil) nil (let ((v (get t (str k)))) (if (= v nil) nil v)))))
|
||||
|
||||
(define lua-set! (fn (t k v) (assoc t (str k) v)))
|
||||
|
||||
(define
|
||||
lua-multi?
|
||||
(fn
|
||||
(v)
|
||||
(and
|
||||
(= (type-of v) "list")
|
||||
(> (len v) 0)
|
||||
(= (first v) (quote lua-multi)))))
|
||||
|
||||
(define
|
||||
lua-first
|
||||
(fn
|
||||
(v)
|
||||
(cond
|
||||
((lua-multi? v) (if (> (len v) 1) (nth v 1) nil))
|
||||
(else v))))
|
||||
|
||||
(define
|
||||
lua-nth-ret
|
||||
(fn
|
||||
(v i)
|
||||
(cond
|
||||
((lua-multi? v)
|
||||
(let ((idx (+ i 1))) (if (< idx (len v)) (nth v idx) nil)))
|
||||
(else (if (= i 0) v nil)))))
|
||||
|
||||
(define
|
||||
lua-pack-build
|
||||
(fn
|
||||
(vals i)
|
||||
(cond
|
||||
((>= i (len vals)) (list))
|
||||
((= i (- (len vals) 1))
|
||||
(let
|
||||
((last (nth vals i)))
|
||||
(if (lua-multi? last) (rest last) (list last))))
|
||||
(else (cons (nth vals i) (lua-pack-build vals (+ i 1)))))))
|
||||
|
||||
(define
|
||||
lua-pack-return
|
||||
(fn
|
||||
(vals)
|
||||
(cond
|
||||
((= (len vals) 0) (list (quote lua-multi)))
|
||||
(else (cons (quote lua-multi) (lua-pack-build vals 0))))))
|
||||
|
||||
@@ -460,6 +460,28 @@ cat > "$TMPFILE" << 'EPOCHS'
|
||||
(epoch 561)
|
||||
(eval "(lua-eval-ast \"local function sum_to(n) local s = 0 for i = 1, n do s = s + i end return s end return sum_to(10)\")")
|
||||
|
||||
;; ── Phase 3: multi-return + unpack ────────────────────────────
|
||||
(epoch 570)
|
||||
(eval "(lua-eval-ast \"local a, b = (function() return 1, 2 end)() return a + b\")")
|
||||
(epoch 571)
|
||||
(eval "(lua-eval-ast \"local function two() return 10, 20 end local a, b = two() return b - a\")")
|
||||
(epoch 572)
|
||||
(eval "(lua-eval-ast \"function swap(a, b) return b, a end local x, y = swap(1, 2) return x * 10 + y\")")
|
||||
(epoch 573)
|
||||
(eval "(lua-eval-ast \"local function three() return 1, 2, 3 end local a, b = three() return a * 10 + b\")")
|
||||
(epoch 574)
|
||||
(eval "(lua-eval-ast \"local function two() return 1, 2 end local a, b, c = two() if c == nil then return a + b else return 0 end\")")
|
||||
(epoch 575)
|
||||
(eval "(lua-eval-ast \"local function two() return 5, 7 end local function outer() return two() end local a, b = outer() return a + b\")")
|
||||
(epoch 576)
|
||||
(eval "(lua-eval-ast \"local function two() return 9, 9 end local a, b = two(), 5 return a * 10 + b\")")
|
||||
(epoch 577)
|
||||
(eval "(lua-eval-ast \"local function pair() return 4, 5 end local x = pair() return x + 1\")")
|
||||
(epoch 578)
|
||||
(eval "(lua-eval-ast \"local function none() return end local a, b = none() if a == nil and b == nil then return 99 else return 0 end\")")
|
||||
(epoch 579)
|
||||
(eval "(lua-eval-ast \"local a = 0 local b = 0 local function m() return 7, 11 end a, b = m() return a + b\")")
|
||||
|
||||
EPOCHS
|
||||
|
||||
OUTPUT=$(timeout 60 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||
@@ -710,6 +732,18 @@ check 551 "twice(+1, 5)" '7'
|
||||
check 560 "max with if" '7'
|
||||
check 561 "sum_to(10) with for" '55'
|
||||
|
||||
# ── Phase 3: multi-return + unpack ────────────────────────────
|
||||
check 570 "anon-fn returns 2, unpack" '3'
|
||||
check 571 "local fn returns 2, unpack" '10'
|
||||
check 572 "swap via multi-return" '21'
|
||||
check 573 "extra returns discarded" '12'
|
||||
check 574 "missing returns nil-padded" '3'
|
||||
check 575 "tail-return passthrough" '12'
|
||||
check 576 "non-last call truncated to 1st" '95'
|
||||
check 577 "single-assign truncates to 1st" '5'
|
||||
check 578 "empty return → all nil" '99'
|
||||
check 579 "multi-assign (non-local)" '18'
|
||||
|
||||
TOTAL=$((PASS + FAIL))
|
||||
if [ $FAIL -eq 0 ]; then
|
||||
echo "ok $PASS/$TOTAL Lua-on-SX tests passed"
|
||||
|
||||
@@ -190,9 +190,13 @@
|
||||
(list
|
||||
(make-symbol "define")
|
||||
(make-symbol (first names))
|
||||
(if (> (len exps) 0) (lua-tx (first exps)) nil)))
|
||||
(else
|
||||
(cons (make-symbol "begin") (lua-tx-local-pairs names exps 0)))))))
|
||||
(if
|
||||
(> (len exps) 0)
|
||||
(list (make-symbol "lua-first") (lua-tx (first exps)))
|
||||
nil)))
|
||||
((= (len exps) 0)
|
||||
(cons (make-symbol "begin") (lua-tx-local-pairs names exps 0)))
|
||||
(else (lua-tx-multi-local names exps))))))
|
||||
|
||||
(define
|
||||
lua-tx-local-pairs
|
||||
@@ -216,9 +220,12 @@
|
||||
((lhss (nth node 1)) (rhss (nth node 2)))
|
||||
(cond
|
||||
((= (len lhss) 1)
|
||||
(lua-tx-single-assign (first lhss) (lua-tx (first rhss))))
|
||||
(else
|
||||
(cons (make-symbol "begin") (lua-tx-assign-pairs lhss rhss 0)))))))
|
||||
(lua-tx-single-assign
|
||||
(first lhss)
|
||||
(list (make-symbol "lua-first") (lua-tx (first rhss)))))
|
||||
((= (len rhss) 0)
|
||||
(cons (make-symbol "begin") (lua-tx-assign-pairs lhss rhss 0)))
|
||||
(else (lua-tx-multi-assign lhss rhss))))))
|
||||
|
||||
(define
|
||||
lua-tx-assign-pairs
|
||||
@@ -399,7 +406,10 @@
|
||||
(cond
|
||||
((= (len exps) 0) nil)
|
||||
((= (len exps) 1) (lua-tx (first exps)))
|
||||
(else (cons (make-symbol "list") (map lua-tx exps)))))))
|
||||
(else
|
||||
(list
|
||||
(make-symbol "lua-pack-return")
|
||||
(cons (make-symbol "list") (lua-tx-multi-args exps 0))))))))
|
||||
|
||||
(define
|
||||
lua-tx-local-function
|
||||
@@ -434,3 +444,91 @@
|
||||
(define
|
||||
lua-eval-ast
|
||||
(fn (src) (let ((sx (lua-transpile src))) (eval-expr sx))))
|
||||
|
||||
(define
|
||||
lua-tx-multi-args
|
||||
(fn
|
||||
(exps i)
|
||||
(cond
|
||||
((>= i (len exps)) (list))
|
||||
((= i (- (len exps) 1))
|
||||
(cons (lua-tx (nth exps i)) (lua-tx-multi-args exps (+ i 1))))
|
||||
(else
|
||||
(cons
|
||||
(list (make-symbol "lua-first") (lua-tx (nth exps i)))
|
||||
(lua-tx-multi-args exps (+ i 1)))))))
|
||||
|
||||
(define
|
||||
lua-tx-multi-rhs
|
||||
(fn
|
||||
(exps)
|
||||
(list
|
||||
(make-symbol "lua-pack-return")
|
||||
(cons (make-symbol "list") (lua-tx-multi-args exps 0)))))
|
||||
|
||||
(define
|
||||
lua-tx-multi-local
|
||||
(fn
|
||||
(names exps)
|
||||
(let
|
||||
((tmp (make-symbol "__rets")))
|
||||
(cons
|
||||
(make-symbol "begin")
|
||||
(append
|
||||
(lua-tx-multi-local-decls names 0)
|
||||
(list
|
||||
(list
|
||||
(make-symbol "let")
|
||||
(list (list tmp (lua-tx-multi-rhs exps)))
|
||||
(cons
|
||||
(make-symbol "begin")
|
||||
(lua-tx-multi-local-sets names tmp 0)))))))))
|
||||
|
||||
(define
|
||||
lua-tx-multi-local-decls
|
||||
(fn
|
||||
(names i)
|
||||
(if
|
||||
(>= i (len names))
|
||||
(list)
|
||||
(cons
|
||||
(list (make-symbol "define") (make-symbol (nth names i)) nil)
|
||||
(lua-tx-multi-local-decls names (+ i 1))))))
|
||||
|
||||
(define
|
||||
lua-tx-multi-local-sets
|
||||
(fn
|
||||
(names tmp i)
|
||||
(if
|
||||
(>= i (len names))
|
||||
(list)
|
||||
(cons
|
||||
(list
|
||||
(make-symbol "set!")
|
||||
(make-symbol (nth names i))
|
||||
(list (make-symbol "lua-nth-ret") tmp i))
|
||||
(lua-tx-multi-local-sets names tmp (+ i 1))))))
|
||||
|
||||
(define
|
||||
lua-tx-multi-assign
|
||||
(fn
|
||||
(lhss rhss)
|
||||
(let
|
||||
((tmp (make-symbol "__rets")))
|
||||
(list
|
||||
(make-symbol "let")
|
||||
(list (list tmp (lua-tx-multi-rhs rhss)))
|
||||
(cons (make-symbol "begin") (lua-tx-multi-assign-pairs lhss tmp 0))))))
|
||||
|
||||
(define
|
||||
lua-tx-multi-assign-pairs
|
||||
(fn
|
||||
(lhss tmp i)
|
||||
(if
|
||||
(>= i (len lhss))
|
||||
(list)
|
||||
(cons
|
||||
(lua-tx-single-assign
|
||||
(nth lhss i)
|
||||
(list (make-symbol "lua-nth-ret") tmp i))
|
||||
(lua-tx-multi-assign-pairs lhss tmp (+ i 1))))))
|
||||
|
||||
@@ -52,7 +52,7 @@ Each item: implement → tests → tick box → update progress log.
|
||||
|
||||
### Phase 3 — tables + functions + first PUC-Rio slice
|
||||
- [x] `function` (anon, local, top-level), closures
|
||||
- [ ] Multi-return: return as list, unpack at call sites
|
||||
- [x] Multi-return: return as list, unpack at call sites
|
||||
- [ ] Table constructors (array + hash + computed keys)
|
||||
- [ ] Raw table access `t.k` / `t[k]` (no metatables yet)
|
||||
- [ ] Vendor PUC-Rio 5.1.5 suite to `lib/lua/lua-tests/` (just `.lua` files)
|
||||
@@ -82,6 +82,7 @@ Each item: implement → tests → tick box → update progress log.
|
||||
|
||||
_Newest first. Agent appends on every commit._
|
||||
|
||||
- 2026-04-24: lua: multi-return — `lua-multi` tagged value, `lua-first`/`lua-nth-ret`/`lua-pack-return` runtime, tail-position spread in return/local/assign. 185 total tests.
|
||||
- 2026-04-24: lua: phase 3 — functions (anon/local/top-level) + closures verified (lexical capture, mutation-through-closure, recursion, HOFs). 175 total tests.
|
||||
- 2026-04-24: lua: phase 2 transpile — arithmetic, comparison, short-circuit logical, `..` concat, if/while/repeat/for-num/local/assign. 157 total tests green.
|
||||
- 2026-04-24: lua: parser (exprs with precedence, all phase-1 statements, funcbody, table ctors, method/chained calls) — 112 total tokenizer+parser tests
|
||||
|
||||
Reference in New Issue
Block a user