@fraczak/k 7.2.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/DOCS/BIG_PICTURE.md +54 -7
  3. package/DOCS/CODECS.md +21 -13
  4. package/DOCS/CODEC_ARCHITECTURE.md +1 -1
  5. package/DOCS/DICTIONARY.md +13 -4
  6. package/DOCS/FILE_FORMATS.md +3 -2
  7. package/DOCS/JSON_APPROACHES_COMPARISON.md +302 -0
  8. package/DOCS/NAMED_PATTERNS.md +317 -0
  9. package/DOCS/PATTERNS.md +59 -11
  10. package/DOCS/REPL.md +13 -2
  11. package/DOCS/WEB_REPL_REQUIREMENTS.md +3 -2
  12. package/Examples/arithmetics.k +22 -17
  13. package/Examples/bnat.k +21 -11
  14. package/Examples/buda.k +37 -20
  15. package/Examples/byte.k +3 -1
  16. package/Examples/code.k +38 -39
  17. package/Examples/djson.k +789 -0
  18. package/Examples/esc.k +1 -1
  19. package/Examples/karatsuba-mult.k +16 -13
  20. package/Examples/list.k +8 -4
  21. package/Examples/nat.k +17 -11
  22. package/Examples/poly.k +11 -3
  23. package/Examples/vhdl_to_k.k +43 -31
  24. package/README.md +40 -16
  25. package/browser/repl-browser.mjs +2 -0
  26. package/browser/tree-view.mjs +35 -16
  27. package/browser/vfs-data.mjs +10 -8
  28. package/codecs/README.md +1 -1
  29. package/codecs/djson.mjs +375 -84
  30. package/core.k +79 -115
  31. package/index.mjs +3 -0
  32. package/named-patterns.mjs +267 -0
  33. package/object.mjs +31 -3
  34. package/package.json +1 -1
  35. package/parser.jison +68 -5
  36. package/parser.mjs +111 -60
  37. package/pretty.mjs +5 -0
  38. package/repl.mjs +188 -22
  39. package/scripts/build-repl-html.mjs +58 -4
  40. package/scripts/run-tests.mjs +10 -0
  41. package/symbol-table.mjs +20 -2
  42. package/tests/test-codecs.mjs +30 -17
  43. package/tests/test-djson-methods.mjs +285 -0
  44. package/tests/test-named-patterns.mjs +189 -0
  45. package/tests/test-repl-html.mjs +47 -4
  46. package/tests/test-repl.mjs +149 -0
