ocaml: phase 4 'M.(expr)' local-open expression form (+3 tests, 481 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 21s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 21s
In parse-atom-postfix, after consuming '.', if the next token is '(',
parse the inner expression and emit (:let-open M EXPR) instead of
:field. Cleanly composes with the existing :let-open evaluator and
loops to allow chained dot postfixes.
List.(length [1;2;3]) = 3
List.(map (fun x -> x + 1) [1;2;3]) = [2;3;4]
Option.(map (fun x -> x * 10) (Some 4)) = Some 40
This commit is contained in:
@@ -562,11 +562,22 @@
|
|||||||
(when (at-op? ".")
|
(when (at-op? ".")
|
||||||
(begin
|
(begin
|
||||||
(advance-tok!)
|
(advance-tok!)
|
||||||
(let ((tok (peek-tok)))
|
(cond
|
||||||
(begin
|
((at-op? "(")
|
||||||
(advance-tok!)
|
(begin
|
||||||
(set! head (list :field head (ocaml-tok-value tok)))
|
(advance-tok!)
|
||||||
(loop)))))))
|
(let ((inner (parse-expr)))
|
||||||
|
(begin
|
||||||
|
(consume! "op" ")")
|
||||||
|
(set! head (list :let-open head inner))
|
||||||
|
(loop)))))
|
||||||
|
(else
|
||||||
|
(let ((tok (peek-tok)))
|
||||||
|
(begin
|
||||||
|
(advance-tok!)
|
||||||
|
(set! head (list :field head
|
||||||
|
(ocaml-tok-value tok)))
|
||||||
|
(loop)))))))))
|
||||||
(loop)
|
(loop)
|
||||||
head))))
|
head))))
|
||||||
(set!
|
(set!
|
||||||
|
|||||||
@@ -1186,6 +1186,14 @@ cat > "$TMPFILE" << 'EPOCHS'
|
|||||||
(epoch 4902)
|
(epoch 4902)
|
||||||
(eval "(ocaml-run \"let open Option in map (fun x -> x + 1) (Some 5)\")")
|
(eval "(ocaml-run \"let open Option in map (fun x -> x + 1) (Some 5)\")")
|
||||||
|
|
||||||
|
;; ── M.(expr) local-open expression form ───────────────────────
|
||||||
|
(epoch 4910)
|
||||||
|
(eval "(ocaml-run \"List.(length [1;2;3])\")")
|
||||||
|
(epoch 4911)
|
||||||
|
(eval "(ocaml-run \"List.(map (fun x -> x + 1) [1;2;3])\")")
|
||||||
|
(epoch 4912)
|
||||||
|
(eval "(ocaml-run \"Option.(map (fun x -> x * 10) (Some 4))\")")
|
||||||
|
|
||||||
EPOCHS
|
EPOCHS
|
||||||
|
|
||||||
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||||
@@ -1880,6 +1888,11 @@ check 4900 "let open List; length" '3'
|
|||||||
check 4901 "let open List; map" '(2 4 6)'
|
check 4901 "let open List; map" '(2 4 6)'
|
||||||
check 4902 "let open Option; map" '("Some" 6)'
|
check 4902 "let open Option; map" '("Some" 6)'
|
||||||
|
|
||||||
|
# ── M.(expr) local-open expression form ──────────────────────────
|
||||||
|
check 4910 "M.(expr) length" '3'
|
||||||
|
check 4911 "M.(expr) map" '(2 3 4)'
|
||||||
|
check 4912 "M.(expr) Option map" '("Some" 40)'
|
||||||
|
|
||||||
TOTAL=$((PASS + FAIL))
|
TOTAL=$((PASS + FAIL))
|
||||||
if [ $FAIL -eq 0 ]; then
|
if [ $FAIL -eq 0 ]; then
|
||||||
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
||||||
|
|||||||
@@ -407,6 +407,12 @@ _Newest first._
|
|||||||
binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree *
|
binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree *
|
||||||
'a tree`) with insert + in-order traversal. Tests parametric ADT,
|
'a tree`) with insert + in-order traversal. Tests parametric ADT,
|
||||||
recursive match, List.append, List.fold_left.
|
recursive match, List.append, List.fold_left.
|
||||||
|
- 2026-05-08 Phase 4 — `M.(expr)` local-open expression form (+3
|
||||||
|
tests, 481 total). Implemented in parse-atom-postfix: after
|
||||||
|
consuming `.`, if next token is `(`, parse the inner expression and
|
||||||
|
emit `(:let-open M EXPR)` instead of `:field`. Cleanly composes with
|
||||||
|
existing `:let-open` evaluator. `List.(length [1;2;3])` → 3,
|
||||||
|
`Option.(map (fun x -> x * 10) (Some 4))` → Some 40.
|
||||||
- 2026-05-08 Phase 4 — `let open M in body` local opens (+3 tests, 478
|
- 2026-05-08 Phase 4 — `let open M in body` local opens (+3 tests, 478
|
||||||
total). Parser detects `let open` as a separate let-form, parses M
|
total). Parser detects `let open` as a separate let-form, parses M
|
||||||
as a path (Ctor(.Ctor)*), and emits `(:let-open PATH BODY)`. Eval
|
as a path (Ctor(.Ctor)*), and emits `(:let-open PATH BODY)`. Eval
|
||||||
|
|||||||
Reference in New Issue
Block a user