@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,317 @@
1
+ # Named Patterns and Parameterized Type Schemes in k
2
+
3
+ ## 1. Overview and Motivation
4
+
5
+ Following commit `a4eec258`, type code expressions (`$ code`) were
6
+ removed in favor of pure filter relations (`? <...> = Self;`).
7
+ While this eliminated the redundant dual syntax of static codes versus
8
+ runtime filters, practical development (notably in `djson` variants and
9
+ standard libraries) revealed a major drawback: **loss of pattern
10
+ composition and reuse**.
11
+
12
+ Without named, reusable patterns:
13
+ - Monolithic structures (such as UTF-8 decoding and IEEE-754 bit
14
+ partitions) had to be copy-pasted inline across dozens of files.
15
+ - Common algebraic shapes like linked lists, pairs, dictionaries, and
16
+ tries could not be defined generically; each variant had to inline
17
+ its own structural definition.
18
+ - Filter relations (`rel?(x)`) perform runtime filtering but cannot be
19
+ used directly as structural type shapes inside other pattern
20
+ definitions.
21
+
22
+ This document establishes the specification for **Named Patterns**:
23
+ parameterized, compositional regular tree grammar templates that re-enable
24
+ reusable type definitions with zero syntax bloat, guaranteed
25
+ termination, and full integration with k's graph-based type system.
26
+
27
+ ---
28
+
29
+ ## 2. The Core Model: Patterns as Open Directed Graphs
30
+
31
+ In k, all values, patterns, and type codes are directed graphs
32
+ representing regular tree languages. A named pattern definition:
33
+
34
+ ```k
35
+ name[ P1, P2, ... Pn ] = pattern_graph;
36
+ ```
37
+
38
+ defines an **open directed graph** with an explicit boundary interface.
39
+
40
+ ### 2.1 The Three Classes of Variables
41
+
42
+ Within a pattern definition, every variable identifier falls into one
43
+ of three orthogonal categories:
44
+
45
+ 1. **External Ports ($\forall$ / Parameters)**:
46
+ Any variable listed in the header brackets `[ P1, ... Pn ]` is an
47
+ **external port**. These represent open inputs to be supplied by the
48
+ caller upon instantiation.
49
+
50
+ 2. **Internal Variables ($\exists$ / Unification Nodes)**:
51
+ Any variable appearing on the right-hand side that is **not** listed
52
+ in `[ P1, ... Pn ]` is an **internal variable**.
53
+ - If an internal variable appears in multiple locations, it asserts
54
+ **structural type equality (unification)** between those sites.
55
+ - Internal variables are existentially quantified ($\exists$) and
56
+ scoped strictly to the pattern definition.
57
+
58
+ 3. **Cycle Knots ($\mu$ / Fixpoints)**:
59
+ Any variable bound via `= KnotName` is an internal recursive knot.
60
+ It creates a back-edge in the directed graph, closing a loop.
61
+ Its scope is purely local: callers cannot see or reference it.
62
+
63
+ ### 2.2 Knot and Variable Hiding ($\alpha$-Equivalence)
64
+
65
+ In:
66
+
67
+ ```k
68
+ list[X] = < {}nil, { X car, Y cdr } cons > = Y;
69
+ ```
70
+
71
+ - `X` is listed in `list[X]` $\implies$ **External Port**.
72
+ - `Y` is bound by `= Y` and omitted from `list[X]` $\implies$
73
+ **Internal Knot**.
74
+
75
+ `Y` is strictly encapsulated. It can be $\alpha$-renamed to any
76
+ internal node ID (`#knot_0`) without changing the pattern's external
77
+ interface or behavior. Callers only interact with the port `X`.
78
+
79
+ ---
80
+
81
+ ## 3. The Four-Bracket Symmetry of k
82
+
83
+ Named patterns introduce square brackets `[...]` into k's grammar.
84
+ This completes an orthogonal four-bracket architecture where each
85
+ bracket style has a dedicated, non-overlapping semantic domain:
86
+
87
+ | Bracket Pair | Semantic Domain | Concrete Purpose |
88
+ | :--- | :--- | :--- |
89
+ | **`{ ... }`** | **Products** | Records, tuples, structs |
90
+ | **`< ... >`** | **Unions** | Variants, sums, choices |
91
+ | **`( ... )`** | **Relations** | Composition, grouping, identity |
92
+ | **`[ ... ]`** | **Patterns** | Type templates, instantiations |
93
+
94
+ No dollar prefix (`$`) is needed anywhere in the language.
95
+
96
+ ### 3.1 Unambiguous Lexical Distinction
97
+
98
+ Because all pattern references carry `[...]`, the lexical distinction
99
+ between variables and patterns is 100% deterministic:
100
+
101
+ - **Identifier without `[...]`** (`X`, `T`, `car`, `Y`):
102
+ - In label position: field or variant tag (`car`, `cdr`, `nil`).
103
+ - In pattern position: variable node (`X`, `T`, knot `Y`).
104
+ - **Identifier with `[...]`** (`bit[]`, `list[T]`, `pair[A, B]`):
105
+ - Always a pattern template lookup or instantiation.
106
+
107
+ ---
108
+
109
+ ## 4. Internal Variables as Unification Knots
110
+
111
+ A critical insight of k's graph-based model is that unparameterized
112
+ patterns can contain internal variables to express equality
113
+ constraints across fields:
114
+
115
+ ```k
116
+ byte[] = { bit 0, bit 1, ... };
117
+ ```
118
+
119
+ Here:
120
+ - `bit` does not have `[]`, so it is a **variable**, not a pattern.
121
+ - `bit` is not in the parameter list `byte[]`, so it is an **internal
122
+ node**.
123
+ - Because `bit` appears at both field `0` and field `1`, it asserts
124
+ that **field `0` and field `1` must share the exact same type**,
125
+ without constraining what that type must be.
126
+
127
+ ### 4.1 Comparison of Pattern Declarations
128
+
129
+ ```k
130
+ -- 1. Homogeneous pair of two fields of the SAME arbitrary type:
131
+ same_pair[] = { T first, T second };
132
+
133
+ -- 2. Heterogeneous pair parameterized by the caller:
134
+ pair[A, B] = { A first, B second };
135
+
136
+ -- 3. Pair of concrete bits:
137
+ bit_pair[] = { bit[] first, bit[] second };
138
+
139
+ -- 4. Instantiation enforcing equality via shared variable:
140
+ diagonal_pair[] = pair[T, T];
141
+ ```
142
+
143
+ In `diagonal_pair[] = pair[T, T]`:
144
+ - `T` is an internal variable.
145
+ - Instantiating `pair` with `T` for both arguments unifies both ports,
146
+ producing a closed pattern requiring equal elements.
147
+
148
+ ---
149
+
150
+ ## 5. Instantiation Semantics (Option B)
151
+
152
+ Arguments inside `[...]` may be either **variables** or **patterns**:
153
+
154
+ 1. **Passing a Variable (`T`, `X`)**:
155
+ Connects the template's input port directly to that existing node in
156
+ the pattern graph, enabling node sharing, unification, and
157
+ polymorphic relations.
158
+
159
+ 2. **Passing an Inline Pattern (`int[]`, `pair[K, V]`, `<{}0, {}1>`)**:
160
+ Creates an anonymous node representing the pattern and connects the
161
+ input port to it.
162
+
163
+ ### 5.1 Equivalence to Variable Binding
164
+
165
+ Passing an inline pattern `P` is semantically equivalent to introducing
166
+ a fresh internal node variable:
167
+
168
+ $$name[P] \;\;\Longleftrightarrow\;\; (P = \_anon) \; name[\_anon]$$
169
+
170
+ Both forms construct isomorphic graph structures that minimize to the
171
+ exact same canonical DFA representation in `codes.mjs`.
172
+
173
+ ### 5.2 Single-Step Finite Graph Substitution
174
+
175
+ Because recursive cycles are closed internally via knots (`= Y`),
176
+ instantiating a template does **not** require recursive unrolling or
177
+ fixpoint searching.
178
+
179
+ Instantiation is a single-step graph substitution:
180
+ 1. Copy the template's graph structure (fresh private IDs for internal
181
+ knots).
182
+ 2. Substitute the caller's arguments into the designated open port nodes.
183
+ 3. Minimize via Hopcroft/Moore DFA partition refinement in `codes.mjs`.
184
+
185
+ ---
186
+
187
+ ## 6. Safety Invariants and Termination
188
+
189
+ To guarantee decidability and termination:
190
+
191
+ 1. **Acyclic Template Dependency Rule**:
192
+ A pattern template `$ name[...]` cannot reference `name` in its own
193
+ definition.
194
+ - All recursion **must** be expressed through internal knots (`= Y`).
195
+ - Consequently, the template dependency graph is a Strictly Acyclic
196
+ Directed Graph (DAG).
197
+ - Non-regular polymorphic recursion (nested datatypes) is structurally
198
+ impossible, guaranteeing that every instantiated pattern is a
199
+ finite regular tree automaton.
200
+
201
+ 2. **Lexical Scope Independence**:
202
+ Internal variable names and knot names are strictly private to each
203
+ definition. Two patterns may both use knot name `Y` or variable `T`
204
+ without collision.
205
+
206
+ 3. **Canonical Confluence**:
207
+ In k, type codes are structural, not nominal. Any two instantiations
208
+ that yield isomorphic regular tree automata produce identical
209
+ canonical hashes and wire encoders.
210
+
211
+ ---
212
+
213
+ ## 7. Concrete Library Examples
214
+
215
+ ### 7.1 Core Data Types
216
+
217
+ ```k
218
+ -- Canonical bit and bit-path numbers:
219
+ bit[] = < {}0, {}1 >;
220
+ bits[] = < {} _, B 0, B 1 > = B;
221
+
222
+ -- Byte as an 8-bit octet product:
223
+ byte[] = {
224
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3,
225
+ bit[] 4, bit[] 5, bit[] 6, bit[] 7
226
+ };
227
+
228
+ -- 7-bit ASCII code points:
229
+ ascii[] = {
230
+ bit[] 6, bit[] 5, bit[] 4, bit[] 3,
231
+ bit[] 2, bit[] 1, bit[] 0
232
+ };
233
+ ```
234
+
235
+ ### 7.2 Generic Data Structures
236
+
237
+ ```k
238
+ -- Generic pair:
239
+ pair[A, B] = { A fst, B snd };
240
+
241
+ -- Generic singly-linked list:
242
+ list[X] = < {}nil, { X car, Y cdr } cons > = Y;
243
+
244
+ -- Generic dictionary:
245
+ dict[K, V] = list[pair[K, V]];
246
+
247
+ -- Generic binary tree with internal knot T:
248
+ tree[X] = < {}nil, { X val, T left, T right } node > = T;
249
+ ```
250
+
251
+ ### 7.3 Usage in Relations
252
+
253
+ ```k
254
+ -- Type guard filter:
255
+ int? = ? int[];
256
+
257
+ -- Polymorphic list destructuring with type unification:
258
+ head = ? { X car, list[X] cdr } X;
259
+
260
+ -- Concrete typed list destructuring:
261
+ sum = ? { int[] = T car, list[T] cdr } ...;
262
+
263
+ -- Anonymous pattern matching:
264
+ validate_ints = ? list[int[]];
265
+ ```
266
+
267
+ ---
268
+
269
+ ## 8. Summary of Grammar Extensions
270
+
271
+ ### 8.1 Lexer Tokens
272
+
273
+ ```
274
+ "[" return 'LB';
275
+ "]" return 'RB';
276
+ ```
277
+
278
+ ### 8.2 Top-Level Definitions
279
+
280
+ ```
281
+ defs
282
+ : /* empty */
283
+ | defs name eq comp sc
284
+ | defs name lb pattern_params rb eq filter sc
285
+ ;
286
+
287
+ pattern_params
288
+ : /* empty */
289
+ | non_empty_pattern_params
290
+ ;
291
+
292
+ non_empty_pattern_params
293
+ : name
294
+ | non_empty_pattern_params comma name
295
+ ;
296
+ ```
297
+
298
+ ### 8.3 Pattern References and Instantiations
299
+
300
+ ```
301
+ filter_
302
+ : lp dots rp
303
+ | la labelled_filters ra
304
+ | lc labelled_filters rc
305
+ | name lb pattern_args rb
306
+ ;
307
+
308
+ pattern_args
309
+ : /* empty */
310
+ | non_empty_pattern_args
311
+ ;
312
+
313
+ non_empty_pattern_args
314
+ : filter
315
+ | non_empty_pattern_args comma filter
316
+ ;
317
+ ```
package/DOCS/PATTERNS.md CHANGED
@@ -1,13 +1,14 @@
1
1
  # Schemas and Pattern Graphs
