@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
package/Examples/bnat.k CHANGED
@@ -1,6 +1,7 @@
1
1
  -- Standard binary encoding of natural numbers
2
2
 
3
- bnat? = ?< {} _, bnat? 0, bnat? 1 > = bnat?;
3
+ bnat[] = < {} _, B 0, B 1 > = B;
4
+ bnat? = ? bnat[];
4
5
 
5
6
  _ = {}|_;
6
7
  _1 = |1;
@@ -23,7 +24,7 @@ remove_leading_zeros = < /0 remove_leading_zeros, () >;
23
24
  reverse = {() x, _ result} _reverse;
24
25
 
25
26
  _reverse =
26
- ?{ <X 0, X 1, {} _>=X x, ... }
27
+ ?{ bnat[] = X x, ... }
27
28
  <
28
29
  {.x/_ if, .result then} .then,
29
30
  {.x/0 x, .result _0 result} _reverse,
@@ -52,7 +53,7 @@ plus =
52
53
 
53
54
  _plus =
54
55
  -- least significant bit first addition with carry
55
- ?{ <X 0, X 1, {} _>=X x, ... }
56
+ ?{ bnat[] = X x, ... }
56
57
  <
57
58
  {.x/_ if1, .y/_ if2, <.c/0 bnat_0, bnat_1> then} .then,
58
59
  {.x/_ if1, .c/0 if2, .y then} .then,
@@ -88,7 +89,7 @@ minus =
88
89
 
89
90
  _minus =
90
91
  -- least significat bit first substraction with carry
91
- ?{ <X 0, X 1, {} _>=X x, <Y 0, Y 1, {} _>=Y y, ... }
92
+ ?{ bnat[] = X x, bnat[] = Y y, ... }
92
93
  <
93
94
  {.x x, .y/_ y, .c/0 if} .x,
94
95
  {.x/1 x, .y/_ y, .c/1 if} .x _0,
@@ -116,10 +117,10 @@ times =
116
117
  ;
117
118
 
118
119
  _times =
119
- ?{ <Y 0, Y 1, {} _>=Y y, ... }
120
+ ?{ bnat[] = Y y, ... }
120
121
  <
121
122
  { .y/_ if, .result then } .then,
122
- { .result _0 result, ._x _x, .y/0 y } _times,
123
+ { .result _0 result, ._x _x, .y/0 y } _times,
123
124
  { { ._x x, .result _0 y, c0 c } _plus result, ._x _x, .y/1 y } _times
124
125
  >
125
126
  ;
@@ -149,7 +150,7 @@ align =
149
150
  ;
150
151
 
151
152
  _align =
152
- ?{ <X 0, X 1, {} _>=X _x, <Y 0, Y 1, {} _>=Y _y, ... }
153
+ ?{ bnat[] = X _x, bnat[] = Y _y, ... }
153
154
  <
154
155
  {._x/_ if1, ._y/_ if2, {.x x, .y y} then} .then,
155
156
  {._x </0, /_ _> _x, ._y </0, /_ _> _y, .x _0 x, .y _0 y} _align,
@@ -166,7 +167,7 @@ gt = {} |gt;
166
167
 
167
168
  compare = align _compare;
168
169
  _compare =
169
- ?{ <X 0, X 1, {} _>=X x, <Y 0, Y 1, {} _>=Y y, ... }
170
+ ?{ bnat[] = X x, bnat[] = Y y, ... }
170
171
  <
171
172
  {.x/_ if1, .y/_ if2 } eq,
172
173
  {.x/0 x, .y/0 y} _compare,
@@ -201,7 +202,11 @@ log2_floor =
201
202
  _log2_floor =
202
203
  <
203
204
  {{.step x, .x y} gt? if, .log then} .then,
204
- {.x x, {.step x, bnat_0 y} gt? .x append_0 step, .log inc log} _log2_floor
205
+ {
206
+ .x x,
207
+ {.step x, bnat_0 y} gt? .x append_0 step,
208
+ .log inc log
209
+ } _log2_floor
205
210
  >
