@fraczak/k 8.0.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Examples/djson.k CHANGED
@@ -1,4 +1,4 @@
1
- -- Examples/djson.k: Universal dynamic JSON schema and helper relations
1
+ -- Examples/djson.k: Universal dynamic JSON schema and standard methods
2
2
  -- Works with codecs/djson.mjs (k-djson) and codecs/utf8.mjs (k-utf8).
3
3
 
4
4
  ---------------------------------------------------------------
@@ -84,240 +84,706 @@ string[] = < {} nil, { unicode[] car, S cdr } cons > = S;
84
84
 
85
85
  bool[] = < {} true, {} false >;
86
86
 
87
+ bits[] = < {} _, B 0, B 1 > = B;
88
+
87
89
  list[X] = < {} nil, { X car, L cdr } cons > = L;
88
90
 
89
- pair[K, V] = { K key, V val };
91
+ opt[V] = < {} nil, V val >;
90
92
 
91
- object[V] = list[pair[string[], V]];
93
+ btrie[V] = <
94
+ {} nil,
95
+ {
96
+ opt[V] val,
97
+ T 0,
98
+ T 1
99
+ } trie
100
+ > = T;
92
101
 
93
102
  djson[] = <
94
103
  number[] number,
95
104
  string[] string,
96
105
  bool[] bool,
97
106
  {} null,
98
- list[J] list,
99
- object[J] object
107
+ btrie[J] list,
108
+ btrie[J] object
100
109
  > = J;
101
110
 
102
- json? = ? djson[];
111
+ djson_btrie[] = djson[];
103
112
 
104
- bit? = ? bit[];
105
- string? = ? string[];
106
- float64? = ? number[];
107
- bool? = ? bool[];
108
- null? = ? {};
109
- list? = ? list[X];
110
- object? = ? list[pair[K, V]];
113
+ json? = ? djson[];
111
114
 
112
115
  ---------------------------------------------------------------
113
116
  -- §2. Constructors and Projections
114
117
  ---------------------------------------------------------------
115
118
 
116
- nil = {} | nil list?;
117
- cons = {.car car, .cdr cdr} | cons list?;
118
- car = list? /cons .car;
119
- cdr = list? /cons .cdr;
119
+ bits? = ? bits[];
120
+ str_list? = ? string[];
121
+ trie? = ? btrie[V];
120
122
 
123
+ 0b = {} | _;
124
+ 0 = 0b | 0;
125
+ 1 = 0b | 1;
126
+
127
+ nil = {} | nil;
121
128
  null = {} | null json?;
122
129
  true = {} | true | bool json?;
123
130
  false = {} | false | bool json?;
124
- number = float64? | number json?;
125
- string = string? | string json?;
126
- bool = bool? | bool json?;
127
- list = list? | list json?;
128
- object = object? | object json?;
131
+ number = | number json?;
132
+ string = | string json?;
133
+ bool = | bool json?;
134
+ list = | list json?;
135
+ object = | object json?;
136
+ empty_list = nil | list json?;
137
+ empty_object = nil | object json?;
129
138
 
130
139
  ---------------------------------------------------------------
131
- -- §3. String Equality (eq_string?)
140
+ -- §3. Direct Binary Bit-Trie Traversal (Zero Equality Checks)
132
141
  ---------------------------------------------------------------
133
142
 
134
- eq_bit? = ?{ <{} 0, {} 1>=B x, B y }
135
- < {.x /0 x, .y /0 y}, {.x /1 x, .y /1 y} > {};
136
-
137
- eq_bits1? = { {.x .0 x, .y .0 y} eq_bit? 0 } {};
138
- eq_bits2? = { {.x x, .y y} eq_bits1? a, {.x .1 x, .y .1 y} eq_bit? 1 } {};
139
- eq_bits3? = { {.x x, .y y} eq_bits2? a, {.x .2 x, .y .2 y} eq_bit? 2 } {};
140
- eq_bits4? = { {.x x, .y y} eq_bits3? a, {.x .3 x, .y .3 y} eq_bit? 3 } {};
141
- eq_bits7? = {
142
- {.x x, .y y} eq_bits4? a,
143
- {.x .4 x, .y .4 y} eq_bit? 4,
144
- {.x .5 x, .y .5 y} eq_bit? 5,
145
- {.x .6 x, .y .6 y} eq_bit? 6
146
- } {};
147
- eq_bits8? = { {.x x, .y y} eq_bits7? a, {.x .7 x, .y .7 y} eq_bit? 7 } {};
148
- eq_bits11? = {
149
- {.x x, .y y} eq_bits8? a,
150
- {.x .8 x, .y .8 y} eq_bit? 8,
151
- {.x .9 x, .y .9 y} eq_bit? 9,
152
- {.x .10 x, .y .10 y} eq_bit? 10
153
- } {};
154
-
155
- eq_bmp_common_hi? = <
156
- {.x /h08_0F x, .y /h08_0F y} eq_bits3?,
157
- {.x /h10_7F x, .y /h10_7F y} eq_bits7?,
158
- {.x /h80_CF x, .y /h80_CF y} eq_bits7?,
159
- {.x /hD0_D7 x, .y /hD0_D7 y} eq_bits3?,
160
- {.x /hF9 x, .y /hF9 y} {},
161
- {.x /hFA_FB x, .y /hFA_FB y} eq_bits1?,
162
- {.x /hFC_FD x, .y /hFC_FD y} eq_bits1?,
163
- {.x /hFE_FF x, .y /hFE_FF y} eq_bits1?
143
+ -- Step one bit (0 or 1) in a binary trie
144
+ step_0 = /trie .0;
145
+ step_1 = /trie .1;
146
+
147
+ step_bit = <
148
+ { .b /0 if, .t step_0 then } .then,
149
+ { .b /1 if, .t step_1 then } .then
164
150
  >;