2
2
 
3
- In `k`, an algebraic **schema** describes the shape of payload trees that may flow
4
- through a relation. In compiler artifacts and serialization, schemas are represented
5
- as property-list arrays of automata nodes. Schemas are used by:
3
+ In `k`, an algebraic **schema** describes the shape of payload trees
4
+ that may flow through a relation. In compiler artifacts and
5
+ serialization, schemas are represented as property-list arrays of
6
+ automata nodes. Schemas are used by:
6
7
 
7
8
  - the contract-derivation engine
8
9
  - the binary codec
9
10
  - runtime framed values `(schema, payload)`
10
- - filter expressions (`?schema`)
11
+ - filter expressions (`?schema` or `?name[...]`)
11
12
 
12
13
  ## Pattern Kinds
13
14
 
@@ -46,26 +47,68 @@ Example:
46
47
 
47
48
  This is not the wire format. It is the canonical readable export form.
48
49
 
49
- ## Filters and Type Names
50
+ ## Named Patterns and Templates
51
+
52
+ Named patterns define reusable, modular regular tree grammars using
53
+ square brackets `[...]`:
54
+
55
+ ```k
56
+ name[ P1, P2, ... Pn ] = filter;
57
+ ```
58
+
59
+ For 0-arity patterns (no parameters), empty brackets `[]` are used:
60
+
61
+ ```k
62
+ bit[] = < {} 0, {} 1 >;
63
+ bits[] = < {} _, B 0, B 1 > = B;
64
+ byte[] = {
65
+ bit[] 0, bit[] 1, bit[] 2, bit[] 3,
66
+ bit[] 4, bit[] 5, bit[] 6, bit[] 7
67
+ };
68
+ ```
69
+
70
+ Parameterized patterns declare external ports in the bracket list:
71
+
72
+ ```k
73
+ list[X] = < {} nil, { X car, Y cdr } cons > = Y;
74
+ pair[A, B] = { A first, B second };
75
+ ```
76
+
77
+ Callers instantiate a named pattern:
78
+ - As a standalone filter: `? list[X]` or `? bits[]`
79
+ - Within relation guards: `?{ nat[] = N x, ... }`
80
+ - As template arguments: `list[byte[]]` or `pair[A, B]`
81
+
82
+ Inside a definition, knot identifiers (`= Y`) close internal recursive
83
+ loops. Recursive loops are private and alpha-renamed during expansion.
84
+ Direct or mutual recursion among templates (`bits[]` calling `bits[]`)
85
+ is disallowed to ensure every template dependency graph is an acyclic
86
+ DAG, guaranteeing finite regular tree automaton compilation.
87
+
88
+ ## Filters and Terminal Positions
50
89
 
