JSON parsing and generation for PTC-Lisp.
Implements (json/parse-string s) and (json/generate-string v) —
Cheshire-shaped builtins. Both functions return nil on failure
rather than raising, matching the DIV-* convention (see
docs/clojure-conformance-gaps.md DIV-23, DIV-24): no try/catch
in the sandbox means raising = unrecoverable program crash.
See Plans/json-support.md §4 for the full spec, including the
string-keyed-only round-trip property and the integer-key /
special-float carve-outs (§4.3).
Summary
Functions
Encode an Elixir value as a JSON string.
Returns the encoded string on success; nil on any failure
(non-encodable input). Encoder pre-validation (per spec §4.4) runs
before Jason.encode/1 is invoked — without it, Jason would
silently coerce non-boolean atoms (e.g. PTC-Lisp keywords like
:fs) into JSON strings, eroding the wire-boundary type signal.
Map keys are restricted to strings and integers — atoms (including
true / false / nil), floats, and other key types fail the
walk and produce nil (§4.2 / §4.3).
Examples
iex> PtcRunner.Lisp.Runtime.Json.generate_string(nil)
"null"
iex> PtcRunner.Lisp.Runtime.Json.generate_string([1, 2, 3])
"[1,2,3]"
iex> PtcRunner.Lisp.Runtime.Json.generate_string("hello")
"\"hello\""
iex> PtcRunner.Lisp.Runtime.Json.generate_string(%{"server" => :fs})
nil
iex> PtcRunner.Lisp.Runtime.Json.generate_string(%{:server => "fs"})
nil
iex> PtcRunner.Lisp.Runtime.Json.generate_string({:ok, 1})
nil
iex> PtcRunner.Lisp.Runtime.Json.generate_string(%{1 => "a"})
"{\"1\":\"a\"}"
Parse a JSON string into an Elixir value.
Returns the parsed value on success; nil on any failure
(invalid JSON, non-binary input, nil input). Map keys are
decoded as strings (no atom keys) to avoid atom memory
leaks on untrusted input.
Examples
iex> PtcRunner.Lisp.Runtime.Json.parse_string(~S|{"a": 1, "b": [2, 3]}|)
%{"a" => 1, "b" => [2, 3]}
iex> PtcRunner.Lisp.Runtime.Json.parse_string("[1, 2, 3]")
[1, 2, 3]
iex> PtcRunner.Lisp.Runtime.Json.parse_string("null")
nil
iex> PtcRunner.Lisp.Runtime.Json.parse_string("not json")
nil
iex> PtcRunner.Lisp.Runtime.Json.parse_string(nil)
nil
iex> PtcRunner.Lisp.Runtime.Json.parse_string(42)
nil