206
211
  ;
207
212
 
@@ -260,7 +265,11 @@ pow =
260
265
  <
261
266
  .exponent zero? bnat_1,
262
267
  {.base base, .exponent half half}
263
- {.base base, .half.rem extra, {.base base, .half.div exponent} pow {()x,()y} times pow}
268
+ {
269
+ .base base,
270
+ .half.rem extra,
271
+ {.base base, .half.div exponent} pow {()x, ()y} times pow
272
+ }
264
273
  <
265
274
  {.extra zero? if, .pow then} .then,
266
275
  {.base x, .pow y} times
@@ -281,7 +290,8 @@ _sqrt =
281
290
  { () aux, {.input.x x, .middle y} div .div middle }
282
291
  {
283
292
  .aux.input.x x,
284
- { .aux.middle x, .middle y } < gt?, {.x y, .y x} > {.y min, .x max} range
293
+ { .aux.middle x, .middle y }
294
+ < gt?, {.x y, .y x} > {.y min, .x max} range
285
295
  } _sqrt
286
296
  >
287
297
  ;
package/Examples/buda.k CHANGED
@@ -1,44 +1,61 @@
1
- // we will use arithmetics.k
1
+ -- Examples/buda.k: Relational list algorithms using named patterns
2
+ -- Uses arbitrary-precision integers from Examples/arithmetics.k.
2
3
 
3
- nths = ?{$int n, LIST list}
4
+ bits[] = < {} _, B 0, B 1 > = B;
5
+ int[] = < bits[] "+", bits[] "-" >;
6
+
7
+ list[X] = < {} nil, { X car, Y cdr } cons > = Y;
8
+ list? = ? list[X];
9
+
10
+ nil = {} | nil list?;
11
+ cons = { .car car, .cdr cdr } | cons list?;
12
+ car = list? /cons .car;
13
+ cdr = list? /cons .cdr;
14
+
15
+ nths = ?{ int[] n, list[X] list }
4
16
  <
5
- {.n pos? dec n, .list cdr list } nths,
6
- {.n zero_int? if, .list list? car then} .then
17
+ { .n pos? dec n, .list cdr list } nths,
18
+ { .n zero_int? if, .list car then } .then
7
19
  >;
8
20
 
9
- reverse = ? LIST list?
10
- {nil ? LIST reversed, () list } _reverse;
21
+ reverse = ? list[X]
22
+ { nil reversed, () list } _reverse;
11
23
 
12
- _reverse = ?{ LIST reversed, LIST list}
24
+ _reverse = ?{ list[X] reversed, list[X] list }
13
25
  <
14
- {{.list car car, .reversed cdr} cons reversed, .list cdr list } _reverse,
26
+ {
27
+ { .list car car, .reversed cdr } cons reversed,
28
+ .list cdr list
29
+ } _reverse,
15
30
  .reversed
16
31
  >
17
32
  ;
18
33
 
19
- split = ? LIST
20
- { nil ? LIST odd, nil ? LIST even, reverse list } _split
34
+ split = ? list[X]
35
+ { nil odd, nil even, reverse list } _split
21
36
  ;
22
37
 
23
- _split = ? { LIST odd, LIST even, LIST list }
38
+ _split = ?{ list[X] odd, list[X] even, list[X] list }
24
39
  <
25
40
  {
26
- {.list car car, .odd cdr} cons odd,
27
- .even even,
28
- .list cdr list
41
+ { .list car car, .odd cdr } cons odd,
42
+ .even even,
43
+ .list cdr list
29
44
  } split_,
30
45
 
31
- {.odd odd, .even even}
46
+ { .odd odd, .even even }
32
47
  >
33
48
  ;
34
49
 
35
- split_ = ? { LIST odd, LIST even, LIST list }
50
+ split_ = ?{ list[X] odd, list[X] even, list[X] list }
36
51
  <