165
151
 
166
- eq_bmp_private_use_hi? = <
167
- {.x /hE0_EF x, .y /hE0_EF y} eq_bits4?,
168
- {.x /hF0_F7 x, .y /hF0_F7 y} eq_bits3?,
169
- {.x /hF8 x, .y /hF8 y} {}
152
+ -- Step N bits from MSB (.N-1) down to LSB (.0)
153
+ step_bits1 = { .x .0 b, .t t } step_bit;
154
+ step_bits2 = { .x x, { .x .1 b, .t t } step_bit t } step_bits1;
155
+ step_bits3 = { .x x, { .x .2 b, .t t } step_bit t } step_bits2;
156
+ step_bits4 = { .x x, { .x .3 b, .t t } step_bit t } step_bits3;
157
+ step_bits5 = { .x x, { .x .4 b, .t t } step_bit t } step_bits4;
158
+ step_bits6 = { .x x, { .x .5 b, .t t } step_bit t } step_bits5;
159
+ step_bits7 = { .x x, { .x .6 b, .t t } step_bit t } step_bits6;
160
+ step_bits8 = { .x x, { .x .7 b, .t t } step_bit t } step_bits7;
161
+ step_bits9 = { .x x, { .x .8 b, .t t } step_bit t } step_bits8;
162
+ step_bits10 = { .x x, { .x .9 b, .t t } step_bit t } step_bits9;
163
+ step_bits11 = { .x x, { .x .10 b, .t t } step_bit t } step_bits10;
164
+
165
+ step_bmp_common_hi = <
166
+ { .hi /h08_0F x, .t step_0 step_0 step_0 t } step_bits3,
167
+ { .hi /h10_7F x, .t step_0 step_0 step_1 t } step_bits7,
168
+ { .hi /h80_CF x, .t step_0 step_1 step_0 t } step_bits7,
169
+ { .hi /hD0_D7 x, .t step_0 step_1 step_1 t } step_bits3,
170
+ { .hi /hF9 if, .t step_1 step_0 step_0 then } .then,
171
+ { .hi /hFA_FB x, .t step_1 step_0 step_1 t } step_bits1,
172
+ { .hi /hFC_FD x, .t step_1 step_1 step_0 t } step_bits1,
173
+ { .hi /hFE_FF x, .t step_1 step_1 step_1 t } step_bits1
170
174
  >;
171
175
 
172
- eq_plane2_16? = <
173
- {.x /p02_03 x, .y /p02_03 y} eq_bits1?,
174
- {.x /p04_07 x, .y /p04_07 y} eq_bits2?,
175
- {.x /p08_0F x, .y /p08_0F y} eq_bits3?,
176
- {.x /p10 x, .y /p10 y} {}
176
+ step_bmp_priv_hi = <
177
+ { .hi /hE0_EF x, .t step_0 t } step_bits4,
178
+ { .hi /hF0_F7 x, .t step_1 step_0 t } step_bits3,
179
+ { .hi /hF8 if, .t step_1 step_1 then } .then
177
180
  >;
178
181
 
179
- eq_char? = <
180
- {.x /ascii x, .y /ascii y} eq_bits7?,
182
+ step_plane2_16 = <
183
+ { .p /p02_03 x, .t step_0 step_0 t } step_bits1,
184
+ { .p /p04_07 x, .t step_0 step_1 t } step_bits2,
185
+ { .p /p08_0F x, .t step_1 step_0 t } step_bits3,
186
+ { .p /p10 if, .t step_1 step_1 then } .then
187
+ >;
188
+
189
+ -- Advance trie by one Unicode character: { char, t } -> t
190
+ step_char = <
191
+ { .char /ascii x, .t step_0 t } step_bits7,
192
+ { .char /plane0 x, .t step_1 step_0 t } step_bits11,
181
193
  {
182
- {.x /bmp_common .hi x, .y /bmp_common .hi y} eq_bmp_common_hi? hi,
183
- {.x /bmp_common .lo x, .y /bmp_common .lo y} eq_bits8? lo
184
- } {},
194
+ .char /bmp_common .lo x,
195
+ { .char /bmp_common .hi hi, .t step_1 step_1 step_0 t }
196
+ step_bmp_common_hi t
197
+ } step_bits8,
185
198
  {
186
- {
187
- .x /bmp_private_use .hi x,
188
- .y /bmp_private_use .hi y
189
- } eq_bmp_private_use_hi? hi,
190
- {.x /bmp_private_use .lo x, .y /bmp_private_use .lo y} eq_bits8? lo
191
- } {},
192
- {.x /plane0 x, .y /plane0 y} eq_bits11?,
199
+ .char /bmp_private_use .lo x,
200
+ { .char /bmp_private_use .hi hi, .t step_1 step_1 step_1 step_0 t }
201
+ step_bmp_priv_hi t
202
+ } step_bits8,
193
203
  {
204
+ .char /supplementary_plane1 .lo x,
194
205
  {
195
- .x /supplementary_plane1 .mid x,
196
- .y /supplementary_plane1 .mid y
197
- } eq_bits8? mid,
198
- {
199
- .x /supplementary_plane1 .lo x,
200
- .y /supplementary_plane1 .lo y
201
- } eq_bits8? lo
202
- } {},
206
+ .char /supplementary_plane1 .mid x,
207
+ .t step_1 step_1 step_1 step_1 step_0 t
208
+ } step_bits8 t
209
+ } step_bits8,
203
210
  {
211
+ .char /supplementary_planes2_16 .lo x,
204
212
  {
205
- .x /supplementary_planes2_16 .plane x,
206
- .y /supplementary_planes2_16 .plane y
207
- } eq_plane2_16? plane,
208
- {
209
- .x /supplementary_planes2_16 .mid x,
210
- .y /supplementary_planes2_16 .mid y
211
- } eq_bits8? mid,
212
- {
213
- .x /supplementary_planes2_16 .lo x,
214
- .y /supplementary_planes2_16 .lo y
215
- } eq_bits8? lo
216
- } {}
213
+ .char /supplementary_planes2_16 .mid x,
214
+ {
215
+ .char /supplementary_planes2_16 .plane p,
216
+ .t step_1 step_1 step_1 step_1 step_1 t
217
+ } step_plane2_16 t
218
+ } step_bits8 t
219
+ } step_bits8
217
220
  >;