51
90
  A k script can describe a pattern through:
52
91
 
53
92
  - a relation in terminal position
54
93
  - a filter expression in terminal position
94
+ - a named pattern invocation (`? name[...]`)
55
95
 
56
96
  Examples:
57
97
 
58
98
  ```k
59
- bits? = ?< {} _, bits? 0, bits? 1 > = bits?;
60
- list? = ?< {} nil, { < {} _, B 0, B 1 >=B car, L cdr } cons > = L;
99
+ bits[] = < {} _, B 0, B 1 > = B;
100
+ list[X] = < {} nil, { X car, Y cdr } cons > = Y;
101
+ list? = ? list[bits[]];
61
102
  list?
62
103
  ```
63
104
 
105
+ Or anonymously:
106
+
64
107
  ```k
65
- ?< {} nil, { < {} _, B 0, B 1 >=B car, X cdr } cons > = X
108
+ ? list[bits[]]
66
109
  ```
67
110
 
68
- In both cases, the compiler derives a root pattern from `__main__`.
111
+ In all cases, the compiler derives a root pattern from `__main__`.
69
112
 
70
113
  ## Pattern Export Helper
71
114
 
@@ -86,13 +129,18 @@ It:
86
129
  Example:
87
130
 
88
131
  ```bash
89
- echo '?< {} nil, { < {} _, B 0, B 1 >=B car, X cdr } cons > = X' | node ./patterns/from-k.mjs
132
+ echo '?< {} nil, { {} car, X cdr } cons > = X' | \
133
+ node ./patterns/from-k.mjs
90
134
  ```
