ocaml: phase 6 List.sort + compare (+7 tests, 339 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 25s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 25s
compare is a host builtin returning -1/0/1 (Stdlib.compare semantics) deferred to host SX </>. List.sort is insertion-sort in OCaml: O(n²) but works correctly. List.stable_sort = sort. Tested: ascending int sort, descending via custom comparator (b - a), empty list, string sort.
This commit is contained in:
@@ -67,6 +67,14 @@
|
||||
(list "print_string" (fn (s) (begin (print s) nil)))
|
||||
(list "print_endline" (fn (s) (begin (println s) nil)))
|
||||
(list "print_int" (fn (i) (begin (print (str i)) nil)))
|
||||
;; Polymorphic compare — returns negative / 0 / positive like
|
||||
;; OCaml's Stdlib.compare. Defers to host SX `<` and `>`.
|
||||
(list "compare"
|
||||
(fn (a) (fn (b)
|
||||
(cond
|
||||
((< a b) -1)
|
||||
((> a b) 1)
|
||||
(else 0)))))
|
||||
;; Hashtbl primitives (one-element list cell holding a dict).
|
||||
;; Keys are coerced to strings via `str` so any value type works
|
||||
;; as a key (matches Hashtbl's polymorphic-key semantics).
|
||||
|
||||
@@ -143,6 +143,20 @@
|
||||
match lst with
|
||||
| [] -> None
|
||||
| (k2, v) :: t -> if k = k2 then Some v else assoc_opt k t
|
||||
|
||||
let rec sort cmp xs =
|
||||
begin
|
||||
let rec insert x ys =
|
||||
match ys with
|
||||
| [] -> [x]
|
||||
| h :: t -> if cmp x h <= 0 then x :: ys else h :: insert x t
|
||||
in
|
||||
match xs with
|
||||
| [] -> []
|
||||
| h :: t -> insert h (sort cmp t)
|
||||
end
|
||||
|
||||
let stable_sort = sort
|
||||
end ;;
|
||||
|
||||
module Option = struct
|
||||
|
||||
@@ -828,6 +828,22 @@ cat > "$TMPFILE" << 'EPOCHS'
|
||||
(epoch 1605)
|
||||
(eval "(ocaml-run-program \"let t = Hashtbl.create 10;; Hashtbl.add t \\\"k\\\" 5;; Hashtbl.find_opt t \\\"k\\\"\")")
|
||||
|
||||
;; ── List.sort + compare ────────────────────────────────────────
|
||||
(epoch 1700)
|
||||
(eval "(ocaml-run \"compare 1 2\")")
|
||||
(epoch 1701)
|
||||
(eval "(ocaml-run \"compare 5 5\")")
|
||||
(epoch 1702)
|
||||
(eval "(ocaml-run \"compare 9 1\")")
|
||||
(epoch 1703)
|
||||
(eval "(ocaml-run \"List.sort compare [3; 1; 4; 1; 5; 9; 2; 6]\")")
|
||||
(epoch 1704)
|
||||
(eval "(ocaml-run \"List.sort (fun a b -> b - a) [3; 1; 4]\")")
|
||||
(epoch 1705)
|
||||
(eval "(ocaml-run \"List.sort compare []\")")
|
||||
(epoch 1706)
|
||||
(eval "(ocaml-run \"List.sort compare [\\\"b\\\"; \\\"a\\\"; \\\"c\\\"]\")")
|
||||
|
||||
EPOCHS
|
||||
|
||||
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||
@@ -1310,6 +1326,15 @@ check 1603 "Hashtbl mem" 'true'
|
||||
check 1604 "Hashtbl replace" '2'
|
||||
check 1605 "Hashtbl find_opt found" '("Some" 5)'
|
||||
|
||||
# ── List.sort + compare ─────────────────────────────────────────
|
||||
check 1700 "compare 1<2" '-1'
|
||||
check 1701 "compare 5=5" '0'
|
||||
check 1702 "compare 9>1" '1'
|
||||
check 1703 "List.sort ascending" '(1 1 2 3 4 5 6 9)'
|
||||
check 1704 "List.sort descending" '(4 3 1)'
|
||||
check 1705 "List.sort empty" '()'
|
||||
check 1706 "List.sort strings" '("a" "b" "c")'
|
||||
|
||||
TOTAL=$((PASS + FAIL))
|
||||
if [ $FAIL -eq 0 ]; then
|
||||
echo "ok $PASS/$TOTAL OCaml-on-SX tests passed"
|
||||
|
||||
@@ -242,8 +242,8 @@ SX CEK evaluator (both JS and OCaml hosts)
|
||||
- [~] `List`: `map`, `filter`, `fold_left`, `fold_right`, `length`, `rev`,
|
||||
`append`, `iter`, `for_all`, `exists`, `mem`, `nth`, `hd`, `tl`,
|
||||
`rev_append`, `concat`/`flatten`, `init`, `iteri`, `mapi`, `find`,
|
||||
`find_opt`, `assoc`, `assoc_opt`, `partition`. _(Pending:
|
||||
sort/stable_sort, combine, split.)_
|
||||
`find_opt`, `assoc`, `assoc_opt`, `partition`, `sort`,
|
||||
`stable_sort` (insertion sort, O(n²)). _(Pending: combine, split.)_
|
||||
- [~] `Option`: `map`, `bind`, `value`, `get`, `is_none`, `is_some`,
|
||||
`iter`, `fold`, `to_list`. _(Pending: join/to_result.)_
|
||||
- [~] `Result`: `map`, `bind`, `is_ok`, `is_error`, `get_ok`,
|
||||
@@ -365,6 +365,11 @@ the "mother tongue" closure: OCaml → SX → OCaml. This means:
|
||||
|
||||
_Newest first._
|
||||
|
||||
- 2026-05-08 Phase 6 — `List.sort` + polymorphic `compare` (+7 tests,
|
||||
339 total). `compare` is a host primitive that returns -1/0/1 like
|
||||
Stdlib.compare, defers to host SX `<`/`>`. `List.sort` is implemented
|
||||
in OCaml as insertion sort: O(n²) but correct, and passes all tests
|
||||
including descending custom comparator and string sort.
|
||||
- 2026-05-08 Phase 6 — `Hashtbl` (+6 tests, 332 total). Backing store is
|
||||
a one-element list cell holding a SX dict; keys are coerced to
|
||||
strings via `str` so any value type can serve as a key. API: create,
|
||||
|
||||
Reference in New Issue
Block a user