37
52
  {
38
- .odd odd,
39
- {.list car car, .even cdr} cons even,
40
- .list cdr list
53
+ .odd odd,
54
+ { .list car car, .even cdr } cons even,
55
+ .list cdr list
41
56
  } _split,
42
- {.odd odd, .even even}
57
+ { .odd odd, .even even }
43
58
  >
44
59
  ;
60
+
61
+ ()
package/Examples/byte.k CHANGED
@@ -11,7 +11,9 @@ map = <
11
11
  _
12
12
  > | ascii;
13
13
 
14
- filter = ?< {} nil, { (...) car, S cdr } cons > = S <
14
+ list[X] = < {} nil, { X car, Y cdr } cons > = Y;
15
+
16
+ filter = ? list[(...)] <
15
17
  /cons {.car map car, .cdr filter cdr} | cons,
16
18
  ()
17
19
  >;
package/Examples/code.k CHANGED
@@ -1,44 +1,43 @@
1
- $ code = < fields product, fields union, chars ref >;
2
- $ fields = < {} nil, { chars car, fields cdr } cons >;
3
- $ chars = <
4
- chars" ", chars"!", chars'"', chars"#", chars"$", chars"%", chars"&", chars"'",
5
- chars"(", chars")", chars"*", chars"+", chars",", chars"-", chars".", chars"/",
6
- chars"0", chars"1", chars"2", chars"3", chars"4", chars"5", chars"6", chars"7",
7
- chars"8", chars"9", chars":", chars";", chars"<", chars"=", chars">", chars"?",
8
- chars"@", chars"A", chars"B", chars"C", chars"D", chars"E", chars"F", chars"G",
9
- chars"H", chars"I", chars"J", chars"K", chars"L", chars"M", chars"N", chars"O",
10
- chars"P", chars"Q", chars"R", chars"S", chars"T", chars"U", chars"V", chars"W",
11
- chars"X", chars"Y", chars"Z", chars"[", chars"\\", chars"]", chars"^", chars"_",
12
- chars"`", chars"a", chars"b", chars"c", chars"d", chars"e", chars"f", chars"g",
13
- chars"h", chars"i", chars"j", chars"k", chars"l", chars"m", chars"n", chars"o",
14
- chars"p", chars"q", chars"r", chars"s", chars"t", chars"u", chars"v", chars"w",
15
- chars"x", chars"y", chars"z", chars"{", chars"|", chars"}", chars"~",
16
- {} end
17
- >;
18
-
19
- $ char = <
20
- {}" ", {}"!", {}'"', {}"#", {}"$", {}"%", {}"&", {}"'",
21
- {}"(", {}")", {}"*", {}"+", {}",", {}"-", {}".", {}"/",
22
- {}"0", {}"1", {}"2", {}"3", {}"4", {}"5", {}"6", {}"7",
23
- {}"8", {}"9", {}":", {}";", {}"<", {}"=", {}">", {}"?",
24
- {}"@", {}"A", {}"B", {}"C", {}"D", {}"E", {}"F", {}"G",
25
- {}"H", {}"I", {}"J", {}"K", {}"L", {}"M", {}"N", {}"O",
26
- {}"P", {}"Q", {}"R", {}"S", {}"T", {}"U", {}"V", {}"W",
27
- {}"X", {}"Y", {}"Z", {}"[", {}"\\", {}"]", {}"^", {}"_",
28
- {}"`", {}"a", {}"b", {}"c", {}"d", {}"e", {}"f", {}"g",
29
- {}"h", {}"i", {}"j", {}"k", {}"l", {}"m", {}"n", {}"o",
30
- {}"p", {}"q", {}"r", {}"s", {}"t", {}"u", {}"v", {}"w",
31
- {}"x", {}"y", {}"z", {}"{", {}"|", {}"}", {}"~"
32
- >;
1
+ -- Examples/code.k: Pattern representation and encoding
33
2
 
