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.