91
135
 
92
136
  Typical output:
93
137
 
94
138
  ```json
95
- [["closed-union",[["nil",1],["cons",2]]],["closed-product",[]],["closed-product",[["car",3],["cdr",0]]],["closed-union",[["_",1],["0",3],["1",3]]]]
139
+ [
140
+ ["closed-union", [["nil", 1], ["cons", 2]]],
141
+ ["closed-product", []],
142
+ ["closed-product", [["car", 1], ["cdr", 0]]]
143
+ ]
96
144
  ```
97
145
 
98
146
  ## Schemas in the Codec
package/DOCS/REPL.md CHANGED
@@ -33,10 +33,13 @@ is complete.
33
33
  | Command | Meaning |
34
34
  | --- | --- |
35
35
  | `:help` | Show command summary |
36
- | `:engine [wasm|js]` | Display or switch evaluation engine (`wasm` or `js`) |
37
- | `:wasm` / `:js` | Shortcut to switch engine |
36
+ | `:engine [wasm\|pkir\|js]` | Display or switch evaluation engine (`wasm`, `pkir`, or `js`) |
37
+ | `:wasm` / `:pkir` / `:js` | Shortcut to switch engine |
38
38
  | `:rel name` | Show relation definition |
39
39
  | `:rels` | List relation aliases |
