@fraczak/k 7.0.2 → 7.2.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 +75 -0
- package/DOCS/CODECS.md +37 -2
- package/DOCS/CODEC_ARCHITECTURE.md +12 -5
- package/DOCS/FILE_FORMATS.md +238 -15
- package/DOCS/POLYMORPHIC_IR.md +104 -0
- package/DOCS/REPL.md +11 -3
- package/DOCS/WEB_REPL_REQUIREMENTS.md +1 -1
- package/JOURNAL.md +288 -0
- package/README.md +12 -3
- package/Value.mjs +28 -3
- package/access-table.mjs +343 -0
- package/backend-api.mjs +23 -1
- package/backends/llvm/README.md +20 -21
- package/backends/llvm/bin/k-llvm-build.mjs +105 -32
- package/backends/llvm/bin/k-llvm-compile.mjs +63 -24
- package/backends/llvm/bin/k-llvm.mjs +292 -0
- package/backends/llvm/runtime/krt.c +8 -0
- package/backends/llvm/runtime/krt.h +1 -0
- package/backends/llvm/src/cli.mjs +95 -17
- package/backends/llvm/src/executable.mjs +128 -11
- package/backends/llvm/src/kvm2llvm.mjs +10 -5
- package/backends/llvm/src/llvm.mjs +121 -9
- package/backends/llvm/tests/integration.sh +11 -11
- package/backends/llvm/{bin → tests}/k-llvm-run.mjs +48 -22
- package/backends/llvm/tests/perf-support.mjs +24 -3
- package/backends/llvm/tests/test-llvm.mjs +22 -1
- package/backends/wasm/bin/k-wasm-compile.mjs +46 -20
- package/backends/wasm/bin/k-wasm-run.mjs +61 -20
- package/backends/wasm/bin/k-wasm.mjs +47 -13
- package/backends/wasm/src/cli.mjs +141 -19
- package/backends/wasm/src/wasm.mjs +130 -23
- package/browser/repl-browser.mjs +16 -5
- package/browser/tree-view.mjs +47 -8
- package/browser/vfs-data.mjs +6 -5
- package/codecs/README.md +1 -0
- package/codecs/djson.mjs +270 -0
- package/codecs/int.mjs +2 -1
- package/codecs/json.mjs +7 -2
- package/codecs/k-parse.mjs +36 -9
- package/codecs/k-print.mjs +26 -6
- package/codecs/runtime/codec-sdk.mjs +24 -6
- 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 +24 -6
- package/codecs/utf16.mjs +2 -1
- package/k.mjs +56 -16
- package/kir.mjs +58 -19
- package/kvm.mjs +49 -12
- package/objects/compile.mjs +37 -23
- package/objects/decompile.mjs +40 -10
- package/objects/extract-aliases.mjs +44 -14
- package/objects/inspect.mjs +19 -14
- package/objects/validate.mjs +18 -11
- package/package.json +11 -3
- package/pkir.mjs +772 -0
- package/repl.mjs +92 -23
- package/scripts/build-repl-html.mjs +22 -3
- package/scripts/perf-ieee.mjs +264 -13
- package/scripts/perf-int.mjs +315 -22
- package/scripts/perf-multiplication.mjs +58 -7
- package/scripts/perf-poly.mjs +306 -24
- package/scripts/run-tests.mjs +3 -0
- package/tests/test-access-table.mjs +213 -0
- package/tests/test-codecs.mjs +168 -0
- package/tests/test-pkir.mjs +530 -0
- package/tests/test-polymorphic-tdd.mjs +196 -0
- package/tests/test-repl-html.mjs +16 -2
- package/tests/test-repl.mjs +63 -1
- package/backends/llvm/bin/k-llvm-jit.mjs +0 -160
package/JOURNAL.md
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Transducer & Polymorphic Execution Journal
|
|
2
|
+
|
|
3
|
+
Branch: `transducer`
|
|
4
|
+
Repository: `@fraczak/k`
|
|
5
|
+
|
|
6
|
+
## Objective
|
|
7
|
+
|
|
8
|
+
Design, specify, and implement an efficient compilation and execution
|
|
9
|
+
model for polymorphic functions in K.
|
|
10
|
+
|
|
11
|
+
The architecture bridges two fundamental physical data representations:
|
|
12
|
+
1. **Sequential Prefix-Free Streams** (Wire / Bitstream) operated by
|
|
13
|
+
**Streaming Pushdown Transducers** for linear/erasing access.
|
|
14
|
+
2. **Random-Access Memory Tables** (Arena Nodes) operated by
|
|
15
|
+
**Layout Witnesses** (Offset Dictionaries) and specialized
|
|
16
|
+
monomorphic kernels (`?S F`).
|
|
17
|
+
3. **The Hybrid Dual-Form Pointer** (`KVal` / `KChild`), allowing values
|
|
18
|
+
to remain compact wire slices by default, with on-demand **Spine
|
|
19
|
+
Promotion** when non-linear (repeated / out-of-order) access occurs.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Architecture Log & Decisions
|
|
24
|
+
|
|
25
|
+
### 2026-10-12: Architectural Foundations & TDD Initiation
|
|
26
|
+
|
|
27
|
+
- **Core Duality Formalized**:
|
|
28
|
+
- *Witness Approach*: Operates on indexed random-access memory tables.
|
|
29
|
+
Static offset vector $\Omega(S, F)$ resolves field access without
|
|
30
|
+
dynamic string lookups.
|
|
31
|
+
- *Transducer Approach*: Operates on sequential prefix-free code
|
|
32
|
+
streams. State transitions over choice bits navigate variants and
|
|
33
|
+
skip unneeded product fields without materialization or re-encoding.
|
|
34
|
+
- **Linearity vs Non-Linearity**:
|
|
35
|
+
- Linear/affine access (erasing access: each field read $\le 1$ time in
|
|
36
|
+
stream order) runs entirely in streaming Transducer mode in
|
|
37
|
+
$O(\text{depth})$ stack memory with zero node allocations.
|
|
38
|
+
- Non-linear access (duplication `{()x, ()x}`, out-of-order reads) is
|
|
39
|
+
handled via:
|
|
40
|
+
- Zero-copy slice duplication for independent linear readers.
|
|
41
|
+
- Demand-driven **Spine Promotion**: materializing only the immediate
|
|
42
|
+
outer product spine into an arena node with child pointers
|
|
43
|
+
remaining as serialized wire slices.
|
|
44
|
+
- **TDD Test Suite Planned & Implemented**:
|
|
45
|
+
- Initial suite created in `tests/test-polymorphic-tdd.mjs` (all 6
|
|
46
|
+
tests passing).
|
|
47
|
+
- Targets 6 orthogonal polymorphic patterns:
|
|
48
|
+
1. Filtered Search (`search`): Opaque payload preservation &
|
|
49
|
+
non-linear condition testing.
|
|
50
|
+
2. Search with Field Reordering: Varied syntax and memory ordering.
|
|
51
|
+
3. Boundary Cases: Empty lists, zero matches, all match.
|
|
52
|
+
4. Multi-Variant Dispatch (`extract_id`): Variable byte offsets
|
|
53
|
+
across variants.
|
|
54
|
+
5. Dual-Stream Zip (`zip`): Concurrent independent polymorphic
|
|
55
|
+
streams.
|
|
56
|
+
6. Polymorphic Reverse (`poly_rev`): Accumulator and spine
|
|
57
|
+
reconstruction.
|
|
58
|
+
|
|
59
|
+
### 2026-10-12: State-Indexed Access Table (`access-table.mjs`)
|
|
60
|
+
|
|
61
|
+
- **Algorithm Implemented (`buildAccessTable`)**:
|
|
62
|
+
- Implemented in `access-table.mjs`.
|
|
63
|
+
- Maps any input value schema $S$ to a function's structural access
|
|
64
|
+
profile $P$.
|
|
65
|
+
- Generates a state-indexed table of `NodeDescriptor` entries:
|
|
66
|
+
- Products: maps logical field slots to physical slots, byte offsets,
|
|
67
|
+
skip counts, and child states.
|
|
68
|
+
- Unions: maps physical discriminators to branch indices and child
|
|
69
|
+
states.
|
|
70
|
+
- Zero runtime string lookups; single-array-load machine instruction
|
|
71
|
+
dispatch.
|
|
72
|
+
- **Unit Verification (`tests/test-access-table.mjs`)**:
|
|
73
|
+
- All tests passing: verifies offset calculation for `search` and
|
|
74
|
+
`extract_id`.
|
|
75
|
+
- Simulates in-memory payload navigation with zero string comparisons.
|
|
76
|
+
|
|
77
|
+
### 2026-10-12: Formal Specification of PKIR (`DOCS/POLYMORPHIC_IR.md`)
|
|
78
|
+
|
|
79
|
+
- Specified the Polymorphic K Intermediate Representation (PKIR):
|
|
80
|
+
- Abstract state-indexed, slot-addressed instruction set.
|
|
81
|
+
- Dual execution strategy: direct interpretation with `AccessTable`
|
|
82
|
+
and fast monomorphic specialization.
|
|
83
|
+
- Pure partial function semantics with failure propagation.
|
|
84
|
+
|
|
85
|
+
### 2026-10-12: PKIR Implementation & Specialization (`pkir.mjs`)
|
|
86
|
+
|
|
87
|
+
- **Compiler Lowering (`compileRelationToPKIR`)**:
|
|
88
|
+
- Traverses relational AST and produces state-indexed PKIR instructions.
|
|
89
|
+
- Automatically derives `accessProfile` per pattern node.
|
|
90
|
+
- **Fat-Pointer Runtime (`KVal` / `valueToKVal` / `kvalToValue`)**:
|
|
91
|
+
- Materialized arena node simulation with dual-form support.
|
|
92
|
+
- Lossless round-trip conversion preserving arbitrary nested payloads.
|
|
93
|
+
- **Direct Execution (`executePKIR`)**:
|
|
94
|
+
- Evaluates PKIR instructions using `AccessTable` descriptors.
|
|
95
|
+
- Supports recursive relation invocation (`call_rel`) and failure
|
|
96
|
+
backtracking across union branches.
|
|
97
|
+
- **Monomorphic Specialization (`specializePKIR`)**:
|
|
98
|
+
- Bakes concrete `AccessTable` into specialized instructions
|
|
99
|
+
(`project_offset`, `match_tag_imm`).
|
|
100
|
+
- Dead branch elimination: prunes non-matching union branches.
|
|
101
|
+
- Direct execution of specialized artifacts without `AccessTable`.
|
|
102
|
+
- **Test Verification (`tests/test-pkir.mjs`)**:
|
|
103
|
+
- Comprehensive 8-test suite verifying lowering, recursive search,
|
|
104
|
+
multi-variant dispatch, specialization, and error handling.
|
|
105
|
+
- Full project test suite (`npm test`) passes with 100% green status.
|
|
106
|
+
|
|
107
|
+
### 2026-10-12: Performance Evaluation (Previous Work vs PKIR)
|
|
108
|
+
|
|
109
|
+
- **Multi-Variant Dispatch Benchmark (`extract_id`, 200k iterations)**:
|
|
110
|
+
- AST Interpreter (`run.mjs`): 225.98 ms (885,035 ops/s)
|
|
111
|
+
[1.00x baseline].
|
|
112
|
+
- kVM Interpreter (`kvm.mjs`): 78.36 ms (2,552,456 ops/s)
|
|
113
|
+
[2.88x speedup].
|
|
114
|
+
- PKIR Generic (`AccessTable`): 74.69 ms (2,677,615 ops/s)
|
|
115
|
+
[3.03x speedup].
|
|
116
|
+
- PKIR Specialized (`specializePKIR`): 62.23 ms (3,214,079 ops/s)
|
|
117
|
+
[3.63x speedup].
|
|
118
|
+
- **Elimination of the Envelope Tax**:
|
|
119
|
+
- In previous work (`scripts/perf-poly.mjs`), polymorphic envelope
|
|
120
|
+
wrapping suffered a 26x performance penalty (31.74 ms envelope-aware
|
|
121
|
+
vs 1.21 ms envelope-free).
|
|
122
|
+
- The Layout Witness approach eliminates envelopes completely: layout
|
|
123
|
+
witnesses index heterogeneous physical records directly without
|
|
124
|
+
boxing or re-encoding.
|
|
125
|
+
- **Sub-30µs Specialization Latency**:
|
|
126
|
+
- `buildAccessTable`: 2.28 µs per table.
|
|
127
|
+
- `specializePKIR`: 24.87 µs per relation specialization.
|
|
128
|
+
- Total Specialization Overhead: ~27.15 µs (compared to 100-1500 ms for
|
|
129
|
+
traditional Wasm/LLVM AOT compilation), enabling instant runtime
|
|
130
|
+
JIT tiering.
|
|
131
|
+
- **Zero Payload Re-encoding in Recursive Traversals (`search_`)**:
|
|
132
|
+
- Evaluated on 100-element lists with arbitrary heterogeneous payloads.
|
|
133
|
+
- Throughput: 404,703 items/sec (0.247 ms per 100-item pass).
|
|
134
|
+
- Opaque payload slices (`data: payload_i`) are forwarded by fat-pointer
|
|
135
|
+
references without traversing, unpacking, or re-serializing them.
|
|
136
|
+
|
|
137
|
+
### 2026-10-12: WebAssembly Integration in REPL (`repl.mjs` & `repl.html`)
|
|
138
|
+
|
|
139
|
+
- **PKIR-to-KVM Lowering (`lowerPKIRToKVM`)**:
|
|
140
|
+
- Implemented and exported `lowerPKIRToKVM(pkir)` in `pkir.mjs` and
|
|
141
|
+
`backend-api.mjs`.
|
|
142
|
+
- Translates state-indexed PKIR instructions (`id`, `filter`,
|
|
143
|
+
`project_slot`, `match_variant`, `make_variant`, `product`, `union`,
|
|
144
|
+
`call_rel`) into machine-level KVM instructions for `lowerToWasm`.
|
|
145
|
+
- Maps top-level input register and branch-local input registers to
|
|
146
|
+
`%in`, enabling seamless integration with Wasm register allocation.
|
|
147
|
+
- **WebAssembly Compilation Pipeline**:
|
|
148
|
+
- Extended `compileModule`, `compileWasmArtifactFromDefs`, and
|
|
149
|
+
`compileWasmArtifactFromObject` in `backends/wasm/src/wasm.mjs` with
|
|
150
|
+
the `usePKIR` option.
|
|
151
|
+
- Implemented and exported `compileWasmArtifactFromPKIR(pkirInput)`.
|
|
152
|
+
- **REPL CLI Support (`repl.mjs`)**:
|
|
153
|
+
- Added `pkir` engine mode: `--pkir`, `--engine=pkir`, `:pkir`,
|
|
154
|
+
`:engine pkir`, and autocompletion in `:engine [wasm|pkir|js]`.
|
|
155
|
+
- In `executeExpressionWithWasm`: routes compilation through PKIR when
|
|
156
|
+
the engine is set to `pkir`.
|
|
157
|
+
- **Browser Web REPL (`repl.html`)**:
|
|
158
|
+
- Updated `browser/repl-browser.mjs` with a 3-way engine badge toggle
|
|
159
|
+
(`wasm-in-process` -> `pkir-wasm` -> `js-in-process`).
|
|
160
|
+
- Added `.engine-badge.pkir-mode` badge styling in
|
|
161
|
+
`scripts/build-repl-html.mjs` and rebuilt `repl.html`.
|
|
162
|
+
- **Verification**:
|
|
163
|
+
- Verified evaluation of arithmetic, boolean logic, and lists via
|
|
164
|
+
PKIR-generated WebAssembly.
|
|
165
|
+
- Test suites (`tests/test-pkir.mjs`, `tests/test-repl.mjs`,
|
|
166
|
+
`tests/test-repl-html.mjs`, and `npm test`) pass with 100% green.
|
|
167
|
+
|
|
168
|
+
### 2026-10-12: Integration into Performance Harnesses (`perf:*`)
|
|
169
|
+
|
|
170
|
+
- **Benchmark Integration**:
|
|
171
|
+
- Integrated `pkir` execution lane into:
|
|
172
|
+
- `scripts/perf-int.mjs`: Big Integer ops and 10-step squaring scale.
|
|
173
|
+
- `scripts/perf-ieee.mjs`: IEEE 754 float ops across 144 evaluations.
|
|
174
|
+
- `scripts/perf-multiplication.mjs`: Multi-backend squaring benchmark.
|
|
175
|
+
- `scripts/perf-poly.mjs`: Polymorphic list ops and macro tracing.
|
|
176
|
+
- Generates and compiles WebAssembly artifacts via
|
|
177
|
+
`compileWasmArtifactFromObject(rel.object, { usePKIR: true })`.
|
|
178
|
+
- **Target Backend Selection**:
|
|
179
|
+
- Added support for `BACKENDS=pkir`, `PKIR_ONLY=1`, and `--pkir-only`.
|
|
180
|
+
- When unrestricted, all backends (`llvm`, `wasm`, `pkir`, `kvm`, `js`)
|
|
181
|
+
execute concurrently for direct side-by-side comparison.
|
|
182
|
+
- **Convenience NPM Scripts (`package.json`)**:
|
|
183
|
+
- Added `perf:int:pkir`: `BACKENDS=pkir node scripts/perf-int.mjs`
|
|
184
|
+
- Added `perf:ieee:pkir`: `BACKENDS=pkir node scripts/perf-ieee.mjs`
|
|
185
|
+
- Added `perf:mult:pkir`:
|
|
186
|
+
`node scripts/perf-multiplication.mjs --backends pkir`
|
|
187
|
+
- Added `perf:poly:pkir`: `BACKENDS=pkir node scripts/perf-poly.mjs`
|
|
188
|
+
- **Verification**:
|
|
189
|
+
- All benchmarks verify 100% output conformance against native K
|
|
190
|
+
oracle values.
|
|
191
|
+
- Squaring benchmarks reach full 10/10 steps with matching outputs.
|
|
192
|
+
|
|
193
|
+
### 2026-10-13: LLVM Backend Integration for PKIR
|
|
194
|
+
|
|
195
|
+
- **Compiler Lowering & CLI Integration**:
|
|
196
|
+
- Implemented `compileLLVMArtifactFromPKIR` and `{ usePKIR: true }` in
|
|
197
|
+
`backends/llvm/src/llvm.mjs` and `backends/llvm/src/executable.mjs`.
|
|
198
|
+
- Added CLI support (`--pkir` and `.pkir` input files) for
|
|
199
|
+
`k-llvm-compile`, `k-llvm-build`, and `k-wasm-compile`.
|
|
200
|
+
- Exported `compilePKIRToExecutable` and `compilePKIRAndRun` from
|
|
201
|
+
`backends/llvm/src/executable.mjs`.
|
|
202
|
+
- **Runtime & Slot Lowering Fixes**:
|
|
203
|
+
- Synthesized union helper `inputPattern`: resolved input pattern in
|
|
204
|
+
`union_expr` and `union_arm` from
|
|
205
|
+
`regPatterns.get(cleanReg(inst.src))`
|
|
206
|
+
so field access in arm functions targets correct physical slots.
|
|
207
|
+
- Open product field indexing in PKIR: restricted static physical slot
|
|
208
|
+
addressing in `getFieldEdgeIndex` to closed products when `usePKIR`
|
|
209
|
+
is active, falling back to dynamic `k_product_get_n` for polymorphic
|
|
210
|
+
open products to prevent physical index misalignment.
|
|
211
|
+
- Wire serialization for polymorphic outputs: implemented and exported
|
|
212
|
+
`k_encode_wire` via `derive_pattern(value)` in `krt.h` and `krt.c`,
|
|
213
|
+
with fallback in `executable.mjs` when static output pattern has
|
|
214
|
+
`KP_ANY`.
|
|
215
|
+
- Pattern graph ID 0 check: updated `compileObjectToLLVM` pattern
|
|
216
|
+
lookups to check `!== undefined` so node ID 0 is not treated as falsy.
|
|
217
|
+
- **Performance Harnesses & NPM Automation**:
|
|
218
|
+
- Added `llvm-pkir` backend lane across:
|
|
219
|
+
- `scripts/perf-multiplication.mjs` (`--backends llvm-pkir`)
|
|
220
|
+
- `scripts/perf-int.mjs` (`BACKENDS=llvm-pkir`)
|
|
221
|
+
- `scripts/perf-poly.mjs` (`BACKENDS=llvm-pkir`)
|
|
222
|
+
- `scripts/perf-ieee.mjs` (`BACKENDS=llvm-pkir`)
|
|
223
|
+
- Added npm scripts to `package.json`:
|
|
224
|
+
- `perf:mult:llvm-pkir`
|
|
225
|
+
- `perf:int:llvm-pkir`
|
|
226
|
+
- `perf:poly:llvm-pkir`
|
|
227
|
+
- `perf:ieee:llvm-pkir`
|
|
228
|
+
- **Verification**:
|
|
229
|
+
- Added PKIR LLVM lowering, compilation, and execution tests
|
|
230
|
+
(Tests 10, 11, 12 in `tests/test-pkir.mjs`).
|
|
231
|
+
- Verified 100% test pass on `npm test` and `npm run test:backends`.
|
|
232
|
+
- Verified 100% output conformance across all `perf:*` benchmarks.
|
|
233
|
+
|
|
234
|
+
### 2026-10-13: Concurrent LLVM & LLVM-PKIR Benchmark Comparison
|
|
235
|
+
|
|
236
|
+
- **Motivation**:
|
|
237
|
+
- The previous harness integration allowed selecting either `llvm` or
|
|
238
|
+
`llvm-pkir` via `BACKENDS=llvm-pkir`, but did not run both
|
|
239
|
+
concurrently in default runs (`npm run perf:int`, etc.).
|
|
240
|
+
- Users expecting direct performance comparisons between the original
|
|
241
|
+
monomorphic LLVM backend and the new polymorphic PKIR LLVM backend
|
|
242
|
+
now see both lanes evaluated side-by-side by default.
|
|
243
|
+
- **Changes Across All Perf Harnesses**:
|
|
244
|
+
- `scripts/perf-int.mjs`: Separated `runLLVM` and `runLLVMPKIR` into
|
|
245
|
+
distinct lanes enabled by default. Both `LLVM` and `LLVM-PKIR` are
|
|
246
|
+
compiled, warmed, timed, and reported in the main integer benchmark
|
|
247
|
+
table and squaring scale benchmark.
|
|
248
|
+
- `scripts/perf-ieee.mjs`: Both `LLVM` and `LLVM-PKIR` executables are
|
|
249
|
+
compiled across specified optimization levels and reported side-by-
|
|
250
|
+
side in the results table and conformance validation.
|
|
251
|
+
- `scripts/perf-poly.mjs`: Both `LLVM` and `LLVM-PKIR` are benchmarked
|
|
252
|
+
side-by-side in default runs and supported in 7-phase execution
|
|
253
|
+
tracing (`--trace`).
|
|
254
|
+
- `scripts/perf-multiplication.mjs`: Added `llvm-pkir` to default
|
|
255
|
+
backend list (`llvm,llvm-pkir,wasm,pkir,kvm,js`) and respected
|
|
256
|
+
`BACKENDS` environment variable.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Work Items & Progress
|
|
261
|
+
|
|
262
|
+
- [x] Branch creation (`transducer`)
|
|
263
|
+
- [x] Execution model & duality analysis documented
|
|
264
|
+
- [x] Initialize `JOURNAL.md`
|
|
265
|
+
- [x] Create `tests/test-polymorphic-tdd.mjs` test harness (passing)
|
|
266
|
+
- [x] Establish evaluator & kVM baseline passes
|
|
267
|
+
- [x] Design & implement `buildAccessTable` algorithm (`access-table.mjs`)
|
|
268
|
+
- [x] Create `tests/test-access-table.mjs` test suite (passing)
|
|
269
|
+
- [x] Formal PKIR specification (`DOCS/POLYMORPHIC_IR.md`)
|
|
270
|
+
- [x] Prototype `KVal` fat-pointer representation (`pkir.mjs`)
|
|
271
|
+
- [x] Implement PKIR compiler lowering (`compileRelationToPKIR`)
|
|
272
|
+
- [x] Implement PKIR execution engine (`executePKIR`)
|
|
273
|
+
- [x] Implement Monomorphic Specializer with dead branch elimination
|
|
274
|
+
- [x] Create `tests/test-pkir.mjs` test suite (passing)
|
|
275
|
+
- [x] Integrate with test runner (`scripts/run-tests.mjs`) & verify
|
|
276
|
+
- [x] Benchmark performance against previous work (AST & kVM baselines)
|
|
277
|
+
- [x] Integrate PKIR into Wasm lowering (`lowerPKIRToKVM`)
|
|
278
|
+
- [x] Enable PKIR in `repl.mjs` (`--pkir`, `:engine pkir`)
|
|
279
|
+
- [x] Enable PKIR in `repl.html` (3-way engine badge toggle)
|
|
280
|
+
- [x] Add PKIR to perf:* harnesses (perf:int, perf:ieee, perf:mult, poly)
|
|
281
|
+
- [x] Integrate PKIR into LLVM lowering (`compileLLVMArtifactFromPKIR`)
|
|
282
|
+
- [x] Add CLI support for PKIR in LLVM tools (`k-llvm-compile`, etc.)
|
|
283
|
+
- [x] Standalone executable compilation (`compilePKIRToExecutable`)
|
|
284
|
+
- [x] Integrate `llvm-pkir` into all `perf:*` benchmarks and
|
|
285
|
+
`package.json`
|
|
286
|
+
- [x] Fix polymorphic open product slot resolution and dynamic wire
|
|
287
|
+
encoding
|
|
288
|
+
- [x] Run both LLVM and LLVM-PKIR side-by-side by default in perf:* tests
|
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
**k is a small language for content-addressable schemas and data transformations.**
|
|
4
4
|
|
|
5
|
+
> [!TIP]
|
|
6
|
+
> **Live Web REPL (`repl.html`):** Try k online with zero install:
|
|
7
|
+
> [**https://fraczak.github.io/k/**](https://fraczak.github.io/k/)
|
|
8
|
+
|
|
5
9
|
It describes data as algebraic schemas, programs as first-order partial
|
|
6
10
|
relations, and runtime values as a self-describing binary `schema + payload`
|
|
7
11
|
stream that can be parsed, transformed, printed, compiled, and inspected.
|
|
@@ -69,7 +73,9 @@ adds one successor. The REPL also prints the inferred value envelope.
|
|
|
69
73
|
|
|
70
74
|
### In the Browser (Zero Install)
|
|
71
75
|
|
|
72
|
-
Try k directly in your browser without installing anything
|
|
76
|
+
Try k directly in your browser without installing anything using the
|
|
77
|
+
live Web REPL (`repl.html`):
|
|
78
|
+
|
|
73
79
|
**[https://fraczak.github.io/k/](https://fraczak.github.io/k/)**
|
|
74
80
|
|
|
75
81
|
The Web REPL is self-contained, powered by an in-process WebAssembly
|
|
@@ -217,7 +223,8 @@ For a detailed guide to all four formats, commands, and workflows, see
|
|
|
217
223
|
|
|
218
224
|
| Command | Purpose |
|
|
219
225
|
| --- | --- |
|
|
220
|
-
| `k-json` | Convert JSON to/from the binary stream |
|
|
226
|
+
| `k-json` | Convert JSON to/from the binary stream (schema-specializing) |
|
|
227
|
+
| `k-djson` | Convert JSON to/from a universal dynamic JSON singleton pattern |
|
|
221
228
|
| `k-int` | Convert decimal integers to/from the binary stream |
|
|
222
229
|
| `k-ieee` | Convert float literals to/from the binary stream |
|
|
223
230
|
| `k-unit` | Produce or validate the unit value |
|
|
@@ -235,7 +242,7 @@ For a detailed guide to all four formats, commands, and workflows, see
|
|
|
235
242
|
| `k-kir` | Export KIR-P from `.ko` or `.klib` |
|
|
236
243
|
| `k-vm` | Execute or inspect lowered kVM bytecode artifacts (`.kvm`) |
|
|
237
244
|
| `k-wasm` / `k-wasm-compile` / `k-wasm-run` | Compile and run via WebAssembly backend |
|
|
238
|
-
| `k-llvm
|
|
245
|
+
| `k-llvm` / `k-llvm-build` / `k-llvm-compile` | Compile and run via LLVM backend |
|
|
239
246
|
|
|
240
247
|
Installed binary names are `k-` plus the source basename without
|
|
241
248
|
`.mjs`, except for `k.mjs` itself. Source names that already include
|
|
@@ -372,6 +379,8 @@ The suite covers:
|
|
|
372
379
|
|
|
373
380
|
## Further Reading
|
|
374
381
|
|
|
382
|
+
- [Web REPL (`repl.html`)](https://fraczak.github.io/k/) -
|
|
383
|
+
live in-browser interpreter (hosted on GitHub Pages)
|
|
375
384
|
- [DOCS/FILE_FORMATS.md](DOCS/FILE_FORMATS.md) - guide to
|
|
376
385
|
.k, .ko, .klib, and .kvm file formats and workflows
|
|
377
386
|
- [DOCS/DICTIONARY.md](DOCS/DICTIONARY.md) - concept names and terminology
|
package/Value.mjs
CHANGED
|
@@ -193,15 +193,40 @@ class Value {
|
|
|
193
193
|
|
|
194
194
|
toJSON() {
|
|
195
195
|
if (isVariant(this)) {
|
|
196
|
-
if (
|
|
196
|
+
if (
|
|
197
|
+
isProduct(this.value) &&
|
|
198
|
+
Object.keys(this.value.product).length === 0
|
|
199
|
+
) {
|
|
197
200
|
return this.tag;
|
|
198
201
|
}
|
|
199
|
-
|
|
202
|
+
const tags = [];
|
|
203
|
+
let curr = this;
|
|
204
|
+
while (isVariant(curr)) {
|
|
205
|
+
if (
|
|
206
|
+
isProduct(curr.value) &&
|
|
207
|
+
Object.keys(curr.value.product).length === 0
|
|
208
|
+
) {
|
|
209
|
+
let res = curr.tag;
|
|
210
|
+
for (let i = tags.length - 1; i >= 0; i--) {
|
|
211
|
+
res = { [tags[i]]: res };
|
|
212
|
+
}
|
|
213
|
+
return res;
|
|
214
|
+
}
|
|
215
|
+
tags.push(curr.tag);
|
|
216
|
+
curr = curr.value;
|
|
217
|
+
}
|
|
218
|
+
let res = curr
|
|
219
|
+
? (typeof curr.toJSON === "function" ? curr.toJSON() : curr)
|
|
220
|
+
: null;
|
|
221
|
+
for (let i = tags.length - 1; i >= 0; i--) {
|
|
222
|
+
res = { [tags[i]]: res };
|
|
223
|
+
}
|
|
224
|
+
return res;
|
|
200
225
|
}
|
|
201
226
|
if (!isProduct(this)) return { type: this.type };
|
|
202
227
|
let vector = toVector(this.product);
|
|
203
228
|
if (vector.length > 0) return vector;
|
|
204
|
-
return this.product;
|
|
229
|
+
return this.product;
|
|
205
230
|
}
|
|
206
231
|
}
|
|
207
232
|
export { Value, fromObject, cloneSubpattern, edgeSubpattern, composePattern, mergePatterns, withPattern, isProduct, isVariant, isValue };
|