JSON API
A standards-compliant JSON encoder and decoder that stringifies Zym values to JSON text and parses JSON text back into Zym values.
Overview
The global identifier JSON is a namespace. Its statics stringify, parse, and create all operate directly on Zym values: stringify takes a Zym value and produces a JSON text string, and parse takes a JSON text string and produces a Zym value. JSON.create() returns a stateful instance whose methods are invoked as j.method(...) and which retains error information and, optionally, the original text.
Conventions
Type Mapping
| Zym | JSON |
|---|---|
null | null |
bool | true / false |
number | JSON number (always written with decimal precision) |
string | JSON string |
list | JSON array |
map | JSON object |
Zym maps are string-keyed by construction, so encoded objects always have string keys. Parsed objects are returned as Zym maps; numeric or other non-string keys (which standard JSON cannot produce) would be coerced to strings.
Numbers
Zym numbers are doubles; integral values round-trip losslessly up to 253. JSON numbers always parse back to Zym numbers.
Errors
Static JSON.parse returns null when the input is not valid JSON; it never raises. Instance j.parse(text) returns false on failure and exposes the error via j.errorLine() and j.errorMessage(). Bad argument types, such as passing a number to parse, raise a Zym runtime error of the form JSON.method(args) ....
Limits & Unsupported Values
Stringify and setData reject values that nest deeper than 512 levels with a runtime error. Closures, structs, enums, and other non-JSON Zym values raise a runtime error during stringify.
Static Methods
Encodes value as JSON text. Output is compact by default, and object keys are sorted by default for stable output. Passing an indent string pretty-prints the result. Values that nest deeper than 512 levels, or that contain non-JSON values such as closures, structs, or enums, raise a runtime error.
value(any) — the Zym value to encode (see Conventions for the type mapping)indent(string, optional) — indent string for pretty-printing (e.g." "or"\t"); pass""for compact outputsortKeys(boolean, optional) — whenfalse, preserves the insertion order of map keys instead of sorting themfullPrecision(boolean, optional) — whentrue, numbers are written with the full IEEE-754 round-trip precision
Returns: A JSON text string.
print(JSON.stringify({"a": 1, "b": [true, null]}, " "))
// {
// "a": 1.0,
// "b": [
// true,
// null
// ]
// }
Parses text as JSON and returns the resulting Zym value. Returns null on any parse error; it never raises on malformed input.
text(string) — the JSON text to parse
Returns: The parsed Zym value, or null on any parse error.
var v = JSON.parse("{not valid}") if (v == null) { print("bad input") }
Builds a new stateful parser that retains error information and, optionally, the original input text.
Returns: A JSON instance whose methods are invoked as j.method(...).
Instance Methods
Returned by JSON.create(). Methods are invoked as j.method(...).
parse clears the error fields, and a failing parse does not overwrite the previously stored data.
Parses text. Returns true on success and stores the result for retrieval with j.data(). On failure, populates j.errorLine() and j.errorMessage() and returns false. When keepText is true, the original input is retained and available from j.parsedText().
text(string) — the JSON text to parsekeepText(boolean, optional) — retain the original input forj.parsedText()
var j = JSON.create() if (j.parse("{\"k\":[1,2,]}", true) == false) { print(j.errorLine()) // line of the offending token print(j.errorMessage()) // e.g. "Expected value, got ',' " print(j.parsedText()) // the original input }
Returns the most recently parsed value, or the value assigned via j.setData(), or null if nothing has been stored.
Replaces the stored data. Useful when an instance is being threaded through code that later wants to introspect or stringify the value. Rejects values that nest deeper than 512 levels with a runtime error.
value(any) — the value to store
Returns: null.
Returns the original input from the last parse(text, true) call, or "" if the text was not retained.
Returns the 0-indexed line number of the last parse error, counting newlines crossed before the offending token, or 0 after a successful parse. Errors on the first line therefore also report 0.
Returns a human-readable message for the last parse error, or "" after a successful parse.
Examples
One-Shot Encode / Decode
var text = JSON.stringify({"name": "ada", "skills": ["math", "code"]}) print(text) // {"name":"ada","skills":["math","code"]} var v = JSON.parse(text) print(v["name"]) // ada print(v["skills"][1]) // code
Round-Trip a Nested Map
var original = { "items": [{"id": 1, "name": "a"}, {"id": 2, "name": "b"}], "count": 2 } var txt = JSON.stringify(original) var back = JSON.parse(txt) print(back["items"][1]["name"]) // b print(back["count"]) // 2