lua: proper early-return via guard+raise sentinel; fixes if-then-return-end-rest +3 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-04-24 21:46:23 +00:00
parent b1bed8e0e5
commit 68b0a279f8
6 changed files with 104 additions and 60 deletions

View File

@@ -1503,9 +1503,15 @@
(guard
(e (true (list (quote lua-multi) nil (str e))))
(let ((compiled (lua-transpile src)))
(let ((wrapped (list (make-symbol "fn") (list (make-symbol "&rest") (make-symbol "__args"))
(list (make-symbol "let") (list) compiled))))
(eval-expr wrapped))))))
(let ((guarded (list
(make-symbol "guard")
(list (make-symbol "e")
(list
(list (make-symbol "lua-return-sentinel?") (make-symbol "e"))
(list (make-symbol "lua-return-value") (make-symbol "e"))))
(list (make-symbol "let") (list) compiled))))
(let ((wrapped (list (make-symbol "fn") (list (make-symbol "&rest") (make-symbol "__args")) guarded)))
(eval-expr wrapped)))))))
(define loadstring lua-loadstring)
(define load lua-loadstring)
@@ -1630,3 +1636,13 @@
(va-build skip)
(dict-set! t "n" n)
t))))
;; Return-sentinel: wrap function bodies so mid-block `return` can escape.
(define
lua-return-sentinel?
(fn (e)
(and (= (type-of e) "list") (> (len e) 0) (= (first e) (quote lua-ret)))))
(define
lua-return-value
(fn (e) (if (> (len e) 1) (nth e 1) nil)))

View File

@@ -11,7 +11,7 @@
"top_failure_modes": [
[
"other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
9
10
],
[
"timeout",
@@ -22,11 +22,7 @@
2
],
[
"other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"lua: attempt to compare incompat",
1
],
[
"other: Unhandled exception: \\\"Not callable: nil (kont=10 frames)\\",
"other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"lua: concat on list and string\\\\",
1
]
],
@@ -47,19 +43,19 @@
"name": "attrib.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 6000
"ms": 6225
},
{
"name": "big.lua",
"status": "timeout",
"reason": "per-test timeout",
"ms": 8006
"ms": 8008
},
{
"name": "calls.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 4946
"ms": 5175
},
{
"name": "checktable.lua",
@@ -71,7 +67,7 @@
"name": "closure.lua",
"status": "timeout",
"reason": "per-test timeout",
"ms": 8003
"ms": 8007
},
{
"name": "code.lua",
@@ -82,8 +78,8 @@
{
"name": "constructs.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"lua: attempt to compare incompat",
"ms": 4533
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"lua: concat on list and string\\\\",
"ms": 4874
},
{
"name": "db.lua",
@@ -94,14 +90,14 @@
{
"name": "errors.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Not callable: nil (kont=10 frames)\\",
"ms": 3217
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 3289
},
{
"name": "events.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 7215
"ms": 7546
},
{
"name": "files.lua",
@@ -119,13 +115,13 @@
"name": "literals.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 1901
"ms": 1888
},
{
"name": "locals.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"lua: attempt to call non-functio",
"ms": 1693
"ms": 1721
},
{
"name": "main.lua",
@@ -137,43 +133,43 @@
"name": "math.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 4095
"ms": 4231
},
{
"name": "nextvar.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 7177
"ms": 7290
},
{
"name": "pm.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 6048
"ms": 6155
},
{
"name": "sort.lua",
"status": "timeout",
"reason": "per-test timeout",
"ms": 8007
"ms": 8006
},
{
"name": "strings.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 3990
"ms": 4215
},
{
"name": "vararg.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"assertion failed!\\\\\\\"\\",
"ms": 2249
"ms": 2288
},
{
"name": "verybig.lua",
"status": "fail",
"reason": "other: Unhandled exception: \\\"Unhandled exception: \\\\\\\"lua: attempt to call non-functio",
"ms": 572
"ms": 622
}
]
}

View File