218
221
 
219
- _eq_string? = {.x string? x, .y string? y} <
220
- {.x /nil x, .y /nil y} {},
222
+ ---------------------------------------------------------------
223
+ -- §4. Object & List Lookup Relations (dot, nth, has_key?)
224
+ ---------------------------------------------------------------
225
+
226
+ -- Low-level lookup string key in object trie: { key, object } -> val
227
+ dot = ?{ K key, T object } { .key str_list? key, .object trie? t } <
228
+ { .key /nil if, .t /trie .val /val then } .then,
221
229
  {
222
- {.x /cons .car x, .y /cons .car y} eq_char? if,
223
- {.x /cons .cdr x, .y /cons .cdr y} then
224
- } .then _eq_string?
230
+ .key /cons .cdr key,
231
+ { .key /cons .car char, .t t } step_char object
232
+ } dot
225
233
  >;
226
234
 
227
- -- Identity filter on {x, y} when strings x and y are equal
228
- eq_string? = ?{ S x, S y } {_eq_string? if, () then} .then;
235
+ -- Low-level lookup bits? index in list trie: { index, list } -> val
236
+ _nth = ?{ K index, T list } { .index bits? index, .list trie? t } <
237
+ { .index /_ if, .t /trie .val /val then } .then,
238
+ { .index /0 index, .t /trie .0 list } _nth,
239
+ { .index /1 index, .t /trie .1 list } _nth
240
+ >;
241
+
242
+ -- Primary accessor: lookup string key in json? object -> json? val
243
+ get = ?{ K key, json? json } {
244
+ .key str_list? key,
245
+ .json /object object
246
+ } dot;
247
+
248
+ -- Primary accessor: lookup bits? index in json? list -> json? elem
249
+ nth = ?{ K index, json? json } {
250
+ .index bits? index,
251
+ .json /list list
252
+ } _nth;
253
+
254
+ -- Filter: succeeds as identity if json? object contains string key
255
+ has_key? = ?{ K key, json? json } { get if, () then } .then;
256
+ has? = has_key?;
257
+
258
+ -- Filter: succeeds as identity if json? list contains index
259
+ has_index? = ?{ K index, json? json } { nth if, () then } .then;
260
+ has_nth? = has_index?;
229
261
 
230
262
  ---------------------------------------------------------------
231
- -- §4. JSON Object Helpers (dot, has_key?, keys, values, remove, put)
263
+ -- §5. Trie Update & Removal (put, remove, put_nth, remove_nth)
232
264
  ---------------------------------------------------------------
233
265
 
234
- -- Lookup key in object entry list: {key, object} -> val
235
- dot = ?{ K key, O object } {.key string? key, .object object? object} <
236
- {
237
- {.key x, .object /cons .car .key y} eq_string? if,
238
- .object /cons .car .val then
239
- } .then,
240
- {.key key, .object /cons .cdr object} dot
241
- >;
266
+ push_bit = ?{ < {} 0, {} 1 > b, < {} _, BITS 0, BITS 1 >=BITS acc } <
267
+ { .b /0 if, .acc |0 then } .then,
268
+ { .b /1 if, .acc |1 then } .then
269
+ > bits?;
242
270
 
