@fraczak/k 6.2.0 → 6.2.1

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.
@@ -0,0 +1,35 @@
1
+ # k Test Suite
2
+
3
+ This directory contains the automated tests, type-derivation validation cases, and integration test scripts for the `k` compiler and runtime.
4
+
5
+ ## Running the Tests
6
+
7
+ ### 1. Run Unit and Integration Test Suite
8
+ To run all core unit tests, type-derivation checks, and integration tests:
9
+ ```bash
10
+ npm test
11
+ ```
12
+ This executes `node scripts/run-tests.mjs`, which discovers and runs the test scripts sequentially.
13
+
14
+ ## Test Directory Structure
15
+
16
+ ### 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.
30
+
31
+ ### 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.
33
+
34
+ ### 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.
@@ -20,7 +20,7 @@ const explicitProductWire = decodeWire(encodeToWire(value, [
20
20
  ["any", []]
21
21
  ]));
22
22
  assert.deepEqual(explicitProductWire.pattern, [
23
- ["open-product", [["a", 1]]],
23
+ ["closed-product", [["a", 1]]],
24
24
  ["closed-product", [["b", 2], ["c", 3]]],
25
25
  ["open-union", [["x", 3]]],
26
26
  ["closed-product", []]
@@ -5,6 +5,9 @@ set -euo pipefail
5
5
 
6
6
  echo "Running './tests/integration.sh' ..."
7
7
 
8
+ TMP_DIR=`mktemp -d`
9
+ trap 'rm -rf "$TMP_DIR"' EXIT
10
+
8
11
  echo '["zebara", "ela", "kupa", ala, owca]' | node ./codecs/k-parse.mjs | ./k.mjs '{.1 0,.3 1}' | node ./codecs/k-print.mjs
9
12
  echo
10
13
  echo '-21' | node ./codecs/int.mjs --parse | node ./codecs/int.mjs --print | grep -qx -- '-21'
@@ -13,14 +16,14 @@ node ./codecs/unit.mjs --parse | node ./codecs/unit.mjs --print | grep -qx '{}'
13
16
  echo
14
17
  printf 'A🙂\nBé~\t' | ./codecs/utf8.mjs --parse | ./k.mjs -k Examples/byte.k |./codecs/utf8.mjs --print
15
18
  echo
16
- ./objects/compile-lib.mjs Examples/ieee.k ieee.klib
17
- MUL=`./objects/extract-aliases.mjs ieee.klib | grep '^mul = @' | sed 's/^mul = \(@[^;]*\);.*$/\1/'`
18
- DIV=`./objects/extract-aliases.mjs ieee.klib | grep '^div = @' | sed 's/^div = \(@[^;]*\);.*$/\1/'`
19
+ ./objects/compile-lib.mjs Examples/ieee.k "$TMP_DIR/ieee.klib"
20
+ MUL=`./objects/extract-aliases.mjs "$TMP_DIR/ieee.klib" | grep '^mul = @' | sed 's/^mul = \(@[^;]*\);.*$/\1/'`
21
+ DIV=`./objects/extract-aliases.mjs "$TMP_DIR/ieee.klib" | grep '^div = @' | sed 's/^div = \(@[^;]*\);.*$/\1/'`
19
22
  ARG=0.12
20
23
  printf "$ARG * $ARG = "
21
- echo $ARG | ./codecs/ieee.mjs --parse | ./k.mjs --lib ieee.klib "{()x,()y} $MUL .result" | ./codecs/ieee.mjs --print
24
+ echo $ARG | ./codecs/ieee.mjs --parse | ./k.mjs --lib "$TMP_DIR/ieee.klib" "{()x,()y} $MUL .result" | ./codecs/ieee.mjs --print
22
25
  printf "$ARG / $ARG = "
23
- DIV_RESULT=`echo $ARG | ./codecs/ieee.mjs --parse | ./k.mjs --lib ieee.klib "{()x,()y} $DIV .result" | ./codecs/ieee.mjs --print`
26
+ DIV_RESULT=`echo $ARG | ./codecs/ieee.mjs --parse | ./k.mjs --lib "$TMP_DIR/ieee.klib" "{()x,()y} $DIV .result" | ./codecs/ieee.mjs --print`
24
27
  echo "$DIV_RESULT"
25
28
  test "$DIV_RESULT" = "1"
26
29
  echo
@@ -0,0 +1,163 @@
1
+ import assert from "node:assert";
2
+ import k from "../index.mjs";
3
+ import { lowerToKVM, executeKVM } from "../kvm.mjs";
4
+ import codes from "../codes.mjs";
5
+ import { fromObject, Product, Variant } from "../Value.mjs";
6
+ import run, { run_converged } from "../run.mjs";
7
+
8
+ function runKVM(script, data, options = {}) {
9
+ const defs = k.annotate(script, {
10
+ convergence: { strategy: "auto" }
11
+ });
12
+ const mainRel = defs.rels.__main__;
13
+ const kvmFunc = lowerToKVM(mainRel, "__main__");
14
+ const context = { rels: defs.rels, findCode: codes.find, options };
15
+ return executeKVM(kvmFunc, fromObject(data), context);
16
+ }
17
+
18
+ function toJSON(value) {
19
+ if (value === undefined) return undefined;
20
+ return JSON.parse(JSON.stringify(value));
21
+ }
22
+
23
+ console.log("==> Starting kVM Tests");
24
+
25
+ // Test 1: Identity
26
+ {
27
+ const result = runKVM("()", { unit: {} });
28
+ assert.deepEqual(toJSON(result), "unit");
29
+ console.log("Test 1 (Identity): Passed");
30
+ }
31
+
32
+ // Test 2: Product field projection
33
+ {
34
+ const result = runKVM(".name", { name: { ala: {} }, age: { twentythree: {} } });
35
+ assert.deepEqual(toJSON(result), "ala");
36
+ console.log("Test 2 (Field projection): Passed");
37
+ }
38
+
39
+ // Test 3: Variant projections and lifting
40
+ {
41
+ const result = runKVM("/tag |tag", { tag: { payload: {} } });
42
+ assert.deepEqual(toJSON(result), { tag: "payload" });
43
+ console.log("Test 3 (Variant projection & construction): Passed");
44
+ }
45
+
46
+ // Test 4: Composition
47
+ {
48
+ const result = runKVM("(.x .y)", { x: { y: { ok: {}, dummy: {} }, dummy: {} }, dummy: {} });
49
+ assert.deepEqual(toJSON(result), { ok: {}, dummy: {} });
50
+ console.log("Test 4 (Composition): Passed");
51
+ }
52
+
53
+ // Test 5: Union (Speculative choice)
54
+ {
55
+ const result1 = runKVM("< /x, /y >", { x: { val: {} } });
56
+ assert.deepEqual(toJSON(result1), "val");
57
+
58
+ const result2 = runKVM("< /x, /y >", { y: { val: {} } });
59
+ assert.deepEqual(toJSON(result2), "val");
60
+
61
+ const result3 = runKVM("< /x, /y >", { z: { val: {} } });
62
+ assert.equal(result3, undefined);
63
+ console.log("Test 5 (Union / Choice): Passed");
64
+ }
65
+
66
+ // Test 6: Parallel Product
67
+ {
68
+ const result = runKVM("{ .x fieldA, .y fieldB }", { x: { valA: {} }, y: { valB: {} } });
69
+ assert.deepEqual(toJSON(result), {
70
+ fieldA: "valA",
71
+ fieldB: "valB"
72
+ });
73
+ console.log("Test 6 (Product): Passed");
74
+ }
75
+
76
+ // Test 7: Filters & Types
77
+ {
78
+ const script = `
79
+ $ bool = < {} true, {} false >;
80
+ $ bool
81
+ `;
82
+ const result1 = runKVM(script, { true: {} });
83
+ assert.deepEqual(toJSON(result1), "true");
84
+
85
+ const result2 = runKVM(script, { unknown_tag: {} });
86
+ assert.deepEqual(toJSON(result2), "unknown_tag");
87
+ console.log("Test 7 (Filters & Type Guards): Passed");
88
+ }
89
+
90
+ // Test 8: Recursive List traversal (Cons/Nil)
91
+ {
92
+ const script = `
93
+ $ bool = < {} true, {} false >;
94
+ true = {} | true $bool;
95
+ false = {} | false $bool;
96
+
97
+ list? = ?< {} nil, {X car, Y cdr} cons > = Y;
98
+ nil = {}|nil list?;
99
+ nil? = list? /nil nil;
100
+ car = list? /cons .car;
101
+ list? {
102
+ < nil? true, false > nil_test,
103
+ < car, {}|none > car
104
+ }
105
+ `;
106
+
107
+ // Test Nil list
108
+ const res1 = runKVM(script, { nil: {} });
109
+ assert.deepEqual(toJSON(res1), { nil_test: "true", car: "none" });
110
+
111
+ // Test Cons list
112
+ const res2 = runKVM(script, {
113
+ cons: {
114
+ car: { unit: {} },
115
+ cdr: { nil: {} }
116
+ }
117
+ });
118
+ assert.deepEqual(toJSON(res2), { nil_test: "false", car: "unit" });
119
+ console.log("Test 8 (Recursive lists): Passed");
120
+ }
121
+
122
+ // Test 9: Comparing KVM execution vs Native JS run (Envelope-aware and Envelope-free)
123
+ {
124
+ const script = `
125
+ $ nat = < {} 0, nat +1 >;
126
+ 0 = {} | 0 $ nat;
127
+ inc = | +1 $ nat;
128
+ dec = $ nat / +1;
129
+ add = $ { nat x, nat y } <
130
+ { . x dec x, . y inc y } add,
131
+ . y
132
+ >;
133
+ `;
134
+
135
+ const inputData = {
136
+ x: { "+1": { "+1": { "0": {} } } }, // 2
137
+ y: { "+1": { "0": {} } } // 1
138
+ };
139
+
140
+ // Run in native JS envelope-aware mode
141
+ const nativeAware = k.run(script + " add", inputData);
142
+ // Run in native JS envelope-free mode
143
+ const defs = k.annotate(script + " add", {
144
+ convergence: { strategy: "auto" }
145
+ });
146
+ run.defs = defs;
147
+ run_converged.defs = defs;
148
+ const nativeFree = run_converged(codes.find, defs.rels.__main__.def, fromObject(inputData), defs.rels.__main__.typePatternGraph);
149
+
150
+ // Run in kVM envelope-aware mode
151
+ const kvmAware = runKVM(script + " add", inputData, { envelopeFree: false });
152
+ // Run in kVM envelope-free mode
153
+ const kvmFree = runKVM(script + " add", inputData, { envelopeFree: true });
154
+
155
+ assert.deepEqual(toJSON(kvmAware), toJSON(nativeAware));
156
+ assert.deepEqual(toJSON(kvmFree), toJSON(nativeFree));
157
+
158
+ // Verify that the output is 3 (i.e. +1(+1(+1(0))))
159
+ assert.deepEqual(toJSON(kvmAware), { "+1": { "+1": { "+1": "0" } } });
160
+ console.log("Test 9 (KVM vs JS run equivalence & Peano addition): Passed");
161
+ }
162
+
163
+ console.log("==> All kVM Tests Passed!");