40
+ | `:pattern name` | Show named pattern definition (alias: `:pat`) |
41
+ | `:patterns` | List defined named pattern templates (alias: `:pats`) |
42
+ | `:limit [num\|none]` | Set maximum characters for value output (default: 4096) |
40
43
  | `:codec load file` | Load a codec from an ES module file (e.g. `:codec load codecs/int.mjs`) |
41
44
  | `:codec unload name` | Unload a registered codec |
42
45
  | `:codec list` | List loaded REPL codecs (alias: `:codecs`) |
@@ -50,6 +53,8 @@ is complete.
50
53
  ## Raw Snippets
51
54
 
52
55
  Raw input is compiled as k source on top of the current state.
56
+ Both relation definitions (`name = expr;`) and named pattern templates
57
+ (`name[...] = filter;`) can be introduced incrementally.
53
58
 
54
59
  Examples:
55
60
 
@@ -58,11 +63,17 @@ Examples:
58
63
  ```
59
64
 
60
65
  ```k
61
- > bool? = ?<{} true, {} false>;
66
+ > bool[] = < {} true, {} false >;
67
+ > bool? = ? bool[];
62
68
  ```
63
69
 
64
70
  ```k
65
- > not = ?<{} true, {} false> < /true | false, /false | true >;
71
+ > list[X] = < {} nil, { X car, Y cdr } cons > = Y;
72
+ > ? list[bool[]]
73
+ ```
74
+
75
+ ```k
76
+ > not = ? bool[] < /true | false, /false | true >;
66
77
  {} |true not