243
- -- Identity filter on {key, object} when key exists in object
244
- has_key? = ?{ K key, O object } {dot if, () then} .then;
271
+ push_bits1 = { .x .0 b, .acc acc } push_bit;
272
+ push_bits2 = { .x .1 b, { .x x, .acc acc } push_bits1 acc } push_bit;
273
+ push_bits3 = { .x .2 b, { .x x, .acc acc } push_bits2 acc } push_bit;
274
+ push_bits4 = { .x .3 b, { .x x, .acc acc } push_bits3 acc } push_bit;
275
+ push_bits5 = { .x .4 b, { .x x, .acc acc } push_bits4 acc } push_bit;
276
+ push_bits6 = { .x .5 b, { .x x, .acc acc } push_bits5 acc } push_bit;
277
+ push_bits7 = { .x .6 b, { .x x, .acc acc } push_bits6 acc } push_bit;
278
+ push_bits8 = { .x .7 b, { .x x, .acc acc } push_bits7 acc } push_bit;
279
+ push_bits9 = { .x .8 b, { .x x, .acc acc } push_bits8 acc } push_bit;
280
+ push_bits10 = { .x .9 b, { .x x, .acc acc } push_bits9 acc } push_bit;
281
+ push_bits11 = { .x .10 b, { .x x, .acc acc } push_bits10 acc } push_bit;
282
+
283
+ push_bmp_common_hi = <
284
+ { .hi /h08_0F x, .acc acc } push_bits3 |0 |0 |0,
285
+ { .hi /h10_7F x, .acc acc } push_bits7 |1 |0 |0,
286
+ { .hi /h80_CF x, .acc acc } push_bits7 |0 |1 |0,
287
+ { .hi /hD0_D7 x, .acc acc } push_bits3 |1 |1 |0,
288
+ { .hi /hF9 if, .acc |0 |0 |1 then } .then,
289
+ { .hi /hFA_FB x, .acc acc } push_bits1 |1 |0 |1,
290
+ { .hi /hFC_FD x, .acc acc } push_bits1 |0 |1 |1,
291
+ { .hi /hFE_FF x, .acc acc } push_bits1 |1 |1 |1
292
+ > bits?;
245
293
 
246
- -- Extract list of keys from an object entry list: object -> list
247
- keys = object? <
248
- /nil nil,
249
- /cons {.car .key car, .cdr keys cdr} cons
250
- >;
294
+ push_bmp_priv_hi = <
295
+ { .hi /hE0_EF x, .acc acc } push_bits4 |0,
296
+ { .hi /hF0_F7 x, .acc acc } push_bits3 |0 |1,
297
+ { .hi /hF8 if, .acc |1 |1 then } .then
298
+ > bits?;
251
299
 
252
- -- Extract list of values from an object entry list: object -> list
253
- values = object? <
254
- /nil nil,
255
- /cons {.car .val car, .cdr values cdr} cons
256
- >;
300
+ push_plane2_16 = <
301
+ { .p /p02_03 x, .acc acc } push_bits1 |0 |0,
302
+ { .p /p04_07 x, .acc acc } push_bits2 |1 |0,
303
+ { .p /p08_0F x, .acc acc } push_bits3 |0 |1,
304
+ { .p /p10 if, .acc |1 |1 then } .then
305
+ > bits?;
257
306
 
258
- -- Remove all entries matching key from object: {key, object} -> object
259
- remove = ?{ K key, O object } {.key string? key, .object object? object} <
260
- {.object /nil if, nil then} .then,
307
+ prepend_char_bits = <
308
+ { .char /ascii x, .acc acc } push_bits7 |0,
309
+ { .char /plane0 x, .acc acc } push_bits11 |0 |1,
261
310
  {
262
- {.key x, .object /cons .car .key y} eq_string? if,
263
- {.key key, .object /cons .cdr object} remove then
264
- } .then,
311
+ .char /bmp_common .hi hi,
312
+ { .char /bmp_common .lo x, .acc acc } push_bits8 acc
313
+ } push_bmp_common_hi |0 |1 |1,
265
314
  {
266
- .object /cons .car car,
267
- {.key key, .object /cons .cdr object} remove cdr
268
- } cons
269
- >;
315
+ .char /bmp_private_use .hi hi,
316
+ { .char /bmp_private_use .lo x, .acc acc } push_bits8 acc
317
+ } push_bmp_priv_hi |0 |1 |1 |1,
318
+ {
319
+ .char /supplementary_plane1 .mid x,
320
+ { .char /supplementary_plane1 .lo x, .acc acc } push_bits8 acc
321
+ } push_bits8 |0 |1 |1 |1 |1,
322
+ {
323
+ .char /supplementary_planes2_16 .plane p,
324
+ {
325
+ .char /supplementary_planes2_16 .mid x,
326
+ { .char /supplementary_planes2_16 .lo x, .acc acc } push_bits8 acc
327
+ } push_bits8 acc
328
+ } push_plane2_16 |1 |1 |1 |1 |1
329
+ > bits?;
330
+
331
+ str_to_bits = str_list? <
332
+ /nil 0b,
333
+ /cons { .car char, .cdr str_to_bits acc } prepend_char_bits
334
+ > bits?;
335
+
336
+ ensure_trie = trie? < /nil { nil val, nil 0, nil 1 }, /trie () >;
270
337
 
