@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.
- package/CHANGELOG.md +99 -0
- package/DOCS/BIG_PICTURE.md +54 -7
- package/DOCS/CODECS.md +47 -2
- package/DOCS/CODEC_ARCHITECTURE.md +14 -5
- package/DOCS/DICTIONARY.md +13 -4
- package/DOCS/FILE_FORMATS.md +3 -2
- package/DOCS/JSON_APPROACHES_COMPARISON.md +306 -0
- package/DOCS/NAMED_PATTERNS.md +317 -0
- package/DOCS/PATTERNS.md +59 -11
- package/DOCS/REPL.md +24 -5
- package/DOCS/WEB_REPL_REQUIREMENTS.md +4 -2
- package/Examples/arithmetics.k +22 -17
- package/Examples/bnat.k +21 -11
- package/Examples/buda.k +37 -20
- package/Examples/byte.k +3 -1
- package/Examples/code.k +38 -39
- package/Examples/djson-btrie.k +414 -0
- package/Examples/djson-ptrie.k +663 -0
- package/Examples/djson.k +323 -0
- package/Examples/esc.k +1 -1
- package/Examples/karatsuba-mult.k +16 -13
- package/Examples/list.k +8 -4
- package/Examples/nat.k +17 -11
- package/Examples/poly.k +11 -3
- package/Examples/vhdl_to_k.k +43 -31
- package/README.md +42 -15
- package/Value.mjs +28 -3
- package/backend-api.mjs +5 -1
- package/browser/repl-browser.mjs +6 -0
- package/browser/tree-view.mjs +82 -24
- package/browser/vfs-data.mjs +21 -12
- package/codecs/README.md +3 -0
- package/codecs/djson-btrie.mjs +560 -0
- package/codecs/djson-ptrie.mjs +587 -0
- package/codecs/djson.mjs +270 -0
- package/codecs/int.mjs +2 -1
- package/codecs/json.mjs +7 -2
- package/codecs/k-parse.mjs +7 -1
- package/codecs/k-print.mjs +4 -0
- package/codecs/runtime/codec-sdk.mjs +16 -2
- package/codecs/runtime/pattern-json.mjs +80 -1
- package/codecs/runtime/prefix-codec.mjs +629 -67
- package/codecs/runtime/show-value.mjs +93 -51
- package/codecs/runtime/unicode-string.mjs +29 -6
- package/codecs/show.mjs +4 -0
- package/codecs/utf16.mjs +2 -1
- package/core.k +79 -115
- package/index.mjs +3 -0
- package/named-patterns.mjs +267 -0
- package/object.mjs +31 -3
- package/package.json +5 -1
- package/parser.jison +68 -5
- package/parser.mjs +111 -60
- package/pretty.mjs +5 -0
- package/repl.mjs +245 -28
- package/scripts/build-repl-html.mjs +76 -5
- package/scripts/perf-djson.mjs +1142 -0
- package/scripts/run-tests.mjs +5 -0
- package/symbol-table.mjs +20 -2
- package/tests/bench-djson-tries.mjs +340 -0
- package/tests/test-codecs.mjs +211 -0
- package/tests/test-named-patterns.mjs +189 -0
- package/tests/test-repl-html.mjs +52 -4
- package/tests/test-repl.mjs +223 -0
|
@@ -0,0 +1,663 @@
|
|
|
1
|
+
-- Examples/djson-ptrie.k: Patricia/Radix Trie JSON schema & helpers
|
|
2
|
+
-- Works with codecs/djson-ptrie.mjs (trie-array style).
|
|
3
|
+
|
|
4
|
+
---------------------------------------------------------------
|
|
5
|
+
-- §1. Named Pattern Definitions & Component Schemas
|
|
6
|
+
---------------------------------------------------------------
|
|
7
|
+
|
|
8
|
+
bit[] = < {} 0, {} 1 >;
|
|
9
|
+
|
|
10
|
+
bits[] = < {} _, B 0, B 1 > = B;
|
|
11
|
+
|
|
12
|
+
sign[] = < {} "+", {} "-" >;
|
|
13
|
+
|
|
14
|
+
exponent[] = {
|
|
15
|
+
bit[] 0, bit[] 1, bit[] 2, bit[] 3, bit[] 4,
|
|
16
|
+
bit[] 5, bit[] 6, bit[] 7, bit[] 8, bit[] 9, bit[] 10
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
fraction[] = {
|
|
20
|
+
bit[] 0, bit[] 1, bit[] 2, bit[] 3, bit[] 4, bit[] 5,
|
|
21
|
+
bit[] 6, bit[] 7, bit[] 8, bit[] 9, bit[] 10, bit[] 11,
|
|
22
|
+
bit[] 12, bit[] 13, bit[] 14, bit[] 15, bit[] 16, bit[] 17,
|
|
23
|
+
bit[] 18, bit[] 19, bit[] 20, bit[] 21, bit[] 22, bit[] 23,
|
|
24
|
+
bit[] 24, bit[] 25, bit[] 26, bit[] 27, bit[] 28, bit[] 29,
|
|
25
|
+
bit[] 30, bit[] 31, bit[] 32, bit[] 33, bit[] 34, bit[] 35,
|
|
26
|
+
bit[] 36, bit[] 37, bit[] 38, bit[] 39, bit[] 40, bit[] 41,
|
|
27
|
+
bit[] 42, bit[] 43, bit[] 44, bit[] 45, bit[] 46, bit[] 47,
|
|
28
|
+
bit[] 48, bit[] 49, bit[] 50, bit[] 51
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
number[] = {
|
|
32
|
+
sign[] sign,
|
|
33
|
+
exponent[] exponent,
|
|
34
|
+
fraction[] fraction
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
byte[] = {
|
|
38
|
+
bit[] 0, bit[] 1, bit[] 2, bit[] 3,
|
|
39
|
+
bit[] 4, bit[] 5, bit[] 6, bit[] 7
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
ascii[] = {
|
|
43
|
+
bit[] 0, bit[] 1, bit[] 2, bit[] 3,
|
|
44
|
+
bit[] 4, bit[] 5, bit[] 6
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
bmp_hi_common[] = <
|
|
48
|
+
{ bit[] 0, bit[] 1, bit[] 2 } h08_0F,
|
|
49
|
+
ascii[] h10_7F,
|
|
50
|
+
ascii[] h80_CF,
|
|
51
|
+
{ bit[] 0, bit[] 1, bit[] 2 } hD0_D7,
|
|
52
|
+
{} hF9,
|
|
53
|
+
{ bit[] 0 } hFA_FB,
|
|
54
|
+
{ bit[] 0 } hFC_FD,
|
|
55
|
+
{ bit[] 0 } hFE_FF
|
|
56
|
+
>;
|
|
57
|
+
|
|
58
|
+
bmp_hi_private_use[] = <
|
|
59
|
+
{ bit[] 0, bit[] 1, bit[] 2, bit[] 3 } hE0_EF,
|
|
60
|
+
{ bit[] 0, bit[] 1, bit[] 2 } hF0_F7,
|
|
61
|
+
{} hF8
|
|
62
|
+
>;
|
|
63
|
+
|
|
64
|
+
plane0[] = {
|
|
65
|
+
bit[] 0, bit[] 1, bit[] 2, bit[] 3, bit[] 4,
|
|
66
|
+
bit[] 5, bit[] 6, bit[] 7, bit[] 8, bit[] 9, bit[] 10
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
plane_02_10[] = <
|
|
70
|
+
{ bit[] 0 } p02_03,
|
|
71
|
+
{ bit[] 0, bit[] 1 } p04_07,
|
|
72
|
+
{ bit[] 0, bit[] 1, bit[] 2 } p08_0F,
|
|
73
|
+
{} p10
|
|
74
|
+
>;
|
|
75
|
+
|
|
76
|
+
unicode[] = <
|
|
77
|
+
ascii[] ascii,
|
|
78
|
+
{ bmp_hi_common[] hi, byte[] lo } bmp_common,
|
|
79
|
+
{ bmp_hi_private_use[] hi, byte[] lo } bmp_private_use,
|
|
80
|
+
plane0[] plane0,
|
|
81
|
+
{ byte[] mid, byte[] lo } supplementary_plane1,
|
|
82
|
+
{ plane_02_10[] plane, byte[] mid, byte[] lo } supplementary_planes2_16
|
|
83
|
+
>;
|
|
84
|
+
|
|
85
|
+
string[] = < {} nil, { unicode[] car, S cdr } cons > = S;
|
|
86
|
+
|
|
87
|
+
bool[] = < {} true, {} false >;
|
|
88
|
+
|
|
89
|
+
opt[V] = < {} nil, V val >;
|
|
90
|
+
|
|
91
|
+
ptrie_list[V] = <
|
|
92
|
+
{} nil,
|
|
93
|
+
{
|
|
94
|
+
bits[] prefix,
|
|
95
|
+
bits[] size,
|
|
96
|
+
opt[V] val,
|
|
97
|
+
L 0,
|
|
98
|
+
L 1
|
|
99
|
+
} trie
|
|
100
|
+
> = L;
|
|
101
|
+
|
|
102
|
+
pair[A, B] = { A char, B trie };
|
|
103
|
+
list[X] = < {} nil, { X car, D cdr } cons > = D;
|
|
104
|
+
|
|
105
|
+
ptrie_obj[V] = <
|
|
106
|
+
{} nil,
|
|
107
|
+
{
|
|
108
|
+
string[] prefix,
|
|
109
|
+
bits[] size,
|
|
110
|
+
opt[V] val,
|
|
111
|
+
list[pair[unicode[], O]] dict
|
|
112
|
+
} trie
|
|
113
|
+
> = O;
|
|
114
|
+
|
|
115
|
+
djson_ptrie[] = <
|
|
116
|
+
number[] number,
|
|
117
|
+
string[] string,
|
|
118
|
+
bool[] bool,
|
|
119
|
+
{} null,
|
|
120
|
+
ptrie_list[J] list,
|
|
121
|
+
ptrie_obj[J] object
|
|
122
|
+
> = J;
|
|
123
|
+
|
|
124
|
+
json? = ? djson_ptrie[];
|
|
125
|
+
|
|
126
|
+
-----------------------------------------------------------------
|
|
127
|
+
-- §2. Unicode Character Equality (eq_char?)
|
|
128
|
+
---------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
eq_bit? = ?{ <{} 0, {} 1>=B x, B y }
|
|
131
|
+
< {.x /0 x, .y /0 y}, {.x /1 x, .y /1 y} > {};
|
|
132
|
+
|
|
133
|
+
eq_bits1? = { {.x .0 x, .y .0 y} eq_bit? 0 } {};
|
|
134
|
+
eq_bits2? = { {.x x, .y y} eq_bits1? a, {.x .1 x, .y .1 y} eq_bit? 1 } {};
|
|
135
|
+
eq_bits3? = { {.x x, .y y} eq_bits2? a, {.x .2 x, .y .2 y} eq_bit? 2 } {};
|
|
136
|
+
eq_bits4? = { {.x x, .y y} eq_bits3? a, {.x .3 x, .y .3 y} eq_bit? 3 } {};
|
|
137
|
+
eq_bits7? = {
|
|
138
|
+
{.x x, .y y} eq_bits4? a,
|
|
139
|
+
{.x .4 x, .y .4 y} eq_bit? 4,
|
|
140
|
+
{.x .5 x, .y .5 y} eq_bit? 5,
|
|
141
|
+
{.x .6 x, .y .6 y} eq_bit? 6
|
|
142
|
+
} {};
|
|
143
|
+
eq_bits8? = { {.x x, .y y} eq_bits7? a, {.x .7 x, .y .7 y} eq_bit? 7 } {};
|
|
144
|
+
eq_bits11? = {
|
|
145
|
+
{.x x, .y y} eq_bits8? a,
|
|
146
|
+
{.x .8 x, .y .8 y} eq_bit? 8,
|
|
147
|
+
{.x .9 x, .y .9 y} eq_bit? 9,
|
|
148
|
+
{.x .10 x, .y .10 y} eq_bit? 10
|
|
149
|
+
} {};
|
|
150
|
+
|
|
151
|
+
eq_bmp_common_hi? = <
|
|
152
|
+
{.x /h08_0F x, .y /h08_0F y} eq_bits3?,
|
|
153
|
+
{.x /h10_7F x, .y /h10_7F y} eq_bits7?,
|
|
154
|
+
{.x /h80_CF x, .y /h80_CF y} eq_bits7?,
|
|
155
|
+
{.x /hD0_D7 x, .y /hD0_D7 y} eq_bits3?,
|
|
156
|
+
{.x /hF9 x, .y /hF9 y} {},
|
|
157
|
+
{.x /hFA_FB x, .y /hFA_FB y} eq_bits1?,
|
|
158
|
+
{.x /hFC_FD x, .y /hFC_FD y} eq_bits1?,
|
|
159
|
+
{.x /hFE_FF x, .y /hFE_FF y} eq_bits1?
|
|
160
|
+
>;
|
|
161
|
+
|
|
162
|
+
eq_bmp_private_use_hi? = <
|
|
163
|
+
{.x /hE0_EF x, .y /hE0_EF y} eq_bits4?,
|
|
164
|
+
{.x /hF0_F7 x, .y /hF0_F7 y} eq_bits3?,
|
|
165
|
+
{.x /hF8 x, .y /hF8 y} {}
|
|
166
|
+
>;
|
|
167
|
+
|
|
168
|
+
eq_plane2_16? = <
|
|
169
|
+
{.x /p02_03 x, .y /p02_03 y} eq_bits1?,
|
|
170
|
+
{.x /p04_07 x, .y /p04_07 y} eq_bits2?,
|
|
171
|
+
{.x /p08_0F x, .y /p08_0F y} eq_bits3?,
|
|
172
|
+
{.x /p10 x, .y /p10 y} {}
|
|
173
|
+
>;
|
|
174
|
+
|
|
175
|
+
eq_char? = <
|
|
176
|
+
{.x /ascii x, .y /ascii y} eq_bits7?,
|
|
177
|
+
{
|
|
178
|
+
{.x /bmp_common .hi x, .y /bmp_common .hi y} eq_bmp_common_hi? hi,
|
|
179
|
+
{.x /bmp_common .lo x, .y /bmp_common .lo y} eq_bits8? lo
|
|
180
|
+
} {},
|
|
181
|
+
{
|
|
182
|
+
{
|
|
183
|
+
.x /bmp_private_use .hi x,
|
|
184
|
+
.y /bmp_private_use .hi y
|
|
185
|
+
} eq_bmp_private_use_hi? hi,
|
|
186
|
+
{.x /bmp_private_use .lo x, .y /bmp_private_use .lo y} eq_bits8? lo
|
|
187
|
+
} {},
|
|
188
|
+
{.x /plane0 x, .y /plane0 y} eq_bits11?,
|
|
189
|
+
{
|
|
190
|
+
{
|
|
191
|
+
.x /supplementary_plane1 .mid x,
|
|
192
|
+
.y /supplementary_plane1 .mid y
|
|
193
|
+
} eq_bits8? mid,
|
|
194
|
+
{
|
|
195
|
+
.x /supplementary_plane1 .lo x,
|
|
196
|
+
.y /supplementary_plane1 .lo y
|
|
197
|
+
} eq_bits8? lo
|
|
198
|
+
} {},
|
|
199
|
+
{
|
|
200
|
+
{
|
|
201
|
+
.x /supplementary_planes2_16 .plane x,
|
|
202
|
+
.y /supplementary_planes2_16 .plane y
|
|
203
|
+
} eq_plane2_16? plane,
|
|
204
|
+
{
|
|
205
|
+
.x /supplementary_planes2_16 .mid x,
|
|
206
|
+
.y /supplementary_planes2_16 .mid y
|
|
207
|
+
} eq_bits8? mid,
|
|
208
|
+
{
|
|
209
|
+
.x /supplementary_planes2_16 .lo x,
|
|
210
|
+
.y /supplementary_planes2_16 .lo y
|
|
211
|
+
} eq_bits8? lo
|
|
212
|
+
} {}
|
|
213
|
+
>;
|
|
214
|
+
|
|
215
|
+
---------------------------------------------------------------
|
|
216
|
+
-- §3. Patricia/Radix Trie Lookup Relations (dot, nth, has_key?)
|
|
217
|
+
---------------------------------------------------------------
|
|
218
|
+
|
|
219
|
+
bits? = ?< {} _, bits? 0, bits? 1 > = bits?;
|
|
220
|
+
0b = {} | _;
|
|
221
|
+
0 = 0b | 0;
|
|
222
|
+
1 = 0b | 1;
|
|
223
|
+
str_list? = ?< {} nil, { C car, S cdr } cons > = S;
|
|
224
|
+
ptrie_list? = ?<
|
|
225
|
+
{} nil,
|
|
226
|
+
{ B1 prefix, B2 size, < {} nil, V val > val, T 0, T 1 } trie
|
|
227
|
+
> = T;
|
|
228
|
+
ptrie_obj? = ?<
|
|
229
|
+
{} nil,
|
|
230
|
+
{
|
|
231
|
+
S prefix,
|
|
232
|
+
B size,
|
|
233
|
+
< {} nil, V val > val,
|
|
234
|
+
< {} nil, { { C char, T trie } car, D cdr } cons >=D dict
|
|
235
|
+
} trie
|
|
236
|
+
> = T;
|
|
237
|
+
ptrie_dict? = ?<
|
|
238
|
+
{} nil,
|
|
239
|
+
{ { C char, T trie } car, D cdr } cons
|
|
240
|
+
> = D;
|
|
241
|
+
|
|
242
|
+
nil = {} | nil;
|
|
243
|
+
null = {} | null json?;
|
|
244
|
+
true = {} | true | bool json?;
|
|
245
|
+
false = {} | false | bool json?;
|
|
246
|
+
number = | number json?;
|
|
247
|
+
string = | string json?;
|
|
248
|
+
bool = | bool json?;
|
|
249
|
+
list = | list json?;
|
|
250
|
+
object = | object json?;
|
|
251
|
+
|
|
252
|
+
-- O(1) subtree size queries (number of elements in list or object)
|
|
253
|
+
list_size = ptrie_list? < /nil 0, /trie .size >;
|
|
254
|
+
obj_size = ptrie_obj? < /nil 0, /trie .size >;
|
|
255
|
+
|
|
256
|
+
match_str_prefix = ?{ P prefix, K key } {
|
|
257
|
+
.prefix str_list? prefix,
|
|
258
|
+
.key str_list? key
|
|
259
|
+
} <
|
|
260
|
+
{ .prefix /nil if, .key then } .then,
|
|
261
|
+
{
|
|
262
|
+
{ .prefix /cons .car x, .key /cons .car y } eq_char? if,
|
|
263
|
+
{ .prefix /cons .cdr prefix, .key /cons .cdr key }
|
|
264
|
+
match_str_prefix then
|
|
265
|
+
} .then
|
|
266
|
+
>;
|
|
267
|
+
|
|
268
|
+
find_in_dict = ?{ C char, D dict } {
|
|
269
|
+
.char char,
|
|
270
|
+
.dict ptrie_dict? dict
|
|
271
|
+
} <
|
|
272
|
+
{
|
|
273
|
+
{ .char x, .dict /cons .car .char y } eq_char? if,
|
|
274
|
+
.dict /cons .car .trie then
|
|
275
|
+
} .then,
|
|
276
|
+
{ .char char, .dict /cons .cdr dict } find_in_dict
|
|
277
|
+
>;
|
|
278
|
+
|
|
279
|
+
-- Lookup string key in radix object trie: { key, object } -> val
|
|
280
|
+
dot = ?{ K key, T object } {
|
|
281
|
+
{ .object ptrie_obj? /trie .prefix prefix, .key str_list? key }
|
|
282
|
+
match_str_prefix rem,
|
|
283
|
+
.object ptrie_obj? /trie t
|
|
284
|
+
} <
|
|
285
|
+
{ .rem /nil if, .t .val /val then } .then,
|
|
286
|
+
{
|
|
287
|
+
.rem /cons .cdr key,
|
|
288
|
+
{ .rem /cons .car char, .t .dict dict } find_in_dict object
|
|
289
|
+
} dot
|
|
290
|
+
>;
|
|
291
|
+
|
|
292
|
+
has_key? = ?{ K key, O object } { dot if, () then } .then;
|
|
293
|
+
|
|
294
|
+
-- Lookup bits? index in Patricia bit-trie list: { index, list } -> val
|
|
295
|
+
match_bit_prefix = ?{ P prefix, K key } {
|
|
296
|
+
.prefix bits? prefix,
|
|
297
|
+
.key bits? key
|
|
298
|
+
} <
|
|
299
|
+
{ .prefix /_ if, .key then } .then,
|
|
300
|
+
{ .prefix /0 prefix, .key /0 key } match_bit_prefix,
|
|
301
|
+
{ .prefix /1 prefix, .key /1 key } match_bit_prefix
|
|
302
|
+
>;
|
|
303
|
+
|
|
304
|
+
nth = ?{ K index, T list } {
|
|
305
|
+
{ .list ptrie_list? /trie .prefix prefix, .index bits? key }
|
|
306
|
+
match_bit_prefix rem,
|
|
307
|
+
.list ptrie_list? /trie t
|
|
308
|
+
} <
|
|
309
|
+
{ .rem /_ if, .t .val /val then } .then,
|
|
310
|
+
{ .rem /0 index, .t .0 list } nth,
|
|
311
|
+
{ .rem /1 index, .t .1 list } nth
|
|
312
|
+
>;
|
|
313
|
+
|
|
314
|
+
-- Binary natural number helpers for size maintenance
|
|
315
|
+
_inv = ?{ < {} _, B 0, B 1 >=B x, B r } <
|
|
316
|
+
{ .x /_ if, .r then } .then,
|
|
317
|
+
{ .x /0 x, .r |0 r } _inv,
|
|
318
|
+
{ .x /1 x, .r |1 r } _inv
|
|
319
|
+
> bits?;
|
|
320
|
+
_dec = ?{ < {} _, B 0, B 1 >=B x, B y } <
|
|
321
|
+
{ .x /1 x, .y |0 r } _inv,
|
|
322
|
+
{ .x /0 x, .y |1 y } _dec
|
|
323
|
+
> bits?;
|
|
324
|
+
_inc = ?{ < {} _, B 0, B 1 >=B x, B y } <
|
|
325
|
+
{ .x /_ if, .y |1 then } .then,
|
|
326
|
+
{ .x /0 x, .y |1 r } _inv,
|
|
327
|
+
{ .x /1 x, .y |0 y } _inc
|
|
328
|
+
> bits?;
|
|
329
|
+
_trim0 = bits? < /0 _trim0, /_ 0, () >;
|
|
330
|
+
dec_nat = { { () x, 0b r } _inv x, 0b y } _dec _trim0;
|
|
331
|
+
inc_nat = { { () x, 0b r } _inv x, 0b y } _inc;
|
|
332
|
+
|
|
333
|
+
-- Remove key from radix object trie: { key, object } -> object
|
|
334
|
+
_remove_step = ?<
|
|
335
|
+
{
|
|
336
|
+
< {} nil, { C car, S cdr } cons >=S key,
|
|
337
|
+
<
|
|
338
|
+
{} nil,
|
|
339
|
+
{
|
|
340
|
+
S prefix,
|
|
341
|
+
< {} _, B 0, B 1 >=B size,
|
|
342
|
+
< {} nil, V val > val,
|
|
343
|
+
< {} nil, { { C char, T trie } car, D cdr } cons >=D dict
|
|
344
|
+
} trie
|
|
345
|
+
>=T object
|
|
346
|
+
} node,
|
|
347
|
+
{ C char, S key, D dict } dict
|
|
348
|
+
> <
|
|
349
|
+
/node {
|
|
350
|
+
{ .object /trie .prefix prefix, .key key } match_str_prefix rem,
|
|
351
|
+
.object /trie t
|
|
352
|
+
} <
|
|
353
|
+
{
|
|
354
|
+
.rem /nil if,
|
|
355
|
+
{
|
|
356
|
+
.t .prefix prefix,
|
|
357
|
+
.t .size dec_nat size,
|
|
358
|
+
nil val,
|
|
359
|
+
.t .dict dict
|
|
360
|
+
} |trie then
|
|
361
|
+
} .then,
|
|
362
|
+
{
|
|
363
|
+
.t .prefix prefix,
|
|
364
|
+
.t .size dec_nat size,
|
|
365
|
+
.t .val val,
|
|
366
|
+
{
|
|
367
|
+
.rem /cons .car char,
|
|
368
|
+
.rem /cons .cdr key,
|
|
369
|
+
.t .dict dict
|
|
370
|
+
} |dict _remove_step /dict dict
|
|
371
|
+
} |trie
|
|
372
|
+
> |node,
|
|
373
|
+
/dict <
|
|
374
|
+
{
|
|
375
|
+
{ .char x, .dict /cons .car .char y } eq_char? if,
|
|
376
|
+
{
|
|
377
|
+
{
|
|
378
|
+
.char char,
|
|
379
|
+
{
|
|
380
|
+
.key key,
|
|
381
|
+
.dict /cons .car .trie object
|
|
382
|
+
} |node _remove_step /node trie
|
|
383
|
+
} car,
|
|
384
|
+
.dict /cons .cdr cdr
|
|
385
|
+
} |cons then
|
|
386
|
+
} .then,
|
|
387
|
+
{
|
|
388
|
+
.dict /cons .car car,
|
|
389
|
+
{
|
|
390
|
+
.char char,
|
|
391
|
+
.key key,
|
|
392
|
+
.dict /cons .cdr dict
|
|
393
|
+
} |dict _remove_step /dict cdr
|
|
394
|
+
} |cons
|
|
395
|
+
> |dict
|
|
396
|
+
>;
|
|
397
|
+
|
|
398
|
+
remove = ?{ K key, O object } {
|
|
399
|
+
.key str_list? key,
|
|
400
|
+
.object ptrie_obj? object
|
|
401
|
+
} <
|
|
402
|
+
{
|
|
403
|
+
{ .key key, .object object } has_key? if,
|
|
404
|
+
{ .key key, .object object } |node _remove_step /node then
|
|
405
|
+
} .then,
|
|
406
|
+
.object
|
|
407
|
+
> ptrie_obj?;
|
|
408
|
+
|
|
409
|
+
-- Split two strings into { common, rem_prefix, rem_key }
|
|
410
|
+
split_str_prefix = ?{
|
|
411
|
+
< {} nil, { C car, S cdr } cons >=S prefix,
|
|
412
|
+
S key
|
|
413
|
+
} <
|
|
414
|
+
{
|
|
415
|
+
.prefix /nil if,
|
|
416
|
+
{ nil common, nil rem_prefix, .key rem_key } then
|
|
417
|
+
} .then,
|
|
418
|
+
{
|
|
419
|
+
.key /nil if,
|
|
420
|
+
{ nil common, .prefix rem_prefix, nil rem_key } then
|
|
421
|
+
} .then,
|
|
422
|
+
{
|
|
423
|
+
{ .prefix /cons .car x, .key /cons .car y } eq_char? if,
|
|
424
|
+
{
|
|
425
|
+
.prefix /cons .car c,
|
|
426
|
+
{
|
|
427
|
+
.prefix /cons .cdr prefix,
|
|
428
|
+
.key /cons .cdr key
|
|
429
|
+
} split_str_prefix sub
|
|
430
|
+
} {
|
|
431
|
+
{ .c car, .sub .common cdr } |cons common,
|
|
432
|
+
.sub .rem_prefix rem_prefix,
|
|
433
|
+
.sub .rem_key rem_key
|
|
434
|
+
} then
|
|
435
|
+
} .then,
|
|
436
|
+
{ nil common, .prefix rem_prefix, .key rem_key }
|
|
437
|
+
> ?{ S1 common, S2 rem_prefix, S3 rem_key } {
|
|
438
|
+
.common str_list? common,
|
|
439
|
+
.rem_prefix str_list? rem_prefix,
|
|
440
|
+
.rem_key str_list? rem_key
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
-- Replace value of an existing key in radix object trie
|
|
444
|
+
_put_replace = ?<
|
|
445
|
+
{
|
|
446
|
+
< {} nil, { C car, S cdr } cons >=S key,
|
|
447
|
+
V val,
|
|
448
|
+
<
|
|
449
|
+
{} nil,
|
|
450
|
+
{
|
|
451
|
+
S prefix,
|
|
452
|
+
< {} _, B 0, B 1 >=B size,
|
|
453
|
+
< {} nil, V val > val,
|
|
454
|
+
< {} nil, { { C char, T trie } car, D cdr } cons >=D dict
|
|
455
|
+
} trie
|
|
456
|
+
>=T object
|
|
457
|
+
} node,
|
|
458
|
+
{ C char, S key, V val, D dict } dict
|
|
459
|
+
> <
|
|
460
|
+
/node {
|
|
461
|
+
{ .object /trie .prefix prefix, .key key } match_str_prefix rem,
|
|
462
|
+
.val val,
|
|
463
|
+
.object /trie t
|
|
464
|
+
} <
|
|
465
|
+
{
|
|
466
|
+
.rem /nil if,
|
|
467
|
+
{
|
|
468
|
+
.t .prefix prefix,
|
|
469
|
+
.t .size size,
|
|
470
|
+
.val |val val,
|
|
471
|
+
.t .dict dict
|
|
472
|
+
} |trie then
|
|
473
|
+
} .then,
|
|
474
|
+
{
|
|
475
|
+
.t .prefix prefix,
|
|
476
|
+
.t .size size,
|
|
477
|
+
.t .val val,
|
|
478
|
+
{
|
|
479
|
+
.rem /cons .car char,
|
|
480
|
+
.rem /cons .cdr key,
|
|
481
|
+
.val val,
|
|
482
|
+
.t .dict dict
|
|
483
|
+
} |dict _put_replace /dict dict
|
|
484
|
+
} |trie
|
|
485
|
+
> |node,
|
|
486
|
+
/dict <
|
|
487
|
+
{
|
|
488
|
+
{ .char x, .dict /cons .car .char y } eq_char? if,
|
|
489
|
+
{
|
|
490
|
+
{
|
|
491
|
+
.char char,
|
|
492
|
+
{
|
|
493
|
+
.key key,
|
|
494
|
+
.val val,
|
|
495
|
+
.dict /cons .car .trie object
|
|
496
|
+
} |node _put_replace /node trie
|
|
497
|
+
} car,
|
|
498
|
+
.dict /cons .cdr cdr
|
|
499
|
+
} |cons then
|
|
500
|
+
} .then,
|
|
501
|
+
{
|
|
502
|
+
.dict /cons .car car,
|
|
503
|
+
{
|
|
504
|
+
.char char,
|
|
505
|
+
.key key,
|
|
506
|
+
.val val,
|
|
507
|
+
.dict /cons .cdr dict
|
|
508
|
+
} |dict _put_replace /dict cdr
|
|
509
|
+
} |cons
|
|
510
|
+
> |dict
|
|
511
|
+
>;
|
|
512
|
+
|
|
513
|
+
-- Insert a new key into radix object trie (splitting prefixes as needed)
|
|
514
|
+
_put_insert = ?<
|
|
515
|
+
{
|
|
516
|
+
< {} nil, { C car, S cdr } cons >=S key,
|
|
517
|
+
V val,
|
|
518
|
+
<
|
|
519
|
+
{} nil,
|
|
520
|
+
{
|
|
521
|
+
S prefix,
|
|
522
|
+
< {} _, B 0, B 1 >=B size,
|
|
523
|
+
< {} nil, V val > val,
|
|
524
|
+
< {} nil, { { C char, T trie } car, D cdr } cons >=D dict
|
|
525
|
+
} trie
|
|
526
|
+
>=T object
|
|
527
|
+
} node,
|
|
528
|
+
{ C char, S key, V val, D dict } dict
|
|
529
|
+
> <
|
|
530
|
+
/node <
|
|
531
|
+
{
|
|
532
|
+
.object /nil if,
|
|
533
|
+
{ .key prefix, 1 size, .val |val val, nil dict } |trie then
|
|
534
|
+
} .then,
|
|
535
|
+
{
|
|
536
|
+
{ .object /trie .prefix prefix, .key key } split_str_prefix sp,
|
|
537
|
+
.val val,
|
|
538
|
+
.object /trie t
|
|
539
|
+
} <
|
|
540
|
+
{
|
|
541
|
+
{ .sp .rem_prefix /nil p, .sp .rem_key /nil k } if,
|
|
542
|
+
{
|
|
543
|
+
.t .prefix prefix,
|
|
544
|
+
.t .size inc_nat size,
|
|
545
|
+
.val |val val,
|
|
546
|
+
.t .dict dict
|
|
547
|
+
} |trie then
|
|
548
|
+
} .then,
|
|
549
|
+
{
|
|
550
|
+
{ .sp .rem_prefix /nil p, .sp .rem_key /cons k } if,
|
|
551
|
+
{
|
|
552
|
+
.t .prefix prefix,
|
|
553
|
+
.t .size inc_nat size,
|
|
554
|
+
.t .val val,
|
|
555
|
+
{
|
|
556
|
+
.sp .rem_key /cons .car char,
|
|
557
|
+
.sp .rem_key /cons .cdr key,
|
|
558
|
+
.val val,
|
|
559
|
+
.t .dict dict
|
|
560
|
+
} |dict _put_insert /dict dict
|
|
561
|
+
} |trie then
|
|
562
|
+
} .then,
|
|
563
|
+
{
|
|
564
|
+
{ .sp .rem_prefix /cons p, .sp .rem_key /nil k } if,
|
|
565
|
+
{
|
|
566
|
+
.sp .common prefix,
|
|
567
|
+
.t .size inc_nat size,
|
|
568
|
+
.val |val val,
|
|
569
|
+
{
|
|
570
|
+
{
|
|
571
|
+
.sp .rem_prefix /cons .car char,
|
|
572
|
+
{
|
|
573
|
+
.sp .rem_prefix /cons .cdr prefix,
|
|
574
|
+
.t .size size,
|
|
575
|
+
.t .val val,
|
|
576
|
+
.t .dict dict
|
|
577
|
+
} |trie trie
|
|
578
|
+
} car,
|
|
579
|
+
nil cdr
|
|
580
|
+
} |cons dict
|
|
581
|
+
} |trie then
|
|
582
|
+
} .then,
|
|
583
|
+
{
|
|
584
|
+
.sp .common prefix,
|
|
585
|
+
.t .size inc_nat size,
|
|
586
|
+
nil val,
|
|
587
|
+
{
|
|
588
|
+
{
|
|
589
|
+
.sp .rem_prefix /cons .car char,
|
|
590
|
+
{
|
|
591
|
+
.sp .rem_prefix /cons .cdr prefix,
|
|
592
|
+
.t .size size,
|
|
593
|
+
.t .val val,
|
|
594
|
+
.t .dict dict
|
|
595
|
+
} |trie trie
|
|
596
|
+
} car,
|
|
597
|
+
{
|
|
598
|
+
{
|
|
599
|
+
.sp .rem_key /cons .car char,
|
|
600
|
+
{
|
|
601
|
+
.sp .rem_key /cons .cdr prefix,
|
|
602
|
+
1 size,
|
|
603
|
+
.val |val val,
|
|
604
|
+
nil dict
|
|
605
|
+
} |trie trie
|
|
606
|
+
} car,
|
|
607
|
+
nil cdr
|
|
608
|
+
} |cons cdr
|
|
609
|
+
} |cons dict
|
|
610
|
+
} |trie
|
|
611
|
+
>
|
|
612
|
+
> |node,
|
|
613
|
+
/dict <
|
|
614
|
+
{
|
|
615
|
+
.dict /nil if,
|
|
616
|
+
{
|
|
617
|
+
{
|
|
618
|
+
.char char,
|
|
619
|
+
{ .key prefix, 1 size, .val |val val, nil dict } |trie trie
|
|
620
|
+
} car,
|
|
621
|
+
nil cdr
|
|
622
|
+
} |cons then
|
|
623
|
+
} .then,
|
|
624
|
+
{
|
|
625
|
+
{ .char x, .dict /cons .car .char y } eq_char? if,
|
|
626
|
+
{
|
|
627
|
+
{
|
|
628
|
+
.char char,
|
|
629
|
+
{
|
|
630
|
+
.key key,
|
|
631
|
+
.val val,
|
|
632
|
+
.dict /cons .car .trie object
|
|
633
|
+
} |node _put_insert /node trie
|
|
634
|
+
} car,
|
|
635
|
+
.dict /cons .cdr cdr
|
|
636
|
+
} |cons then
|
|
637
|
+
} .then,
|
|
638
|
+
{
|
|
639
|
+
.dict /cons .car car,
|
|
640
|
+
{
|
|
641
|
+
.char char,
|
|
642
|
+
.key key,
|
|
643
|
+
.val val,
|
|
644
|
+
.dict /cons .cdr dict
|
|
645
|
+
} |dict _put_insert /dict cdr
|
|
646
|
+
} |cons
|
|
647
|
+
> |dict
|
|
648
|
+
>;
|
|
649
|
+
|
|
650
|
+
-- Insert or replace { key, val, object } -> object
|
|
651
|
+
put = ?{ K key, V val, O object } {
|
|
652
|
+
.key str_list? key,
|
|
653
|
+
.val json? val,
|
|
654
|
+
.object ptrie_obj? object
|
|
655
|
+
} <
|
|
656
|
+
{
|
|
657
|
+
{ .key key, .object object } has_key? if,
|
|
658
|
+
{ .key key, .val val, .object object } |node _put_replace /node then
|
|
659
|
+
} .then,
|
|
660
|
+
{ .key key, .val val, .object object } |node _put_insert /node
|
|
661
|
+
> ptrie_obj?;
|
|
662
|
+
|
|
663
|
+
|