ocaml: phase 5.1 baseline 8/8 — quicksort + exceptions + closures
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 38s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 38s
Added 3 baseline programs: - closures.ml — curried make_adder; verifies closure capture - quicksort.ml — recursive sort using List.filter + List.append, sums result - exception_handle.ml — exception NegArg of int + raise + try/with All 8/8 baseline programs pass through ocaml-run-program. Combined the suite exercises: let-rec, modules, refs, for-loops, pattern matching, exceptions, lambdas, list ops (map/filter/append/fold), arithmetic. run.sh streamlined to one sx_server invocation per program. End-to-end runtime ≈2 min.
This commit is contained in:
5
lib/ocaml/baseline/closures.ml
Normal file
5
lib/ocaml/baseline/closures.ml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
(* Baseline: closures + curried application *)
|
||||||
|
let make_adder n = fun x -> n + x ;;
|
||||||
|
let add5 = make_adder 5 ;;
|
||||||
|
let add10 = make_adder 10 ;;
|
||||||
|
add5 100 + add10 200
|
||||||
17
lib/ocaml/baseline/exception_handle.ml
Normal file
17
lib/ocaml/baseline/exception_handle.ml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
(* Baseline: exception declaration + raise + try-with *)
|
||||||
|
exception NegArg of int ;;
|
||||||
|
let safe_sqrt n =
|
||||||
|
if n < 0 then raise (NegArg n)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
let rec find_sqrt i =
|
||||||
|
if i * i > n then i - 1
|
||||||
|
else find_sqrt (i + 1)
|
||||||
|
in find_sqrt 0
|
||||||
|
end ;;
|
||||||
|
let result =
|
||||||
|
try
|
||||||
|
safe_sqrt 16
|
||||||
|
with
|
||||||
|
| NegArg _ -> 0 ;;
|
||||||
|
result
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
{
|
{
|
||||||
|
"closures.ml": 315,
|
||||||
|
"exception_handle.ml": 4,
|
||||||
"factorial.ml": 3628800,
|
"factorial.ml": 3628800,
|
||||||
"list_ops.ml": 30,
|
"list_ops.ml": 30,
|
||||||
"option_match.ml": 5,
|
|
||||||
"module_use.ml": 3,
|
"module_use.ml": 3,
|
||||||
|
"option_match.ml": 5,
|
||||||
|
"quicksort.ml": 44,
|
||||||
"sum_squares.ml": 385
|
"sum_squares.ml": 385
|
||||||
}
|
}
|
||||||
|
|||||||
10
lib/ocaml/baseline/quicksort.ml
Normal file
10
lib/ocaml/baseline/quicksort.ml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
(* Baseline: quicksort over a list, returns sum of sorted result *)
|
||||||
|
let rec quicksort lst =
|
||||||
|
match lst with
|
||||||
|
| [] -> []
|
||||||
|
| pivot :: rest ->
|
||||||
|
let smaller = List.filter (fun x -> x < pivot) rest in
|
||||||
|
let larger = List.filter (fun x -> x >= pivot) rest in
|
||||||
|
List.append (quicksort smaller) (pivot :: quicksort larger) ;;
|
||||||
|
let sorted = quicksort [3; 1; 4; 1; 5; 9; 2; 6; 5; 3; 5] ;;
|
||||||
|
List.fold_left (fun a b -> a + b) 0 sorted
|
||||||
@@ -22,25 +22,7 @@ for f in lib/ocaml/baseline/*.ml; do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
TMP=$(mktemp)
|
TMP=$(mktemp)
|
||||||
cat > "$TMP" << EPOCHS
|
cat > "$TMP" << EOF
|
||||||
(epoch 1)
|
|
||||||
(load "lib/guest/lex.sx")
|
|
||||||
(load "lib/guest/prefix.sx")
|
|
||||||
(load "lib/guest/pratt.sx")
|
|
||||||
(load "lib/ocaml/tokenizer.sx")
|
|
||||||
(load "lib/ocaml/parser.sx")
|
|
||||||
(load "lib/ocaml/eval.sx")
|
|
||||||
(load "lib/ocaml/runtime.sx")
|
|
||||||
(eval "(ocaml-load-stdlib!)")
|
|
||||||
(epoch 2)
|
|
||||||
(eval "(ocaml-run-program (file-read \\"$f\\"))")
|
|
||||||
EPOCHS
|
|
||||||
|
|
||||||
output=$(timeout 60 "$SX_SERVER" < "$TMP" 2>/dev/null | grep -E '^\(ok-len 2|^\(ok 2' | head -1)
|
|
||||||
rm -f "$TMP"
|
|
||||||
|
|
||||||
# Pull the next line which has the value
|
|
||||||
result=$(timeout 60 "$SX_SERVER" < <(cat <<EPOCHS
|
|
||||||
(epoch 1)
|
(epoch 1)
|
||||||
(load "lib/guest/lex.sx")
|
(load "lib/guest/lex.sx")
|
||||||
(load "lib/guest/prefix.sx")
|
(load "lib/guest/prefix.sx")
|
||||||
@@ -52,8 +34,15 @@ EPOCHS
|
|||||||
(eval "(ocaml-load-stdlib!)")
|
(eval "(ocaml-load-stdlib!)")
|
||||||
(epoch 2)
|
(epoch 2)
|
||||||
(eval "(ocaml-run-program (file-read \"$f\"))")
|
(eval "(ocaml-run-program (file-read \"$f\"))")
|
||||||
EPOCHS
|
EOF
|
||||||
) 2>/dev/null | awk '/^\(ok-len 2 / {getline; print; exit} /^\(ok 2 / {sub(/^\(ok 2 /, ""); sub(/\)$/, ""); print; exit}')
|
|
||||||
|
output=$(timeout 60 "$SX_SERVER" < "$TMP" 2>/dev/null)
|
||||||
|
rm -f "$TMP"
|
||||||
|
|
||||||
|
result=$(echo "$output" | awk '
|
||||||
|
/^\(ok-len 2 / { getline; print; exit }
|
||||||
|
/^\(ok 2 [^)]+\)$/ { sub(/^\(ok 2 /, ""); sub(/\)$/, ""); print; exit }
|
||||||
|
')
|
||||||
|
|
||||||
if [ "$result" = "$expected" ]; then
|
if [ "$result" = "$expected" ]; then
|
||||||
PASS=$((PASS + 1))
|
PASS=$((PASS + 1))
|
||||||
|
|||||||
@@ -372,6 +372,13 @@ the "mother tongue" closure: OCaml → SX → OCaml. This means:
|
|||||||
|
|
||||||
_Newest first._
|
_Newest first._
|
||||||
|
|
||||||
|
- 2026-05-08 Phase 5.1 — baseline expanded to 8 programs (8/8 pass).
|
||||||
|
Added: closures.ml (curried adders), quicksort.ml (recursive sort
|
||||||
|
on lists), exception_handle.ml (exception decl + raise + try/with).
|
||||||
|
All 8 programs together exercise let-rec, modules, refs, for-loops,
|
||||||
|
pattern matching, exceptions, lambdas, list functions, arithmetic.
|
||||||
|
Run.sh streamlined to one sx_server invocation per program (was
|
||||||
|
two). End-to-end runtime ≈2 min for the suite.
|
||||||
- 2026-05-08 Phase 5.1 — `lib/ocaml/baseline/` with five sample OCaml
|
- 2026-05-08 Phase 5.1 — `lib/ocaml/baseline/` with five sample OCaml
|
||||||
programs (.ml files), driven by `lib/ocaml/baseline/run.sh` through
|
programs (.ml files), driven by `lib/ocaml/baseline/run.sh` through
|
||||||
`ocaml-run-program (file-read F)`. All 5/5 pass: factorial,
|
`ocaml-run-program (file-read F)`. All 5/5 pass: factorial,
|
||||||
|
|||||||
Reference in New Issue
Block a user