67
78
  ```
68
79
 
@@ -92,6 +103,7 @@ The interpreter keeps:
92
103
 
93
104
  - `rels`: canonical compiled relations
94
105
  - `relAliases`: human relation names to canonical hashes
106
+ - `patterns`: defined named pattern templates
95
107
  - `value`: current value, initially `{}`
96
108
 
97
109
  Definitions are content-addressed. Rebinding an alias changes the
@@ -231,11 +243,13 @@ The REPL supports two evaluation engines:
231
243
 
232
244
  ### CLI Options
233
245
 
234
- When starting `k-repl`, choose the engine with:
246
+ When starting `k-repl`, choose the engine or output limit with:
235
247
 
236
248
  ```bash
237
249
  k-repl --engine=js # or k-repl --js
250
+ k-repl --engine=pkir # or k-repl --pkir
238
251
  k-repl --engine=wasm # or k-repl --wasm (default)
252
+ k-repl --limit=8192 # set max characters for rendered output
239
253
  ```
240
254
 
241
255
  ## Timing and Profiling
@@ -297,6 +311,11 @@ Evaluated values print in k syntax together with the inferred envelope:
297
311
  {}|0|+1 ?<<{} 0, ...> +1, ...>
298
312
  ```
299
313
 
314
+ Large values are rendered iteratively and truncated at `maxChars`
315
+ (default: `4096` characters) so deeply nested or large values print
316
+ instantly without exhausting stack or terminal buffers. Use
317
+ `:limit <num>` or `:limit none` to adjust or disable the limit.
318
+
300
319
  `undefined` prints as:
301
320
 
