F2.2: std/json reader — explicit-alloc parse with error surfacing

Add the JSON reader (parser) to library/modules/std/json.sx, the inverse
of the F2.1 writer over the same value model: insertion-ordered objects,
arrays, strings (full unescaping incl. \uXXXX + surrogate pairs), s64
integers, bool, null.

Heap discipline (binding): exactly two allocation kinds, both through the
EXPLICIT `alloc` parameter, never the implicit context allocator —
composite backing stores (Array/Object.items via add/put) and decoded
escaped-string buffers (bounded by the raw span). Un-escaped string
values are zero-copy VIEWS into the input buffer (valid only while it
lives); scalars carry no heap.

Failure surfacing (hard contract): malformed input raises a meaningful
JsonParseError variant (UnexpectedToken / UnexpectedEnd / BadEscape /
BadNumber / TrailingGarbage) on the error channel, never a bogus value.
Trailing non-whitespace is TrailingGarbage; fractions/exponents,
out-of-s64 magnitudes, and leading zeros are BadNumber. Number
accumulation runs in negative space so s64 MIN parses exactly.

examples/0714-modules-json-reader.sx asserts the parsed structure
(insertion order, every kind), proves the view-vs-decoded heap split by
pointer containment, round-trips back through the writer byte-for-byte,
decodes a surrogate-pair into 4 UTF-8 bytes, and checks every malformed
variant.

Filed issues/0078: a string `==` (or any sub-CFG operand) used in a
short-circuit `and`/`or` emits invalid LLVM IR (stale PHI predecessor),
hit while writing the example's assertions and worked around there by not
combining comparisons with `and`/`or`. src/ untouched.
This commit is contained in:
agra
2026-06-04 01:41:33 +03:00
parent 295d95d51a
commit 88be541778
6 changed files with 615 additions and 4 deletions

View File

@@ -0,0 +1,37 @@
root-is-object: ok
member-count: ok
key-order-0: ok
string-plain: ok
string-escaped: ok
array-len: ok
array-pos: ok
array-neg: ok
bool-value: ok
null-value: ok
nested-key: ok
nested-val: ok
plain-is-view: ok
escaped-allocated: ok
round-trip: ok
ws-count: ok
ws-first: ok
ws-last: ok
empty-array: ok
empty-object: ok
uni-len: ok
uni-A: ok
uni-e1: ok
uni-e2: ok
uni-s0: ok
uni-s1: ok
uni-s2: ok
uni-s3: ok
err-truncated: ok
err-bad-escape: ok
err-trailing-junk: ok
err-bad-token: ok
err-fraction: ok
err-leading-zero: ok
err-overflow: ok
err-unterminated: ok
=== DONE ===