diff --git a/lib/lua/transpile.sx b/lib/lua/transpile.sx index 424cb2e5..94b12e01 100644 --- a/lib/lua/transpile.sx +++ b/lib/lua/transpile.sx @@ -532,11 +532,48 @@ (define lua-transpile (fn (src) (lua-tx (lua-parse src)))) +(define + lua-ret-raise? + (fn (x) + (and (= (type-of x) "list") + (= (len x) 2) + (= (first x) (make-symbol "raise")) + (= (type-of (nth x 1)) "list") + (= (len (nth x 1)) 3) + (= (first (nth x 1)) (make-symbol "list")) + (= (type-of (nth (nth x 1) 1)) "list") + (= (first (nth (nth x 1) 1)) (make-symbol "quote")) + (= (nth (nth (nth x 1) 1) 1) (make-symbol "lua-ret"))))) + +(define + lua-ret-value + (fn (raise-form) (nth (nth raise-form 1) 2))) + +(define + lua-unwrap-final-return + (fn (sx) + (cond + ((lua-ret-raise? sx) (lua-ret-value sx)) + ((and (= (type-of sx) "list") (> (len sx) 0) (= (first sx) (make-symbol "begin"))) + (let ((items (rest sx))) + (cond + ((= (len items) 0) sx) + (else + (let ((last-item (nth items (- (len items) 1)))) + (cond + ((lua-ret-raise? last-item) + (let ((val (lua-ret-value last-item)) + (prefix (lua-init-before items 0 (- (len items) 1)))) + (cons (make-symbol "begin") (append prefix (list val))))) + (else sx))))))) + (else sx)))) + (define lua-eval-ast (fn (src) (let ((sx (lua-transpile src))) - (eval-expr (lua-tx-function-guard sx))))) + (let ((sx2 (lua-unwrap-final-return sx))) + (eval-expr (lua-tx-function-guard sx2)))))) (define lua-tx-multi-args diff --git a/plans/lua-on-sx.md b/plans/lua-on-sx.md index 974a1866..97abea0c 100644 --- a/plans/lua-on-sx.md +++ b/plans/lua-on-sx.md @@ -82,6 +82,7 @@ Each item: implement → tests → tick box → update progress log. _Newest first. Agent appends on every commit._ +- 2026-04-24: lua: scoreboard iteration — added `lua-unwrap-final-return` (post-processor that rewrites top-level `(raise (list 'lua-ret V))` → `V` so top-level defines leak to SX top and loadstring closures can see them). Tried dropping the function-guard at top level, but too many tests use `if x then return 0 else return err end` at chunk tail, whose returns aren't at the *statement-list* tail — guard still needed. Kept guard + unwrap-as-no-op. Scoreboard unchanged. - 2026-04-24: lua: scoreboard iteration — `lua-pat-strip-captures` helper lets patterns with `(...)` capture parens at least match (captures themselves aren't returned yet — match returns whole match). Unblocks common Lua pattern idioms like `(%a+)=(%d+)`. Scoreboard unchanged. - 2026-04-24: lua: scoreboard iteration — extended pattern engine to `string.match`/`gmatch`/`gsub`. `gsub` now supports string/function/table replacement modes. 381/381 green (+6 pattern tests). - 2026-04-24: lua: scoreboard iteration — **Lua pattern engine (minimal)** for `string.find`. Supports character classes (`%d`/`%a`/`%s`/`%w`/`%p`/`%l`/`%u`/`%c`/`%x` + complements), `.` any, `^`/`$` anchors, quantifiers `*`/`+`/`-`/`?`, literal chars, `%%`. Added `plain` arg pathway. match/gmatch/gsub still literal. Scoreboard unchanged (pattern-using tests still hit other issues downstream).