diff --git a/lib/ocaml/baseline/closures.ml b/lib/ocaml/baseline/closures.ml new file mode 100644 index 00000000..628dd9c3 --- /dev/null +++ b/lib/ocaml/baseline/closures.ml @@ -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 diff --git a/lib/ocaml/baseline/exception_handle.ml b/lib/ocaml/baseline/exception_handle.ml new file mode 100644 index 00000000..4f2b7993 --- /dev/null +++ b/lib/ocaml/baseline/exception_handle.ml @@ -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 diff --git a/lib/ocaml/baseline/expected.json b/lib/ocaml/baseline/expected.json index f5c089ad..167d68c1 100644 --- a/lib/ocaml/baseline/expected.json +++ b/lib/ocaml/baseline/expected.json @@ -1,7 +1,10 @@ { + "closures.ml": 315, + "exception_handle.ml": 4, "factorial.ml": 3628800, "list_ops.ml": 30, - "option_match.ml": 5, "module_use.ml": 3, + "option_match.ml": 5, + "quicksort.ml": 44, "sum_squares.ml": 385 } diff --git a/lib/ocaml/baseline/quicksort.ml b/lib/ocaml/baseline/quicksort.ml new file mode 100644 index 00000000..8b49889c --- /dev/null +++ b/lib/ocaml/baseline/quicksort.ml @@ -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 diff --git a/lib/ocaml/baseline/run.sh b/lib/ocaml/baseline/run.sh index 516d855c..6e62e688 100755 --- a/lib/ocaml/baseline/run.sh +++ b/lib/ocaml/baseline/run.sh @@ -22,25 +22,7 @@ for f in lib/ocaml/baseline/*.ml; do fi TMP=$(mktemp) - cat > "$TMP" << EPOCHS -(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 < "$TMP" << EOF (epoch 1) (load "lib/guest/lex.sx") (load "lib/guest/prefix.sx") @@ -52,8 +34,15 @@ EPOCHS (eval "(ocaml-load-stdlib!)") (epoch 2) (eval "(ocaml-run-program (file-read \"$f\"))") -EPOCHS -) 2>/dev/null | awk '/^\(ok-len 2 / {getline; print; exit} /^\(ok 2 / {sub(/^\(ok 2 /, ""); sub(/\)$/, ""); print; exit}') +EOF + + 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 PASS=$((PASS + 1)) diff --git a/plans/ocaml-on-sx.md b/plans/ocaml-on-sx.md index 8ad74a6f..6a279534 100644 --- a/plans/ocaml-on-sx.md +++ b/plans/ocaml-on-sx.md @@ -372,6 +372,13 @@ the "mother tongue" closure: OCaml → SX → OCaml. This means: _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 programs (.ml files), driven by `lib/ocaml/baseline/run.sh` through `ocaml-run-program (file-read F)`. All 5/5 pass: factorial,