From fcedfddf00b3f994e4f4e40332ac7fc192c63244 Mon Sep 17 00:00:00 2001 From: polwex Date: Sun, 5 Oct 2025 21:56:51 +0700 Subject: claude is gud --- vere/pkg/noun/jets/e/json_en.c | 416 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 416 insertions(+) create mode 100644 vere/pkg/noun/jets/e/json_en.c (limited to 'vere/pkg/noun/jets/e/json_en.c') diff --git a/vere/pkg/noun/jets/e/json_en.c b/vere/pkg/noun/jets/e/json_en.c new file mode 100644 index 0000000..f605ab4 --- /dev/null +++ b/vere/pkg/noun/jets/e/json_en.c @@ -0,0 +1,416 @@ +/// @file + +#include "jets/k.h" +#include "jets/q.h" +#include "jets/w.h" + +#include "noun.h" + +/* +** structs +*/ + +typedef struct _json_buffer { + c3_y *buf_y; + c3_w len_w; +} json_buffer; + +/* +** constants +*/ + +const c3_y _JSON_NULL[] = "null"; +const c3_y _JSON_TRUE[] = "true"; +const c3_y _JSON_FALSE[] = "false"; +const c3_y _JSON_NEWLINE[] = "\\n"; +const c3_y _JSON_DOQ[] = "\\\""; +const c3_y _JSON_BAS[] = "\\\\"; +const c3_y _JSON_DEL[] = "\\u007f"; +const c3_y *_JSON_UNICODES[] = { + (c3_y*)"\\u0000", // 0 + (c3_y*)"\\u0001", // 1 + (c3_y*)"\\u0002", // 2 + (c3_y*)"\\u0003", // 3 + (c3_y*)"\\u0004", // 4 + (c3_y*)"\\u0005", // 5 + (c3_y*)"\\u0006", // 6 + (c3_y*)"\\u0007", // 7 + (c3_y*)"\\u0008", // 8 + (c3_y*)"\\u0009", // 9 + (c3_y*)"\\u000a", // 10 + (c3_y*)"\\u000b", // 11 + (c3_y*)"\\u000c", // 12 + (c3_y*)"\\u000d", // 13 + (c3_y*)"\\u000e", // 14 + (c3_y*)"\\u000f", // 15 + (c3_y*)"\\u0010", // 16 + (c3_y*)"\\u0011", // 17 + (c3_y*)"\\u0012", // 18 + (c3_y*)"\\u0013", // 19 + (c3_y*)"\\u0014", // 20 + (c3_y*)"\\u0015", // 21 + (c3_y*)"\\u0016", // 22 + (c3_y*)"\\u0017", // 23 + (c3_y*)"\\u0018", // 24 + (c3_y*)"\\u0019", // 25 + (c3_y*)"\\u001a", // 26 + (c3_y*)"\\u001b", // 27 + (c3_y*)"\\u001c", // 28 + (c3_y*)"\\u001d", // 29 + (c3_y*)"\\u001e", // 30 + (c3_y*)"\\u001f", // 31 +}; + +/* +** forward declarations +*/ + +static c3_w +_measure(u3_noun a); + +static void +_serialize(json_buffer*, u3_noun); + +/* +** core jet logic +*/ + +static void +_append_char(json_buffer *buf_u, c3_y c_y) +{ + buf_u->buf_y[(buf_u->len_w)++] = c_y; +} + +static void +_append_text(json_buffer *buf_u, const c3_y *buf_y, c3_w len_w) +{ + memcpy(&(buf_u->buf_y[buf_u->len_w]), buf_y, len_w); + buf_u->len_w += len_w; +} + +static c3_w +_measure_loobean(u3_noun a) +{ + switch ( a ) { + default: u3m_bail(c3__exit); + case c3y: return sizeof(_JSON_TRUE) - 1; + case c3n: return sizeof(_JSON_FALSE) - 1; + } +} + +static void +_serialize_loobean(json_buffer *buf_u, u3_noun a) +{ + switch ( a ) { + default: u3_assert(0); + case c3y: _append_text(buf_u, _JSON_TRUE, sizeof(_JSON_TRUE) - 1); break; + case c3n: _append_text(buf_u, _JSON_FALSE, sizeof(_JSON_FALSE) - 1); break; + } +} + +static c3_w +_measure_number(u3_noun a) +{ + if ( _(u3du(a)) ) { + u3m_bail(c3__exit); + } + + return u3r_met(3, a); +} + +static void +_serialize_number(json_buffer *buf_u, u3_noun a) +{ + const c3_y *byt_y; + + // XX assumes little-endian + // + if ( c3y == u3a_is_cat(a) ) { + byt_y = (c3_y*)&a; + } + else { + u3a_atom* vat_u = u3a_to_ptr(a); + byt_y = (c3_y*)vat_u->buf_w; + } + + _append_text(buf_u, byt_y, u3r_met(3, a)); +} + +static c3_w +_measure_string(u3_noun a) +{ + if ( _(u3du(a)) ) { + u3m_bail(c3__exit); + } + + c3_w len_w = u3r_met(3, a); + c3_w siz_w = 0; + + for (c3_w i = 0; i < len_w; ++i) { + c3_y c_y = u3r_byte(i, a); + + switch ( c_y ) { + case 0 ... 9: + case 11 ... 31: { + siz_w += 6; + } break; + + case 10: { + siz_w += sizeof(_JSON_NEWLINE) - 1; + } break; + + case 34: { + siz_w += sizeof(_JSON_DOQ) - 1; + } break; + + case 92: { + siz_w += sizeof(_JSON_BAS) - 1; + } break; + + case 127: { + siz_w += sizeof(_JSON_DEL) - 1; + } break; + + default: { + siz_w += 1; + } break; + } + } + + // surrounding double quotes + return (siz_w + 2); +} + +static void +_serialize_string(json_buffer *buf_u, u3_noun a) +{ + c3_w len_w = u3r_met(3, a); + + _append_char(buf_u, '"'); + for (c3_w i = 0; i < len_w; ++i) { + c3_y c_y = u3r_byte(i, a); + + switch ( c_y ) { + case 0 ... 9: + case 11 ... 31: { + _append_text(buf_u, _JSON_UNICODES[c_y], 6); + } break; + + case 10: { + _append_text(buf_u, _JSON_NEWLINE, sizeof(_JSON_NEWLINE) - 1); + } break; + + case 34: { + _append_text(buf_u, _JSON_DOQ, sizeof(_JSON_DOQ) - 1); + } break; + + case 92: { + _append_text(buf_u, _JSON_BAS, sizeof(_JSON_BAS) - 1); + } break; + + case 127: { + _append_text(buf_u, _JSON_DEL, sizeof(_JSON_DEL) - 1); + } break; + + default: { + _append_char(buf_u, c_y); + } break; + } + } + _append_char(buf_u, '"'); +} + +static c3_w +_measure_array(u3_noun a) +{ + if ( u3_nul != a ) { + u3_noun i, t = a; + // array open brace + c3_w siz_w = 1; + + while ( u3_nul != t ) { + u3x_cell(t, &i, &t); + siz_w += _measure(i); + // comma or array close brace + siz_w += 1; + } + + return siz_w; + } + else { + // empty array + return 2; + } +} + +static void +_serialize_array(json_buffer *buf_u, u3_noun a) +{ + _append_char(buf_u, '['); + + if ( u3_nul != a ) { + u3_noun i, t = a; + + while ( u3_nul != t ) { + u3x_cell(t, &i, &t); + _serialize(buf_u, i); + _append_char(buf_u, ','); + } + + // Remove trailing comma from array contents + --buf_u->len_w; + } + + _append_char(buf_u, ']'); +} + +static c3_w +_measure_object_helper(u3_noun a) +{ + c3_w siz_w = 0; + + if ( u3_nul != a ) { + u3_noun n_a, l_a, r_a; + u3_noun pn_a, qn_a; + u3x_trel(a, &n_a, &l_a, &r_a); + u3x_cell(n_a, &pn_a, &qn_a); + + siz_w += _measure_object_helper(r_a); + siz_w += _measure_object_helper(l_a); + + siz_w += _measure_string(pn_a); + siz_w += _measure(qn_a); + + // colon and comma (or closing brace) + siz_w += 2; + } + + return siz_w; +} + +static void +_serialize_object_helper(json_buffer *buf_u, u3_noun a) +{ + if ( u3_nul != a ) { + u3_noun n_a, l_a, r_a; + u3_noun pn_a, qn_a; + u3x_trel(a, &n_a, &l_a, &r_a); + u3x_cell(n_a, &pn_a, &qn_a); + + // order is important to match unjetted tree traversal + _serialize_object_helper(buf_u, r_a); + + _serialize_string(buf_u, pn_a); + _append_char(buf_u, ':'); + _serialize(buf_u, qn_a); + _append_char(buf_u, ','); + + _serialize_object_helper(buf_u, l_a); + } +} + +static c3_w +_measure_object(u3_noun a) +{ + if ( u3_nul != a ) { + // opening brace + return 1 + _measure_object_helper(a); + } + else { + // empty object + return 2; + } +} + +static void +_serialize_object(json_buffer *buf_u, u3_noun a) +{ + _append_char(buf_u, '{'); + + if ( u3_nul != a ) { + _serialize_object_helper(buf_u, a); + + // Remove trailing comma from object contents + --buf_u->len_w; + } + + _append_char(buf_u, '}'); +} + +static c3_w +_measure(u3_noun a) +{ + if ( u3_nul == a ) { + return sizeof(_JSON_NULL) - 1; + } + else { + u3_noun s, p; + u3x_cell(a, &s, &p); + + switch ( s ) { + default: u3m_bail(c3__fail); + case c3__a: return _measure_array(p); + case c3__o: return _measure_object(p); + case c3__b: return _measure_loobean(p); + case c3__n: return _measure_number(p); + case c3__s: return _measure_string(p); + } + } +} + +static void +_serialize(json_buffer *buf_u, u3_noun a) +{ + if ( u3_nul == a ) { + _append_text(buf_u, _JSON_NULL, sizeof(_JSON_NULL) - 1); + } + else { + u3_noun s, p; + u3x_cell(a, &s, &p); + + switch ( s ) { + default: u3_assert(0); + case c3__a: _serialize_array(buf_u, p); break; + case c3__o: _serialize_object(buf_u, p); break; + case c3__b: _serialize_loobean(buf_u, p); break; + case c3__n: _serialize_number(buf_u, p); break; + case c3__s: _serialize_string(buf_u, p); break; + } + } +} + +/* +** jet interface functions +*/ + +u3_atom +u3qe_json_en(u3_noun a) +{ + u3i_slab sab_u; + json_buffer bof_u; + json_buffer *buf_u = &bof_u; + c3_w siz_w = _measure(a); + + u3i_slab_init(&sab_u, 3, siz_w); + buf_u->buf_y = sab_u.buf_y; + buf_u->len_w = 0; + + // note that it's structurally integral to call measure before serialize + _serialize(buf_u, a); + + return u3i_slab_mint_bytes(&sab_u); +} + +u3_atom +u3ke_json_en(u3_noun a) +{ + u3_atom res = u3qe_json_en(a); + u3z(a); + return res; +} + +u3_atom +u3we_json_en(u3_noun cor) +{ + return u3qe_json_en(u3x_at(u3x_sam, cor)); +} -- cgit v1.2.3