JSON

The JSON: module parses, inspects, builds, and serializes JSON. Documents are identified by numeric handles assigned at creation and held in memory until freed. Paths use dot notation; numeric parts index arrays. Use "" for the root node.


Call Effect
JSON:New(handle) Create an empty document; assigns numeric handle → outVar
JSON:Parse(str, handle) Parse JSON string into doc
JSON:Free(handle) Release document
JSON:Stringify(path, handle, outVar) Serialize doc or subtree → outVar
JSON:Get(path, handle, outVar) Read value → outVar (typed: Number/String/Boolean; objects/arrays → JSON string)
JSON:Has(path, handle, outVar) true if path exists → outVar
JSON:Type(path, handle, outVar) "object" "array" "string" "number" "bool" "null"outVar
JSON:Length(path, handle, outVar) Element count for array or object → outVar
JSON:Keys(path, handle, listName) Object keys → pre-declared List:String
JSON:Set(path, value, handle) Write scalar at path (creates keys as needed)
JSON:Push(path, value, handle) Append scalar to array at path ("" = root)

Path examples: "name", "user.age", "items.0", "data.scores.2". Use "" for root.

Var:Number resp;
Var:Number status;
Var:String name;
Var:String typeStr;
Var:Number len;
Var:String out;

// Parse and read
JSON:New(resp);
JSON:Parse("{\"status\":200,\"user\":{\"name\":\"Alice\",\"scores\":[95,82]}}", resp);
JSON:Get("status", resp, status);
Konsol:Print(status);                // 200
JSON:Get("user.name", resp, name);
Konsol:Print(name);                  // Alice
JSON:Type("user.scores", resp, typeStr);
Konsol:Print(typeStr);               // array
JSON:Length("user.scores", resp, len);
Konsol:Print(len);                   // 2

// Build and serialize
Var:Number cfg;
JSON:New(cfg);
JSON:Set("host", "localhost", cfg);
JSON:Set("port", 8080, cfg);
JSON:Stringify("", cfg, out);
Konsol:Print(out);                   // {"host":"localhost","port":8080}

// Build array
Var:Number tags;
JSON:New(tags);
JSON:Push("", "fast", tags);
JSON:Push("", "safe", tags);
JSON:Stringify("", tags, out);
Konsol:Print(out);                   // ["fast","safe"]

JSON:Free(resp);
JSON:Free(cfg);
JSON:Free(tags);

Examples

// 25_json.ks - JSON module

Var:String strVal;
Var:Number numVal;
Var:Boolean boolVal;
Var:Boolean found;
Var:String typeStr;
Var:Number sz;
List:New keyList:String;

Konsol:Print("=== parse flat object ===");
JSON:New user;
JSON:Parse("{\"name\":\"Alice\",\"age\":30,\"active\":true}", user);
JSON:Get("name", user, strVal);
Konsol:Print(strVal);           // Alice
JSON:Get("age", user, numVal);
Konsol:Print(numVal);           // 30
JSON:Get("active", user, boolVal);
Konsol:Print(boolVal);          // true

Konsol:Print("=== type detection ===");
JSON:Type("name", user, typeStr);
Konsol:Print(typeStr);          // string
JSON:Type("age", user, typeStr);
Konsol:Print(typeStr);          // number
JSON:Type("active", user, typeStr);
Konsol:Print(typeStr);          // bool

Konsol:Print("=== has ===");
JSON:Has("name", user, found);
Konsol:Print(found);            // true
JSON:Has("missing", user, found);
Konsol:Print(found);            // false

Konsol:Print("=== keys ===");
JSON:Keys("", user, keyList);
List:Size(keyList, sz);
Konsol:Print(sz);               // 3

Konsol:Print("=== parse array ===");
JSON:New nums;
JSON:Parse("[10,20,30,40,50]", nums);
JSON:Type("", nums, typeStr);
Konsol:Print(typeStr);          // array
JSON:Length("", nums, sz);
Konsol:Print(sz);               // 5
JSON:Get("0", nums, numVal);
Konsol:Print(numVal);           // 10
JSON:Get("4", nums, numVal);
Konsol:Print(numVal);           // 50

Konsol:Print("=== nested object ===");
JSON:New resp;
JSON:Parse("{\"status\":200,\"data\":{\"id\":7,\"name\":\"Bob\",\"scores\":[95,82,77]}}", resp);
JSON:Get("status", resp, numVal);
Konsol:Print(numVal);           // 200
JSON:Get("data.name", resp, strVal);
Konsol:Print(strVal);           // Bob
JSON:Get("data.id", resp, numVal);
Konsol:Print(numVal);           // 7
JSON:Get("data.scores.0", resp, numVal);
Konsol:Print(numVal);           // 95
JSON:Get("data.scores.2", resp, numVal);
Konsol:Print(numVal);           // 77
JSON:Length("data.scores", resp, sz);
Konsol:Print(sz);               // 3
JSON:Type("data", resp, typeStr);
Konsol:Print(typeStr);          // object
JSON:Type("data.scores", resp, typeStr);
Konsol:Print(typeStr);          // array

Konsol:Print("=== build object ===");
JSON:New doc;
JSON:Set("title", "minks", doc);
JSON:Set("version", 1, doc);
JSON:Set("stable", true, doc);
JSON:Stringify("", doc, strVal);
Konsol:Print(strVal);           // {"title":"minks","version":1,"stable":true}

Konsol:Print("=== build array ===");
JSON:New arr;
JSON:Push("", "alpha", arr);
JSON:Push("", "beta", arr);
JSON:Push("", "gamma", arr);
JSON:Stringify("", arr, strVal);
Konsol:Print(strVal);           // ["alpha","beta","gamma"]
JSON:Length("", arr, sz);
Konsol:Print(sz);               // 3

Konsol:Print("=== push auto-array ===");
JSON:New scores;
JSON:Push("data", 95, scores);
JSON:Push("data", 82, scores);
JSON:Push("data", 77, scores);
JSON:Stringify("", scores, strVal);
Konsol:Print(strVal);           // {"data":[95,82,77]}

Konsol:Print("=== stringify nested ===");
JSON:Stringify("data.scores", resp, strVal);
Konsol:Print(strVal);           // [95,82,77]

Konsol:Print("=== loop over array ===");
Var:Number count;
JSON:Length("data.scores", resp, count);
for (Var:Number i = 0; i < count; i++) {
    Var:String path = "data.scores." + i;
    JSON:Get(path, resp, numVal);
    Konsol:Print(numVal);       // 95 82 77
}

Konsol:Print("=== free ===");
JSON:Free(user);
JSON:Free(nums);
JSON:Free(resp);
JSON:Free(doc);
JSON:Free(arr);
JSON:Free(scores);
Konsol:Print("done");