@fraczak/k 6.3.3 → 6.5.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 (157) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/DOCS/CODECS.md +258 -0
  3. package/DOCS/DICTIONARY.md +1172 -0
  4. package/DOCS/KIR_SPECIALIZATION_DESIGN.md +51 -46
  5. package/DOCS/KIR_V1.md +221 -0
  6. package/DOCS/KVM_EXECUTION_MODEL.md +56 -19
  7. package/DOCS/OBJECT_FILE_AND_PATTERN.md +2 -1
  8. package/DOCS/PROFILING_AND_TRACING.md +196 -0
  9. package/DOCS/REPL.md +61 -4
  10. package/DOCS/WEB_REPL_REQUIREMENTS.md +135 -0
  11. package/DOCS/dependency-graph.md +144 -0
  12. package/Examples/arithmetics.k +108 -82
  13. package/Examples/bnat.k +1 -1
  14. package/Examples/buda.k +44 -0
  15. package/Examples/ieee.k +300 -8671
  16. package/Examples/poly.k +67 -0
  17. package/README.md +68 -19
  18. package/Value.mjs +8 -2
  19. package/augmentation.mjs +9 -7
  20. package/backend-api.mjs +11 -2
  21. package/backends/arm64/README.md +104 -0
  22. package/backends/arm64/bin/k-arm64-compile.mjs +101 -0
  23. package/backends/arm64/bin/k-arm64-run.mjs +58 -0
  24. package/backends/arm64/bin/k-arm64.mjs +88 -0
  25. package/backends/arm64/scripts/run-tests.mjs +41 -0
  26. package/backends/arm64/src/arm64.mjs +229 -0
  27. package/backends/arm64/src/cli.mjs +155 -0
  28. package/backends/arm64/src/kvm2arm64.mjs +906 -0
  29. package/backends/arm64/src/runtime.c +728 -0
  30. package/backends/arm64/tests/integration.sh +112 -0
  31. package/backends/arm64/tests/test-arm64.mjs +240 -0
  32. package/backends/llvm/README.md +135 -0
  33. package/backends/llvm/bin/k-llvm-build.mjs +71 -0
  34. package/backends/llvm/bin/k-llvm-compile.mjs +68 -0
  35. package/backends/llvm/bin/k-llvm-jit.mjs +160 -0
  36. package/backends/llvm/bin/k-llvm-run.mjs +90 -0
  37. package/backends/llvm/runtime/krt.c +1508 -0
  38. package/backends/llvm/runtime/krt.h +109 -0
  39. package/backends/llvm/scripts/conformance.mjs +76 -0
  40. package/backends/llvm/scripts/run-tests.mjs +28 -0
  41. package/backends/llvm/src/executable.mjs +562 -0
  42. package/backends/llvm/src/kvm2llvm.mjs +998 -0
  43. package/backends/llvm/src/llvm.mjs +1092 -0
  44. package/backends/llvm/tests/composition-driver.c +22 -0
  45. package/backends/llvm/tests/identity-driver.c +27 -0
  46. package/backends/llvm/tests/integration.sh +153 -0
  47. package/backends/llvm/tests/perf-support.mjs +735 -0
  48. package/backends/llvm/tests/product-driver.c +23 -0
  49. package/backends/llvm/tests/projection-driver.c +19 -0
  50. package/backends/llvm/tests/relation-driver.c +29 -0
  51. package/backends/llvm/tests/test-llvm.mjs +240 -0
  52. package/backends/llvm/tests/union-driver.c +31 -0
  53. package/backends/llvm/tests/variant-driver.c +19 -0
  54. package/backends/llvm/tests/variant-projection-driver.c +21 -0
  55. package/backends/wasm/DOCS/USE-WEB-ASSEMBLY.md +233 -0
  56. package/backends/wasm/README.md +97 -0
  57. package/backends/wasm/TECHNICAL-DEBT.md +58 -0
  58. package/backends/wasm/bin/k-wasm-compile.mjs +50 -0
  59. package/backends/wasm/bin/k-wasm-run.mjs +140 -0
  60. package/backends/wasm/bin/k-wasm.mjs +49 -0
  61. package/backends/wasm/demo_ieee.mjs +319 -0
  62. package/backends/wasm/runtime.wat +475 -0
  63. package/backends/wasm/scripts/run-tests.mjs +41 -0
  64. package/backends/wasm/src/cli.mjs +133 -0
  65. package/backends/wasm/src/kvm2wasm.mjs +697 -0
  66. package/backends/wasm/src/wasm.mjs +1054 -0
  67. package/backends/wasm/tests/integration.sh +182 -0
  68. package/backends/wasm/tests/perf-support.mjs +336 -0
  69. package/backends/wasm/tests/test-wasm.mjs +625 -0
  70. package/browser/repl-browser.mjs +1584 -0
  71. package/browser/shims/assert.mjs +19 -0
  72. package/browser/shims/buffer.mjs +224 -0
  73. package/browser/shims/crypto.mjs +103 -0
  74. package/browser/shims/fs.mjs +159 -0
  75. package/browser/shims/os.mjs +17 -0
  76. package/browser/shims/path.mjs +54 -0
  77. package/browser/shims/process.mjs +44 -0
  78. package/browser/shims/readline.mjs +11 -0
  79. package/browser/shims/url.mjs +12 -0
  80. package/browser/vfs-data.mjs +19 -0
  81. package/codecs/README.md +3 -0
  82. package/codecs/runtime/show-value.mjs +12 -3
  83. package/conformance/helper-reuse/case.json +8 -0
  84. package/conformance/helper-reuse/expected.kv +1 -0
  85. package/conformance/helper-reuse/input.kv +1 -0
  86. package/conformance/helper-reuse/program.k +2 -0
  87. package/conformance/identity/case.json +8 -0
  88. package/conformance/identity/expected.kv +1 -0
  89. package/conformance/identity/input.kv +1 -0
  90. package/conformance/identity/program.k +1 -0
  91. package/conformance/product-projection/case.json +8 -0
  92. package/conformance/product-projection/expected.kv +1 -0
  93. package/conformance/product-projection/input.kv +1 -0
  94. package/conformance/product-projection/program.k +1 -0
  95. package/conformance/run.mjs +149 -0
  96. package/conformance/variant-construction/case.json +8 -0
  97. package/conformance/variant-construction/expected.kv +1 -0
  98. package/conformance/variant-construction/input.kv +1 -0
  99. package/conformance/variant-construction/program.k +1 -0
  100. package/harness/adapters/arm64.mjs +105 -0
  101. package/harness/adapters/kvm.mjs +144 -0
  102. package/harness/adapters/llvm.mjs +118 -0
  103. package/harness/adapters/native.mjs +77 -0
  104. package/harness/adapters/wasm.mjs +169 -0
  105. package/harness/backend.mjs +95 -0
  106. package/harness/cli.mjs +130 -0
  107. package/harness/format.mjs +95 -0
  108. package/harness/index.mjs +25 -0
  109. package/harness/persistent.mjs +121 -0
  110. package/harness/registry.mjs +44 -0
  111. package/harness/suite.mjs +257 -0
  112. package/harness/suites/poly.mjs +156 -0
  113. package/harness/trace.mjs +50 -0
  114. package/harness/util.mjs +92 -0
  115. package/intrinsics.mjs +41 -0
  116. package/kir.mjs +399 -0
  117. package/kvm.mjs +585 -81
  118. package/objects/README.md +37 -3
  119. package/objects/compile.mjs +15 -22
  120. package/objects/inspect.mjs +96 -0
  121. package/objects/validate.mjs +415 -0
  122. package/package.json +51 -19
  123. package/repl-codecs.mjs +105 -6
  124. package/repl.mjs +335 -49
  125. package/run.mjs +2 -7
  126. package/scripts/benchmark.mjs +406 -22
  127. package/scripts/build-repl-html.mjs +1784 -0
  128. package/scripts/perf-ieee.mjs +586 -0
  129. package/scripts/perf-int.mjs +531 -0
  130. package/scripts/perf-poly.mjs +945 -0
  131. package/scripts/render-benchmark.mjs +12 -8
  132. package/scripts/run-tests.mjs +6 -0
  133. package/tests/integration.sh +19 -2
  134. package/tests/test-arithmetics.mjs +54 -0
  135. package/tests/test-ieee-arithmetic.mjs +4 -0
  136. package/tests/test-kir.mjs +85 -0
  137. package/tests/test-kvm-polymorphic.mjs +278 -0
  138. package/tests/test-kvm.mjs +25 -6
  139. package/tests/test-poly.mjs +129 -0
  140. package/tests/test-repl-html.mjs +303 -0
  141. package/tests/test-repl.mjs +144 -1
  142. package/tests/test-validate-object.mjs +40 -0
  143. package/a.klib +0 -1
  144. package/a.kvm +0 -142676
  145. package/a.wasm +0 -0
  146. package/benchmark-results.html +0 -532
  147. package/benchmark-results.json +0 -480
  148. package/k-vscode/.vscode/launch.json +0 -14
  149. package/k-vscode/README.md +0 -75
  150. package/k-vscode/extension.js +0 -273
  151. package/k-vscode/language-configuration.json +0 -42
  152. package/k-vscode/package.json +0 -79
  153. package/k-vscode/snippets/k.json +0 -92
  154. package/k-vscode/syntaxes/k.tmLanguage.json +0 -599
  155. package/k-vscode/test/background-ranges.test.js +0 -50
  156. package/k-vscode/themes/k-contrast-color-theme.json +0 -104
  157. package/scripts/git-hooks/pre-commit +0 -10