3
+ chars[] = <
4
+ C " ", C "!", C '"', C "#", C "$", C "%", C "&", C "'",
5
+ C "(", C ")", C "*", C "+", C ",", C "-", C ".", C "/",
6
+ C "0", C "1", C "2", C "3", C "4", C "5", C "6", C "7",
7
+ C "8", C "9", C ":", C ";", C "<", C "=", C ">", C "?",
8
+ C "@", C "A", C "B", C "C", C "D", C "E", C "F", C "G",
9
+ C "H", C "I", C "J", C "K", C "L", C "M", C "N", C "O",
10
+ C "P", C "Q", C "R", C "S", C "T", C "U", C "V", C "W",
11
+ C "X", C "Y", C "Z", C "[", C "\\", C "]", C "^", C "_",
12
+ C "`", C "a", C "b", C "c", C "d", C "e", C "f", C "g",
13
+ C "h", C "i", C "j", C "k", C "l", C "m", C "n", C "o",
14
+ C "p", C "q", C "r", C "s", C "t", C "u", C "v", C "w",
15
+ C "x", C "y", C "z", C "{", C "|", C "}", C "~",
16
+ {} end
17
+ > = C;
34
18
 
35
- nil = {}|nil;
36
- _ = {}|end $chars;
19
+ char[] = <
20
+ {} " ", {} "!", {} '"', {} "#", {} "$", {} "%", {} "&", {} "'",
21
+ {} "(", {} ")", {} "*", {} "+", {} ",", {} "-", {} ".", {} "/",
22
+ {} "0", {} "1", {} "2", {} "3", {} "4", {} "5", {} "6", {} "7",
23
+ {} "8", {} "9", {} ":", {} ";", {} "<", {} "=", {} ">", {} "?",
24
+ {} "@", {} "A", {} "B", {} "C", {} "D", {} "E", {} "F", {} "G",
25
+ {} "H", {} "I", {} "J", {} "K", {} "L", {} "M", {} "N", {} "O",
26
+ {} "P", {} "Q", {} "R", {} "S", {} "T", {} "U", {} "V", {} "W",
27
+ {} "X", {} "Y", {} "Z", {} "[", {} "\\", {} "]", {} "^", {} "_",
28
+ {} "`", {} "a", {} "b", {} "c", {} "d", {} "e", {} "f", {} "g",
29
+ {} "h", {} "i", {} "j", {} "k", {} "l", {} "m", {} "n", {} "o",
30
+ {} "p", {} "q", {} "r", {} "s", {} "t", {} "u", {} "v", {} "w",
31
+ {} "x", {} "y", {} "z", {} "{", {} "|", {} "}", {} "~"
32
+ >;
37
33
 
38
- KL = _|L|K $chars;
39
-
40
- bool =
41
- { KL car, { KL car, nil cdr } | cons cdr } | cons | union
42
- $code;
34
+ fields[] = < {} nil, { chars[] car, F cdr } cons > = F;
43
35
 
36
+ code[] = < fields[] product, fields[] union, chars[] ref >;
37
+
38
+ nil = {} | nil;
39
+ _ = ({} | end) ? chars[];
40
+ KL = (_ | L | K) ? chars[];
41
+
42
+ bool = { KL car, { KL car, nil cdr } | cons cdr } | cons | union ? code[];
44
43
  bool
