@fraczak/k 7.1.0 → 8.0.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 (64) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/DOCS/BIG_PICTURE.md +54 -7
  3. package/DOCS/CODECS.md +47 -2
  4. package/DOCS/CODEC_ARCHITECTURE.md +14 -5
  5. package/DOCS/DICTIONARY.md +13 -4
  6. package/DOCS/FILE_FORMATS.md +3 -2
  7. package/DOCS/JSON_APPROACHES_COMPARISON.md +306 -0
  8. package/DOCS/NAMED_PATTERNS.md +317 -0
  9. package/DOCS/PATTERNS.md +59 -11
  10. package/DOCS/REPL.md +24 -5
  11. package/DOCS/WEB_REPL_REQUIREMENTS.md +4 -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-btrie.k +414 -0
  18. package/Examples/djson-ptrie.k +663 -0
  19. package/Examples/djson.k +323 -0
  20. package/Examples/esc.k +1 -1
  21. package/Examples/karatsuba-mult.k +16 -13
  22. package/Examples/list.k +8 -4
  23. package/Examples/nat.k +17 -11
  24. package/Examples/poly.k +11 -3
  25. package/Examples/vhdl_to_k.k +43 -31
  26. package/README.md +42 -15
  27. package/Value.mjs +28 -3
  28. package/backend-api.mjs +5 -1
  29. package/browser/repl-browser.mjs +6 -0
  30. package/browser/tree-view.mjs +82 -24
  31. package/browser/vfs-data.mjs +21 -12
  32. package/codecs/README.md +3 -0
  33. package/codecs/djson-btrie.mjs +560 -0
  34. package/codecs/djson-ptrie.mjs +587 -0
  35. package/codecs/djson.mjs +270 -0
  36. package/codecs/int.mjs +2 -1
  37. package/codecs/json.mjs +7 -2
  38. package/codecs/k-parse.mjs +7 -1
  39. package/codecs/k-print.mjs +4 -0
  40. package/codecs/runtime/codec-sdk.mjs +16 -2
  41. package/codecs/runtime/pattern-json.mjs +80 -1
  42. package/codecs/runtime/prefix-codec.mjs +629 -67
  43. package/codecs/runtime/show-value.mjs +93 -51
  44. package/codecs/runtime/unicode-string.mjs +29 -6
  45. package/codecs/show.mjs +4 -0
  46. package/codecs/utf16.mjs +2 -1
  47. package/core.k +79 -115
  48. package/index.mjs +3 -0
  49. package/named-patterns.mjs +267 -0
  50. package/object.mjs +31 -3
  51. package/package.json +5 -1
  52. package/parser.jison +68 -5
  53. package/parser.mjs +111 -60
  54. package/pretty.mjs +5 -0
  55. package/repl.mjs +245 -28
  56. package/scripts/build-repl-html.mjs +76 -5
  57. package/scripts/perf-djson.mjs +1142 -0
  58. package/scripts/run-tests.mjs +5 -0
  59. package/symbol-table.mjs +20 -2
  60. package/tests/bench-djson-tries.mjs +340 -0
  61. package/tests/test-codecs.mjs +211 -0
  62. package/tests/test-named-patterns.mjs +189 -0
  63. package/tests/test-repl-html.mjs +52 -4
  64. package/tests/test-repl.mjs +223 -0
