ocaml: phase 6 Option/Result/Bytes extensions (+9 tests, 439 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 29s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 29s
Option: join, to_result, some, none. Result: value, iter, fold. Bytes: length, get, of_string, to_string, concat, sub — thin alias of String (SX has no separate immutable byte type). Ordering fix: Bytes module placed after String so its closures capture String in scope. Earlier draft put Bytes before String which made String.* lookups fail with 'not a record/module' (treated as nullary ctor).
This commit is contained in:
@@ -274,6 +274,19 @@
|
|||||||
match o with
|
match o with
|
||||||
| None -> []
|
| None -> []
|
||||||
| Some x -> [x]
|
| Some x -> [x]
|
||||||
|
|
||||||
|
let join oo =
|
||||||
|
match oo with
|
||||||
|
| None -> None
|
||||||
|
| Some inner -> inner
|
||||||
|
|
||||||
|
let to_result none_v o =
|
||||||
|
match o with
|
||||||
|
| None -> Error none_v
|
||||||
|
| Some x -> Ok x
|
||||||
|
|
||||||
|
let some x = Some x
|
||||||
|
let none = None
|
||||||
end ;;
|
end ;;
|
||||||
|
|
||||||
module Result = struct
|
module Result = struct
|
||||||
@@ -316,6 +329,21 @@
|
|||||||
match r with
|
match r with
|
||||||
| Ok x -> Some x
|
| Ok x -> Some x
|
||||||
| Error _ -> None
|
| Error _ -> None
|
||||||
|
|
||||||
|
let value r default =
|
||||||
|
match r with
|
||||||
|
| Ok x -> x
|
||||||
|
| Error _ -> default
|
||||||
|
|
||||||
|
let iter f r =
|
||||||
|
match r with
|
||||||
|
| Ok x -> f x
|
||||||
|
| Error _ -> ()
|
||||||
|
|
||||||
|
let fold ok_f err_f r =
|
||||||
|
match r with
|
||||||
|
| Ok x -> ok_f x
|
||||||
|
| Error e -> err_f e
|
||||||
end ;;
|
end ;;
|
||||||
|
|
||||||
module String = struct
|
module String = struct
|
||||||
@@ -334,6 +362,16 @@
|
|||||||
let index_of s sub = _string_index_of s sub
|
let index_of s sub = _string_index_of s sub
|
||||||
end ;;
|
end ;;
|
||||||
|
|
||||||
|
module Bytes = struct
|
||||||
|
(* Thin alias of String — SX has no separate immutable byte type. *)
|
||||||
|
let length s = String.length s
|
||||||
|
let get s i = String.get s i
|
||||||
|
let of_string s = s
|
||||||
|
let to_string s = s
|
||||||
|
let concat sep xs = String.concat sep xs
|
||||||
|
let sub s i n = String.sub s i n
|
||||||
|
end ;;
|
||||||
|
|
||||||
module Char = struct
|
module Char = struct
|
||||||
let code c = _char_code c
|
let code c = _char_code c
|
||||||
let chr n = _char_chr n
|
let chr n = _char_chr n
|
||||||
|
|||||||
@@ -1064,6 +1064,26 @@ cat > "$TMPFILE" << 'EPOCHS'
|
|||||||
(epoch 3604)
|
(epoch 3604)
|
||||||
(eval "(ocaml-run-program \"let q = Queue.create () ;; Queue.push 1 q ;; Queue.push 2 q ;; Queue.length q\")")
|
(eval "(ocaml-run-program \"let q = Queue.create () ;; Queue.push 1 q ;; Queue.push 2 q ;; Queue.length q\")")
|
||||||
|
|
||||||
|
;; ── Option/Result/Bytes extensions ────────────────────────────
|
||||||
|
(epoch 3700)
|
||||||
|
(eval "(ocaml-run \"Option.join (Some (Some 5))\")")
|
||||||
|
(epoch 3701)
|
||||||
|
(eval "(ocaml-run \"Option.join None\")")
|
||||||
|
(epoch 3702)
|
||||||
|
(eval "(ocaml-run \"Option.to_result \\\"missing\\\" None\")")
|
||||||
|
(epoch 3703)
|
||||||
|
(eval "(ocaml-run \"Option.to_result \\\"missing\\\" (Some 7)\")")
|
||||||
|
(epoch 3704)
|
||||||
|
(eval "(ocaml-run \"Result.value (Ok 5) 0\")")
|
||||||
|
(epoch 3705)
|
||||||
|
(eval "(ocaml-run \"Result.value (Error \\\"e\\\") 99\")")
|
||||||
|
(epoch 3706)
|
||||||
|
(eval "(ocaml-run \"Result.fold (fun x -> x * 10) (fun e -> 0) (Ok 5)\")")
|
||||||
|
(epoch 3707)
|
||||||
|
(eval "(ocaml-run \"Bytes.length \\\"hello\\\"\")")
|
||||||
|
(epoch 3708)
|
||||||
|
(eval "(ocaml-run \"Bytes.concat \\\"-\\\" [\\\"a\\\";\\\"b\\\";\\\"c\\\"]\")")
|
||||||
|
|
||||||
EPOCHS
|
EPOCHS
|
||||||
|
|
||||||
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
OUTPUT=$(timeout 180 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||||
@@ -1684,6 +1704,17 @@ check 3602 "Stack.top" '1'
|
|||||||
check 3603 "Queue.pop FIFO" '1'
|
check 3603 "Queue.pop FIFO" '1'
|
||||||
check 3604 "Queue.length" '2'
|
check 3604 "Queue.length" '2'
|
||||||
|
|
||||||
|
# ── Option/Result/Bytes extensions ─────────────────────────────
|
||||||
|
check 3700 "Option.join nested" '("Some" 5)'
|
||||||
|
check 3701 "Option.join None" '("None")'
|
||||||
|
check 3702 "Option.to_result None" '("Error" "missing")'
|
||||||
|
check 3703 "Option.to_result Some" '("Ok" 7)'
|
||||||
|
check 3704 "Result.value Ok" '5'
|
||||||
|
check 3705 "Result.value Error fallback" '99'
|
||||||
|
check 3706 "Result.fold Ok" '50'
|
||||||
|
check 3707 "Bytes.length" '5'
|
||||||
|
check 3708 "Bytes.concat" '"a-b-c"'
|
||||||
|
|
||||||
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"
|
||||||
|
|||||||
@@ -399,6 +399,12 @@ _Newest first._
|
|||||||
recognise `!` as the prefix-deref of an application argument, so
|
recognise `!` as the prefix-deref of an application argument, so
|
||||||
`String.concat "" (List.rev !b)` parses as `(... (deref b))`. Buffer
|
`String.concat "" (List.rev !b)` parses as `(... (deref b))`. Buffer
|
||||||
uses a ref holding a string list; contents reverses and concats.
|
uses a ref holding a string list; contents reverses and concats.
|
||||||
|
- 2026-05-08 Phase 6 — Option/Result/Bytes extensions (+9 tests, 439
|
||||||
|
total). Option: join, to_result, some, none. Result: value, iter,
|
||||||
|
fold. Bytes: length, get, of_string, to_string, concat, sub (thin
|
||||||
|
alias of String — SX has no separate immutable byte type). Ordering
|
||||||
|
fix: Bytes module placed after String so its closures capture String
|
||||||
|
in scope.
|
||||||
- 2026-05-08 Phase 6 — `Stack` and `Queue` modules in OCaml (+5 tests,
|
- 2026-05-08 Phase 6 — `Stack` and `Queue` modules in OCaml (+5 tests,
|
||||||
430 total). Stack: ref-holding-list LIFO with push/pop/top/length/
|
430 total). Stack: ref-holding-list LIFO with push/pop/top/length/
|
||||||
is_empty/clear. Queue: amortised O(1) two-list `(front, back)` queue
|
is_empty/clear. Queue: amortised O(1) two-list `(front, back)` queue
|
||||||
|
|||||||
Reference in New Issue
Block a user