271
- -- Insert or replace {key, val} in object: {key, val, object} -> object
338
+ -- Insert or replace { index, val, list } -> list
339
+ put_nth = ?{ K index, V val, T list } {
340
+ .index bits? index,
341
+ .val val,
342
+ .list trie? ensure_trie t
343
+ } <
344
+ {
345
+ .index /_ if,
346
+ { .val |val val, .t .0 0, .t .1 1 } |trie then
347
+ } .then,
348
+ {
349
+ .index /0 if,
350
+ {
351
+ .t .val val,
352
+ { .index /0 index, .val val, .t .0 list } put_nth 0,
353
+ .t .1 1
354
+ } |trie then
355
+ } .then,
356
+ {
357
+ .index /1 if,
358
+ {
359
+ .t .val val,
360
+ .t .0 0,
361
+ { .index /1 index, .val val, .t .1 list } put_nth 1
362
+ } |trie then
363
+ } .then
364
+ > trie?;
365
+
366
+ -- Remove entry at bits? index from trie: { index, list } -> list
367
+ remove_nth = ?{ K index, T list } { .index bits? index, .list trie? t } <
368
+ { .t /nil if, nil then } .then,
369
+ {
370
+ .index /_ if,
371
+ { nil val, .t /trie .0 0, .t /trie .1 1 } |trie then
372
+ } .then,
373
+ {
374
+ .index /0 if,
375
+ {
376
+ .t /trie .val val,
377
+ { .index /0 index, .t /trie .0 list } remove_nth 0,
378
+ .t /trie .1 1
379
+ } |trie then
380
+ } .then,
381
+ {
382
+ .index /1 if,
383
+ {
384
+ .t /trie .val val,
385
+ .t /trie .0 0,
386
+ { .index /1 index, .t /trie .1 list } remove_nth 1
387
+ } |trie then
388
+ } .then
389
+ > trie?;
390
+
391
+ -- Insert or replace { key, val, object } -> object
272
392
  put = ?{ K key, V val, O object } {
273
- {.key string? key, .val val} car,
274
- {.key key, .object object} remove cdr
275
- } cons;
393
+ .key str_to_bits index,
394
+ .val val,
395
+ .object list
396
+ } put_nth;
397
+
398
+ -- Remove key from object trie: { key, object } -> object
399
+ remove = ?{ K key, O object } {
400
+ .key str_to_bits index,
401
+ .object list
402
+ } remove_nth;
403
+
404
+ -- Set string key in json? object: { key, val, json } -> json
405
+ set = ?{ K key, json? val, json? json } {
406
+ .key str_list? key,
407
+ .val val,
408
+ .json /object object
409
+ } put |object json?;
410
+
411
+ -- Remove string key from json? object: { key, json } -> json
412
+ del = ?{ K key, json? json } {
413
+ .key str_list? key,
414
+ .json /object object
415
+ } remove |object json?;
416
+
417
+ -- Set element at bits? index in json? list: { index, val, json } -> json
418
+ set_nth = ?{ K index, json? val, json? json } {
419
+ .index bits? index,
420
+ .val val,
421
+ .json /list list
422
+ } put_nth |list json?;
423
+
424
+ -- Remove element at bits? index from json? list: { index, json } -> json
425
+ del_nth = ?{ K index, json? json } {
426
+ .index bits? index,
427
+ .json /list list
428
+ } remove_nth |list json?;
276
429
 
277
- -- Lookup bits? index in cons-list: {index, list} -> value
278
- bits? = ?< {} _, bits? 0, bits? 1 > = bits?;
279
- 0b = {} | _;
280
- 0 = 0b | 0;
281
- 1 = 0b | 1;
430
+ ---------------------------------------------------------------
431
+ -- §6. Cardinality & Length Relations
432
+ ---------------------------------------------------------------
282
433
 
283
434
  _inv = ?{ < {} _, B 0, B 1 >=B x, B r } <
284
435
  { .x /_ if, .r then } .then,
285
436
  { .x /0 x, .r |0 r } _inv,
286
437
  { .x /1 x, .r |1 r } _inv
287
438
  > bits?;
288
- _dec = ?{ < {} _, B 0, B 1 >=B x, B y } <
289
- { .x /1 x, .y |0 r } _inv,
290
- { .x /0 x, .y |1 y } _dec
291
- > bits?;
292
439
  _inc = ?{ < {} _, B 0, B 1 >=B x, B y } <
293
440
  { .x /_ if, .y |1 then } .then,
294
441
  { .x /0 x, .y |1 r } _inv,
295
442
  { .x /1 x, .y |0 y } _inc
296
443
  > bits?;
297
- _trim0 = bits? < /0 _trim0, /_ 0, () >;
298
- dec_nat = { { () x, 0b r } _inv x, 0b y } _dec _trim0;
299
444
  inc_nat = { { () x, 0b r } _inv x, 0b y } _inc;
300
445
 