@@ -0,0 +1,414 @@
1
+ -- Examples/djson-btrie.k: Binary Bit-Trie JSON schema and helpers
2
+ -- Works with codecs/djson-btrie.mjs and codecs/utf8.mjs.
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
+ opt[V] = < {} nil, V val >;
88
+
89
+ btrie[V] = <
90
+ {} nil,
91
+ {
92
+ opt[V] val,
93
+ T 0,
94
+ T 1
95
+ } trie
96
+ > = T;
97
+
98
+ djson_btrie[] = <
99
+ number[] number,
100
+ string[] string,
101
+ bool[] bool,
102
+ {} null,
103
+ btrie[J] list,
104
+ btrie[J] object
105
+ > = J;
106
+
107
+ json? = ? djson_btrie[];
108
+
109
+ ---------------------------------------------------------------
110
+ -- §2. Constructors and Projections
111
+ ---------------------------------------------------------------
112
+
113
+ bits? = ?< {} _, B 0, B 1 > = B;
114
+ str_list? = ?< {} nil, { C car, S cdr } cons > = S;
115
+ trie? = ? btrie[V];
116
+
117
+ 0b = {} | _;
118
+ 0 = 0b | 0;
119
+ 1 = 0b | 1;
120
+
121
+ nil = {} | nil;
122
+ null = {} | null json?;
123
+ true = {} | true | bool json?;
124
+ false = {} | false | bool json?;
125
+ number = | number json?;
126
+ string = | string json?;
127
+ bool = | bool json?;
128
+ list = | list json?;
129
+ object = | object json?;
130
+
131
+ ---------------------------------------------------------------
132
+ -- §3. Direct Binary Bit-Trie Traversal (Zero Equality Checks)
133
+ ---------------------------------------------------------------
134
+
135
+ -- Step one bit (0 or 1) in a binary trie
136
+ step_0 = /trie .0;
137
+ step_1 = /trie .1;
138
+
139
+ step_bit = <
140
+ { .b /0 if, .t step_0 then } .then,
141
+ { .b /1 if, .t step_1 then } .then
142
+ >;
143
+
144
+ -- Step N bits from MSB (.N-1) down to LSB (.0)
145
+ step_bits1 = { .x .0 b, .t t } step_bit;
146
+ step_bits2 = { .x x, { .x .1 b, .t t } step_bit t } step_bits1;
147
+ step_bits3 = { .x x, { .x .2 b, .t t } step_bit t } step_bits2;
148
+ step_bits4 = { .x x, { .x .3 b, .t t } step_bit t } step_bits3;
149
+ step_bits5 = { .x x, { .x .4 b, .t t } step_bit t } step_bits4;
150
+ step_bits6 = { .x x, { .x .5 b, .t t } step_bit t } step_bits5;
151
+ step_bits7 = { .x x, { .x .6 b, .t t } step_bit t } step_bits6;
152
+ step_bits8 = { .x x, { .x .7 b, .t t } step_bit t } step_bits7;
153
+ step_bits9 = { .x x, { .x .8 b, .t t } step_bit t } step_bits8;
154
+ step_bits10 = { .x x, { .x .9 b, .t t } step_bit t } step_bits9;
155
+ step_bits11 = { .x x, { .x .10 b, .t t } step_bit t } step_bits10;
156
+
157
+ step_bmp_common_hi = <
158
+ { .hi /h08_0F x, .t step_0 step_0 step_0 t } step_bits3,
159
+ { .hi /h10_7F x, .t step_0 step_0 step_1 t } step_bits7,
160
+ { .hi /h80_CF x, .t step_0 step_1 step_0 t } step_bits7,
161
+ { .hi /hD0_D7 x, .t step_0 step_1 step_1 t } step_bits3,
162
+ { .hi /hF9 if, .t step_1 step_0 step_0 then } .then,
163
+ { .hi /hFA_FB x, .t step_1 step_0 step_1 t } step_bits1,
164
+ { .hi /hFC_FD x, .t step_1 step_1 step_0 t } step_bits1,
165
+ { .hi /hFE_FF x, .t step_1 step_1 step_1 t } step_bits1
166
+ >;
167
+
168
+ step_bmp_priv_hi = <
169
+ { .hi /hE0_EF x, .t step_0 t } step_bits4,
170
+ { .hi /hF0_F7 x, .t step_1 step_0 t } step_bits3,
171
+ { .hi /hF8 if, .t step_1 step_1 then } .then
172
+ >;
173
+
174
+ step_plane2_16 = <
175
+ { .p /p02_03 x, .t step_0 step_0 t } step_bits1,
176
+ { .p /p04_07 x, .t step_0 step_1 t } step_bits2,
177
+ { .p /p08_0F x, .t step_1 step_0 t } step_bits3,
178
+ { .p /p10 if, .t step_1 step_1 then } .then
179
+ >;
180
+
181
+ -- Advance trie by one Unicode character: { char, t } -> t
182
+ step_char = <
183
+ { .char /ascii x, .t step_0 t } step_bits7,
184
+ { .char /plane0 x, .t step_1 step_0 t } step_bits11,
185
+ {
186
+ .char /bmp_common .lo x,
187
+ { .char /bmp_common .hi hi, .t step_1 step_1 step_0 t }
188
+ step_bmp_common_hi t
189
+ } step_bits8,
190
+ {
191
+ .char /bmp_private_use .lo x,
192
+ { .char /bmp_private_use .hi hi, .t step_1 step_1 step_1 step_0 t }
193
+ step_bmp_priv_hi t
194
+ } step_bits8,
195
+ {
196
+ .char /supplementary_plane1 .lo x,
197
+ {
198
+ .char /supplementary_plane1 .mid x,
199
+ .t step_1 step_1 step_1 step_1 step_0 t
200
+ } step_bits8 t
201
+ } step_bits8,
202
+ {
203
+ .char /supplementary_planes2_16 .lo x,
204
+ {
205
+ .char /supplementary_planes2_16 .mid x,
206
+ {
207
+ .char /supplementary_planes2_16 .plane p,
208
+ .t step_1 step_1 step_1 step_1 step_1 t
209
+ } step_plane2_16 t
210
+ } step_bits8 t
211
+ } step_bits8
212
+ >;
213
+
214
+ ---------------------------------------------------------------
215
+ -- §4. Object & List Lookup Relations (dot, nth, has_key?)
216
+ ---------------------------------------------------------------
217
+
218
+ -- Lookup string key in object trie: { key, object } -> value
219
+ dot = ?{ K key, T object } { .key str_list? key, .object trie? t } <
220
+ { .key /nil if, .t /trie .val /val then } .then,
221
+ {
222
+ .key /cons .cdr key,
223
+ { .key /cons .car char, .t t } step_char object
224
+ } dot
225
+ >;
226
+
227
+ -- Filter: succeeds as identity if object contains key
228
+ has_key? = ?{ K key, O object } { dot if, () then } .then;
229
+
230
+ -- Lookup bits? index in list trie: { index, list } -> value
231
+ nth = ?{ K index, T list } { .index bits? index, .list trie? t } <
232
+ { .index /_ if, .t /trie .val /val then } .then,
233
+ { .index /0 index, .t /trie .0 list } nth,
234
+ { .index /1 index, .t /trie .1 list } nth
235
+ >;
236
+
237
+ ---------------------------------------------------------------
238
+ -- §5. Trie Update & Removal (put, remove, put_nth, remove_nth)
239
+ ---------------------------------------------------------------
240
+
241
+ push_bit = ?{ < {} 0, {} 1 > b, < {} _, BITS 0, BITS 1 >=BITS acc } <
242
+ { .b /0 if, .acc |0 then } .then,
243
+ { .b /1 if, .acc |1 then } .then
244
+ > bits?;
245
+
246
+ push_bits1 = { .x .0 b, .acc acc } push_bit;
247
+ push_bits2 = { .x .1 b, { .x x, .acc acc } push_bits1 acc } push_bit;
248
+ push_bits3 = { .x .2 b, { .x x, .acc acc } push_bits2 acc } push_bit;
249
+ push_bits4 = { .x .3 b, { .x x, .acc acc } push_bits3 acc } push_bit;
250
+ push_bits5 = { .x .4 b, { .x x, .acc acc } push_bits4 acc } push_bit;
251
+ push_bits6 = { .x .5 b, { .x x, .acc acc } push_bits5 acc } push_bit;
252
+ push_bits7 = { .x .6 b, { .x x, .acc acc } push_bits6 acc } push_bit;
253
+ push_bits8 = { .x .7 b, { .x x, .acc acc } push_bits7 acc } push_bit;
254
+ push_bits9 = { .x .8 b, { .x x, .acc acc } push_bits8 acc } push_bit;
255
+ push_bits10 = { .x .9 b, { .x x, .acc acc } push_bits9 acc } push_bit;
256
+ push_bits11 = { .x .10 b, { .x x, .acc acc } push_bits10 acc } push_bit;
257
+
258
+ push_bmp_common_hi = <
259
+ { .hi /h08_0F x, .acc acc } push_bits3 |0 |0 |0,
260
+ { .hi /h10_7F x, .acc acc } push_bits7 |1 |0 |0,
261
+ { .hi /h80_CF x, .acc acc } push_bits7 |0 |1 |0,
262
+ { .hi /hD0_D7 x, .acc acc } push_bits3 |1 |1 |0,
263
+ { .hi /hF9 if, .acc |0 |0 |1 then } .then,
264
+ { .hi /hFA_FB x, .acc acc } push_bits1 |1 |0 |1,
265
+ { .hi /hFC_FD x, .acc acc } push_bits1 |0 |1 |1,
266
+ { .hi /hFE_FF x, .acc acc } push_bits1 |1 |1 |1
267
+ > bits?;
268
+
269
+ push_bmp_priv_hi = <
270
+ { .hi /hE0_EF x, .acc acc } push_bits4 |0,
271
+ { .hi /hF0_F7 x, .acc acc } push_bits3 |0 |1,
272
+ { .hi /hF8 if, .acc |1 |1 then } .then
273
+ > bits?;
274
+
275
+ push_plane2_16 = <
276
+ { .p /p02_03 x, .acc acc } push_bits1 |0 |0,
277
+ { .p /p04_07 x, .acc acc } push_bits2 |1 |0,
278
+ { .p /p08_0F x, .acc acc } push_bits3 |0 |1,
279
+ { .p /p10 if, .acc |1 |1 then } .then
280
+ > bits?;
281
+
282
+ prepend_char_bits = <
283
+ { .char /ascii x, .acc acc } push_bits7 |0,
284
+ { .char /plane0 x, .acc acc } push_bits11 |0 |1,
285
+ {
286
+ .char /bmp_common .hi hi,
287
+ { .char /bmp_common .lo x, .acc acc } push_bits8 acc
288
+ } push_bmp_common_hi |0 |1 |1,
289
+ {
290
+ .char /bmp_private_use .hi hi,
291
+ { .char /bmp_private_use .lo x, .acc acc } push_bits8 acc
292
+ } push_bmp_priv_hi |0 |1 |1 |1,
293
+ {
294
+ .char /supplementary_plane1 .mid x,
295
+ { .char /supplementary_plane1 .lo x, .acc acc } push_bits8 acc
296
+ } push_bits8 |0 |1 |1 |1 |1,
297
+ {
298
+ .char /supplementary_planes2_16 .plane p,
299
+ {
300
+ .char /supplementary_planes2_16 .mid x,
301
+ { .char /supplementary_planes2_16 .lo x, .acc acc } push_bits8 acc
302
+ } push_bits8 acc
303
+ } push_plane2_16 |1 |1 |1 |1 |1
304
+ > bits?;
305
+
306
+ str_to_bits = str_list? <
307
+ /nil 0b,
308
+ /cons { .car char, .cdr str_to_bits acc } prepend_char_bits
309
+ > bits?;
310
+
311
+ ensure_trie = trie? < /nil { nil val, nil 0, nil 1 }, /trie () >;
312
+
313
+ -- Insert or replace { index, val, list } -> list
314
+ put_nth = ?{ K index, V val, T list } {
315
+ .index bits? index,
316
+ .val val,
317
+ .list trie? ensure_trie t
318
+ } <
319
+ {
320
+ .index /_ if,
321
+ { .val |val val, .t .0 0, .t .1 1 } |trie then
322
+ } .then,
323
+ {
324
+ .index /0 if,
325
+ {
326
+ .t .val val,
327
+ { .index /0 index, .val val, .t .0 list } put_nth 0,
328
+ .t .1 1
329
+ } |trie then
330
+ } .then,
331
+ {
332
+ .index /1 if,
333
+ {
334
+ .t .val val,
335
+ .t .0 0,
336
+ { .index /1 index, .val val, .t .1 list } put_nth 1
337
+ } |trie then
338
+ } .then
339
+ > trie?;
340
+
341
+ -- Remove entry at bits? index from trie: { index, list } -> list
342
+ remove_nth = ?{ K index, T list } { .index bits? index, .list trie? t } <
343
+ { .t /nil if, nil then } .then,
344
+ {
345
+ .index /_ if,
346
+ { nil val, .t /trie .0 0, .t /trie .1 1 } |trie then
347
+ } .then,
348
+ {
349
+ .index /0 if,
350
+ {
351
+ .t /trie .val val,
352
+ { .index /0 index, .t /trie .0 list } remove_nth 0,
353
+ .t /trie .1 1
354
+ } |trie then
355
+ } .then,
356
+ {
357
+ .index /1 if,
358
+ {
359
+ .t /trie .val val,
360
+ .t /trie .0 0,
361
+ { .index /1 index, .t /trie .1 list } remove_nth 1
362
+ } |trie then
363
+ } .then
364
+ > trie?;
365
+
366
+ -- Insert or replace { key, val, object } -> object
367
+ put = ?{ K key, V val, O object } {
368
+ .key str_to_bits index,
369
+ .val val,
370
+ .object list
371
+ } put_nth;
372
+
373
+ -- Remove key from object trie: { key, object } -> object
374
+ remove = ?{ K key, O object } {
375
+ .key str_to_bits index,
376
+ .object list
377
+ } remove_nth;
378
+
379
+ -- Count elements in list or object trie: trie -> bits?
380
+ _inv = ?{ < {} _, B 0, B 1 >=B x, B r } <
381
+ { .x /_ if, .r then } .then,
382
+ { .x /0 x, .r |0 r } _inv,
383
+ { .x /1 x, .r |1 r } _inv
384
+ > bits?;
385
+ _inc = ?{ < {} _, B 0, B 1 >=B x, B y } <
386
+ { .x /_ if, .y |1 then } .then,
387
+ { .x /0 x, .y |1 r } _inv,
388
+ { .x /1 x, .y |0 y } _inc
389
+ > bits?;
390
+ inc_nat = { { () x, 0b r } _inv x, 0b y } _inc;
391
+
392
+ _trie_size = ?{
393
+ < {} nil, { < {} nil, V val > val, T 0, T 1 } trie >=T t,
394
+ < {} _, B 0, B 1 >=B acc
395
+ } <
396
+ { .t /nil if, .acc then } .then,
397
+ {
398
+ .t /trie .val /nil if,
399
+ {
400
+ .t /trie .1 t,
401
+ { .t /trie .0 t, .acc acc } _trie_size acc
402
+ } _trie_size then
403
+ } .then,
404
+ {
405
+ .t /trie .val /val if,
406
+ {
407
+ .t /trie .1 t,
408
+ { .t /trie .0 t, .acc inc_nat acc } _trie_size acc
409
+ } _trie_size then
410
+ } .then
411
+ > bits?;
412
+
413
+ list_size = { trie? t, 0 acc } _trie_size;
414
+ obj_size = { trie? t, 0 acc } _trie_size;