@@ -5,11 +5,10 @@ fail=13 timeout=3 skip=8 total=24
## Top failure modes
- **9x** other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\
- **10x** other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\
- **3x** timeout
- **2x** other: Unhandled exception: \"Unhandled exception: \\\"lua: attempt to call non-functio
- **1x** other: Unhandled exception: \"Unhandled exception: \\\"lua: attempt to compare incompat
- **1x** other: Unhandled exception: \"Not callable: nil (kont=10 frames)\
- **1x** other: Unhandled exception: \"Unhandled exception: \\\"lua: concat on list and string\\
## Per-test results
@@ -17,25 +16,25 @@ fail=13 timeout=3 skip=8 total=24
|---|---|---|---:|
| all.lua | skip | driver uses dofile to chain other tests | 0 |
| api.lua | skip | requires testC (C debug library) | 0 |
| attrib.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 6000 |
| big.lua | timeout | per-test timeout | 8006 |
| calls.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 4946 |
| attrib.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 6225 |
| big.lua | timeout | per-test timeout | 8008 |
| calls.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 5175 |
| checktable.lua | skip | internal debug helpers | 0 |
| closure.lua | timeout | per-test timeout | 8003 |
| closure.lua | timeout | per-test timeout | 8007 |
| code.lua | skip | bytecode inspection via debug library | 0 |
| constructs.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"lua: attempt to compare incompat | 4533 |
| constructs.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"lua: concat on list and string\\ | 4874 |
| db.lua | skip | debug library | 0 |
| errors.lua | fail | other: Unhandled exception: \"Not callable: nil (kont=10 frames)\ | 3217 |
| events.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 7215 |
| errors.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 3289 |
| events.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 7546 |
| files.lua | skip | io library | 0 |
| gc.lua | skip | collectgarbage / finalisers | 0 |
| literals.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 1901 |
| locals.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"lua: attempt to call non-functio | 1693 |
| literals.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 1888 |
| locals.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"lua: attempt to call non-functio | 1721 |
| main.lua | skip | standalone interpreter driver | 0 |
| math.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 4095 |
| nextvar.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 7177 |
| pm.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 6048 |
| sort.lua | timeout | per-test timeout | 8007 |
| strings.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 3990 |
| vararg.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 2249 |
| verybig.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"lua: attempt to call non-functio | 572 |
| math.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 4231 |
| nextvar.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 7290 |
| pm.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 6155 |
| sort.lua | timeout | per-test timeout | 8006 |
| strings.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 4215 |
| vararg.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"assertion failed!\\\"\ | 2288 |
| verybig.lua | fail | other: Unhandled exception: \"Unhandled exception: \\\"lua: attempt to call non-functio | 622 |

View File

@@ -936,6 +936,14 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 1842)
(eval "(lua-eval-ast \"if -2^2 == -4 then return 1 else return 0 end\")")
;; ── Early-return inside nested block (guard+raise sentinel) ──
(epoch 1850)
(eval "(lua-eval-ast \"local function f(n) if n < 0 then return -1 end return n * 2 end return f(-5)\")")
(epoch 1851)
(eval "(lua-eval-ast \"local function f(n) if n < 0 then return -1 end return n * 2 end return f(7)\")")
(epoch 1852)
(eval "(lua-eval-ast \"function f(i) if type(i) ~= \\\"number\\\" then return i, \\\"jojo\\\" end if i > 0 then return i, f(i-1) end end local a, b = f(3) return a\")")
EPOCHS
OUTPUT=$(timeout 60 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
@@ -1414,6 +1422,11 @@ check 1840 "-2^2 = -4" '-4'
check 1841 "2^3^2 = 512 (right-assoc)" '512'
check 1842 "-2^2 == -4 true" '1'
# ── Early-return inside nested block ─────────────────────────
check 1850 "early return negative path" '-1'
check 1851 "non-early return path" '14'
check 1852 "nested early-return recursion" '3'
TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then
echo "ok $PASS/$TOTAL Lua-on-SX tests passed"

View File

@@ -187,6 +187,17 @@
(make-symbol "arg")
(list (make-symbol "lua-varargs-arg-table") (make-symbol "__args") n))))
(define
lua-tx-function-guard
(fn (body-sx)
(list
(make-symbol "guard")
(list (make-symbol "e")
(list
(list (make-symbol "lua-return-sentinel?") (make-symbol "e"))
(list (make-symbol "lua-return-value") (make-symbol "e"))))
body-sx)))
(define
lua-tx-function
(fn
@@ -200,7 +211,7 @@
(list
(make-symbol "fn")
(list (make-symbol "&rest") (make-symbol "__args"))
(lua-tx body)))
(lua-tx-function-guard (lua-tx body))))
(else
(let
((bindings (lua-tx-function-bindings params 0)))
@@ -215,10 +226,11 @@
(list
(make-symbol "fn")
(list (make-symbol "&rest") (make-symbol "__args"))
(list
(make-symbol "let")
all-bindings
(lua-tx body))))))))))
(lua-tx-function-guard
(list
(make-symbol "let")
all-bindings
(lua-tx body)))))))))))
(define
lua-tx-block
@@ -460,13 +472,18 @@
(node)
(let
((exps (nth node 1)))
(cond
((= (len exps) 0) nil)
((= (len exps) 1) (lua-tx (first exps)))
(else
(list
(make-symbol "lua-pack-return")
(cons (make-symbol "list") (lua-tx-multi-args exps 0))))))))
(let
((val
(cond
((= (len exps) 0) nil)
((= (len exps) 1) (lua-tx (first exps)))
(else
(list
(make-symbol "lua-pack-return")
(cons (make-symbol "list") (lua-tx-multi-args exps 0)))))))
(list
(make-symbol "raise")
(list (make-symbol "list") (list (make-symbol "quote") (make-symbol "lua-ret")) val))))))
(define
lua-tx-local-function
@@ -500,7 +517,9 @@
(define
lua-eval-ast
(fn (src) (let ((sx (lua-transpile src))) (eval-expr sx))))
(fn (src)
(let ((sx (lua-transpile src)))
(eval-expr (lua-tx-function-guard sx)))))
(define
lua-tx-multi-args