@fraczak/k 6.3.3 → 6.4.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/DOCS/CODECS.md +258 -0
- package/DOCS/DICTIONARY.md +1172 -0
- package/DOCS/KIR_SPECIALIZATION_DESIGN.md +51 -46
- package/DOCS/KIR_V1.md +221 -0
- package/DOCS/KVM_EXECUTION_MODEL.md +56 -19
- package/DOCS/OBJECT_FILE_AND_PATTERN.md +2 -1
- package/DOCS/PROFILING_AND_TRACING.md +196 -0
- package/DOCS/REPL.md +61 -4
- package/DOCS/WEB_REPL_REQUIREMENTS.md +135 -0
- package/DOCS/dependency-graph.md +144 -0
- package/Examples/arithmetics.k +51 -48
- package/Examples/bnat.k +1 -1
- package/Examples/buda.k +44 -0
- package/Examples/ieee.k +300 -8671
- package/Examples/poly.k +67 -0
- package/README.md +68 -19
- package/augmentation.mjs +9 -7
- package/backend-api.mjs +11 -2
- package/backends/arm64/README.md +104 -0
- package/backends/arm64/bin/k-arm64-compile.mjs +101 -0
- package/backends/arm64/bin/k-arm64-run.mjs +58 -0
- package/backends/arm64/bin/k-arm64.mjs +88 -0
- package/backends/arm64/scripts/run-tests.mjs +41 -0
- package/backends/arm64/src/arm64.mjs +229 -0
- package/backends/arm64/src/cli.mjs +155 -0
- package/backends/arm64/src/kvm2arm64.mjs +906 -0
- package/backends/arm64/src/runtime.c +728 -0
- package/backends/arm64/tests/integration.sh +112 -0
- package/backends/arm64/tests/test-arm64.mjs +240 -0
- package/backends/llvm/README.md +135 -0
- package/backends/llvm/bin/k-llvm-build.mjs +71 -0
- package/backends/llvm/bin/k-llvm-compile.mjs +68 -0
- package/backends/llvm/bin/k-llvm-jit.mjs +160 -0
- package/backends/llvm/bin/k-llvm-run.mjs +90 -0
- package/backends/llvm/runtime/krt.c +1508 -0
- package/backends/llvm/runtime/krt.h +109 -0
- package/backends/llvm/scripts/conformance.mjs +76 -0
- package/backends/llvm/scripts/run-tests.mjs +28 -0
- package/backends/llvm/src/executable.mjs +562 -0
- package/backends/llvm/src/kvm2llvm.mjs +998 -0
- package/backends/llvm/src/llvm.mjs +1092 -0
- package/backends/llvm/tests/composition-driver.c +22 -0
- package/backends/llvm/tests/identity-driver.c +27 -0
- package/backends/llvm/tests/integration.sh +153 -0
- package/backends/llvm/tests/perf-support.mjs +735 -0
- package/backends/llvm/tests/product-driver.c +23 -0
- package/backends/llvm/tests/projection-driver.c +19 -0
- package/backends/llvm/tests/relation-driver.c +29 -0
- package/backends/llvm/tests/test-llvm.mjs +240 -0
- package/backends/llvm/tests/union-driver.c +31 -0
- package/backends/llvm/tests/variant-driver.c +19 -0
- package/backends/llvm/tests/variant-projection-driver.c +21 -0
- package/backends/wasm/DOCS/USE-WEB-ASSEMBLY.md +233 -0
- package/backends/wasm/README.md +97 -0
- package/backends/wasm/TECHNICAL-DEBT.md +60 -0
- package/backends/wasm/bin/k-wasm-compile.mjs +50 -0
- package/backends/wasm/bin/k-wasm-run.mjs +140 -0
- package/backends/wasm/bin/k-wasm.mjs +49 -0
- package/backends/wasm/demo_ieee.mjs +319 -0
- package/backends/wasm/runtime.wat +102 -0
- package/backends/wasm/scripts/run-tests.mjs +41 -0
- package/backends/wasm/src/cli.mjs +133 -0
- package/backends/wasm/src/kvm2wasm.mjs +661 -0
- package/backends/wasm/src/wasm.mjs +1010 -0
- package/backends/wasm/tests/integration.sh +182 -0
- package/backends/wasm/tests/perf-support.mjs +336 -0
- package/backends/wasm/tests/test-wasm.mjs +617 -0
- package/browser/repl-browser.mjs +1584 -0
- package/browser/shims/assert.mjs +19 -0
- package/browser/shims/buffer.mjs +224 -0
- package/browser/shims/crypto.mjs +103 -0
- package/browser/shims/fs.mjs +159 -0
- package/browser/shims/os.mjs +17 -0
- package/browser/shims/path.mjs +54 -0
- package/browser/shims/process.mjs +44 -0
- package/browser/shims/readline.mjs +11 -0
- package/browser/shims/url.mjs +12 -0
- package/browser/vfs-data.mjs +19 -0
- package/codecs/README.md +3 -0
- package/codecs/runtime/show-value.mjs +2 -2
- package/conformance/helper-reuse/case.json +8 -0
- package/conformance/helper-reuse/expected.kv +1 -0
- package/conformance/helper-reuse/input.kv +1 -0
- package/conformance/helper-reuse/program.k +2 -0
- package/conformance/identity/case.json +8 -0
- package/conformance/identity/expected.kv +1 -0
- package/conformance/identity/input.kv +1 -0
- package/conformance/identity/program.k +1 -0
- package/conformance/product-projection/case.json +8 -0
- package/conformance/product-projection/expected.kv +1 -0
- package/conformance/product-projection/input.kv +1 -0
- package/conformance/product-projection/program.k +1 -0
- package/conformance/run.mjs +149 -0
- package/conformance/variant-construction/case.json +8 -0
- package/conformance/variant-construction/expected.kv +1 -0
- package/conformance/variant-construction/input.kv +1 -0
- package/conformance/variant-construction/program.k +1 -0
- package/harness/adapters/arm64.mjs +105 -0
- package/harness/adapters/kvm.mjs +144 -0
- package/harness/adapters/llvm.mjs +118 -0
- package/harness/adapters/native.mjs +77 -0
- package/harness/adapters/wasm.mjs +169 -0
- package/harness/backend.mjs +95 -0
- package/harness/cli.mjs +130 -0
- package/harness/format.mjs +95 -0
- package/harness/index.mjs +25 -0
- package/harness/persistent.mjs +121 -0
- package/harness/registry.mjs +44 -0
- package/harness/suite.mjs +257 -0
- package/harness/suites/poly.mjs +156 -0
- package/harness/trace.mjs +50 -0
- package/harness/util.mjs +92 -0
- package/intrinsics.mjs +41 -0
- package/kir.mjs +399 -0
- package/kvm.mjs +585 -81
- package/objects/README.md +37 -3
- package/objects/compile.mjs +15 -22
- package/objects/inspect.mjs +96 -0
- package/objects/validate.mjs +415 -0
- package/package.json +51 -19
- package/repl-codecs.mjs +105 -6
- package/repl.mjs +335 -49
- package/run.mjs +2 -7
- package/scripts/benchmark.mjs +406 -22
- package/scripts/build-repl-html.mjs +1784 -0
- package/scripts/perf-ieee.mjs +586 -0
- package/scripts/perf-int.mjs +531 -0
- package/scripts/perf-poly.mjs +945 -0
- package/scripts/render-benchmark.mjs +12 -8
- package/scripts/run-tests.mjs +6 -0
- package/tests/integration.sh +19 -2
- package/tests/test-arithmetics.mjs +54 -0
- package/tests/test-ieee-arithmetic.mjs +4 -0
- package/tests/test-kir.mjs +85 -0
- package/tests/test-kvm-polymorphic.mjs +278 -0
- package/tests/test-kvm.mjs +25 -6
- package/tests/test-poly.mjs +129 -0
- package/tests/test-repl-html.mjs +303 -0
- package/tests/test-repl.mjs +144 -1
- package/tests/test-validate-object.mjs +40 -0
- package/a.klib +0 -1
- package/a.kvm +0 -142676
- package/a.wasm +0 -0
- package/benchmark-results.html +0 -532
- package/benchmark-results.json +0 -480
- package/k-vscode/.vscode/launch.json +0 -14
- package/k-vscode/README.md +0 -75
- package/k-vscode/extension.js +0 -273
- package/k-vscode/language-configuration.json +0 -42
- package/k-vscode/package.json +0 -79
- package/k-vscode/snippets/k.json +0 -92
- package/k-vscode/syntaxes/k.tmLanguage.json +0 -599
- package/k-vscode/test/background-ranges.test.js +0 -50
- package/k-vscode/themes/k-contrast-color-theme.json +0 -104
- package/scripts/git-hooks/pre-commit +0 -10
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`.
|