@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.
Files changed (45) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/DOCS/BIG_PICTURE.md +174 -100
  3. package/DOCS/CODECS.md +74 -29
  4. package/DOCS/CODEC_ARCHITECTURE.md +87 -31
  5. package/DOCS/CONVERGENCE.md +42 -11
  6. package/DOCS/DICTIONARY.md +69 -2
  7. package/DOCS/FILE_FORMATS.md +420 -0
  8. package/DOCS/KIR_V1.md +53 -42
  9. package/DOCS/KVM_EXECUTION_MODEL.md +189 -147
  10. package/DOCS/OBJECT_FILE_AND_PATTERN.md +35 -17
  11. package/DOCS/PATTERNS.md +10 -6
  12. package/DOCS/REPL.md +100 -60
  13. package/DOCS/TEXTUAL_VALUES.md +24 -19
  14. package/DOCS/TYPE_DERIVATION.md +68 -22
  15. package/Examples/karatsuba-mult.k +215 -0
  16. package/README.md +92 -58
  17. package/backends/arm64/scripts/run-tests.mjs +16 -0
  18. package/backends/llvm/bin/k-llvm-build.mjs +40 -14
  19. package/backends/llvm/bin/k-llvm-compile.mjs +29 -12
  20. package/backends/llvm/runtime/krt.c +10 -10
  21. package/backends/llvm/runtime/krt.h +6 -1
  22. package/backends/llvm/scripts/run-tests.mjs +16 -0
  23. package/backends/llvm/src/cli.mjs +1 -1
  24. package/backends/llvm/src/executable.mjs +36 -0
  25. package/backends/llvm/src/kvm2llvm.mjs +10 -4
  26. package/backends/llvm/tests/integration.sh +11 -0
  27. package/backends/llvm/tests/test-llvm.mjs +15 -1
  28. package/backends/wasm/scripts/run-tests.mjs +16 -0
  29. package/browser/vfs-data.mjs +1 -1
  30. package/codecs/README.md +78 -67
  31. package/core.k +5 -5
  32. package/objects/README.md +57 -37
  33. package/package.json +2 -1
  34. package/scripts/benchmark-idempotency.mjs +27 -0
  35. package/scripts/benchmark.mjs +51 -0
  36. package/scripts/build-repl-html.mjs +17 -0
  37. package/scripts/generate-dependency-graph.mjs +25 -1
  38. package/scripts/perf-ieee.mjs +75 -0
  39. package/scripts/perf-int.mjs +67 -0
  40. package/scripts/perf-multiplication.mjs +644 -0
  41. package/scripts/perf-poly.mjs +67 -0
  42. package/scripts/render-benchmark.mjs +25 -0
  43. package/scripts/run-tests.mjs +19 -0
  44. package/tests/README.md +28 -17
  45. 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
 
@@ -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 the automated tests, type-derivation validation cases, and integration test scripts for the `k` compiler and runtime.
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 test scripts sequentially.
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](file:///Users/wojtek/gits/k/tests/test.mjs)**: Verifies basic parser and runtime execution behavior.
18
- - **[test-kvm.mjs](file:///Users/wojtek/gits/k/tests/test-kvm.mjs)**: Comprehensive conformance testing for the kVM register compiler and interpreter under both envelope-aware and envelope-free modes.
19
- - **[test-ieee-arithmetic.mjs](file:///Users/wojtek/gits/k/tests/test-ieee-arithmetic.mjs)**: Verifies IEEE-754 double precision float arithmetic implementation (`Examples/ieee.k`).
20
- - **[test-repl.mjs](file:///Users/wojtek/gits/k/tests/test-repl.mjs)**: Tests interactive REPL commands, state transitions, imports, and auto-completions.
21
- - **[test-k-object.mjs](file:///Users/wojtek/gits/k/tests/test-k-object.mjs)**: Tests serialization, compilation, and loading of `.ko` binary objects.
22
- - **[test-fingerprint.mjs](file:///Users/wojtek/gits/k/tests/test-fingerprint.mjs)**: Tests semantic expression and relation hashing/fingerprinting.
23
- - **[test-hash-normalization.mjs](file:///Users/wojtek/gits/k/tests/test-hash-normalization.mjs)**: Verifies consistent normalization of type pattern graphs and hashes.
24
- - **[test-hash-fuzz.mjs](file:///Users/wojtek/gits/k/tests/test-hash-fuzz.mjs)**: Fuzzes expression/relation hashing to guard against collisions.
25
-
26
- ### WebAssembly Benchmarks
27
-
28
- The WebAssembly execution benchmark moved to the separate
29
- [`fraczak/k-wasm`](https://github.com/fraczak/k-wasm) backend repository.
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/](file:///Users/wojtek/gits/k/tests/code-derivation)**: Houses individual files (each containing a focused test scenario) validating type-derivation convergence and pattern-envelope generation.
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](file:///Users/wojtek/gits/k/tests/integration.sh)**: Shell script checking boundary data pipelines (`k-parse`, `k-show`, `k-print`) against binary outputs.
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
+ }