@@ -0,0 +1,789 @@
1
+ -- Examples/djson.k: Universal dynamic JSON schema and standard methods
2
+ -- Works with codecs/djson.mjs (k-djson) and codecs/utf8.mjs (k-utf8).
3
+
4
+ ---------------------------------------------------------------
5
+ -- §1. Named Pattern Definitions & Component Schemas
6
+ ---------------------------------------------------------------
7
+
8
+ bit[] = < {} 0, {} 1 >;
9
+
10
+ sign[] = < {} "+", {} "-" >;
11
+
12
+ exponent[] = {
13
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3, bit[] 4,
14
+ bit[] 5, bit[] 6, bit[] 7, bit[] 8, bit[] 9, bit[] 10
15
+ };
16
+
17
+ fraction[] = {
18
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3, bit[] 4, bit[] 5,
19
+ bit[] 6, bit[] 7, bit[] 8, bit[] 9, bit[] 10, bit[] 11,
20
+ bit[] 12, bit[] 13, bit[] 14, bit[] 15, bit[] 16, bit[] 17,
21
+ bit[] 18, bit[] 19, bit[] 20, bit[] 21, bit[] 22, bit[] 23,
22
+ bit[] 24, bit[] 25, bit[] 26, bit[] 27, bit[] 28, bit[] 29,
23
+ bit[] 30, bit[] 31, bit[] 32, bit[] 33, bit[] 34, bit[] 35,
24
+ bit[] 36, bit[] 37, bit[] 38, bit[] 39, bit[] 40, bit[] 41,
25
+ bit[] 42, bit[] 43, bit[] 44, bit[] 45, bit[] 46, bit[] 47,
26
+ bit[] 48, bit[] 49, bit[] 50, bit[] 51
27
+ };
28
+
29
+ number[] = {
30
+ sign[] sign,
31
+ exponent[] exponent,
32
+ fraction[] fraction
33
+ };
34
+
35
+ byte[] = {
36
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3,
37
+ bit[] 4, bit[] 5, bit[] 6, bit[] 7
38
+ };
39
+
40
+ ascii[] = {
41
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3,
42
+ bit[] 4, bit[] 5, bit[] 6
43
+ };
44
+
45
+ bmp_hi_common[] = <
46
+ { bit[] 0, bit[] 1, bit[] 2 } h08_0F,
47
+ ascii[] h10_7F,
48
+ ascii[] h80_CF,
49
+ { bit[] 0, bit[] 1, bit[] 2 } hD0_D7,
50
+ {} hF9,
51
+ { bit[] 0 } hFA_FB,
52
+ { bit[] 0 } hFC_FD,
53
+ { bit[] 0 } hFE_FF
54
+ >;
55
+
56
+ bmp_hi_private_use[] = <
57
+ { bit[] 0, bit[] 1, bit[] 2, bit[] 3 } hE0_EF,
58
+ { bit[] 0, bit[] 1, bit[] 2 } hF0_F7,
59
+ {} hF8
60
+ >;
61
+
62
+ plane0[] = {
63
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3, bit[] 4,
64
+ bit[] 5, bit[] 6, bit[] 7, bit[] 8, bit[] 9, bit[] 10
65
+ };
66
+
67
+ plane_02_10[] = <
68
+ { bit[] 0 } p02_03,
69
+ { bit[] 0, bit[] 1 } p04_07,
70
+ { bit[] 0, bit[] 1, bit[] 2 } p08_0F,
71
+ {} p10
72
+ >;
73
+
74
+ unicode[] = <
75
+ ascii[] ascii,
76
+ { bmp_hi_common[] hi, byte[] lo } bmp_common,
77
+ { bmp_hi_private_use[] hi, byte[] lo } bmp_private_use,
78
+ plane0[] plane0,
79
+ { byte[] mid, byte[] lo } supplementary_plane1,
80
+ { plane_02_10[] plane, byte[] mid, byte[] lo } supplementary_planes2_16
81
+ >;
82
+
83
+ string[] = < {} nil, { unicode[] car, S cdr } cons > = S;
84
+
85
+ bool[] = < {} true, {} false >;
86
+
87
+ bits[] = < {} _, B 0, B 1 > = B;
88
+
89
+ list[X] = < {} nil, { X car, L cdr } cons > = L;
90
+
91
+ opt[V] = < {} nil, V val >;
92
+
93
+ btrie[V] = <
94
+ {} nil,
95
+ {
96
+ opt[V] val,
97
+ T 0,
98
+ T 1
99
+ } trie
100
+ > = T;
101
+
102
+ djson[] = <
103
+ number[] number,
104
+ string[] string,
105
+ bool[] bool,
106
+ {} null,
107
+ btrie[J] list,
108
+ btrie[J] object
109
+ > = J;
110
+
111
+ djson_btrie[] = djson[];
112
+
113
+ json? = ? djson[];
114
+
115
+ ---------------------------------------------------------------
116
+ -- §2. Constructors and Projections
117
+ ---------------------------------------------------------------
118
+
119
+ bits? = ? bits[];
120
+ str_list? = ? string[];
121
+ trie? = ? btrie[V];
122
+
123
+ 0b = {} | _;
124
+ 0 = 0b | 0;
125
+ 1 = 0b | 1;
126
+
127
+ nil = {} | nil;
128
+ null = {} | null json?;
129
+ true = {} | true | bool json?;
130
+ false = {} | false | bool 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?;
138
+
139
+ ---------------------------------------------------------------
140
+ -- §3. Direct Binary Bit-Trie Traversal (Zero Equality Checks)
141
+ ---------------------------------------------------------------
142
+
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
150
+ >;
151
+
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
174
+ >;
175
+
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
180
+ >;
181
+
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,
193
+ {
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,
198
+ {
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,
203
+ {
204
+ .char /supplementary_plane1 .lo x,
205
+ {
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,
210
+ {
211
+ .char /supplementary_planes2_16 .lo x,
212
+ {
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
220
+ >;
221
+
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,
229
+ {
230
+ .key /cons .cdr key,
231
+ { .key /cons .car char, .t t } step_char object
232
+ } dot
233
+ >;
234
+
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?;
261
+
262
+ ---------------------------------------------------------------
263
+ -- §5. Trie Update & Removal (put, remove, put_nth, remove_nth)
264
+ ---------------------------------------------------------------
265
+
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?;
270
+
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?;
293
+
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?;
299
+
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?;
306
+
307
+ prepend_char_bits = <
308
+ { .char /ascii x, .acc acc } push_bits7 |0,
309
+ { .char /plane0 x, .acc acc } push_bits11 |0 |1,
310
+ {
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,
314
+ {
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 () >;
337
+
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
392
+ put = ?{ K key, V val, O object } {
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?;
429
+
430
+ ---------------------------------------------------------------
431
+ -- §6. Cardinality & Length Relations
432
+ ---------------------------------------------------------------
433
+
434
+ _inv = ?{ < {} _, B 0, B 1 >=B x, B r } <
435
+ { .x /_ if, .r then } .then,
436
+ { .x /0 x, .r |0 r } _inv,
437
+ { .x /1 x, .r |1 r } _inv
438
+ > bits?;
439
+ _inc = ?{ < {} _, B 0, B 1 >=B x, B y } <
440
+ { .x /_ if, .y |1 then } .then,
441
+ { .x /0 x, .y |1 r } _inv,
442
+ { .x /1 x, .y |0 y } _inc
443
+ > bits?;
444
+ inc_nat = { { () x, 0b r } _inv x, 0b y } _inc;
445
+
446
+ _trie_size = ?{
447
+ < {} nil, { < {} nil, V val > val, T 0, T 1 } trie >=T t,
448
+ < {} _, B 0, B 1 >=B acc
449
+ } <
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
465
+ > bits?;
466
+
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
653
+ } <
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[];