@fraczak/k 6.10.2 → 6.10.4
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 +73 -0
- package/DOCS/BIG_PICTURE.md +174 -100
- package/DOCS/CODECS.md +74 -29
- package/DOCS/CODEC_ARCHITECTURE.md +87 -31
- package/DOCS/CONVERGENCE.md +42 -11
- package/DOCS/DICTIONARY.md +69 -2
- package/DOCS/FILE_FORMATS.md +420 -0
- package/DOCS/KIR_V1.md +53 -42
- package/DOCS/KVM_EXECUTION_MODEL.md +189 -147
- package/DOCS/OBJECT_FILE_AND_PATTERN.md +35 -17
- package/DOCS/PATTERNS.md +10 -6
- package/DOCS/REPL.md +100 -60
- package/DOCS/TEXTUAL_VALUES.md +24 -19
- package/DOCS/TYPE_DERIVATION.md +68 -22
- package/Examples/karatsuba-mult.k +215 -0
- package/README.md +92 -58
- package/backends/arm64/scripts/run-tests.mjs +16 -0
- package/backends/llvm/bin/k-llvm-build.mjs +40 -14
- package/backends/llvm/bin/k-llvm-compile.mjs +29 -12
- package/backends/llvm/runtime/krt.c +10 -10
- package/backends/llvm/runtime/krt.h +6 -1
- package/backends/llvm/scripts/run-tests.mjs +16 -0
- package/backends/llvm/src/cli.mjs +1 -1
- package/backends/llvm/src/executable.mjs +36 -0
- package/backends/llvm/src/kvm2llvm.mjs +10 -4
- package/backends/llvm/tests/integration.sh +11 -0
- package/backends/llvm/tests/test-llvm.mjs +15 -1
- package/backends/wasm/scripts/run-tests.mjs +16 -0
- package/browser/vfs-data.mjs +1 -1
- package/codecs/README.md +78 -67
- package/core.k +5 -5
- package/objects/README.md +57 -37
- package/package.json +2 -1
- package/scripts/benchmark-idempotency.mjs +27 -0
- package/scripts/benchmark.mjs +51 -0
- package/scripts/build-repl-html.mjs +17 -0
- package/scripts/generate-dependency-graph.mjs +25 -1
- package/scripts/perf-ieee.mjs +75 -0
- package/scripts/perf-int.mjs +67 -0
- package/scripts/perf-multiplication.mjs +644 -0
- package/scripts/perf-poly.mjs +67 -0
- package/scripts/render-benchmark.mjs +25 -0
- package/scripts/run-tests.mjs +19 -0
- package/tests/README.md +28 -17
- package/tests/test-karatsuba.mjs +133 -0
|
@@ -5,6 +5,31 @@ import path from "node:path";
|
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
|
|
7
7
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
8
|
+
|
|
9
|
+
function printHelp() {
|
|
10
|
+
console.log(
|
|
11
|
+
`Usage: node scripts/render-benchmark.mjs [in.json] [out.html]
|
|
12
|
+
|
|
13
|
+
Renders benchmark results JSON into a standalone interactive HTML report.
|
|
14
|
+
|
|
15
|
+
Arguments:
|
|
16
|
+
input-json
|
|
17
|
+
Path to benchmark results JSON file.
|
|
18
|
+
(default: benchmark-results.json)
|
|
19
|
+
output-html
|
|
20
|
+
Destination path for generated HTML report.
|
|
21
|
+
(default: benchmark-results.html)
|
|
22
|
+
|
|
23
|
+
Options:
|
|
24
|
+
-h, --help
|
|
25
|
+
Show this help message and exit.`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (process.argv.includes("-h") || process.argv.includes("--help")) {
|
|
29
|
+
printHelp();
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
8
33
|
const inputPath = path.resolve(root, process.argv[2] || "benchmark-results.json");
|
|
9
34
|
const outputPath = path.resolve(root, process.argv[3] || "benchmark-results.html");
|
|
10
35
|
|
package/scripts/run-tests.mjs
CHANGED
|
@@ -7,6 +7,24 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
|
|
8
8
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
9
9
|
const node = process.execPath;
|
|
10
|
+
|
|
11
|
+
function printHelp() {
|
|
12
|
+
console.log(`Usage: node scripts/run-tests.mjs [options]
|
|
13
|
+
|
|
14
|
+
Runs the comprehensive K language test suite, including core unit tests,
|
|
15
|
+
type derivation, codecs, object encoding, conformance, REPL, interpreter,
|
|
16
|
+
and arithmetic suites.
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
-h, --help
|
|
20
|
+
Show this help message and exit.`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (process.argv.includes("-h") || process.argv.includes("--help")) {
|
|
24
|
+
printHelp();
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
10
28
|
const derivationTests = fs.readdirSync(path.join(root, "tests/code-derivation"))
|
|
11
29
|
.filter((name) => name.endsWith(".mjs"))
|
|
12
30
|
.sort()
|
|
@@ -31,6 +49,7 @@ const tests = [
|
|
|
31
49
|
["tests/test-kvm.mjs", node, ["tests/test-kvm.mjs"]],
|
|
32
50
|
["tests/test-kvm-polymorphic.mjs", node, ["tests/test-kvm-polymorphic.mjs"]],
|
|
33
51
|
["tests/test-arithmetics.mjs", node, ["tests/test-arithmetics.mjs"]],
|
|
52
|
+
["tests/test-karatsuba.mjs", node, ["tests/test-karatsuba.mjs"]],
|
|
34
53
|
["tests/test-poly.mjs", node, ["tests/test-poly.mjs"]],
|
|
35
54
|
["tests/test-ieee-arithmetic.mjs", node, ["tests/test-ieee-arithmetic.mjs"]],
|
|
36
55
|
["tests/integration.sh", path.join(root, "tests/integration.sh"), []]
|
package/tests/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# k Test Suite
|
|
2
2
|
|
|
3
|
-
This directory contains
|
|
3
|
+
This directory contains automated tests, type-derivation validation
|
|
4
|
+
cases, and integration test scripts for the `k` compiler and runtime.
|
|
4
5
|
|
|
5
6
|
## Running the Tests
|
|
6
7
|
|
|
@@ -9,27 +10,37 @@ To run all core unit tests, type-derivation checks, and integration tests:
|
|
|
9
10
|
```bash
|
|
10
11
|
npm test
|
|
11
12
|
```
|
|
12
|
-
This executes `node scripts/run-tests.mjs`, which discovers and runs the
|
|
13
|
+
This executes `node scripts/run-tests.mjs`, which discovers and runs the
|
|
14
|
+
test scripts sequentially.
|
|
13
15
|
|
|
14
16
|
## Test Directory Structure
|
|
15
17
|
|
|
16
18
|
### Core Test Files
|
|
17
|
-
- **[test.mjs](
|
|
18
|
-
|
|
19
|
-
- **[test-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- **[test-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
[
|
|
19
|
+
- **[test.mjs](test.mjs)**: Verifies basic parser and runtime
|
|
20
|
+
execution behavior.
|
|
21
|
+
- **[test-kvm.mjs](test-kvm.mjs)**: Conformance testing for the kVM
|
|
22
|
+
register compiler and interpreter in envelope-aware and envelope-free
|
|
23
|
+
modes.
|
|
24
|
+
- **[test-kvm-polymorphic.mjs](test-kvm-polymorphic.mjs)**: Tests for
|
|
25
|
+
polymorphic `.kvm` templates (`layer: "KVM-P"`) and runtime input
|
|
26
|
+
envelope specialization (`specializeKVM`).
|
|
27
|
+
- **[test-ieee-arithmetic.mjs](test-ieee-arithmetic.mjs)**: Verifies
|
|
28
|
+
IEEE-754 double precision float arithmetic (`Examples/ieee.k`).
|
|
29
|
+
- **[test-repl.mjs](test-repl.mjs)**: Tests interactive REPL commands,
|
|
30
|
+
state transitions, imports, `.klib` and `.ko` exports.
|
|
31
|
+
- **[test-k-object.mjs](test-k-object.mjs)**: Tests serialization,
|
|
32
|
+
compilation, and loading of `.ko` binary objects and `.klib` libraries.
|
|
33
|
+
- **[test-fingerprint.mjs](test-fingerprint.mjs)**: Tests semantic
|
|
34
|
+
expression and relation hashing/fingerprinting (`@hash`).
|
|
35
|
+
- **[test-hash-normalization.mjs](test-hash-normalization.mjs)**:
|
|
36
|
+
Verifies consistent normalization of type pattern graphs and hashes.
|
|
37
|
+
- **[test-hash-fuzz.mjs](test-hash-fuzz.mjs)**: Fuzzes expression and
|
|
38
|
+
relation hashing to guard against collisions.
|
|
30
39
|
|
|
31
40
|
### Type Derivation Suites
|
|
32
|
-
- **[code-derivation/](
|
|
41
|
+
- **[code-derivation/](code-derivation/)**: Individual files validating
|
|
42
|
+
type-derivation convergence and pattern-envelope generation.
|
|
33
43
|
|
|
34
44
|
### Integration Scripts
|
|
35
|
-
- **[integration.sh](
|
|
45
|
+
- **[integration.sh](integration.sh)**: Shell script checking boundary
|
|
46
|
+
data pipelines (`k-parse`, `k-show`, `k-print`) against binary outputs.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const root = path.resolve(scriptDir, "..");
|
|
10
|
+
const node = process.execPath;
|
|
11
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "k-karatsuba-"));
|
|
12
|
+
const libPath = path.join(tmpDir, "karatsuba-mult.klib");
|
|
13
|
+
const kSource = path.join(root, "Examples/karatsuba-mult.k");
|
|
14
|
+
const program = "{() x, () y} karatsuba";
|
|
15
|
+
|
|
16
|
+
const smallInput =
|
|
17
|
+
"111111122222233333344444445555556666667777777888888999999000000" +
|
|
18
|
+
"11111122222233333344444455555";
|
|
19
|
+
|
|
20
|
+
function run(command, args, options = {}) {
|
|
21
|
+
const result = spawnSync(command, args, {
|
|
22
|
+
cwd: root,
|
|
23
|
+
input: options.input,
|
|
24
|
+
encoding: options.encoding ?? null,
|
|
25
|
+
maxBuffer: 64 * 1024 * 1024
|
|
26
|
+
});
|
|
27
|
+
if (result.error && result.status == null) throw result.error;
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function assertOk(result, label) {
|
|
32
|
+
if (result.status !== 0) {
|
|
33
|
+
const stderr = Buffer.isBuffer(result.stderr)
|
|
34
|
+
? result.stderr.toString("utf8")
|
|
35
|
+
: String(result.stderr ?? "");
|
|
36
|
+
const stdout = Buffer.isBuffer(result.stdout)
|
|
37
|
+
? result.stdout.toString("utf8")
|
|
38
|
+
: String(result.stdout ?? "");
|
|
39
|
+
assert.fail(
|
|
40
|
+
`${label} failed (status ${result.status})\n` +
|
|
41
|
+
`STDERR:\n${stderr}\nSTDOUT:\n${stdout}`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function parseIntWire(text) {
|
|
47
|
+
const result = run(node, ["codecs/int.mjs", "--parse"], {
|
|
48
|
+
input: `${text}\n`
|
|
49
|
+
});
|
|
50
|
+
assertOk(result, `parse int ${text}`);
|
|
51
|
+
return result.stdout;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function printIntWire(wire, label) {
|
|
55
|
+
const result = run(node, ["codecs/int.mjs", "--print"], {
|
|
56
|
+
input: wire,
|
|
57
|
+
encoding: "utf8"
|
|
58
|
+
});
|
|
59
|
+
assertOk(result, `${label} print`);
|
|
60
|
+
return result.stdout.trim();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function runKaratsuba(inputText) {
|
|
64
|
+
const wire = parseIntWire(inputText);
|
|
65
|
+
const result = run(node, [
|
|
66
|
+
"k.mjs",
|
|
67
|
+
"--lib", libPath,
|
|
68
|
+
"--export", "karatsuba:karatsuba",
|
|
69
|
+
program
|
|
70
|
+
], { input: wire });
|
|
71
|
+
assertOk(result, `native karatsuba(${inputText})`);
|
|
72
|
+
return printIntWire(result.stdout, `native karatsuba`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function expectedSquare(inputText) {
|
|
76
|
+
const n = BigInt(inputText);
|
|
77
|
+
return (n * n).toString();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
assertOk(
|
|
82
|
+
run(node, ["objects/compile.mjs", kSource, libPath], {
|
|
83
|
+
encoding: "utf8"
|
|
84
|
+
}),
|
|
85
|
+
"compile Examples/karatsuba-mult.k"
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const testInputs = [
|
|
89
|
+
"0",
|
|
90
|
+
"1",
|
|
91
|
+
"-1",
|
|
92
|
+
"7",
|
|
93
|
+
"-7",
|
|
94
|
+
"42",
|
|
95
|
+
"-42",
|
|
96
|
+
"123456789",
|
|
97
|
+
"-123456789",
|
|
98
|
+
"987654321987654321",
|
|
99
|
+
"-987654321987654321",
|
|
100
|
+
smallInput,
|
|
101
|
+
`-${smallInput}`
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
for (const input of testInputs) {
|
|
105
|
+
assert.equal(
|
|
106
|
+
runKaratsuba(input),
|
|
107
|
+
expectedSquare(input),
|
|
108
|
+
`karatsuba square(${input.slice(0, 20)}...) mismatch`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Test asymmetric pair multiplication with mixed signs via int list
|
|
113
|
+
const pairWire = parseIntWire(
|
|
114
|
+
"[12345678901234567890, -98765432109876543210]"
|
|
115
|
+
);
|
|
116
|
+
const pairProgram = "/cons { .car x, .cdr /cons .car y } karatsuba";
|
|
117
|
+
const resPair = run(node, [
|
|
118
|
+
"k.mjs",
|
|
119
|
+
"--lib", libPath,
|
|
120
|
+
"--export", "karatsuba:karatsuba",
|
|
121
|
+
pairProgram
|
|
122
|
+
], { input: pairWire });
|
|
123
|
+
assertOk(resPair, "pair multiplication");
|
|
124
|
+
assert.equal(
|
|
125
|
+
printIntWire(resPair.stdout, "pair multiplication"),
|
|
126
|
+
(12345678901234567890n * -98765432109876543210n).toString(),
|
|
127
|
+
"asymmetric pair multiplication should match BigInt oracle"
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
console.log("OK");
|
|
131
|
+
} finally {
|
|
132
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
133
|
+
}
|