ocaml: phase 4 integer division semantics + Int module + max_int/min_int (+5 tests, 525 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 27s
Three things in this commit: 1. Integer / is now truncate-toward-zero on ints, IEEE on floats. The eval-op handler for '/' checks (number? + (= (round x) x)) on both sides; if both integral, applies host floor/ceil based on sign; otherwise falls through to host '/'. 2. Fixes Int.rem, which was returning 0 because (a - b * (a / b)) was using float division: 17 - 5 * 3.4 = 0.0. Now Int.rem 17 5 = 2. 3. Int module fleshed out: max_int / min_int / zero / one / minus_one, succ / pred / neg, add / sub / mul / div / rem, equal, compare. Also adds globals: max_int, min_int, abs_float, float_of_int, int_of_float (the latter two are identity in our dynamic runtime). 17 / 5 = 3 -17 / 5 = -3 (trunc toward zero) Int.rem 17 5 = 2 Int.compare 5 3 = 1
This commit is contained in:
@@ -418,7 +418,15 @@
|
|||||||
((= op "+") (+ lhs rhs))
|
((= op "+") (+ lhs rhs))
|
||||||
((= op "-") (- lhs rhs))
|
((= op "-") (- lhs rhs))
|
||||||
((= op "*") (* lhs rhs))
|
((= op "*") (* lhs rhs))
|
||||||
((= op "/") (/ lhs rhs))
|
((= op "/")
|
||||||
|
;; OCaml's `/` is integer division on ints, float on floats.
|
||||||
|
;; Pick floor on ints.
|
||||||
|
(cond
|
||||||
|
((and (number? lhs) (number? rhs)
|
||||||
|
(= (round lhs) lhs) (= (round rhs) rhs))
|
||||||
|
(let ((q (/ lhs rhs)))
|
||||||
|
(if (>= q 0) (floor q) (ceil q))))
|
||||||
|
(else (/ lhs rhs))))
|
||||||
((= op "+.") (+ lhs rhs))
|
((= op "+.") (+ lhs rhs))
|
||||||
((= op "-.") (- lhs rhs))
|
((= op "-.") (- lhs rhs))
|
||||||
((= op "*.") (* lhs rhs))
|
((= op "*.") (* lhs rhs))
|
||||||
|
|||||||
@@ -466,6 +466,21 @@
|
|||||||
let abs n = if n < 0 then 0 - n else n
|
let abs n = if n < 0 then 0 - n else n
|
||||||
let max a b = if a > b then a else b
|
let max a b = if a > b then a else b
|
||||||
let min a b = if a < b then a else b
|
let min a b = if a < b then a else b
|
||||||
|
let max_int = 4611686018427387903
|
||||||
|
let min_int = -4611686018427387904
|
||||||
|
let zero = 0
|
||||||
|
let one = 1
|
||||||
|
let minus_one = -1
|
||||||
|
let succ n = n + 1
|
||||||
|
let pred n = n - 1
|
||||||
|
let neg n = 0 - n
|
||||||
|
let add a b = a + b
|
||||||
|
let sub a b = a - b
|
||||||
|
let mul a b = a * b
|
||||||
|
let div a b = a / b
|
||||||
|
let rem a b = a - b * (a / b)
|
||||||
|
let equal a b = a = b
|
||||||
|
let compare a b = if a < b then -1 else if a > b then 1 else 0
|
||||||
end ;;
|
end ;;
|
||||||
|
|
||||||
module Float = struct
|
module Float = struct
|
||||||
@@ -832,6 +847,11 @@
|
|||||||
let string_of_float f = _string_of_float f
|
let string_of_float f = _string_of_float f
|
||||||
let string_of_bool b = if b then \"true\" else \"false\"
|
let string_of_bool b = if b then \"true\" else \"false\"
|
||||||
let int_of_string s = _int_of_string s
|
let int_of_string s = _int_of_string s
|
||||||
|
let max_int = 4611686018427387903
|
||||||
|
let min_int = -4611686018427387904
|
||||||
|
let abs_float f = if f < 0.0 then 0.0 -. f else f
|
||||||
|
let float_of_int n = n
|
||||||
|
let int_of_float f = f
|
||||||
")
|
")
|
||||||
|
|
||||||
(define ocaml-stdlib-loaded false)
|
(define ocaml-stdlib-loaded false)
|
||||||
|
|||||||
@@ -1298,6 +1298,18 @@ cat > "$TMPFILE" << 'EPOCHS'
|
|||||||
(epoch 5044)
|
(epoch 5044)
|
||||||
(eval "(ocaml-run \"let a = Array.of_list [1;2;3;4;5] in Array.mem 3 a\")")
|
(eval "(ocaml-run \"let a = Array.of_list [1;2;3;4;5] in Array.mem 3 a\")")
|
||||||
|
|
||||||
|
;; ── Integer division + Int module + max_int ──────────────────
|
||||||
|
(epoch 5050)
|
||||||
|
(eval "(ocaml-run \"17 / 5\")")
|
||||||
|
(epoch 5051)
|
||||||
|
(eval "(ocaml-run \"-17 / 5\")")
|
||||||
|
(epoch 5052)
|
||||||
|
(eval "(ocaml-run \"Int.rem 17 5\")")
|
||||||
|
(epoch 5053)
|
||||||
|
(eval "(ocaml-run \"Int.compare 5 3\")")
|
||||||
|
(epoch 5054)
|
||||||
|
(eval "(ocaml-run \"max_int + min_int\")")
|
||||||
|
|
||||||
EPOCHS
|
EPOCHS
|
||||||
|
|
||||||
OUTPUT=$(timeout 360 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
OUTPUT=$(timeout 360 "$SX_SERVER" < "$TMPFILE" 2>/dev/null)
|
||||||
@@ -2062,6 +2074,13 @@ check 5042 "Array.append 6-len sum" '21'
|
|||||||
check 5043 "Array.exists = 6" 'true'
|
check 5043 "Array.exists = 6" 'true'
|
||||||
check 5044 "Array.mem 3 [1..5]" 'true'
|
check 5044 "Array.mem 3 [1..5]" 'true'
|
||||||
|
|
||||||
|
# ── Int module + integer division ───────────────────────────────
|
||||||
|
check 5050 "17 / 5 = 3 (int div)" '3'
|
||||||
|
check 5051 "-17 / 5 = -3 (trunc-zero)" '-3'
|
||||||
|
check 5052 "Int.rem 17 5" '2'
|
||||||
|
check 5053 "Int.compare 5 3" '1'
|
||||||
|
check 5054 "max_int + min_int (host int)" '0'
|
||||||
|
|
||||||
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"
|
||||||
|
|||||||
@@ -407,6 +407,13 @@ _Newest first._
|
|||||||
binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree *
|
binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree *
|
||||||
'a tree`) with insert + in-order traversal. Tests parametric ADT,
|
'a tree`) with insert + in-order traversal. Tests parametric ADT,
|
||||||
recursive match, List.append, List.fold_left.
|
recursive match, List.append, List.fold_left.
|
||||||
|
- 2026-05-09 Phase 4 — integer `/` is now truncate-toward-zero on
|
||||||
|
ints, IEEE on floats. Both operands integral → host floor/ceil based
|
||||||
|
on sign; otherwise host `/`. Fixes `Int.rem` (which was returning 0
|
||||||
|
for `Int.rem 17 5` because `a / b` was producing a float). Also adds
|
||||||
|
Int.{max_int,min_int,zero,one,minus_one,succ,pred,neg,add,sub,mul,
|
||||||
|
div,rem,equal,compare} and global max_int/min_int/abs_float/
|
||||||
|
float_of_int/int_of_float (+5 tests, 525 total).
|
||||||
- 2026-05-09 Phase 6 — Array.sort/stable_sort/fast_sort + sub +
|
- 2026-05-09 Phase 6 — Array.sort/stable_sort/fast_sort + sub +
|
||||||
append + exists + for_all + mem (+5 tests, 520 total). All
|
append + exists + for_all + mem (+5 tests, 520 total). All
|
||||||
delegate to the corresponding List operation on the cell's
|
delegate to the corresponding List operation on the cell's
|
||||||
|
|||||||
Reference in New Issue
Block a user