~/bend-docscommunity

json.bend source

json.bend on the hub · documented module

# json.bend: A production-grade, highly reusable JSON library for Bend 2.# Compliant with RFC 8259 (JSON specification) and RFC 6901 (JSON Pointer).## Supports:#   - Full JSON AST: Null, Bool, Number (Pos Nat, Neg Nat), String, Array, Object#   - Full RFC 8259 character escaping and unescaping#   - Safe type guards and typed value unwrapping#   - Comprehensive Object operations: get, has, set, remove, obj_len, keys, values, entries, merge, sort_keys#   - Functional Array combinators: arr_len, arr_get, arr_push, arr_set, arr_pop, arr_remove, arr_insert, arr_map, arr_filter, arr_fold#   - Ergonomic typed field extractors with fallback defaults: get_str, get_num, get_bool, etc.#   - RFC 6901 JSON Pointer queries and deep path updates: pointer, pointer_set#   - High-performance compact serialization: stringify#   - Configurable pretty printing with arbitrary indentation: pretty, pretty_indent#   - Streaming NDJSON (Newline Delimited JSON): parse_ndjson, stringify_ndjson#   - Fast JSON validation: validate#   - Linear recursive-descent parser: parseimport Base# ==============================================================================# 1. AST Data Types# ==============================================================================type Json is Data:  JNull{}  JBool{val: Bool}  JNum{val: Nat}  JNeg{val: Nat}  JStr{val: String}  JArr{vals: List<&2, Json>}  JObj{kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}# Parser stack framestype Frame is Data:  FArr{items: List<&2, Json>}  FObjVal{key: String, kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}# String parser typestype StrCharKind is Data:  SCQuote{}  SCSlash{}  SCOther{}type StrRes is Data:  SErr{msg: String}  SOk{val: String, rest: String}type StrState is Data:  StrNormal{}  StrEscaping{}  StrChar{kind: StrCharKind, c: U32}type PtrUnescState is Data:  PUNormal{}  PUTilde{}  PUChar{is_tilde: Bool, c: U32}  PUTildeChar{is_one: Bool, is_zero: Bool, c: U32}type PtrSplitState is Data:  PSNormal{}  PSChar{is_slash: Bool, c: U32}type NatState is Data:  NParseDigits{}  NCheckDigit{is_d: Bool, c: U32}type LineSplitState is Data:  LSNormal{}  LSCheckNl{is_nl: Bool, c: U32}  LSEmpty{is_empty: Bool, line: String}# Number parser resulttype NumRes is Data:  NRes{val: Nat, rest: String}# General character classificationtype CharKind is Data:  KindLBracket{}  KindRBracket{}  KindLBrace{}  KindRBrace{}  KindQuote{}  KindComma{}  KindColon{}  KindNull{}  KindTrue{}  KindFalse{}  KindMinus{}  KindDigit{}  KindOther{}# Parser state machine actionstype StepAct is Data:  ActValStart{}  ActValChar{kind: CharKind, c: U32}  ActArrOpen{}  ActArrOpenChar{kind: CharKind, c: U32}  ActArrNext{v: Json, items: List<&2, Json>}  ActArrNextChar{kind: CharKind, v: Json, items: List<&2, Json>}  ActObjOpen{}  ActObjOpenChar{kind: CharKind, c: U32}  ActKeyStart{kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}  ActKeyStartChar{kind: CharKind, kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}  ActKeyParsed{res: StrRes, kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}  ActColon{key: String, kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}  ActColonChar{kind: CharKind, key: String, kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}  ActObjNext{key: String, v: Json, kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}  ActObjNextChar{kind: CharKind, key: String, v: Json, kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}  ActHaveVal{v: Json}  ActCheckEof{v: Json}  ActStrParsed{res: StrRes}  ActNumParsed{neg_flag: Bool, res: NumRes}  ActLitCheck{expected: String, val: Json, ok: Bool, rest: String}# Serializer stack tasktype PrintTask is Data:  PVal{j: Json}  PArr{items: List<&2, Json>}  PObj{kvs: List<&2, Sigma<&2, &2, String, _ => Json>>}  PLit{s: String}# Pretty printer stack tasktype PrettyTask is Data:  PrVal{j: Json, indent: Nat}  PrArr{items: List<&2, Json>, indent: Nat}  PrObj{kvs: List<&2, Sigma<&2, &2, String, _ => Json>>, indent: Nat}  PrLit{s: String}# ==============================================================================# 2. Constructors and Builders# ==============================================================================def null() -> Json:  JNull{}def bool(b: Bool) -> Json:  JBool{b}def true_val() -> Json:  JBool{True{}}def false_val() -> Json:  JBool{False{}}def num(n: Nat) -> Json:  JNum{n}def neg(n: Nat) -> Json:  JNeg{n}def str(s: String) -> Json:  JStr{s}def arr(vals: List<&2, Json>) -> Json:  JArr{vals}def obj(kvs: List<&2, Sigma<&2, &2, String, _ => Json>>) -> Json:  JObj{kvs}def kv(key: String, val: Json) -> Sigma<&2, &2, String, _ => Json>:  Tuple{key, val}# ==============================================================================# 3. Type Checking and Guards# ==============================================================================def is_null(j: Json) -> Bool:  match j:    case JNull{}:      True{}    case _:      False{}def is_bool(j: Json) -> Bool:  match j:    case JBool{_}:      True{}    case _:      False{}def is_num(j: Json) -> Bool:  match j:    case JNum{_}:      True{}    case _:      False{}def is_neg(j: Json) -> Bool:  match j:    case JNeg{_}:      True{}    case _:      False{}def is_str(j: Json) -> Bool:  match j:    case JStr{_}:      True{}    case _:      False{}def is_arr(j: Json) -> Bool:  match j:    case JArr{_}:      True{}    case _:      False{}def is_obj(j: Json) -> Bool:  match j:    case JObj{_}:      True{}    case _:      False{}# ==============================================================================# 4. Value Extraction# ==============================================================================def as_bool(j: Json) -> Maybe<&2, Bool>:  match j:    case JBool{b}:      Some{b}    case _:      None{}def as_num(j: Json) -> Maybe<&2, Nat>:  match j:    case JNum{n}:      Some{n}    case _:      None{}def as_neg(j: Json) -> Maybe<&2, Nat>:  match j:    case JNeg{n}:      Some{n}    case _:      None{}def as_str(j: Json) -> Maybe<&2, String>:  match j:    case JStr{s}:      Some{s}    case _:      None{}def as_arr(j: Json) -> Maybe<&2, List<&2, Json>>:  match j:    case JArr{vals}:      Some{vals}    case _:      None{}def as_obj(j: Json) -> Maybe<&2, List<&2, Sigma<&2, &2, String, _ => Json>>>:  match j:    case JObj{kvs}:      Some{kvs}    case _:      None{}# ==============================================================================# 5. Object Operations & Dictionary Utilities# ==============================================================================def get_kv(kvs: List<&2, Sigma<&2, &2, String, _ => Json>>, +key: String) -> Maybe<&2, Json>:  match kvs:    case Nil{}:      None{}    case Tuple{k, +v} <> t:      Bool.pick(Maybe<&2, Json>, String.eq(k, key),        Some{v},        get_kv(t, key))def get(j: Json, key: String) -> Maybe<&2, Json>:  match j:    case JObj{kvs}:      get_kv(kvs, key)    case _:      None{}def has.is_some(m: Maybe<&2, Json>) -> Bool:  match m:    case Some{_}:      True{}    case None{}:      False{}def has(j: Json, key: String) -> Bool:  has.is_some(get(j, key))def set_kv(kvs: List<&2, Sigma<&2, &2, String, _ => Json>>, +key: String, +val: Json) -> List<&2, Sigma<&2, &2, String, _ => Json>>:  match kvs:    case Nil{}:      [Tuple{key, val}]    case Tuple{+k, +v} <> +t:      Bool.pick(List<&2, Sigma<&2, &2, String, _ => Json>>, String.eq(k, key),        Tuple{key, val} <> t,        Tuple{k, v} <> set_kv(t, key, val))def set(j: Json, key: String, val: Json) -> Json:  match j:    case JObj{kvs}:      JObj{set_kv(kvs, key, val)}    case _:      JObj{[Tuple{key, val}]}def remove_kv(kvs: List<&2, Sigma<&2, &2, String, _ => Json>>, +key: String) -> List<&2, Sigma<&2, &2, String, _ => Json>>:  match kvs:    case Nil{}:      Nil{}    case Tuple{+k, +v} <> +t:      Bool.pick(List<&2, Sigma<&2, &2, String, _ => Json>>, String.eq(k, key),        t,        Tuple{k, v} <> remove_kv(t, key))def remove(j: Json, key: String) -> Json:  match j:    case JObj{kvs}:      JObj{remove_kv(kvs, key)}    case _:      jdef obj_len_kv(kvs: List<&2, Sigma<&2, &2, String, _ => Json>>) -> Nat:  match kvs:    case Nil{}:      0n    case _ <> t:      1n+obj_len_kv(t)def obj_len(j: Json) -> Nat:  match j:    case JObj{kvs}:      obj_len_kv(kvs)    case _:      0ndef keys_kv(kvs: List<&2, Sigma<&2, &2, String, _ => Json>>) -> List<&2, String>:  match kvs:    case Nil{}:      Nil{}    case Tuple{k, _} <> t:      k <> keys_kv(t)def keys(j: Json) -> List<&2, String>:  match j:    case JObj{kvs}:      keys_kv(kvs)    case _:      Nil{}def values_kv(kvs: List<&2, Sigma<&2, &2, String, _ => Json>>) -> List<&2, Json>:  match kvs:    case Nil{}:      Nil{}    case Tuple{_, v} <> t:      v <> values_kv(t)def values(j: Json) -> List<&2, Json>:  match j:    case JObj{kvs}:      values_kv(kvs)    case _:      Nil{}def entries(j: Json) -> List<&2, Sigma<&2, &2, String, _ => Json>>:  match j:    case JObj{kvs}:      kvs    case _:      Nil{}def merge_kvs(overrides: List<&2, Sigma<&2, &2, String, _ => Json>>, base: List<&2, Sigma<&2, &2, String, _ => Json>>) -> List<&2, Sigma<&2, &2, String, _ => Json>>:  match overrides:    case Nil{}:      base    case Tuple{k, v} <> t:      merge_kvs(t, set_kv(base, k, v))def merge(j1: Json, j2: Json) -> Json:  match j1:    case JObj{kvs1}:      match j2:        case JObj{kvs2}:          JObj{merge_kvs(kvs2, kvs1)}        case _:          j2    case _:      j2def insert_kv_go(+ek: String, +ev: Json, +kvs: List<&2, Sigma<&2, &2, String, _ => Json>>) -> List<&2, Sigma<&2, &2, String, _ => Json>>:  match kvs:    case Nil{}:      [Tuple{ek, ev}]    case Tuple{+k, +v} <> +t:      Bool.pick(List<&2, Sigma<&2, &2, String, _ => Json>>, String.is_le(ek, k),        Tuple{ek, ev} <> Tuple{k, v} <> t,        Tuple{k, v} <> insert_kv_go(ek, ev, t))def insert_kv(elem: Sigma<&2, &2, String, _ => Json>, kvs: List<&2, Sigma<&2, &2, String, _ => Json>>) -> List<&2, Sigma<&2, &2, String, _ => Json>>:  Tuple{ek, ev} = elem  insert_kv_go(ek, ev, kvs)def sort_kvs(kvs: List<&2, Sigma<&2, &2, String, _ => Json>>) -> List<&2, Sigma<&2, &2, String, _ => Json>>:  match kvs:    case Nil{}:      Nil{}    case h <> t:      insert_kv(h, sort_kvs(t))def sort_keys(j: Json) -> Json:  match j:    case JObj{kvs}:      JObj{sort_kvs(kvs)}    case _:      jdef to_map(j: Json) -> Maybe<&2, Map<&2, Json>>:  match j:    case JObj{kvs}:      Some{Map.from_list(&2, Json, kvs)}    case _:      None{}def from_map(m: Map<&2, Json>) -> Json:  JObj{Map.to_list(&2, Json, m)}# ==============================================================================# 6. Array Operations & Functional Combinators# ==============================================================================def arr_len_list(vals: List<&2, Json>) -> Nat:  match vals:    case Nil{}:      0n    case _ <> t:      1n+arr_len_list(t)def arr_len(j: Json) -> Nat:  match j:    case JArr{vals}:      arr_len_list(vals)    case _:      0ndef arr_get_list(vals: List<&2, Json>, idx: Nat) -> Maybe<&2, Json>:  match vals:    case Nil{}:      None{}    case h <> t:      match idx:        case 0n:          Some{h}        case 1n+p:          arr_get_list(t, p)def arr_get(j: Json, idx: Nat) -> Maybe<&2, Json>:  match j:    case JArr{vals}:      arr_get_list(vals, idx)    case _:      None{}def arr_push(j: Json, elem: Json) -> Json:  match j:    case JArr{vals}:      JArr{List.append(&2, Json, vals, [elem])}    case _:      JArr{[elem]}def list_set_idx(xs: List<&2, Json>, idx: Nat, +val: Json) -> List<&2, Json>:  match xs:    case Nil{}:      Nil{}    case +h <> +t:      match idx:        case 0n:          val <> t        case 1n+p:          h <> list_set_idx(t, p, val)def arr_set(j: Json, idx: Nat, val: Json) -> Json:  match j:    case JArr{vals}:      JArr{list_set_idx(vals, idx, val)}    case _:      jdef list_pop_step(h: Json, res: Pair(Maybe<&2, Json>, List<&2, Json>)) -> Pair(Maybe<&2, Json>, List<&2, Json>):  Tuple{m, rem} = res  Tuple{m, h <> rem}def list_pop_last(xs: List<&2, Json>) -> Pair(Maybe<&2, Json>, List<&2, Json>):  match xs:    case Nil{}:      Tuple{None{}, Nil{}}    case h <> t:      match t:        case Nil{}:          Tuple{Some{h}, Nil{}}        case th <> tt:          list_pop_step(h, list_pop_last(th <> tt))def arr_pop_step(res: Pair(Maybe<&2, Json>, List<&2, Json>)) -> Pair(Maybe<&2, Json>, Json):  Tuple{m, rem} = res  Tuple{m, JArr{rem}}def arr_pop(j: Json) -> Pair(Maybe<&2, Json>, Json):  match j:    case JArr{vals}:      arr_pop_step(list_pop_last(vals))    case _:      Tuple{None{}, j}def list_remove(xs: List<&2, Json>, idx: Nat) -> List<&2, Json>:  match xs:    case Nil{}:      Nil{}    case h <> t:      match idx:        case 0n:          t        case 1n+p:          h <> list_remove(t, p)def arr_remove(j: Json, idx: Nat) -> Json:  match j:    case JArr{vals}:      JArr{list_remove(vals, idx)}    case _:      jdef list_insert(xs: List<&2, Json>, idx: Nat, +val: Json) -> List<&2, Json>:  match xs:    case Nil{}:      [val]    case h <> t:      match idx:        case 0n:          val <> h <> t        case 1n+p:          h <> list_insert(t, p, val)def arr_insert(j: Json, idx: Nat, val: Json) -> Json:  match j:    case JArr{vals}:      JArr{list_insert(vals, idx, val)}    case _:      JArr{[val]}def list_map(~f: Json -> Json, xs: List<&2, Json>) -> List<&2, Json>:  match xs:    case Nil{}:      Nil{}    case h <> t:      f(h) <> list_map(~f, t)def arr_map(~f: Json -> Json, j: Json) -> Json:  match j:    case JArr{vals}:      JArr{list_map(~f, vals)}    case _:      jdef list_filter(~f: Json -> Bool, +xs: List<&2, Json>) -> List<&2, Json>:  match xs:    case Nil{}:      Nil{}    case +h <> +t:      Bool.pick(List<&2, Json>, f(h),        h <> list_filter(~f, t),        list_filter(~f, t))def arr_filter(~f: Json -> Bool, j: Json) -> Json:  match j:    case JArr{vals}:      JArr{list_filter(~f, vals)}    case _:      jdef list_fold(~f: Json -> Json -> Json, xs: List<&2, Json>, acc: Json) -> Json:  match xs:    case Nil{}:      acc    case h <> t:      list_fold(~f, t, f(acc, h))def arr_fold(~f: Json -> Json -> Json, acc: Json, j: Json) -> Json:  match j:    case JArr{vals}:      list_fold(~f, vals, acc)    case _:      acc# ==============================================================================# 7. Ergonomic Typed Field Extractors# ==============================================================================def get_str_step(m: Maybe<&2, Json>) -> Maybe<&2, String>:  match m:    case Some{v}:      as_str(v)    case None{}:      None{}def get_str(j: Json, key: String) -> Maybe<&2, String>:  get_str_step(get(j, key))def get_num_step(m: Maybe<&2, Json>) -> Maybe<&2, Nat>:  match m:    case Some{v}:      as_num(v)    case None{}:      None{}def get_num(j: Json, key: String) -> Maybe<&2, Nat>:  get_num_step(get(j, key))def get_neg_step(m: Maybe<&2, Json>) -> Maybe<&2, Nat>:  match m:    case Some{v}:      as_neg(v)    case None{}:      None{}def get_neg(j: Json, key: String) -> Maybe<&2, Nat>:  get_neg_step(get(j, key))def get_bool_step(m: Maybe<&2, Json>) -> Maybe<&2, Bool>:  match m:    case Some{v}:      as_bool(v)    case None{}:      None{}def get_bool(j: Json, key: String) -> Maybe<&2, Bool>:  get_bool_step(get(j, key))def get_arr_step(m: Maybe<&2, Json>) -> Maybe<&2, List<&2, Json>>:  match m:    case Some{v}:      as_arr(v)    case None{}:      None{}def get_arr(j: Json, key: String) -> Maybe<&2, List<&2, Json>>:  get_arr_step(get(j, key))def get_obj_step(m: Maybe<&2, Json>) -> Maybe<&2, List<&2, Sigma<&2, &2, String, _ => Json>>>:  match m:    case Some{v}:      as_obj(v)    case None{}:      None{}def get_obj(j: Json, key: String) -> Maybe<&2, List<&2, Sigma<&2, &2, String, _ => Json>>>:  get_obj_step(get(j, key))def get_str_or_step(m: Maybe<&2, String>, dflt: String) -> String:  match m:    case Some{s}:      s    case None{}:      dfltdef get_str_or(j: Json, key: String, dflt: String) -> String:  get_str_or_step(get_str(j, key), dflt)def get_num_or_step(m: Maybe<&2, Nat>, dflt: Nat) -> Nat:  match m:    case Some{n}:      n    case None{}:      dfltdef get_num_or(j: Json, key: String, dflt: Nat) -> Nat:  get_num_or_step(get_num(j, key), dflt)def get_bool_or_step(m: Maybe<&2, Bool>, dflt: Bool) -> Bool:  match m:    case Some{b}:      b    case None{}:      dfltdef get_bool_or(j: Json, key: String, dflt: Bool) -> Bool:  get_bool_or_step(get_bool(j, key), dflt)# ==============================================================================# 8. RFC 6901 JSON Pointer Traversal & Deep Mutation# ==============================================================================def unescape_ptr_loop(fuel: Nat, st: PtrUnescState, s: String, +acc: List<&2, Char>) -> String:  match fuel:    case 0n:      String.from_list(List.reverse(&2, Char, acc))    case 1n++p:      match st:        case PUNormal{}:          match s:            case SNil{}:              String.from_list(List.reverse(&2, Char, acc))            case SCon{Chr{+c}, +t}:              unescape_ptr_loop(p, PUChar{U32.is_eq(c, 126), c}, t, acc)        case PUChar{is_tilde, c}:          match is_tilde:            case True{}:              unescape_ptr_loop(p, PUTilde{}, s, acc)            case False{}:              unescape_ptr_loop(p, PUNormal{}, s, Chr{c} <> acc)        case PUTilde{}:          match s:            case SNil{}:              String.from_list(List.reverse(&2, Char, Chr{126} <> acc))            case SCon{Chr{+c}, +t}:              unescape_ptr_loop(p, PUTildeChar{U32.is_eq(c, 49), U32.is_eq(c, 48), c}, t, acc)        case PUTildeChar{is_one, is_zero, c}:          match is_one:            case True{}:              unescape_ptr_loop(p, PUNormal{}, s, Chr{47} <> acc)            case False{}:              match is_zero:                case True{}:                  unescape_ptr_loop(p, PUNormal{}, s, Chr{126} <> acc)                case False{}:                  unescape_ptr_loop(p, PUNormal{}, s, Chr{c} <> Chr{126} <> acc)def unescape_ptr_token(+s: String) -> String:  unescape_ptr_loop(Nat.add(Nat.mul(String.length(s), 2n), 10n), PUNormal{}, s, Nil{})def split_ptr_loop(fuel: Nat, st: PtrSplitState, s: String, +cur: String) -> List<&2, String>:  match fuel:    case 0n:      [unescape_ptr_token(String.reverse(cur))]    case 1n++p:      match st:        case PSNormal{}:          match s:            case SNil{}:              [unescape_ptr_token(String.reverse(cur))]            case SCon{Chr{+c}, +t}:              split_ptr_loop(p, PSChar{U32.is_eq(c, 47), c}, t, cur)        case PSChar{is_slash, c}:          match is_slash:            case True{}:              unescape_ptr_token(String.reverse(cur)) <> split_ptr_loop(p, PSNormal{}, s, "")            case False{}:              split_ptr_loop(p, PSNormal{}, s, SCon{Chr{c}, cur})def split_ptr_tokens(+s: String) -> List<&2, String>:  split_ptr_loop(Nat.add(Nat.mul(String.length(s), 2n), 10n), PSNormal{}, s, "")def parse_ptr_tokens_slash(is_slash: Bool, +t: String) -> Maybe<&2, List<&2, String>>:  match is_slash:    case True{}:      Some{split_ptr_tokens(t)}    case False{}:      None{}def parse_ptr_tokens(+path: String) -> Maybe<&2, List<&2, String>>:  match path:    case SNil{}:      Some{Nil{}}    case SCon{Chr{+c}, +t}:      parse_ptr_tokens_slash(U32.is_eq(c, 47), t)def parse_nat_loop(fuel: Nat, st: NatState, s: String, +acc: Nat) -> Maybe<&2, Nat>:  match fuel:    case 0n:      Some{acc}    case 1n++p:      match st:        case NParseDigits{}:          match s:            case SNil{}:              Some{acc}            case SCon{Chr{+c}, +t}:              parse_nat_loop(p, NCheckDigit{Bool.and(U32.is_ge(c, 48), U32.is_le(c, 57)), c}, t, acc)        case NCheckDigit{is_d, c}:          match is_d:            case True{}:              parse_nat_loop(p, NParseDigits{}, s, Nat.add(Nat.mul(acc, 10n), U32.to_nat(U32.sub(c, 48))))            case False{}:              None{}def parse_nat_lead(is_zero: Bool, is_digit: Bool, +c: U32, +t: String) -> Maybe<&2, Nat>:  match is_zero:    case True{}:      match t:        case SNil{}:          Some{0n}        case _:          None{}    case False{}:      match is_digit:        case True{}:          +fuel = {Nat.add(String.length(t), 10n) : Nat}          parse_nat_loop(fuel, NParseDigits{}, t, U32.to_nat(U32.sub(c, 48)))        case False{}:          None{}def parse_nat(+s: String) -> Maybe<&2, Nat>:  match s:    case SNil{}:      None{}    case SCon{Chr{+c}, +t}:      is_zero = U32.is_eq(c, 48)      is_digit = Bool.and(U32.is_ge(c, 49), U32.is_le(c, 57))      parse_nat_lead(is_zero, is_digit, c, t)def pointer_resolve_arr(j: Json, m: Maybe<&2, Nat>) -> Maybe<&2, Json>:  match m:    case Some{idx}:      arr_get(j, idx)    case None{}:      None{}def pointer_resolve_token(j: Json, token: String) -> Maybe<&2, Json>:  match j:    case JObj{_}:      get(j, token)    case JArr{_}:      pointer_resolve_arr(j, parse_nat(token))    case _:      None{}def pointer_traverse_loop(+tokens: List<&2, String>, cur: Maybe<&2, Json>) -> Maybe<&2, Json>:  match tokens:    case Nil{}:      cur    case token <> rest:      match cur:        case None{}:          None{}        case Some{j}:          pointer_traverse_loop(rest, pointer_resolve_token(j, token))def pointer_start(m: Maybe<&2, List<&2, String>>, j: Json) -> Maybe<&2, Json>:  match m:    case Some{tokens}:      pointer_traverse_loop(tokens, Some{j})    case None{}:      None{}def pointer(j: Json, path: String) -> Maybe<&2, Json>:  pointer_start(parse_ptr_tokens(path), j)def pointer_set_arr_leaf(m: Maybe<&2, Nat>, j: Json, val: Json) -> Json:  match m:    case Some{idx}:      arr_set(j, idx, val)    case None{}:      jdef child_or_obj(m: Maybe<&2, Json>) -> Json:  match m:    case Some{c}:      c    case None{}:      JObj{Nil{}}def child_or_null(m: Maybe<&2, Json>) -> Json:  match m:    case Some{c}:      c    case None{}:      JNull{}def arr_child(j: Json, m: Maybe<&2, Nat>) -> Json:  match m:    case Some{idx}:      child_or_null(arr_get(j, idx))    case None{}:      JNull{}def pointer_set_arr_res(m: Maybe<&2, Nat>, j: Json, new_child: Json) -> Json:  match m:    case Some{idx}:      arr_set(j, idx, new_child)    case None{}:      jdef pointer_set_traverse(+tokens: List<&2, String>, +j: Json, +val: Json) -> Json:  match tokens:    case Nil{}:      val    case +token <> rest:      match rest:        case Nil{}:          match j:            case JObj{_}:              set(j, token, val)            case JArr{_}:              pointer_set_arr_leaf(parse_nat(token), j, val)            case _:              j        case _ <> _:          match j:            case JObj{_}:              +child = child_or_obj(get(j, token))              set(j, token, pointer_set_traverse(rest, child, val))            case JArr{_}:              +idx_m = parse_nat(token)              +child = arr_child(j, idx_m)              pointer_set_arr_res(idx_m, j, pointer_set_traverse(rest, child, val))            case _:              jdef pointer_set_step(m: Maybe<&2, List<&2, String>>, j: Json, val: Json) -> Json:  match m:    case Some{tokens}:      pointer_set_traverse(tokens, j, val)    case None{}:      jdef pointer_set(j: Json, path: String, val: Json) -> Json:  pointer_set_step(parse_ptr_tokens(path), j, val)# ==============================================================================# 9. String Escaping & Serialization (stringify)# ==============================================================================def escape_char(+c: Char) -> String:  match c:    case Chr{+code}:      Bool.pick(String, U32.is_eq(code, 34), "\\\"",        Bool.pick(String, U32.is_eq(code, 92), "\\\\",          Bool.pick(String, U32.is_eq(code, 10), "\\n",            Bool.pick(String, U32.is_eq(code, 9), "\\t",              Bool.pick(String, U32.is_eq(code, 13), "\\r",                Char.show(Chr{code}))))))def escape_string(s: String) -> String:  match s:    case SNil{}:      ""    case SCon{c, t}:      escape_char(c) ++ escape_string(t)def quote_string(s: String) -> String:  "\"" ++ escape_string(s) ++ "\""def stringify_loop(fuel: Nat, +tasks: List<&2, PrintTask>, acc: String) -> String:  match fuel:    case 0n:      acc    case 1n++p:      match tasks:        case Nil{}:          acc        case h <> t:          match h:            case PLit{s}:              stringify_loop(p, t, acc ++ s)            case PVal{j}:              match j:                case JNull{}:                  stringify_loop(p, t, acc ++ "null")                case JBool{b}:                  match b:                    case True{}:                      stringify_loop(p, t, acc ++ "true")                    case False{}:                      stringify_loop(p, t, acc ++ "false")                case JNum{n}:                  stringify_loop(p, t, acc ++ Nat.show(n))                case JNeg{n}:                  stringify_loop(p, t, acc ++ "-" ++ Nat.show(n))                case JStr{s}:                  stringify_loop(p, t, acc ++ quote_string(s))                case JArr{vals}:                  match vals:                    case Nil{}:                      stringify_loop(p, t, acc ++ "[]")                    case vh <> vt:                      stringify_loop(p, PVal{vh} <> PArr{vt} <> PLit{"]"} <> t, acc ++ "[")                case JObj{kvs}:                  match kvs:                    case Nil{}:                      stringify_loop(p, t, acc ++ "{}")                    case Tuple{k, v} <> kt:                      stringify_loop(p, PVal{v} <> PObj{kt} <> PLit{"}"} <> t, acc ++ "{" ++ quote_string(k) ++ ":")            case PArr{items}:              match items:                case Nil{}:                  stringify_loop(p, t, acc)                case vh <> vt:                  stringify_loop(p, PVal{vh} <> PArr{vt} <> t, acc ++ ",")            case PObj{kvs}:              match kvs:                case Nil{}:                  stringify_loop(p, t, acc)                case Tuple{k, v} <> kt:                  stringify_loop(p, PVal{v} <> PObj{kt} <> t, acc ++ "," ++ quote_string(k) ++ ":")def stringify(j: Json) -> String:  stringify_loop(1000n, [PVal{j}], "")# ==============================================================================# 10. Pretty Printing with Configurable Indentation# ==============================================================================def make_spaces(n: Nat) -> String:  match n:    case 0n:      ""    case 1n+p:      " " ++ make_spaces(p)def make_custom_indent(fuel: Nat, count: Nat, +step_str: String) -> String:  match fuel:    case 0n:      ""    case 1n++p:      match count:        case 0n:          ""        case 1n+cp:          step_str ++ make_custom_indent(p, cp, step_str)def pretty_indent_loop(fuel: Nat, +tasks: List<&2, PrettyTask>, +step_str: String, acc: String) -> String:  match fuel:    case 0n:      acc    case 1n++p:      match tasks:        case Nil{}:          acc        case h <> t:          match h:            case PrLit{s}:              pretty_indent_loop(p, t, step_str, acc ++ s)            case PrVal{j, +ind}:              match j:                case JNull{}:                  pretty_indent_loop(p, t, step_str, acc ++ "null")                case JBool{b}:                  match b:                    case True{}:                      pretty_indent_loop(p, t, step_str, acc ++ "true")                    case False{}:                      pretty_indent_loop(p, t, step_str, acc ++ "false")                case JNum{n}:                  pretty_indent_loop(p, t, step_str, acc ++ Nat.show(n))                case JNeg{n}:                  pretty_indent_loop(p, t, step_str, acc ++ "-" ++ Nat.show(n))                case JStr{s}:                  pretty_indent_loop(p, t, step_str, acc ++ quote_string(s))                case JArr{vals}:                  match vals:                    case Nil{}:                      pretty_indent_loop(p, t, step_str, acc ++ "[]")                    case vh <> vt:                      +next_ind = {1n+ind : Nat}                      +ind_str = make_custom_indent(10n, next_ind, step_str)                      +close_ind = make_custom_indent(10n, ind, step_str)                      pretty_indent_loop(p, PrVal{vh, next_ind} <> PrArr{vt, next_ind} <> PrLit{"\n" ++ close_ind ++ "]"} <> t, step_str, acc ++ "[\n" ++ ind_str)                case JObj{kvs}:                  match kvs:                    case Nil{}:                      pretty_indent_loop(p, t, step_str, acc ++ "{}")                    case Tuple{k, v} <> kt:                      +next_ind = {1n+ind : Nat}                      +ind_str = make_custom_indent(10n, next_ind, step_str)                      +close_ind = make_custom_indent(10n, ind, step_str)                      pretty_indent_loop(p, PrVal{v, next_ind} <> PrObj{kt, next_ind} <> PrLit{"\n" ++ close_ind ++ "}"} <> t, step_str, acc ++ "{\n" ++ ind_str ++ quote_string(k) ++ ": ")            case PrArr{items, +ind}:              match items:                case Nil{}:                  pretty_indent_loop(p, t, step_str, acc)                case vh <> vt:                  +ind_str = make_custom_indent(10n, ind, step_str)                  pretty_indent_loop(p, PrVal{vh, ind} <> PrArr{vt, ind} <> t, step_str, acc ++ ",\n" ++ ind_str)            case PrObj{kvs, +ind}:              match kvs:                case Nil{}:                  pretty_indent_loop(p, t, step_str, acc)                case Tuple{k, v} <> kt:                  +ind_str = make_custom_indent(10n, ind, step_str)                  pretty_indent_loop(p, PrVal{v, ind} <> PrObj{kt, ind} <> t, step_str, acc ++ ",\n" ++ ind_str ++ quote_string(k) ++ ": ")def pretty_indent(j: Json, step: Nat) -> String:  pretty_indent_loop(1000n, [PrVal{j, 0n}], make_spaces(step), "")def pretty(j: Json) -> String:  pretty_indent(j, 2n)# ==============================================================================# 11. Parser Implementation (parse)# ==============================================================================def classify_str_char(+c: U32) -> StrCharKind:  Bool.pick(StrCharKind, U32.is_eq(c, 34), SCQuote{},    Bool.pick(StrCharKind, U32.is_eq(c, 92), SCSlash{},      SCOther{}))def classify_char(+c: U32) -> CharKind:  Bool.pick(CharKind, U32.is_eq(c, 91), KindLBracket{},    Bool.pick(CharKind, U32.is_eq(c, 93), KindRBracket{},      Bool.pick(CharKind, U32.is_eq(c, 123), KindLBrace{},        Bool.pick(CharKind, U32.is_eq(c, 125), KindRBrace{},          Bool.pick(CharKind, U32.is_eq(c, 34), KindQuote{},            Bool.pick(CharKind, U32.is_eq(c, 44), KindComma{},              Bool.pick(CharKind, U32.is_eq(c, 58), KindColon{},                Bool.pick(CharKind, U32.is_eq(c, 110), KindNull{},                  Bool.pick(CharKind, U32.is_eq(c, 116), KindTrue{},                    Bool.pick(CharKind, U32.is_eq(c, 102), KindFalse{},                      Bool.pick(CharKind, U32.is_eq(c, 45), KindMinus{},                        Bool.pick(CharKind, Bool.and(U32.is_ge(c, 48), U32.is_le(c, 57)), KindDigit{},                          KindOther{}))))))))))))def parse_esc(+code: U32) -> Char:  Bool.pick(Char, U32.is_eq(code, 110), Chr{10},    Bool.pick(Char, U32.is_eq(code, 116), Chr{9},      Bool.pick(Char, U32.is_eq(code, 114), Chr{13},        Bool.pick(Char, U32.is_eq(code, 34), Chr{34},          Bool.pick(Char, U32.is_eq(code, 92), Chr{92},            Chr{code})))))def parse_str.loop(fuel: Nat, st: StrState, s: String, +acc: List<&2, Char>) -> StrRes:  match fuel:    case 0n:      SErr{"fuel exhausted in string parse"}    case 1n++p:      match st:        case StrNormal{}:          match s:            case SNil{}:              SErr{"unterminated string literal"}            case SCon{Chr{+c}, +t}:              parse_str.loop(p, StrChar{classify_str_char(c), c}, t, acc)        case StrEscaping{}:          match s:            case SNil{}:              SErr{"unterminated string escape"}            case SCon{Chr{+c}, +t}:              parse_str.loop(p, StrNormal{}, t, parse_esc(c) <> acc)        case StrChar{kind, c}:          match kind:            case SCQuote{}:              SOk{String.from_list(List.reverse(&2, Char, acc)), s}            case SCSlash{}:              parse_str.loop(p, StrEscaping{}, s, acc)            case SCOther{}:              parse_str.loop(p, StrNormal{}, s, Chr{c} <> acc)def skip_ws(s: String) -> String:  String.trim_start(s)type DigitsState is Data:  DStart{}  DChar{is_d: Bool, code: U32}def parse_digits.loop(fuel: Nat, st: DigitsState, s: String, +acc: Nat) -> NumRes:  match fuel:    case 0n:      NRes{acc, s}    case 1n++p:      match st:        case DStart{}:          match s:            case SNil{}:              NRes{acc, ""}            case SCon{Chr{+code}, +t}:              is_d = Bool.and(U32.is_ge(code, 48), U32.is_le(code, 57))              parse_digits.loop(p, DChar{is_d, code}, t, acc)        case DChar{is_d, code}:          match is_d:            case True{}:              +next_acc = Nat.add(Nat.mul(acc, 10n), U32.to_nat(U32.sub(code, 48)))              parse_digits.loop(p, DStart{}, s, next_acc)            case False{}:              NRes{acc, SCon{Chr{code}, s}}def parse_digits(fuel: Nat, s: String, acc: Nat) -> NumRes:  parse_digits.loop(fuel, DStart{}, s, acc)def parse_step(fuel: Nat, act: StepAct, +stack: List<&2, Frame>, s: String) -> Result<&2, &2, String, Json>:  match fuel:    case 0n:      Fail{"fuel exhausted in parser"}    case 1n++p:      match act:        case ActCheckEof{+v}:          match s:            case SNil{}:              Done{v}            case SCon{c, t}:              Fail{"unexpected trailing characters after JSON root"}        case ActHaveVal{+v}:          match stack:            case Nil{}:              parse_step(p, ActCheckEof{v}, Nil{}, skip_ws(s))            case FArr{items} <> rest_stack:              parse_step(p, ActArrNext{v, items}, rest_stack, skip_ws(s))            case FObjVal{key, kvs} <> rest_stack:              parse_step(p, ActObjNext{key, v, kvs}, rest_stack, skip_ws(s))        case ActArrOpen{}:          match s:            case SNil{}:              Fail{"unexpected EOF in array: missing ']'"}            case SCon{Chr{+c}, +t}:              parse_step(p, ActArrOpenChar{classify_char(c), c}, stack, t)        case ActArrOpenChar{kind, c}:          match kind:            case KindRBracket{}:              parse_step(p, ActHaveVal{JArr{Nil{}}}, stack, s)            case _:              parse_step(p, ActValStart{}, FArr{Nil{}} <> stack, SCon{Chr{c}, s})        case ActArrNext{+v, +items}:          match s:            case SNil{}:              Fail{"unexpected EOF in array: missing ']'"}            case SCon{Chr{+c}, +t}:              parse_step(p, ActArrNextChar{classify_char(c), v, items}, stack, t)        case ActArrNextChar{kind, +v, +items}:          match kind:            case KindRBracket{}:              parse_step(p, ActHaveVal{JArr{List.reverse(&2, Json, v <> items)}}, stack, s)            case KindComma{}:              parse_step(p, ActValStart{}, FArr{v <> items} <> stack, skip_ws(s))            case _:              Fail{"expected ',' or ']' in array"}        case ActObjOpen{}:          match s:            case SNil{}:              Fail{"unexpected EOF in object: missing '}'"}            case SCon{Chr{+c}, +t}:              parse_step(p, ActObjOpenChar{classify_char(c), c}, stack, t)        case ActObjOpenChar{kind, c}:          match kind:            case KindRBrace{}:              parse_step(p, ActHaveVal{JObj{Nil{}}}, stack, s)            case _:              parse_step(p, ActKeyStart{Nil{}}, stack, SCon{Chr{c}, s})        case ActKeyStart{+kvs}:          match s:            case SNil{}:              Fail{"unexpected EOF in object: missing key string"}            case SCon{Chr{+c}, +t}:              parse_step(p, ActKeyStartChar{classify_char(c), kvs}, stack, t)        case ActKeyStartChar{kind, +kvs}:          match kind:            case KindQuote{}:              parse_step(p, ActKeyParsed{parse_str.loop(p, StrNormal{}, s, Nil{}), kvs}, stack, "")            case KindRBrace{}:              parse_step(p, ActHaveVal{JObj{List.reverse(&2, Sigma<&2, &2, String, _ => Json>, kvs)}}, stack, s)            case _:              Fail{"expected string key or '}' in object"}        case ActKeyParsed{res, +kvs}:          match res:            case SErr{msg}:              Fail{msg}            case SOk{key, rest}:              parse_step(p, ActColon{key, kvs}, stack, skip_ws(rest))        case ActColon{key, +kvs}:          match s:            case SNil{}:              Fail{"expected ':' after object key"}            case SCon{Chr{+c}, +t}:              parse_step(p, ActColonChar{classify_char(c), key, kvs}, stack, t)        case ActColonChar{kind, key, +kvs}:          match kind:            case KindColon{}:              parse_step(p, ActValStart{}, FObjVal{key, kvs} <> stack, skip_ws(s))            case _:              Fail{"expected ':' after object key"}        case ActObjNext{key, +v, +kvs}:          match s:            case SNil{}:              Fail{"unexpected EOF in object: missing '}'"}            case SCon{Chr{+c}, +t}:              parse_step(p, ActObjNextChar{classify_char(c), key, v, kvs}, stack, t)        case ActObjNextChar{kind, +key, +v, +kvs}:          match kind:            case KindRBrace{}:              parse_step(p, ActHaveVal{JObj{List.reverse(&2, Sigma<&2, &2, String, _ => Json>, Tuple{key, v} <> kvs)}}, stack, s)            case KindComma{}:              parse_step(p, ActKeyStart{Tuple{key, v} <> kvs}, stack, skip_ws(s))            case _:              Fail{"expected ',' or '}' in object"}        case ActStrParsed{res}:          match res:            case SErr{msg}:              Fail{msg}            case SOk{val, rest}:              parse_step(p, ActHaveVal{JStr{val}}, stack, rest)        case ActNumParsed{neg_flag, res}:          match neg_flag res:            case True{} NRes{n, rest}:              parse_step(p, ActHaveVal{JNeg{n}}, stack, rest)            case False{} NRes{n, rest}:              parse_step(p, ActHaveVal{JNum{n}}, stack, rest)        case ActLitCheck{expected, +val, ok, rest}:          match ok:            case True{}:              parse_step(p, ActHaveVal{val}, stack, rest)            case False{}:              Fail{"invalid literal: expected " ++ expected}        case ActValStart{}:          match s:            case SNil{}:              Fail{"unexpected EOF: expected a JSON value"}            case SCon{Chr{+c}, +t}:              parse_step(p, ActValChar{classify_char(c), c}, stack, t)        case ActValChar{kind, c}:          match kind:            case KindLBracket{}:              parse_step(p, ActArrOpen{}, stack, skip_ws(s))            case KindLBrace{}:              parse_step(p, ActObjOpen{}, stack, skip_ws(s))            case KindQuote{}:              parse_step(p, ActStrParsed{parse_str.loop(p, StrNormal{}, s, Nil{})}, stack, "")            case KindNull{}:              +full_str = {SCon{Chr{c}, s} : String}              parse_step(p, ActLitCheck{"null", JNull{}, String.starts_with(full_str, "null"), String.drop(full_str, 4n)}, stack, "")            case KindTrue{}:              +full_str = {SCon{Chr{c}, s} : String}              parse_step(p, ActLitCheck{"true", JBool{True{}}, String.starts_with(full_str, "true"), String.drop(full_str, 4n)}, stack, "")            case KindFalse{}:              +full_str = {SCon{Chr{c}, s} : String}              parse_step(p, ActLitCheck{"false", JBool{False{}}, String.starts_with(full_str, "false"), String.drop(full_str, 5n)}, stack, "")            case KindMinus{}:              parse_step(p, ActNumParsed{True{}, parse_digits(p, s, 0n)}, stack, "")            case KindDigit{}:              parse_step(p, ActNumParsed{False{}, parse_digits(p, s, U32.to_nat(U32.sub(c, 48)))}, stack, "")            case _:              Fail{"unexpected character when reading JSON value"}def parse(+s: String) -> Result<&2, &2, String, Json>:  +fuel = {Nat.add(Nat.mul(String.length(s), 8n), 100n) : Nat}  parse_step(fuel, ActValStart{}, Nil{}, skip_ws(s))# ==============================================================================# 12. Validation & Streaming NDJSON Support# ==============================================================================def validate_step(r: Result<&2, &2, String, Json>) -> Bool:  match r:    case Done{_}:      True{}    case Fail{_}:      False{}def validate(s: String) -> Bool:  validate_step(parse(s))def stringify_ndjson(xs: List<&2, Json>) -> String:  match xs:    case Nil{}:      ""    case h <> t:      stringify(h) ++ "\n" ++ stringify_ndjson(t)def split_lines_done(is_empty: Bool, +line: String) -> List<&2, String>:  match is_empty:    case True{}:      Nil{}    case False{}:      [line]def split_lines.loop(fuel: Nat, st: LineSplitState, s: String, +cur: String) -> List<&2, String>:  match fuel:    case 0n:      +line = String.trim(String.reverse(cur))      split_lines_done(String.is_empty(line), line)    case 1n++p:      match st:        case LSNormal{}:          match s:            case SNil{}:              +line = String.trim(String.reverse(cur))              split_lines_done(String.is_empty(line), line)            case SCon{Chr{+c}, +t}:              split_lines.loop(p, LSCheckNl{U32.is_eq(c, 10), c}, t, cur)        case LSCheckNl{is_nl, c}:          match is_nl:            case True{}:              +line = String.trim(String.reverse(cur))              split_lines.loop(p, LSEmpty{String.is_empty(line), line}, s, "")            case False{}:              split_lines.loop(p, LSNormal{}, s, SCon{Chr{c}, cur})        case LSEmpty{is_empty, line}:          match is_empty:            case True{}:              split_lines.loop(p, LSNormal{}, s, "")            case False{}:              line <> split_lines.loop(p, LSNormal{}, s, "")def split_lines_loop(+s: String, cur: String) -> List<&2, String>:  fuel = Nat.add(Nat.mul(String.length(s), 3n), 20n)  split_lines.loop(fuel, LSNormal{}, s, cur)def list_parse_lines(lines: List<&2, String>) -> List<&2, Result<&2, &2, String, Json>>:  match lines:    case Nil{}:      Nil{}    case h <> t:      parse(h) <> list_parse_lines(t)def parse_ndjson(s: String) -> List<&2, Result<&2, &2, String, Json>>:  list_parse_lines(split_lines_loop(s, ""))