302
321
  ```text
@@ -112,8 +112,10 @@ The bundled VFS and UI examples must include only verified useful files:
112
112
 
113
113
  #### 1. Curated Files Explorer
114
114
  In the Web REPL "Files" (VFS) explorer, the visible files are strictly curated to verified examples and codecs:
115
- - **k-codes**: `core.k`, `arithmetics.k`, `ieee.k`
116
- - **codecs**: `json.mjs`, `utf8.mjs`, `int.mjs`, `unit.mjs`, `ieee.mjs`
115
+ - **k-codes**: `core.k`, `arithmetics.k`, `ieee.k`, `djson.k`,
116
+ `djson-btrie.k`, `djson-ptrie.k`
117
+ - **codecs**: `json.mjs`, `djson.mjs`, `djson-btrie.mjs`,
118
+ `djson-ptrie.mjs`, `utf8.mjs`, `int.mjs`, `unit.mjs`, `ieee.mjs`
117
119
  - User-created or uploaded files remain visible.
118
120
  - Internal runtime artifacts (`backends/wasm/runtime.wat`) and redundant directory prefixes (`Examples/`, `codecs/`) are kept accessible internally but hidden from the default file listing.
119
121
  - Clicking "Load" on a `.mjs` file automatically executes `:codec load <filename>`.
@@ -3,7 +3,8 @@ swap_yes_no = < /yes |no, /no |yes >;
3
3
  yes = {}|yes;
4
4
  no = yes swap_yes_no;
5
5
 
6
- bits? = ?< {} _, bits? 0, bits? 1 > = bits?;
6
+ bits[] = < {} _, B 0, B 1 > = B;
7
+ bits? = ? bits[];
7
8
 
8
9
  0b = {} | _;
9
10
  -- |1 = | 1;
@@ -28,7 +29,7 @@ empty = < /_ yes, no >;
28
29
  empty? = {empty /yes if, () then} .then;
29
30
 
30
31
  concat = {.x inv x, .y y} concat_;
31
- concat_ = ?{ <X 0, X 1, {} _>=X x, ... }
32
+ concat_ = ?{ bits[] = X x, ... }
32
33
  <
33
34
  {.x empty? if, .y then} .then,
34
35
  <
@@ -37,7 +38,7 @@ concat_ = ?{ <X 0, X 1, {} _>=X x, ... }
37
38
  > concat_
38
39
  >;
39
40
  inv = {()x, 0b r} _inv;
40
- _inv = ?{ <X 0, X 1, {} _>=X x, ... }
41
+ _inv = ?{ bits[] = X x, ... }
41
42
  <
42
43
  {.x empty? if, .r then} .then,
43
44
  <
@@ -47,7 +48,7 @@ _inv = ?{ <X 0, X 1, {} _>=X x, ... }
47
48
  >;
48
49
 
49
50
  inOrder = {.x inv x, .y inv y, yes inOrder} inOrder_;
50
- inOrder_ = ?{ <X 0, X 1, {} _>=X x, ... }
51
+ inOrder_ = ?{ bits[] = X x, ... }
51
52
  <
52
53
  {.x </0,/1> if1, .y /_ if2, .inOrder swap_yes_no then} .then,
53
54
  {.x /_ if, .inOrder then} .then,
@@ -64,7 +65,8 @@ GT = {inOrder /no if, () then} . then;
64
65
  EQ = {inOrder /yes if, {.x y, .y x} inOrder /yes and, () then} .then;
65
66
 
66
67
  --------------------------------------
67
- int? = ?< <bits 0, bits 1, {} _>=bits "+", bits "-" >;
68
+ int[] = < bits[] "+", bits[] "-" >;
69
+ int? = ? int[];
68
70
 
69
71
  remove_leading_zeros = <
70
72
  /0 remove_leading_zeros,
@@ -85,7 +87,7 @@ inc = <
85
87
  /'-' {inv x, 0b y} _dec nat |'-'
86
88
  >;
87
89
 
88
- _inc = ?{ <X 0, X 1, {} _>=X x, ... } <
90
+ _inc = ?{ bits[] = X x, ... } <
89
91
  {.x empty? if, .y |1 then} .then,
90
92
  {.x /0 x, .y |1 y} concat_,
91
93
  {.x /1 x, .y |0 y} _inc
@@ -97,7 +99,7 @@ dec = <
97
99
  /'-' {inv x, 0b y} _inc nat |'-'
98
100
  >;
99
101
 
100
- _dec = ?{ <X 0, X 1, {} _>=X x, ... } <
102
+ _dec = ?{ bits[] = X x, ... } <
101
103
  {.x /1 x, .y |0 y} concat_,
102
104
  {.x /0 x, .y |1 y} _dec
103
105
  >;
@@ -128,7 +130,7 @@ _plus = {.x x, .y y, .c c, 0b r} _plus_;
128
130
 
129
131
  _plus_ =
130
132
  -- least significant bit first addition with carry
131
- ?{ <X 0, X 1, {} _>=X x, ... }
133
+ ?{ bits[] = X x, ... }
132
134
  <
133
135
  {.x empty? if, .y empty? and, .c/0 c, .r inv then} .then,
134
136
  {.x empty? if, .y empty? and, {.r x, 1 r} _inv then} .then,
@@ -156,7 +158,7 @@ _minus = {.x x, .y y, .c c, 0b r} _minus_;
156
158
 
157
159
  _minus_ =
158
160
  -- least significant bit first substraction with carry
159
- ?{ <X 0, X 1, {} _>=X x, ... }
161
+ ?{ bits[] = X x, ... }
160
162
  <
161
163
  {.y empty? if, .c/0 and, {.r x, .x r} _inv then} .then,
162
164
  <
@@ -199,7 +201,7 @@ times =
199
201
  ;
200
202
 
201
203
  _times =
202
- ?{ <Y 0, Y 1, {} _>=Y y, ... }
204
+ ?{ bits[] = Y y, ... }
203
205
  <
204
206
  { .y empty? if, .result then } .then,
205
207
  <
@@ -226,7 +228,7 @@ shift_in_1 = inv |1 inv nat;
226
228
  sub_bits = {.x inv x, .y inv y, c0 c} _minus inv nat;
227
229
 
228
230
  _div_restoring =
229
- ?{ <X 0, X 1, {} _>=X x, ... }
231
+ ?{ bits[] = X x, ... }
230
232
  <
231
233
  {.x empty? if, {.q inv int div, .r rem} then} .then,
232
234
  <
@@ -241,13 +243,16 @@ _div_restoring =
241
243
  {.y x, .r y} inOrder test
242
244
  }
243
245
  <
244
- {.test /yes if, {.x x, .y y, .q |1 q, {.r x, .y y} sub_bits r} then} .then,
246
+ {
247
+ .test /yes if,
248
+ {.x x, .y y, .q |1 q, {.r x, .y y} sub_bits r} then
249
+ } .then,
245
250
  {.test /no if, {.x x, .y y, .q |0 q, .r r} then} .then
246
251
  >
247
252
  _div_restoring
248
253
  >;
249
254
 
250
- _pad_down = ?{ <X 0, X 1, {} _>=X x, <S 0, S 1, {} _>=S steps, ... }
255
+ _pad_down = ?{ bits[] = X x, bits[] = S steps, ... }
251
256
  <
252
257
  {.x empty? if, {._y _y, .steps steps} then} .then,
253
258
  {
@@ -257,7 +262,7 @@ _pad_down = ?{ <X 0, X 1, {} _>=X x, <S 0, S 1, {} _>=S steps, ... }
257
262
  } _pad_down
258
263
  >;
259
264
 
260
- _align_down = ?{ <X 0, X 1, {} _>=X x, <Y 0, Y 1, {} _>=Y y, ... }
265
+ _align_down = ?{ bits[] = X x, bits[] = Y y, ... }
261
266
  <
262
267
  {
263
268
  .x </0, /1> x,
@@ -277,7 +282,7 @@ _align_down = ?{ <X 0, X 1, {} _>=X x, <Y 0, Y 1, {} _>=Y y, ... }
277
282
  } .then
278
283
  >;
279
284
 
280
- _div_down = ?{ <X 0, X 1, {} _>=X steps, ... }
285
+ _div_down = ?{ bits[] = X steps, ... }
281
286
  {
282
287
  .x x,
283
288
  ._y _y,
@@ -321,7 +326,7 @@ _div_down = ?{ <X 0, X 1, {} _>=X steps, ... }
321
326
  } _div_down
322
327
  >;
323
328
 
324
- _check_2y = ?{ <X 0, X 1, {} _>=X x, <Y 0, Y 1, {} _>=Y y, ... }
329
+ _check_2y = ?{ bits[] = X x, bits[] = Y y, ... }
325
330
  <
326
331
  {.x empty? if, {} | down_shift then} .then,
327
332
  {.y empty? if, {} | restore then} .then,
@@ -393,7 +398,7 @@ gcd =
393
398
  > _gcd
394
399
  ;
395
400
 
396
- _gcd = ?{ <X 0, X 1, {} _>=X x, ... } <
401
+ _gcd = ?{ bits[] = X x, ... } <
397
402
  { .y remove_leading_zeros empty? if, .x nat then } .then,
398
403
  { .y x, mod y } _gcd
399
404
  >;