package/CHANGELOG.md CHANGED
@@ -7,6 +7,23 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [6.5.0] — 2026-09-22 — Tail-loop arena compaction & OOM diagnostics
11
+
12
+ ### WebAssembly Backend
13
+
14
+ - Added threshold-based arena compaction in self-tail-recursive loops to reclaim dead scratch space, allowing deep computations (e.g. multi-thousand-bit arithmetic) without exhausting linear memory.
15
+ - Added explicit Out-Of-Memory error reporting (`OutOfMemoryError`), tracking allocation failure and 32-bit offset overflow via exported runtime globals.
16
+
17
+ ### Runtime & REPL
18
+
19
+ - Replaced recursive traversal in `codecs/runtime/show-value.mjs` and `Value.mjs` with iterative loops, eliminating `Maximum call stack size exceeded` errors when rendering deep variant chains.
20
+
21
+ ### Examples
22
+
23
+ - Converted arithmetic helper functions in `Examples/arithmetics.k` to tail-recursive relations.
24
+
25
+ ---
26
+
10
27
  ## [6.2.3] — 2026-06-03 — Unified k compiler output
11
28
 
12
29
  ### Toolchain
package/DOCS/CODECS.md ADDED
@@ -0,0 +1,258 @@
1
+ # Writing Codecs
2
+
3
+ A codec is a small ES module that translates between some external text format
4
+ and k `Value` objects. The same module may serve two entry points:
5
+
6
+ - a command-line codec such as `k-int --parse` or `k-int --print`,
7
+ - a REPL codec loaded with `:codec load file`.
8
+
9
+ The command-line entry point reads or writes the binary pattern+value stream.
10
+ The REPL entry point exports `name`, type metadata, `parse`, and `print`
11
+ functions.
12
+
13
+ ## Choose The Shape
14
+
15
+ Use a type-specific codec when the external format belongs to one k type. The
16
+ module exports either `codes` or `patterns`.
17
+
18
+ ```js
19
+ export const name = "unit";
20
+ export const patterns = [[
21
+ ["closed-product", []]
22
+ ]];
23
+ ```
24
+
25
+ Use a universal codec when the external format can describe many k types. A
26
+ universal codec is available for any type named by `:input`; the REPL validates
27
+ the parsed value against that requested type before accepting it.
28
+
29
+ ```js
30
+ export const name = "json";
31
+ export const universal = true;
32
+ ```
33
+
34
+ Prefer `patterns` for codecs that live in the source tree because the REPL
35
+ recomputes the canonical code hash. Use `codes` only when the codec is tied to a
36
+ known canonical hash:
37
+
38
+ ```js
39
+ export const codes = ["@..."];
40
+ ```
41
+
42
+ ## Implement The REPL API
43
+
44
+ A REPL codec exports:
45
+
46
+ ```js
47
+ export const name = "mycodec";
48
+ export const patterns = [MY_PATTERN]; // or codes = ["@..."], or universal = true
49
+
50
+ export function parse(text, context) {
51
+ // text is the line entered after :input
52
+ // return a k Value
53
+ }
54
+
55
+ export function print(value, context) {
56
+ // return text shown under normal REPL output
57
+ }
58
+ ```
59
+
60
+ `context` contains:
61
+
62
+ - `codeHash`: the canonical code hash selected by `:input`,
63
+ - `pattern`: the closed property-list pattern for that type,
64
+ - `state`: the current REPL state.
65
+
66
+ Most codecs do not need `context`. Universal codecs can use it when the same
67
+ text syntax needs to adapt to the requested type.
68
+
69
+ `parse` should throw an `Error` for invalid external text. `print` should throw
70
+ when the value is not representable by the external format. For universal
71
+ codecs, REPL output suppresses `print` errors so a generic codec does not add
72
+ noise to every value.
73
+
74
+ ## Build Values
75
+
76
+ Use the structural `Value` API:
77
+
78
+ ```js
79
+ import { Value, isProduct, isVariant } from "../Value.mjs";
80
+
81
+ const unit = Value.product({});
82
+ const yes = Value.variant("true", unit);
83
+ const point = Value.product({
84
+ x: Value.variant("+", unit),
85
+ y: Value.variant("-", unit)
86
+ });
87
+ ```
88
+
89
+ Products are JavaScript objects whose keys are k field labels. Variants have a
90
+ string tag and a payload value.
91
+
92
+ ## Minimal Type-Specific Codec
93
+
94
+ This codec accepts `yes` and `no` for the type `<{} true, {} false>`.
95
+
96
+ ```js
97
+ import { Value, isVariant } from "../Value.mjs";
98
+
99
+ const BOOL_PATTERN = [
100
+ ["closed-union", [["false", 1], ["true", 1]]],
101
+ ["closed-product", []]
102
+ ];
103
+
104
+ export const name = "yesno";
105
+ export const patterns = [BOOL_PATTERN];
106
+
107
+ export function parse(text) {
108
+ const word = text.trim();
109
+ if (word === "yes") return Value.variant("true", Value.product({}));
110
+ if (word === "no") return Value.variant("false", Value.product({}));
111
+ throw new Error("expected yes or no");
112
+ }
113
+
114
+ export function print(value) {
115
+ if (!isVariant(value)) throw new Error("expected bool variant");
116
+ if (value.tag === "true") return "yes";
117
+ if (value.tag === "false") return "no";
118
+ throw new Error("expected true or false");
119
+ }
120
+ ```
121
+
122
+ Load it in the REPL:
123
+
124
+ ```text
125
+ > :codec load ./codecs/yesno.mjs
126
+ loaded codec yesno for @...
127
+ > :input <{} true, {} false> yesno
128
+ input @... using yesno: enter value text
129
+ yesno> yes
130
+ {}|true ?<{} false, {} true>
131
+ yesno: yes
132
+ ```
133
+
134
+ ## Add The CLI Boundary
135
+
136
+ To make the same module usable as an installed command, add a `main` function
137
+ that supports `--parse`, `--print`, and `--help`.
138
+
139
+ ```js
140
+ #!/usr/bin/env node
141
+
142
+ import { stdin, stdout, argv, exit } from "node:process";
143
+ import { decodeWire, encodeToWire } from "./runtime/prefix-codec.mjs";
144
+ import { isMainEntrypoint } from "./runtime/cli-entry.mjs";
145
+
146
+ function usage(stream = console.error) {
147
+ stream(`Usage: ${argv[1]} --parse | --print`);
148
+ stream(" --parse Read yes/no text, write binary pattern+value stream.");
149
+ stream(" --print Read binary pattern+value stream, write yes/no text.");
150
+ stream(" -h, --help Show this help.");
151
+ }
152
+
153
+ function readAll(stream) {
154
+ return new Promise((resolve, reject) => {
155
+ const chunks = [];
156
+ stream.on("data", c => chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(c)));
157
+ stream.on("end", () => resolve(Buffer.concat(chunks)));
158
+ stream.on("error", reject);
159
+ });
160
+ }
161
+
162
+ async function main() {
163
+ const args = argv.slice(2);
164
+ if (args.includes("-h") || args.includes("--help")) {
165
+ usage(console.log);
166
+ exit(0);
167
+ }
168
+ if (args.length !== 1 || (args[0] !== "--parse" && args[0] !== "--print")) {
169
+ usage();
170
+ exit(1);
171
+ }
172
+
173
+ const input = await readAll(stdin);
174
+ if (args[0] === "--parse") {
175
+ stdout.write(encodeToWire(parse(input.toString("utf8")), BOOL_PATTERN));
176
+ } else {
177
+ stdout.write(`${print(decodeWire(input).value)}\n`);
178
+ }
179
+ }
180
+
181
+ if (isMainEntrypoint(import.meta.url, argv[1])) {
182
+ main().catch(error => {
183
+ console.error(error.message || String(error));
184
+ exit(1);
185
+ });
186
+ }
187
+ ```
188
+
189
+ The command-line interface must write only the binary stream to stdout in
190
+ `--parse` mode. Diagnostics belong on stderr.
191
+
192
+ Installed codec binaries use the `k-` prefix plus the source basename without
193
+ `.mjs`. For example, `codecs/yesno.mjs` installs as `k-yesno` when added to
194
+ `package.json`.
195
+
196
+ ## Universal Codecs
197
+
198
+ Universal codecs omit `codes` and `patterns`:
199
+
200
+ ```js
201
+ export const name = "json";
202
+ export const universal = true;
203
+
204
+ export function parse(text) {
205
+ // Convert external text to a Value.
206
+ }
207
+
208
+ export function print(value) {
209
+ // Convert a Value to external text.
210
+ }
211
+ ```
212
+
213
+ The built-in [`../codecs/json.mjs`](../codecs/json.mjs) codec is the reference
214
+ example. It derives a pattern for command-line `--parse`, but in the REPL the
215
+ requested `:input` type supplies the target type.
216
+
217
+ ## Test A Codec
218
+
219
+ For CLI codecs, test both directions:
220
+
221
+ ```sh
222
+ printf 'yes\n' | node codecs/yesno.mjs --parse | node codecs/yesno.mjs --print
223
+ ```
224
+
225
+ For REPL codecs, add a focused case to [`../tests/test-repl.mjs`](../tests/test-repl.mjs):
226
+
227
+ ```js
228
+ const state = createState();
229
+ let output = await evaluateInput(":codec load ./codecs/yesno.mjs", state);
230
+ assert.match(output[0], /^loaded codec yesno for @/);
231
+ output = await evaluateInput(":input <{} true, {} false> yesno", state);
232
+ assert.match(output[0], /^input @[^ ]+ using yesno: enter value text$/);
233
+ output = await evaluateInput("yes", state);
234
+ assert.match(output[0], /yesno: yes/);
235
+ ```
236
+
237
+ Run the targeted test first:
238
+
239
+ ```sh
240
+ node tests/test-repl.mjs
241
+ ```
242
+
243
+ Then run the full suite before committing:
244
+
245
+ ```sh
246
+ npm test
247
+ ```
248
+
249
+ ## Checklist
250
+
251
+ - Export a stable `name`.
252
+ - Export exactly one dispatch shape: `patterns`, `codes`, or `universal = true`.
253
+ - Keep `parse` and `print` deterministic.
254
+ - Return structural `Value` objects from `parse`.
255
+ - Validate shapes in `print` and throw clear errors.
256
+ - Keep command-line `--parse` stdout binary-only.
257
+ - Add `-h` and `--help` for installed commands.
258
+ - Add REPL coverage for `:codec load` and `:input`.