ocaml: numeric tower — Integer/Number distinction + float contagion

Add `Integer of int` to sx_types.ml alongside `Number of float`. Parser
produces Integer for whole-number literals. Arithmetic primitives apply
float contagion (int op int → Integer, int op float → Number). Division
always returns Number. Rounding (floor/truncate/round) returns Integer.
Predicates: integer?, float?, exact?, inexact?, exact->inexact,
inexact->exact. run_tests.ml updated for json_of_value, value_of_json,
identical?, random-int mock, DOM accessors, and parser pattern matches.
New spec/tests/test-numeric-tower.sx — 92 tests, all pass (394 unchanged).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 12:10:50 +00:00
parent 8f0fc4ce52
commit c70bbdeb36
6 changed files with 498 additions and 141 deletions

View File

@@ -90,9 +90,21 @@ let read_symbol s =
String.sub s.src start (s.pos - start)
let try_number str =
match float_of_string_opt str with
| Some n -> Some (Number n)
| None -> None
(* Integers (no '.' or 'e'/'E') → exact Integer; floats → inexact Number *)
let has_dec = String.contains str '.' in
let has_exp = String.contains str 'e' || String.contains str 'E' in
if has_dec || has_exp then
match float_of_string_opt str with
| Some n -> Some (Number n)
| None -> None
else
match int_of_string_opt str with
| Some n -> Some (Integer n)
| None ->
(* handles "nan", "inf", "-inf" *)
match float_of_string_opt str with
| Some n -> Some (Number n)
| None -> None
let rec read_value s : value =
skip_whitespace_and_comments s;