js-on-sx: optional chaining ?.

Parser: jp-parse-postfix handles op "?." followed by ident / [ / (
emitting (js-optchain-member obj name), (js-optchain-index obj k),
or (js-optchain-call callee args).

Transpile: each emits (js-optchain-get obj key) or (js-optchain-call
fn args).

Runtime: js-optchain-get and js-optchain-call short-circuit to
js-undefined when receiver is null/undefined.

423/425 unit (+5), 148/148 slice unchanged.
This commit is contained in:
2026-04-23 22:38:45 +00:00
parent 067c0ab34a
commit 18ae63b0bd
4 changed files with 103 additions and 0 deletions

View File

@@ -1081,6 +1081,18 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 2603)
(eval "(js-eval \"var pt = {px: 100}; var {px} = pt; px + 1\")")
;; ── Phase 11.optchain: ?. optional chaining ─────────────────────
(epoch 2700)
(eval "(js-eval \"var o = {x: 5}; o?.x\")")
(epoch 2701)
(eval "(js-eval \"var o = null; o?.x\")")
(epoch 2702)
(eval "(js-eval \"var o = undefined; o?.x\")")
(epoch 2703)
(eval "(js-eval \"var o = {a:{b:7}}; o?.a?.b\")")
(epoch 2704)
(eval "(js-eval \"var o = {a:null}; var r = o?.a?.b; r === undefined\")")
EPOCHS
@@ -1664,6 +1676,13 @@ check 2601 "arr destructure" '6'
check 2602 "arr destructure skip" '4'
check 2603 "obj partial+add" '101'
# ── Phase 11.optchain ──────────────────────────────────────────
check 2700 "?. obj present" '5'
check 2701 "?. obj null" 'undefined'
check 2702 "?. obj undef" 'undefined'
check 2703 "?. chained" '7'
check 2704 "?. null-chain" 'true'
TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then
echo "$PASS/$TOTAL JS-on-SX tests passed"