code wiki / (root) / nx_json_test.nx

nx_json_test.nx source

↩ module page · 114 lines · 3530 B

1// nx_json_test.nx -- exercise both the tokenizer (nx_json.nx) and the 2// emitter (nx_json_emit.nx) end-to-end. 3// 4// Strategy: 5// 1. Use the emitter to build an object with strings (incl. 6// escapes), ints, bool, null, nested array/object. 7// 2. Confirm the emitted bytes parse cleanly via the tokenizer. 8// 3. Spot-check a handful of token kinds + escape behaviour. 9 10import "nx_syscalls.nx" 11import "nx_runtime.nx" 12import "nx_json.nx" 13import "nx_json_emit.nx" 14import "json_emit.nx" // the RFC 8259 JsonWriter API this test actually exercises. nx_json_emit.nx 15 // is a DIFFERENT organ -- the tiny je_* emitter -- and never carried it. 16 17func main() -> i64 { 18 // ===== Emit phase =============================================== 19 let buf: *u8 = sys_mmap(512) 20 let w_raw: *u8 = sys_mmap(128) 21 let w: *JsonWriter = w_raw as *JsonWriter 22 json_writer_init(w, buf, 512) 23 24 json_begin_object(w) 25 26 json_emit_key(w, "who", 3) 27 json_emit_string(w, "sketch_hll", 10) 28 29 json_emit_key(w, "msg", 3) 30 // Contains a quote + backslash to exercise escape paths. 31 json_emit_string(w, "has \"quotes\" and \\back", 22) 32 33 json_emit_key(w, "count", 5) 34 json_emit_int(w, 42) 35 36 json_emit_key(w, "negative", 8) 37 json_emit_int(w, 0 - 7) 38 39 json_emit_key(w, "active", 6) 40 json_emit_bool(w, 1) 41 42 json_emit_key(w, "missing", 7) 43 json_emit_null(w) 44 45 json_emit_key(w, "tags", 4) 46 json_begin_array(w) 47 json_emit_string(w, "alpha", 5) 48 json_emit_string(w, "beta", 4) 49 json_end_array(w) 50 51 json_end_object(w) 52 53 let total: i64 = w.pos 54 if total <= 0 { return 1 } 55 // First byte is '{'. 56 if buf[0] != 0x7B { return 2 } 57 // Last emitted byte is '}'. 58 if buf[total - 1] != 0x7D { return 3 } 59 60 // ===== Tokenizer phase ========================================== 61 let t: *NxJsonTok = nx_json_new(buf, total) 62 63 // Token 1: LBRACE. 64 nx_json_next(t) 65 if t.kind != NX_JSON_LBRACE { return 4 } 66 67 // Token 2: STRING "who". 68 nx_json_next(t) 69 if t.kind != NX_JSON_STRING { return 5 } 70 71 // Token 3: COLON. 72 nx_json_next(t) 73 if t.kind != NX_JSON_COLON { return 6 } 74 75 // Token 4: STRING "sketch_hll". 76 nx_json_next(t) 77 if t.kind != NX_JSON_STRING { return 7 } 78 79 // Token 5: COMMA. 80 nx_json_next(t) 81 if t.kind != NX_JSON_COMMA { return 8 } 82 83 // Token 6: STRING "msg" (the escaped one's KEY). 84 nx_json_next(t) 85 if t.kind != NX_JSON_STRING { return 9 } 86 87 // Skip COLON + escaped-string value + COMMA. 88 nx_json_next(t) 89 if t.kind != NX_JSON_COLON { return 10 } 90 nx_json_next(t) 91 if t.kind != NX_JSON_STRING { return 11 } 92 // The escaped string's span includes the quotes; verify its first 93 // byte is `"` and last byte is `"`. 94 if buf[t.tok_off] != 0x22 { return 12 } 95 if buf[t.tok_off + t.tok_len - 1] != 0x22 { return 13 } 96 97 nx_json_next(t) 98 if t.kind != NX_JSON_COMMA { return 14 } 99 100 // "count":42 101 nx_json_next(t) // STRING key 102 if t.kind != NX_JSON_STRING { return 15 } 103 nx_json_next(t) // COLON 104 if t.kind != NX_JSON_COLON { return 16 } 105 nx_json_next(t) // NUMBER 42 106 if t.kind != NX_JSON_NUMBER { return 17 } 107 108 // We don't drain to EOF -- enough to confirm the emitter produced 109 // tokenizer-clean JSON across object + array + escape + int + 110 // negative + bool + null paths. 111 112 println("nx_json: emitter + tokenizer round-trip PASS" as *u8) 113 return 0 114}