301
- nth = ?{ I index, L list } { .index bits? index, .list list? list } <
302
- { .index /0 /_ if, .list /cons .car then } .then,
303
- { .index dec_nat index, .list /cons .cdr list } nth
304
- >;
305
-
306
- -- Count elements in list or object: list -> bits?, object -> bits?
307
- _list_size = ?{
308
- < {} nil, { X car, L cdr } cons >=L list,
446
+ _trie_size = ?{
447
+ < {} nil, { < {} nil, V val > val, T 0, T 1 } trie >=T t,
309
448
  < {} _, B 0, B 1 >=B acc
310
449
  } <
311
- { .list /nil if, .acc then } .then,
312
- { .list /cons .cdr list, .acc inc_nat acc } _list_size
450
+ { .t /nil if, .acc then } .then,
451
+ {
452
+ .t /trie .val /nil if,
453
+ {
454
+ .t /trie .1 t,
455
+ { .t /trie .0 t, .acc acc } _trie_size acc
456
+ } _trie_size then
457
+ } .then,
458
+ {
459
+ .t /trie .val /val if,
460
+ {
461
+ .t /trie .1 t,
462
+ { .t /trie .0 t, .acc inc_nat acc } _trie_size acc
463
+ } _trie_size then
464
+ } .then
313
465
  > bits?;
314
- list_size = { list? list, 0 acc } _list_size;
315
466
 
316
- _obj_size = ?{
317
- < {} nil, { { K key, V val } car, O cdr } cons >=O object,
318
- < {} _, B 0, B 1 >=B acc
467
+ list_size = { trie? t, 0 acc } _trie_size;
468
+ obj_size = { trie? t, 0 acc } _trie_size;
469
+
470
+ _str_len = ?{ string[] str, bits[] acc } <
471
+ { .str /nil if, .acc then } .then,
472
+ { .str /cons .cdr str, .acc inc_nat acc } _str_len
473
+ > ? bits[];
474
+ str_len = { str_list? str, 0 acc } _str_len;
475
+
476
+ -- Count items in json? (object entries, list elements, or string chars)
477
+ length_nat = json? <
478
+ /object obj_size,
479
+ /list list_size,
480
+ /string str_len
481
+ >;
482
+
483
+ pos_sign = {} |"+";
484
+ bit0 = {} |0;
485
+ bit1 = {} |1;
486
+
487
+ pos_zero = {
488
+ pos_sign sign,
489
+ {
490
+ bit0 0, bit0 1, bit0 2, bit0 3, bit0 4,
491
+ bit0 5, bit0 6, bit0 7, bit0 8, bit0 9, bit0 10
492
+ } exponent,
493
+ {
494
+ bit0 0, bit0 1, bit0 2, bit0 3, bit0 4,
495
+ bit0 5, bit0 6, bit0 7, bit0 8, bit0 9,
496
+ bit0 10, bit0 11, bit0 12, bit0 13, bit0 14,
497
+ bit0 15, bit0 16, bit0 17, bit0 18, bit0 19,
498
+ bit0 20, bit0 21, bit0 22, bit0 23, bit0 24,
499
+ bit0 25, bit0 26, bit0 27, bit0 28, bit0 29,
500
+ bit0 30, bit0 31, bit0 32, bit0 33, bit0 34,
501
+ bit0 35, bit0 36, bit0 37, bit0 38, bit0 39,
502
+ bit0 40, bit0 41, bit0 42, bit0 43, bit0 44,
503
+ bit0 45, bit0 46, bit0 47, bit0 48, bit0 49,
504
+ bit0 50, bit0 51
505
+ } fraction
506
+ };
507
+
508
+ exp_bias = {
509
+ bit1 0, bit1 1, bit1 2, bit1 3, bit1 4,
510
+ bit1 5, bit1 6, bit1 7, bit1 8, bit1 9, bit0 10
511
+ };
512
+
513
+ exp_half_adder = <
514
+ { .a /0 a, .c_in /0 c_in } { bit0 sum, bit0 carry },
515
+ { .a /0 a, .c_in /1 c_in } { bit1 sum, bit0 carry },
516
+ { .a /1 a, .c_in /0 c_in } { bit1 sum, bit0 carry },
517
+ { .a /1 a, .c_in /1 c_in } { bit0 sum, bit1 carry }
518
+ >;
519
+
520
+ inc_exp = {
521
+ { .0 a, bit1 c_in } exp_half_adder e0,
522
+ .1 b1, .2 b2, .3 b3, .4 b4, .5 b5, .6 b6, .7 b7, .8 b8, .9 b9, .10 b10
523
+ } {
524
+ .e0.sum 0,
525
+ { .b1 a, .e0.carry c_in } exp_half_adder e1,
526
+ .b2 b2, .b3 b3, .b4 b4, .b5 b5, .b6 b6, .b7 b7, .b8 b8, .b9 b9, .b10 b10
527
+ } {
528
+ .0 0, .e1.sum 1,
529
+ { .b2 a, .e1.carry c_in } exp_half_adder e2,
530
+ .b3 b3, .b4 b4, .b5 b5, .b6 b6, .b7 b7, .b8 b8, .b9 b9, .b10 b10
531
+ } {
532
+ .0 0, .1 1, .e2.sum 2,
533
+ { .b3 a, .e2.carry c_in } exp_half_adder e3,
534
+ .b4 b4, .b5 b5, .b6 b6, .b7 b7, .b8 b8, .b9 b9, .b10 b10
535
+ } {
536
+ .0 0, .1 1, .2 2, .e3.sum 3,
537
+ { .b4 a, .e3.carry c_in } exp_half_adder e4,
538
+ .b5 b5, .b6 b6, .b7 b7, .b8 b8, .b9 b9, .b10 b10
539
+ } {
540
+ .0 0, .1 1, .2 2, .3 3, .e4.sum 4,
541
+ { .b5 a, .e4.carry c_in } exp_half_adder e5,
542
+ .b6 b6, .b7 b7, .b8 b8, .b9 b9, .b10 b10
543
+ } {
544
+ .0 0, .1 1, .2 2, .3 3, .4 4, .e5.sum 5,
545
+ { .b6 a, .e5.carry c_in } exp_half_adder e6,
546
+ .b7 b7, .b8 b8, .b9 b9, .b10 b10
547
+ } {
548
+ .0 0, .1 1, .2 2, .3 3, .4 4, .5 5, .e6.sum 6,
549
+ { .b7 a, .e6.carry c_in } exp_half_adder e7,
550
+ .b8 b8, .b9 b9, .b10 b10
551
+ } {
552
+ .0 0, .1 1, .2 2, .3 3, .4 4, .5 5, .6 6, .e7.sum 7,
553
+ { .b8 a, .e7.carry c_in } exp_half_adder e8,
554
+ .b9 b9, .b10 b10
555
+ } {
556
+ .0 0, .1 1, .2 2, .3 3, .4 4, .5 5, .6 6, .7 7, .e8.sum 8,
557
+ { .b9 a, .e8.carry c_in } exp_half_adder e9,
558
+ .b10 b10
559
+ } {
560
+ .0 0, .1 1, .2 2, .3 3, .4 4, .5 5, .6 6, .7 7, .8 8, .e9.sum 9,
561
+ { .b10 a, .e9.carry c_in } exp_half_adder e10
562
+ } {
563
+ .0 0, .1 1, .2 2, .3 3, .4 4, .5 5, .6 6, .7 7, .8 8, .9 9, .e10.sum 10
564
+ };
565
+
566
+ shift_frac = ?{ bit[] b, fraction[] f } {
567
+ .f.1 0, .f.2 1, .f.3 2, .f.4 3, .f.5 4,
568
+ .f.6 5, .f.7 6, .f.8 7, .f.9 8, .f.10 9,
569
+ .f.11 10, .f.12 11, .f.13 12, .f.14 13, .f.15 14,
570
+ .f.16 15, .f.17 16, .f.18 17, .f.19 18, .f.20 19,
571
+ .f.21 20, .f.22 21, .f.23 22, .f.24 23, .f.25 24,
572
+ .f.26 25, .f.27 26, .f.28 27, .f.29 28, .f.30 29,
573
+ .f.31 30, .f.32 31, .f.33 32, .f.34 33, .f.35 34,
574
+ .f.36 35, .f.37 36, .f.38 37, .f.39 38, .f.40 39,
575
+ .f.41 40, .f.42 41, .f.43 42, .f.44 43, .f.45 44,
576
+ .f.46 45, .f.47 46, .f.48 47, .f.49 48, .f.50 49,
577
+ .f.51 50, .b 51
578
+ };
579
+
580
+ _nat_step = ?{ bits[] bits, exponent[] exp, fraction[] frac } <
581
+ {
582
+ .bits /_ if,
583
+ { pos_sign sign, .exp exponent, .frac fraction } then
584
+ } .then,
585
+ {
586
+ .bits /0 bits,
587
+ .exp inc_exp exp,
588
+ { bit0 b, .frac f } shift_frac frac
589
+ } _nat_step,
590
+ {
591
+ .bits /1 bits,
592
+ .exp inc_exp exp,
593
+ { bit1 b, .frac f } shift_frac frac
594
+ } _nat_step
595
+ >;
596
+
597
+ inv_bits = { () x, 0b r } _inv;
598
+
599
+ nat_to_float64 = bits? <
600
+ /_ { pos_zero then } .then,
601
+ /0 { pos_zero then } .then,
602
+ /1 { () inv_bits bits, exp_bias exp, pos_zero .fraction frac } _nat_step
603
+ >;
604
+
605
+ -- Count items in json? -> json? number
606
+ length = length_nat nat_to_float64 |number json?;
607
+
608
+ -- Append element to json? list: { val, json } -> json
609
+ push = ?{ json? val, json? json } {
610
+ (.json /list list_size) index,
611
+ .val val,
612
+ .json json
613
+ } set_nth;
614
+
615
+ ---------------------------------------------------------------
616
+ -- §7. Keys & Values Extraction
617
+ ---------------------------------------------------------------
618
+
619
+ read_bit = bits? <
620
+ /0 { {} |0 bit, () rest },
621
+ /1 { {} |1 bit, () rest }
622
+ >;
623
+
624
+ read_bits7 =
625
+ read_bit
626
+ { .bit b6, (.rest read_bit) r5 }
627
+ { .b6 b6, .r5 .bit b5, (.r5 .rest read_bit) r4 }
628
+ { .b6 b6, .b5 b5, .r4 .bit b4, (.r4 .rest read_bit) r3 }
629
+ { .b6 b6, .b5 b5, .b4 b4, .r3 .bit b3, (.r3 .rest read_bit) r2 }
630
+ { .b6 b6, .b5 b5, .b4 b4, .b3 b3, .r2 .bit b2, (.r2 .rest read_bit) r1 }
631
+ {
632
+ .b6 b6, .b5 b5, .b4 b4, .b3 b3, .b2 b2,
633
+ .r1 .bit b1, (.r1 .rest read_bit) r0
634
+ }
635
+ {
636
+ { .r0 .bit 0, .b1 1, .b2 2, .b3 3, .b4 4, .b5 5, .b6 6 } |ascii val,
637
+ .r0 .rest rest
638
+ };
639
+
640
+ read_char = bits? <
641
+ /0 read_bits7
642
+ >;
643
+
644
+ bits_to_str = bits? <
645
+ /_ {} |nil,
646
+ read_char { .val car, (.rest bits_to_str) cdr } |cons
647
+ > str_list?;
648
+
649
+ _collect_keys = ?{
650
+ btrie[V] tree,
651
+ bits[] rev_path,
652
+ list[string[]] acc
319
653
  } <
320
- { .object /nil if, .acc then } .then,
321
- { .object /cons .cdr object, .acc inc_nat acc } _obj_size
322
- > bits?;
323
- obj_size = { object? object, 0 acc } _obj_size;
654
+ { .tree /nil if, .acc then } .then,
655
+ {
656
+ .tree /trie .val /nil if,
657
+ {
658
+ .tree /trie .0 tree,
659
+ .rev_path |0 rev_path,
660
+ {
661
+ .tree /trie .1 tree,
662
+ .rev_path |1 rev_path,
663
+ .acc acc
664
+ } _collect_keys acc
665
+ } _collect_keys then
666
+ } .then,
667
+ {
668
+ .tree /trie .val /val if,
669
+ {
670
+ .tree /trie .0 tree,
671
+ .rev_path |0 rev_path,
672
+ {
673
+ .tree /trie .1 tree,
674
+ .rev_path |1 rev_path,
675
+ {
676
+ (.rev_path inv_bits bits_to_str) car,
677
+ .acc cdr
678
+ } |cons acc
679
+ } _collect_keys acc
680
+ } _collect_keys then
681
+ } .then
682
+ > ? list[string[]];
683
+
684
+ _obj_keys_raw = { () tree, 0b rev_path, {} |nil acc } _collect_keys;
685
+
686
+ -- Extract all keys from json? object as raw list: json? -> list[string[]]
687
+ keys_raw = json? /object _obj_keys_raw;
688
+
689
+ _keys_to_trie = ?{
690
+ list[string[]] klist,
691
+ bits[] index,
692
+ btrie[djson_btrie[]] acc
693
+ } <
694
+ { .klist /nil if, .acc then } .then,
695
+ {
696
+ .klist /cons .cdr klist,
697
+ .index inc_nat index,
698
+ {
699
+ .index index,
700
+ .klist /cons .car |string val,
701
+ .acc list
702
+ } put_nth acc
703
+ } _keys_to_trie
704
+ >;
705
+
706
+ -- Extract all keys from json? object as a json? list: json? -> json?
707
+ keys = json? /object _obj_keys_raw
708
+ { () klist, 0 index, {} |nil acc } _keys_to_trie
709
+ |list json?;
710
+
711
+ _collect_values = ?{
712
+ btrie[V] tree,
713
+ list[V] acc
714
+ } <
715
+ { .tree /nil if, .acc then } .then,
716
+ {
717
+ .tree /trie .val /nil if,
718
+ {
719
+ .tree /trie .0 tree,
720
+ { .tree /trie .1 tree, .acc acc } _collect_values acc
721
+ } _collect_values then
722
+ } .then,
723
+ {
724
+ .tree /trie .val /val if,
725
+ {
726
+ .tree /trie .0 tree,
727
+ {
728
+ .tree /trie .1 tree,
729
+ { .tree /trie .val /val car, .acc cdr } |cons acc
730
+ } _collect_values acc
731
+ } _collect_values then
732
+ } .then
733
+ > ? list[V];
734
+
735
+ _obj_values_raw = { () tree, {} |nil acc } _collect_values;
736
+
737
+ -- Extract all values from json? object or list as raw list
738
+ values_raw = json? <
739
+ /object _obj_values_raw,
740
+ /list _obj_values_raw
741
+ >;
742
+
743
+ _values_to_trie = ?{
744
+ list[djson_btrie[]] klist,
745
+ bits[] index,
746
+ btrie[djson_btrie[]] acc
747
+ } <
748
+ { .klist /nil if, .acc then } .then,
749
+ {
750
+ .klist /cons .cdr klist,
751
+ .index inc_nat index,
752
+ {
753
+ .index index,
754
+ .klist /cons .car val,
755
+ .acc list
756
+ } put_nth acc
757
+ } _values_to_trie
758
+ >;
759
+
760
+ -- Extract all values from json? as a json? list: json? -> json?
761
+ values = <
762
+ json? /object _obj_values_raw
763
+ { () klist, 0 index, {} |nil acc } _values_to_trie
764
+ |list json?,
765
+ json? /list |list json?
766
+ >;
767
+
768
+ ---------------------------------------------------------------
769
+ -- §8. Type Predicates
770
+ ---------------------------------------------------------------
771
+
772
+ is_null? = json? /null ();
773
+ is_bool? = json? /bool ();
774
+ is_number? = json? /number ();
775
+ is_string? = json? /string ();
776
+ is_list? = json? /list ();
777
+ is_object? = json? /object ();
778
+
779
+ json_type[] = <
780
+ {} null, {} bool, {} number, {} string, {} list, {} object
781
+ >;
782
+ type_of = json? <
783
+ /null {} |null,
784
+ /bool {} |bool,
785
+ /number {} |number,
786
+ /string {} |string,
787
+ /list {} |list,
788
+ /object {} |object
789
+ > ? json_type[];