@@ -0,0 +1,587 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Dynamic JSON Patricia/Radix Trie (djson-ptrie) codec.
5
+ *
6
+ * Implements the trie-array data structure for both JSON arrays (list)
7
+ * and JSON objects (object):
8
+ *
9
+ * - `list`: Radix/Patricia bit-trie with compressed bit `prefix` and
10
+ * subtree `size`:
11
+ * LIST = <
12
+ * {} nil,
13
+ * {
14
+ * BITS prefix,
15
+ * BITS size,
16
+ * < {} nil, JSON val > val,
17
+ * LIST 0,
18
+ * LIST 1
19
+ * } trie
20
+ * >
21
+ *
22
+ * - `object`: Character-level Radix/Patricia trie (trie-array over
23
+ * Unicode characters) with compressed `prefix` string, `size`, `val`,
24
+ * and sorted `dict` of `{ CHAR char, OBJ trie }` branches:
25
+ * OBJ = <
26
+ * {} nil,
27
+ * {
28
+ * Str prefix,
29
+ * BITS size,
30
+ * < {} nil, JSON val > val,
31
+ * <
32
+ * {} nil,
33
+ * { { CHAR char, OBJ trie } car, DICT cdr } cons
34
+ * >=DICT dict
35
+ * } trie
36
+ * >
37
+ */
38
+
39
+ import {
40
+ Value,
41
+ isProduct,
42
+ isVariant,
43
+ withPattern,
44
+ patternFromFilter,
45
+ runCodecCLI
46
+ } from "./runtime/codec-sdk.mjs";
47
+ import { encodeNumberToValue, decodeValueToNumber } from "./ieee.mjs";
48
+ import {
49
+ codePointToUnicodeValue,
50
+ unicodeValueToCodePoint,
51
+ textToStringValue,
52
+ stringValueToText
53
+ } from "./runtime/unicode-string.mjs";
54
+ import { indexToBitPath, bitPathToIndex } from "./djson-btrie.mjs";
55
+
56
+ export const doc = `
57
+ Dynamic JSON Patricia/Radix Trie (djson-ptrie) codec (trie-array style).
58
+
59
+ Represents JSON arrays with a compressed bit-radix trie (with prefix &
60
+ size) and JSON objects with a character-level radix trie (with prefix,
61
+ size, val, and sorted dict).
62
+ `;
63
+
64
+ export const DJSON_PTRIE_PATTERN = patternFromFilter(`
65
+ ? <
66
+ {
67
+ < {} "+", {} "-" > sign,
68
+ {
69
+ < {} 0, {} 1 >=Bit 0,
70
+ Bit 1, Bit 2, Bit 3, Bit 4, Bit 5,
71
+ Bit 6, Bit 7, Bit 8, Bit 9, Bit 10
72
+ } exponent,
73
+ {
74
+ Bit 0, Bit 1, Bit 2, Bit 3, Bit 4, Bit 5,
75
+ Bit 6, Bit 7, Bit 8, Bit 9, Bit 10, Bit 11,
76
+ Bit 12, Bit 13, Bit 14, Bit 15, Bit 16, Bit 17,
77
+ Bit 18, Bit 19, Bit 20, Bit 21, Bit 22, Bit 23,
78
+ Bit 24, Bit 25, Bit 26, Bit 27, Bit 28, Bit 29,
79
+ Bit 30, Bit 31, Bit 32, Bit 33, Bit 34, Bit 35,
80
+ Bit 36, Bit 37, Bit 38, Bit 39, Bit 40, Bit 41,
81
+ Bit 42, Bit 43, Bit 44, Bit 45, Bit 46, Bit 47,
82
+ Bit 48, Bit 49, Bit 50, Bit 51
83
+ } fraction
84
+ } number,
85
+
86
+ <
87
+ {} nil,
88
+ {
89
+ <
90
+ {
91
+ < {} 0, {} 1 >=Bit7 0,
92
+ Bit7 1, Bit7 2, Bit7 3, Bit7 4, Bit7 5, Bit7 6
93
+ }=Bits7 ascii,
94
+ {
95
+ <
96
+ { Bit7 0, Bit7 1, Bit7 2 }=Bits3 h08_0F,
97
+ Bits7 h10_7F,
98
+ Bits7 h80_CF,
99
+ Bits3 hD0_D7,
100
+ {} hF9,
101
+ { Bit7 0 }=Bits1 hFA_FB,
102
+ Bits1 hFC_FD,
103
+ Bits1 hFE_FF
104
+ > hi,
105
+ {
106
+ Bit7 0, Bit7 1, Bit7 2, Bit7 3,
107
+ Bit7 4, Bit7 5, Bit7 6, Bit7 7
108
+ }=Bits8 lo
109
+ } bmp_common,
110
+ {
111
+ <
112
+ { Bit7 0, Bit7 1, Bit7 2, Bit7 3 } hE0_EF,
113
+ Bits3 hF0_F7,
114
+ {} hF8
115
+ > hi,
116
+ Bits8 lo
117
+ } bmp_private_use,
118
+ {
119
+ Bit7 0, Bit7 1, Bit7 2, Bit7 3, Bit7 4, Bit7 5,
120
+ Bit7 6, Bit7 7, Bit7 8, Bit7 9, Bit7 10
121
+ } plane0,
122
+ { Bits8 mid, Bits8 lo } supplementary_plane1,
123
+ {
124
+ <
125
+ Bits1 p02_03,
126
+ { Bit7 0, Bit7 1 } p04_07,
127
+ Bits3 p08_0F,
128
+ {} p10
129
+ > plane,
130
+ Bits8 mid,
131
+ Bits8 lo
132
+ } supplementary_planes2_16
133
+ >=CHAR car,
134
+ Str cdr
135
+ } cons
136
+ > = Str string,
137
+
138
+ < {} true, {} false > bool,
139
+ {} null,
140
+
141
+ <
142
+ {} nil,
143
+ {
144
+ < {} _, BITS 0, BITS 1 >=BITS prefix,
145
+ BITS size,
146
+ < {} nil, JSON val > val,
147
+ LIST 0,
148
+ LIST 1
149
+ } trie
150
+ > = LIST list,
151
+
152
+ <
153
+ {} nil,
154
+ {
155
+ Str prefix,
156
+ BITS size,
157
+ < {} nil, JSON val > val,
158
+ <
159
+ {} nil,
160
+ {
161
+ { CHAR char, OBJ trie } car,
162
+ DICT cdr
163
+ } cons
164
+ >=DICT dict
165
+ } trie
166
+ > = OBJ object
167
+ > = JSON
168
+ `);
169
+
170
+ const UNIT = Value.product({});
171
+ const NIL = Value.variant("nil", UNIT);
172
+ const BITS_EMPTY = Value.variant("_", UNIT);
173
+
174
+ function requireProduct(value, where) {
175
+ if (!isProduct(value)) {
176
+ throw new Error(`${where}: expected Product`);
177
+ }
178
+ return value.product;
179
+ }
180
+
181
+ /**
182
+ * Encode an array of bits [b0, b1, ..., bk-1] into a `bits?` chain
183
+ * where b0 is the outermost tag (`|0` or `|1`) and `_` is at the base.
184
+ */
185
+ function bitArrayToBitsK(bits) {
186
+ let out = BITS_EMPTY;
187
+ for (let i = bits.length - 1; i >= 0; i--) {
188
+ out = Value.variant(bits[i] === 1 ? "1" : "0", out);
189
+ }
190
+ return out;
191
+ }
192
+
193
+ function bitsKToBitArray(val) {
194
+ const out = [];
195
+ let cur = val;
196
+ while (true) {
197
+ if (!isVariant(cur)) {
198
+ throw new Error("djson-ptrie.bits: expected variant");
199
+ }
200
+ if (cur.tag === "_") return out;
201
+ if (cur.tag === "0") {
202
+ out.push(0);
203
+ cur = cur.value;
204
+ } else if (cur.tag === "1") {
205
+ out.push(1);
206
+ cur = cur.value;
207
+ } else {
208
+ throw new Error(`djson-ptrie.bits: unexpected tag ${cur.tag}`);
209
+ }
210
+ }
211
+ }
212
+
213
+ function natToBitsK(n) {
214
+ return bitArrayToBitsK(indexToBitPath(n));
215
+ }
216
+
217
+ // ----------------------------------------------------------------------
218
+ // 1. Patricia Bit-Trie for `list` (trie-array over bits)
219
+ // ----------------------------------------------------------------------
220
+
221
+ function commonBitPrefixLen(a, b) {
222
+ const len = Math.min(a.length, b.length);
223
+ let i = 0;
224
+ while (i < len && a[i] === b[i]) i++;
225
+ return i;
226
+ }
227
+
228
+ function splitBitTrieNode(x, n) {
229
+ const bitAtN = x.prefix[n];
230
+ const y = {
231
+ size: x.size - 1,
232
+ prefix: x.prefix.slice(n + 1),
233
+ val: x.val,
234
+ b0: x.b0,
235
+ b1: x.b1
236
+ };
237
+ x.prefix = x.prefix.slice(0, n);
238
+ x.val = null;
239
+ x.b0 = bitAtN === 0 ? y : null;
240
+ x.b1 = bitAtN === 1 ? y : null;
241
+ }
242
+
243
+ function addToBitTrie(t, bits, kVal) {
244
+ let curr = t;
245
+ let s = bits;
246
+ while (true) {
247
+ curr.size++;
248
+ const pLen = commonBitPrefixLen(curr.prefix, s);
249
+ if (pLen === s.length && pLen === curr.prefix.length) {
250
+ curr.val = kVal;
251
+ return;
252
+ }
253
+ if (pLen === s.length) {
254
+ splitBitTrieNode(curr, pLen);
255
+ curr.val = kVal;
256
+ return;
257
+ }
258
+ if (pLen !== curr.prefix.length) {
259
+ splitBitTrieNode(curr, pLen);
260
+ const nextBit = s[pLen];
261
+ const newChild = {
262
+ size: 1,
263
+ prefix: s.slice(pLen + 1),
264
+ val: kVal,
265
+ b0: null,
266
+ b1: null
267
+ };
268
+ if (nextBit === 0) curr.b0 = newChild;
269
+ else curr.b1 = newChild;
270
+ return;
271
+ }
272
+ const nextBit = s[pLen];
273
+ const q = nextBit === 0 ? curr.b0 : curr.b1;
274
+ if (!q) {
275
+ const newChild = {
276
+ size: 1,
277
+ prefix: s.slice(pLen + 1),
278
+ val: kVal,
279
+ b0: null,
280
+ b1: null
281
+ };
282
+ if (nextBit === 0) curr.b0 = newChild;
283
+ else curr.b1 = newChild;
284
+ return;
285
+ }
286
+ curr = q;
287
+ s = s.slice(pLen + 1);
288
+ }
289
+ }
290
+
291
+ function bitTrieNodeToK(node) {
292
+ if (!node) return NIL;
293
+ return Value.variant("trie", Value.product({
294
+ prefix: bitArrayToBitsK(node.prefix),
295
+ size: natToBitsK(node.size),
296
+ val: node.val !== null ? Value.variant("val", node.val) : NIL,
297
+ 0: bitTrieNodeToK(node.b0),
298
+ 1: bitTrieNodeToK(node.b1)
299
+ }));
300
+ }
301
+
302
+ function collectBitTrieEntries(kNode, pathBits = [], entries = []) {
303
+ if (!isVariant(kNode)) {
304
+ throw new Error("djson-ptrie.list: expected variant");
305
+ }
306
+ if (kNode.tag === "nil") return entries;
307
+ if (kNode.tag !== "trie") {
308
+ throw new Error(`djson-ptrie.list: unexpected tag ${kNode.tag}`);
309
+ }
310
+ const prod = requireProduct(kNode.value, "djson-ptrie.list.trie");
311
+ const nodePrefix = bitsKToBitArray(prod.prefix);
312
+ const fullPrefix = pathBits.concat(nodePrefix);
313
+ if (isVariant(prod.val) && prod.val.tag === "val") {
314
+ entries.push({ bits: fullPrefix, val: prod.val.value });
315
+ }
316
+ collectBitTrieEntries(prod[0], fullPrefix.concat([0]), entries);
317
+ collectBitTrieEntries(prod[1], fullPrefix.concat([1]), entries);
318
+ return entries;
319
+ }
320
+
321
+ // ----------------------------------------------------------------------
322
+ // 2. Character-Level Radix Trie for `object` (Unicode radix-tree)
323
+ // ----------------------------------------------------------------------
324
+
325
+ function commonCharPrefixLen(a, b) {
326
+ const len = Math.min(a.length, b.length);
327
+ let i = 0;
328
+ while (i < len && a[i] === b[i]) i++;
329
+ return i;
330
+ }
331
+
332
+ function splitCharTrieNode(x, n) {
333
+ const charAtN = x.prefix[n];
334
+ const y = {
335
+ size: x.size - 1,
336
+ prefix: x.prefix.slice(n + 1),
337
+ val: x.val,
338
+ dict: x.dict,
339
+ order: x.order
340
+ };
341
+ x.dict = new Map([[charAtN, y]]);
342
+ x.order = [charAtN];
343
+ x.prefix = x.prefix.slice(0, n);
344
+ x.val = null;
345
+ }
346
+
347
+ function addToCharTrie(t, cpArray, kVal) {
348
+ let curr = t;
349
+ let s = cpArray;
350
+ while (true) {
351
+ curr.size++;
352
+ const pLen = commonCharPrefixLen(curr.prefix, s);
353
+ if (pLen === s.length && pLen === curr.prefix.length) {
354
+ curr.val = kVal;
355
+ return;
356
+ }
357
+ if (pLen === s.length) {
358
+ splitCharTrieNode(curr, pLen);
359
+ curr.val = kVal;
360
+ return;
361
+ }
362
+ if (pLen !== curr.prefix.length) {
363
+ splitCharTrieNode(curr, pLen);
364
+ const c = s[pLen];
365
+ curr.dict.set(c, {
366
+ size: 1,
367
+ prefix: s.slice(pLen + 1),
368
+ val: kVal,
369
+ dict: new Map(),
370
+ order: []
371
+ });
372
+ curr.order.push(c);
373
+ curr.order.sort((a, b) => a - b);
374
+ return;
375
+ }
376
+ const c = s[pLen];
377
+ const q = curr.dict.get(c);
378
+ if (!q) {
379
+ curr.dict.set(c, {
380
+ size: 1,
381
+ prefix: s.slice(pLen + 1),
382
+ val: kVal,
383
+ dict: new Map(),
384
+ order: []
385
+ });
386
+ curr.order.push(c);
387
+ curr.order.sort((a, b) => a - b);
388
+ return;
389
+ }
390
+ curr = q;
391
+ s = s.slice(pLen + 1);
392
+ }
393
+ }
394
+
395
+ function cpArrayToStringK(cpArray) {
396
+ let out = NIL;
397
+ for (let i = cpArray.length - 1; i >= 0; i--) {
398
+ out = Value.variant("cons", Value.product({
399
+ car: codePointToUnicodeValue(cpArray[i]),
400
+ cdr: out
401
+ }));
402
+ }
403
+ return out;
404
+ }
405
+
406
+ function charTrieNodeToK(node) {
407
+ if (!node) return NIL;
408
+ let dictK = NIL;
409
+ for (let i = node.order.length - 1; i >= 0; i--) {
410
+ const cp = node.order[i];
411
+ const child = node.dict.get(cp);
412
+ dictK = Value.variant("cons", Value.product({
413
+ car: Value.product({
414
+ char: codePointToUnicodeValue(cp),
415
+ trie: charTrieNodeToK(child)
416
+ }),
417
+ cdr: dictK
418
+ }));
419
+ }
420
+ return Value.variant("trie", Value.product({
421
+ prefix: cpArrayToStringK(node.prefix),
422
+ size: natToBitsK(node.size),
423
+ val: node.val !== null ? Value.variant("val", node.val) : NIL,
424
+ dict: dictK
425
+ }));
426
+ }
427
+
428
+ function collectCharTrieEntries(kNode, prefixStr = "", entries = []) {
429
+ if (!isVariant(kNode)) {
430
+ throw new Error("djson-ptrie.object: expected variant");
431
+ }
432
+ if (kNode.tag === "nil") return entries;
433
+ if (kNode.tag !== "trie") {
434
+ throw new Error(`djson-ptrie.object: unexpected tag ${kNode.tag}`);
435
+ }
436
+ const prod = requireProduct(kNode.value, "djson-ptrie.object.trie");
437
+ const nodePrefix = stringValueToText(prod.prefix);
438
+ const fullPrefix = prefixStr + nodePrefix;
439
+ if (isVariant(prod.val) && prod.val.tag === "val") {
440
+ entries.push({ key: fullPrefix, val: prod.val.value });
441
+ }
442
+ let curDict = prod.dict;
443
+ while (true) {
444
+ if (!isVariant(curDict)) {
445
+ throw new Error("djson-ptrie.object.dict: expected variant");
446
+ }
447
+ if (curDict.tag === "nil") break;
448
+ if (curDict.tag !== "cons") {
449
+ throw new Error(
450
+ `djson-ptrie.object.dict: unexpected tag ${curDict.tag}`
451
+ );
452
+ }
453
+ const pair = requireProduct(
454
+ curDict.value,
455
+ "djson-ptrie.object.dict.cons"
456
+ );
457
+ const entry = requireProduct(pair.car, "djson-ptrie.object.dict.car");
458
+ const ch = String.fromCodePoint(unicodeValueToCodePoint(entry.char));
459
+ collectCharTrieEntries(entry.trie, fullPrefix + ch, entries);
460
+ curDict = pair.cdr;
461
+ }
462
+ return entries;
463
+ }
464
+
465
+ export function fromJsonValue(value) {
466
+ if (value === null) {
467
+ return Value.variant("null", UNIT);
468
+ }
469
+ if (typeof value === "boolean") {
470
+ return Value.variant(
471
+ "bool",
472
+ Value.variant(value ? "true" : "false", UNIT)
473
+ );
474
+ }
475
+ if (typeof value === "number") {
476
+ if (!Number.isFinite(value)) {
477
+ throw new Error("JSON numbers must be finite");
478
+ }
479
+ return Value.variant("number", encodeNumberToValue(value));
480
+ }
481
+ if (typeof value === "string") {
482
+ return Value.variant("string", textToStringValue(value));
483
+ }
484
+ if (Array.isArray(value)) {
485
+ if (value.length === 0) {
486
+ return Value.variant("list", NIL);
487
+ }
488
+ const firstBits = indexToBitPath(0);
489
+ const root = {
490
+ size: 1,
491
+ prefix: firstBits,
492
+ val: fromJsonValue(value[0]),
493
+ b0: null,
494
+ b1: null
495
+ };
496
+ for (let i = 1; i < value.length; i++) {
497
+ addToBitTrie(root, indexToBitPath(i), fromJsonValue(value[i]));
498
+ }
499
+ return Value.variant("list", bitTrieNodeToK(root));
500
+ }
501
+ if (value && typeof value === "object") {
502
+ const keys = Object.keys(value);
503
+ if (keys.length === 0) {
504
+ return Value.variant("object", NIL);
505
+ }
506
+ const firstCps = Array.from(keys[0]).map((c) => c.codePointAt(0));
507
+ const root = {
508
+ size: 1,
509
+ prefix: firstCps,
510
+ val: fromJsonValue(value[keys[0]]),
511
+ dict: new Map(),
512
+ order: []
513
+ };
514
+ for (let i = 1; i < keys.length; i++) {
515
+ const cps = Array.from(keys[i]).map((c) => c.codePointAt(0));
516
+ addToCharTrie(root, cps, fromJsonValue(value[keys[i]]));
517
+ }
518
+ return Value.variant("object", charTrieNodeToK(root));
519
+ }
520
+ throw new Error(`Unsupported JSON value: ${value}`);
521
+ }
522
+
523
+ export function toJsonValue(value) {
524
+ if (!isVariant(value)) {
525
+ throw new Error("djson-ptrie: expected top-level Variant");
526
+ }
527
+ if (value.tag === "null") {
528
+ requireProduct(value.value, "djson-ptrie.null");
529
+ return null;
530
+ }
531
+ if (value.tag === "bool") {
532
+ if (!isVariant(value.value)) {
533
+ throw new Error("djson-ptrie.bool: expected variant");
534
+ }
535
+ if (value.value.tag === "true") return true;
536
+ if (value.value.tag === "false") return false;
537
+ throw new Error(`djson-ptrie.bool: invalid tag ${value.value.tag}`);
538
+ }
539
+ if (value.tag === "number") {
540
+ return decodeValueToNumber(value.value);
541
+ }
542
+ if (value.tag === "string") {
543
+ return stringValueToText(value.value);
544
+ }
545
+ if (value.tag === "list") {
546
+ const entries = collectBitTrieEntries(value.value);
547
+ entries.sort((a, b) =>
548
+ bitPathToIndex(a.bits) - bitPathToIndex(b.bits)
549
+ );
550
+ return entries.map((e) => toJsonValue(e.val));
551
+ }
552
+ if (value.tag === "object") {
553
+ const entries = collectCharTrieEntries(value.value);
554
+ const result = {};
555
+ for (const e of entries) {
556
+ result[e.key] = toJsonValue(e.val);
557
+ }
558
+ return result;
559
+ }
560
+ throw new Error(`djson-ptrie: unsupported tag ${value.tag}`);
561
+ }
562
+
563
+ export const pattern = DJSON_PTRIE_PATTERN;
564
+
565
+ export function parse(rawText) {
566
+ const text = String(rawText).trim();
567
+ if (!text) throw new Error("Empty JSON input");
568
+ const parsed = JSON.parse(text);
569
+ const val = fromJsonValue(parsed);
570
+ return withPattern(val, DJSON_PTRIE_PATTERN);
571
+ }
572
+
573
+ export function print(value) {
574
+ return JSON.stringify(toJsonValue(value));
575
+ }
576
+
577
+ export const codec = {
578
+ name: "djson-ptrie",
579
+ doc,
580
+ pattern: DJSON_PTRIE_PATTERN,
581
+ parse,
582
+ print
583
+ };
584
+
585
+ export default codec;
586
+
587
+ runCodecCLI(import.meta.url, { parse, print, doc });