ocaml: phase 6 Printf.sprintf %d/%s/%f/%c/%b/%% + global string_of_* (+5 tests, 492 total)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 21s

Replaces the stub sprintf in runtime.sx with a real implementation:
walk fmt char-by-char accumulating a prefix; on recognised %X return a
one-arg fn that formats the arg and recurses on the rest of fmt. The
function self-curries to the spec count — there's no separate arity
machinery, just a closure chain.

Specs: %d (int), %s (string), %f (float), %c (char/string in our model),
%b (bool), %% (literal). Unknown specs pass through.

Same expression returns a string (no specs) or a function (>=1 spec) —
OCaml proper would reject this; works fine in OCaml-on-SX's dynamic
runtime.

Also adds top-level aliases:
  string_of_int   = _string_of_int
  string_of_float = _string_of_float
  string_of_bool  = if b then "true" else "false"
  int_of_string   = _int_of_string

  Printf.sprintf "x=%d" 42              = "x=42"
  Printf.sprintf "%s = %d" "answer" 42  = "answer = 42"
  Printf.sprintf "%d%%" 50               = "50%"
This commit is contained in:
2026-05-09 00:42:35 +00:00
parent 14b52cfaa7
commit 1b38f89055
3 changed files with 67 additions and 3 deletions

View File

@@ -407,6 +407,18 @@ _Newest first._
binary search tree (`type 'a tree = Leaf | Node of 'a * 'a tree *
'a tree`) with insert + in-order traversal. Tests parametric ADT,
recursive match, List.append, List.fold_left.
- 2026-05-09 Phase 6 — Printf.sprintf with %d/%s/%f/%c/%b/%% (+4
tests) and global `string_of_int`/`string_of_float`/`string_of_bool`
(+1 test). 492 total. sprintf walks fmt char-by-char accumulating
a prefix; on a recognised spec it returns a one-arg fn that formats
the arg and recurses on the rest of fmt — naturally curries to the
right arity since the spec count drives the chain. Dynamic typing
lets us return either a string (no specs) or a function (≥1 spec)
from the same expression, which OCaml proper would reject.
Examples:
Printf.sprintf "x=%d" 42 = "x=42"
Printf.sprintf "%s = %d" "answer" 42 = "answer = 42"
Printf.sprintf "%d%%" 50 = "50%"
- 2026-05-09 Phase 4 — `assert EXPR` (+3 tests, 487 total). Tokenizer
already classified `assert` as a keyword; parse-prefix now handles
it like `not` (advance, recur, wrap). Eval evaluates the operand and