ocaml: phase 1+5.1 type aliases + poly_stack baseline (+3 tests, 469 / 19 baseline)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 39s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 39s
Parser: in parse-decl-type, dispatch on the post-= token:
'|' or Ctor -> sum type
'{' -> record type
otherwise -> type alias (skip to boundary)
AST (:type-alias NAME PARAMS) with body discarded. Runtime no-op since
SX has no nominal types.
poly_stack.ml baseline exercises:
module type ELEMENT = sig type t val show : t -> string end
module IntElem = struct type t = int let show x = ... end
module Make (E : ELEMENT) = struct ... use E.show ... end
module IntStack = Make(IntElem)
Demonstrates the substrate handles signature decls + abstract types +
functor parameter with sig constraint.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
"module_use.ml": 3,
|
||||
"mutable_record.ml": 10,
|
||||
"option_match.ml": 5,
|
||||
"poly_stack.ml": 5,
|
||||
"queens.ml": 2,
|
||||
"quicksort.ml": 44,
|
||||
"sum_squares.ml": 385,
|
||||
|
||||
27
lib/ocaml/baseline/poly_stack.ml
Normal file
27
lib/ocaml/baseline/poly_stack.ml
Normal file
@@ -0,0 +1,27 @@
|
||||
(* Baseline: polymorphic stack via functor over an Element module *)
|
||||
module type ELEMENT = sig type t val show : t -> string end ;;
|
||||
|
||||
module IntElem = struct
|
||||
type t = int
|
||||
let show x = Int.to_string x
|
||||
end ;;
|
||||
|
||||
module Make (E : ELEMENT) = struct
|
||||
let create () = ref []
|
||||
let push x s = s := x :: !s
|
||||
let pop s =
|
||||
match !s with
|
||||
| [] -> None
|
||||
| h :: t -> s := t ; Some h
|
||||
let length s = List.length !s
|
||||
let to_string s =
|
||||
String.concat "," (List.map E.show !s)
|
||||
end ;;
|
||||
|
||||
module IntStack = Make(IntElem) ;;
|
||||
|
||||
let s = IntStack.create () ;;
|
||||
IntStack.push 1 s ;;
|
||||
IntStack.push 2 s ;;
|
||||
IntStack.push 3 s ;;
|
||||
String.length (IntStack.to_string s)
|
||||
@@ -807,6 +807,7 @@
|
||||
(set! result (merge result (dict mname mod-val))))))))
|
||||
((= tag "type-def") nil)
|
||||
((= tag "type-def-record") nil)
|
||||
((= tag "type-alias") nil)
|
||||
((= tag "exception-def") nil)
|
||||
((= tag "module-type-def") nil)
|
||||
((= tag "open")
|
||||
@@ -993,6 +994,9 @@
|
||||
;; type r = { x : T; y : T } — runtime no-op; records
|
||||
;; are already dynamic dicts.
|
||||
nil)
|
||||
((= tag "type-alias")
|
||||
;; type t = SomeType — runtime no-op (no nominal types).
|
||||
nil)
|
||||
((= tag "module-type-def")
|
||||
;; module type S = sig … end — no-op at runtime.
|
||||
nil)
|
||||
|
||||
@@ -1242,6 +1242,29 @@
|
||||
(field-more)
|
||||
(consume! "op" "}")
|
||||
(list :type-def-record name tparams fields)))))
|
||||
;; Type alias: type t = int / type t = 'a list / etc.
|
||||
;; Detected when next token is NOT `|` and NOT a ctor.
|
||||
((and (not (at-op? "|"))
|
||||
(not (= (ocaml-tok-type (peek-tok)) "ctor")))
|
||||
(begin
|
||||
;; Skip the alias source up to the next boundary.
|
||||
(define skip-alias
|
||||
(fn ()
|
||||
(cond
|
||||
((>= idx tok-len) nil)
|
||||
((= (ocaml-tok-type (peek-tok)) "eof") nil)
|
||||
((at-op? ";;") nil)
|
||||
((at-kw? "let") nil)
|
||||
((at-kw? "type") nil)
|
||||
((at-kw? "and") nil)
|
||||
((at-kw? "module") nil)
|
||||
((at-kw? "exception") nil)
|
||||
((at-kw? "open") nil)
|
||||
((at-kw? "include") nil)
|
||||
((at-kw? "end") nil)
|
||||
(else (begin (advance-tok!) (skip-alias))))))
|
||||
(skip-alias)
|
||||
(list :type-alias name tparams)))
|
||||
(else
|
||||
(begin
|
||||
(when (at-op? "|") (advance-tok!))
|
||||
|
||||
@@ -1156,6 +1156,12 @@ cat > "$TMPFILE" << 'EPOCHS'
|
||||
(epoch 4502)
|
||||
(eval "(ocaml-run \"try raise (E 5) with | E n when n > 100 -> n | E n -> n + 1000\")")
|
||||
|
||||
;; ── type aliases ──────────────────────────────────────────────
|
||||
(epoch 4600)
|
||||
(eval "(ocaml-parse-program \"type t = int\")")
|
||||
(epoch 4601)
|
||||
(eval "(ocaml-run-program \"type t = int;; 42\")")
|
||||
|
||||
EPOCHS
|
||||
|
||||
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||
@@ -1831,6 +1837,10 @@ check 4500 "try when guard fires" '5'
|
||||
check 4501 "try when guard skips" '0'
|
||||
check 4502 "try when fall through" '1005'
|
||||
|
||||
# ── type aliases ───────────────────────────────────────────────
|
||||
check 4600 "type t = int parses" '("type-alias" "t" ())'
|
||||
check 4601 "type alias decl + use" '42'
|
||||
|
||||
TOTAL=$((PASS + FAIL))
|
||||
if [ $FAIL -eq 0 ]; then
|
||||
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
||||
|
||||
@@ -407,6 +407,13 @@ _Newest first._
|
||||
binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree *
|
||||
'a tree`) with insert + in-order traversal. Tests parametric ADT,
|
||||
recursive match, List.append, List.fold_left.
|
||||
- 2026-05-08 Phase 1+5.1 — type aliases + poly_stack baseline (+3
|
||||
tests, 469 total + 19 baseline). Parser dispatch on the post-`=`
|
||||
token: `|` or `Ctor` → sum, `{` → record, otherwise → alias (skip
|
||||
to boundary). AST `(:type-alias NAME PARAMS)` with body discarded.
|
||||
Runtime no-op. poly_stack.ml baseline exercises a functor whose
|
||||
parameter has `type t = int` (record alias) + `let show : t ->
|
||||
string`. Stack uses ref + module field lookup to format ints.
|
||||
- 2026-05-08 Phase 2+3 — `try ... with | pat when GUARD -> body` guard
|
||||
support (+3 tests, 467 total). parse-try mirrors match/function;
|
||||
eval-try clause loop now dispatches on `case`/`case-when` and falls
|
||||
|
||||
Reference in New Issue
Block a user