ocaml: phase 1 unit/wildcard params + 180s timeout (+5 tests, 283 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 34s

Parser: try-consume-param! handles ident, wildcard _ (fresh __wild_N
name), unit () (fresh __unit_N), typed (x : T) (skips signature).
parse-fun and parse-let (inline) reuse the helper; top-level
parse-decl-let inlines a similar test.

test.sh timeout bumped from 60s to 180s — the growing suite was hitting
the cap and reporting spurious failures.
This commit is contained in:
2026-05-08 09:21:06 +00:00
parent c8bfd22786
commit 74b80e6b0e
3 changed files with 100 additions and 22 deletions

View File

@@ -282,6 +282,56 @@
(list :pcons lhs (parse-pattern-cons))))
(else lhs)))))
(set! parse-pattern (fn () (parse-pattern-cons)))
(define peek-tok-at
(fn (n)
(if (< (+ idx n) tok-len) (nth tokens (+ idx n)) nil)))
;; Param consumption — matches ident, `_` (wildcard), or `()`
;; (unit). Returns a fresh ident name or nil if no param at cursor.
(define wild-counter (list 0))
(define try-consume-param!
(fn ()
(cond
((and (check-tok? "ident" nil)
(= (ocaml-tok-value (peek-tok)) "_"))
(begin
(advance-tok!)
(set-nth! wild-counter 0 (+ (nth wild-counter 0) 1))
(str "__wild_" (nth wild-counter 0))))
((check-tok? "ident" nil)
(let ((nm (ocaml-tok-value (peek-tok))))
(begin (advance-tok!) nm)))
((and (at-op? "(") (= (ocaml-tok-value (peek-tok-at 1)) ")"))
(begin
(advance-tok!) (advance-tok!)
(set-nth! wild-counter 0 (+ (nth wild-counter 0) 1))
(str "__unit_" (nth wild-counter 0))))
((and (at-op? "(") (= (ocaml-tok-type (peek-tok-at 1)) "ident"))
;; (x : T) — typed param. Skip the `: T` part.
(let ((nm (ocaml-tok-value (peek-tok-at 1))))
(begin
(advance-tok!) (advance-tok!)
(when (at-op? ":")
(begin
;; Skip until matching `)`.
(let ((d 1))
(begin
(define skip
(fn ()
(cond
((>= idx tok-len) nil)
((at-op? "(")
(begin (set! d (+ d 1)) (advance-tok!) (skip)))
((at-op? ")")
(cond
((= d 1) nil)
(else (begin (set! d (- d 1)) (advance-tok!) (skip)))))
(else (begin (advance-tok!) (skip))))))
(skip)))))
(consume! "op" ")")
nm)))
(else nil))))
(define parse-expr (fn () nil))
(define parse-expr-no-seq (fn () nil))
(define parse-tuple (fn () nil))
@@ -492,14 +542,10 @@
(begin
(define
collect-params
(fn
()
(when
(check-tok? "ident" nil)
(begin
(append! params (ocaml-tok-value (peek-tok)))
(advance-tok!)
(collect-params)))))
(fn ()
(let ((nm (try-consume-param!)))
(when (not (= nm nil))
(begin (append! params nm) (collect-params))))))
(collect-params)
(when
(= (len params) 0)
@@ -522,14 +568,10 @@
(begin
(define
collect-params
(fn
()
(when
(check-tok? "ident" nil)
(begin
(append! params (ocaml-tok-value (peek-tok)))
(advance-tok!)
(collect-params)))))
(fn ()
(let ((nm (try-consume-param!)))
(when (not (= nm nil))
(begin (append! params nm) (collect-params))))))
(collect-params)
(consume! "op" "=")
(let
@@ -806,11 +848,22 @@
(begin
(define collect-params
(fn ()
(when (check-tok? "ident" nil)
(begin
(append! ps (ocaml-tok-value (peek-tok)))
(advance-tok!)
(collect-params)))))
(cond
((check-tok? "ident" nil)
(begin
(append! ps (ocaml-tok-value (peek-tok)))
(advance-tok!)
(collect-params)))
((and (at-op? "(")
(< (+ idx 1) tok-len)
(let ((t1 (nth tokens (+ idx 1))))
(and (= (ocaml-tok-type t1) "op")
(= (ocaml-tok-value t1) ")"))))
(begin
(advance-tok!) (advance-tok!)
(append! ps (str "__unit_" idx))
(collect-params)))
(else nil))))
(collect-params)
(consume! "op" "=")
(let ((expr-start (cur-pos)))

View File

@@ -702,9 +702,21 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 974)
(eval "(ocaml-run \"Int.min 7 3\")")
;; ── Unit / wildcard parameters ──────────────────────────────────
(epoch 1000)
(eval "(ocaml-run \"let f () = 42 in f ()\")")
(epoch 1001)
(eval "(ocaml-run \"(fun () -> 99) ()\")")
(epoch 1002)
(eval "(ocaml-run \"let f _ = 1 in f 5\")")
(epoch 1003)
(eval "(ocaml-run-program \"let f () = 7;; f ()\")")
(epoch 1004)
(eval "(ocaml-run-program \"let g _ x = x + 1;; g 99 41\")")
EPOCHS
OUTPUT=$(timeout 60 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
check() {
local epoch="$1" desc="$2" expected="$3"
@@ -1112,6 +1124,13 @@ check 972 "Int.abs -5" '5'
check 973 "Int.max" '7'
check 974 "Int.min" '3'
# ── Unit / wildcard parameters ──────────────────────────────────
check 1000 "let f () = 42 in f ()" '42'
check 1001 "(fun () -> 99) ()" '99'
check 1002 "let f _ = 1 in f 5" '1'
check 1003 "top-level let f () =" '7'
check 1004 "wildcard top-level" '42'
TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"

View File

@@ -343,6 +343,12 @@ the "mother tongue" closure: OCaml → SX → OCaml. This means:
_Newest first._
- 2026-05-08 Phase 1 — unit `()` and wildcard `_` parameters in `let f ()
= …` / `fun _ -> …` / `let f _ = …`. Parser helper `try-consume-param!`
now handles ident, wildcard `_` (renamed to `__wild_N`), unit `()`
(renamed to `__unit_N`), and typed `(x : T)` (signature skipped).
Same for top-level `parse-decl-let`. test.sh timeout extended from
60s to 180s for the growing suite. 283/283 (+5).
- 2026-05-08 Phase 6 — extended stdlib slice (+13 tests, 278 total).
Host primitives exposed via `_string_*`, `_char_*`, `_int_*`,
`_string_of_*` underscore-prefixed builtins so the OCaml-side