@fraczak/k 7.0.1 → 7.1.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 (89) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/DOCS/BIG_PICTURE.md +5 -5
  3. package/DOCS/FILE_FORMATS.md +241 -18
  4. package/DOCS/OBJECT_FILE_AND_PATTERN.md +9 -9
  5. package/DOCS/PATTERNS.md +3 -3
  6. package/DOCS/POLYMORPHIC_IR.md +104 -0
  7. package/DOCS/PROFILING_AND_TRACING.md +60 -72
  8. package/DOCS/REPL.md +3 -3
  9. package/DOCS/book/03-types-as-finite-automata.md +4 -4
  10. package/DOCS/book/06-values-in-memory.md +9 -9
  11. package/DOCS/book/08-operational-semantics-and-execution.md +1 -1
  12. package/DOCS/book/09-compiler-architecture.md +2 -2
  13. package/DOCS/book/10-from-ast-to-intermediate-representation.md +2 -2
  14. package/DOCS/book/14-canonical-serialization.md +1 -1
  15. package/Examples/arithmetics.k +2 -2
  16. package/Examples/bnat.k +1 -1
  17. package/Examples/karatsuba-mult.k +2 -2
  18. package/JOURNAL.md +288 -0
  19. package/README.md +13 -10
  20. package/access-table.mjs +343 -0
  21. package/backend-api.mjs +18 -0
  22. package/backends/llvm/README.md +20 -21
  23. package/backends/llvm/bin/k-llvm-build.mjs +105 -32
  24. package/backends/llvm/bin/k-llvm-compile.mjs +63 -24
  25. package/backends/llvm/bin/k-llvm.mjs +292 -0
  26. package/backends/llvm/runtime/krt.c +41 -0
  27. package/backends/llvm/runtime/krt.h +2 -0
  28. package/backends/llvm/src/cli.mjs +95 -17
  29. package/backends/llvm/src/executable.mjs +132 -15
  30. package/backends/llvm/src/kvm2llvm.mjs +50 -23
  31. package/backends/llvm/src/llvm.mjs +133 -20
  32. package/backends/llvm/tests/integration.sh +11 -11
  33. package/backends/llvm/{bin → tests}/k-llvm-run.mjs +48 -22
  34. package/backends/llvm/tests/perf-support.mjs +25 -58
  35. package/backends/llvm/tests/test-llvm.mjs +25 -4
  36. package/backends/wasm/bin/k-wasm-compile.mjs +46 -20
  37. package/backends/wasm/bin/k-wasm-run.mjs +61 -20
  38. package/backends/wasm/bin/k-wasm.mjs +47 -13
  39. package/backends/wasm/src/cli.mjs +141 -19
  40. package/backends/wasm/src/wasm.mjs +132 -24
  41. package/backends/wasm/tests/test-wasm.mjs +5 -5
  42. package/browser/repl-browser.mjs +16 -5
  43. package/browser/vfs-data.mjs +5 -5
  44. package/codecs/k-parse.mjs +29 -8
  45. package/codecs/k-print.mjs +22 -6
  46. package/codecs/runtime/codec-sdk.mjs +8 -4
  47. package/codecs/show.mjs +20 -6
  48. package/core.k +8 -8
  49. package/harness/format.mjs +2 -2
  50. package/harness/registry.mjs +0 -2
  51. package/k.mjs +56 -16
  52. package/kir.mjs +200 -75
  53. package/kvm.mjs +49 -12
  54. package/objects/compile.mjs +37 -23
  55. package/objects/decompile.mjs +40 -10
  56. package/objects/extract-aliases.mjs +44 -14
  57. package/objects/inspect.mjs +19 -14
  58. package/objects/validate.mjs +18 -11
  59. package/package.json +10 -7
  60. package/pkir.mjs +772 -0
  61. package/repl.mjs +36 -18
  62. package/scripts/benchmark-idempotency.mjs +12 -8
  63. package/scripts/benchmark.mjs +5 -9
  64. package/scripts/build-repl-html.mjs +16 -4
  65. package/scripts/perf-ieee.mjs +253 -103
  66. package/scripts/perf-int.mjs +585 -297
  67. package/scripts/perf-multiplication.mjs +66 -25
  68. package/scripts/perf-poly.mjs +292 -164
  69. package/scripts/run-tests.mjs +3 -0
  70. package/tests/code-derivation/pattern-envelope.mjs +4 -4
  71. package/tests/test-access-table.mjs +213 -0
  72. package/tests/test-kvm-polymorphic.mjs +2 -2
  73. package/tests/test-pkir.mjs +530 -0
  74. package/tests/test-polymorphic-tdd.mjs +196 -0
  75. package/tests/test-repl-html.mjs +15 -2
  76. package/tests/test-repl.mjs +30 -1
  77. package/backends/arm64/README.md +0 -103
  78. package/backends/arm64/bin/k-arm64-compile.mjs +0 -93
  79. package/backends/arm64/bin/k-arm64-run.mjs +0 -58
  80. package/backends/arm64/bin/k-arm64.mjs +0 -88
  81. package/backends/arm64/scripts/run-tests.mjs +0 -57
  82. package/backends/arm64/src/arm64.mjs +0 -229
  83. package/backends/arm64/src/cli.mjs +0 -155
  84. package/backends/arm64/src/kvm2arm64.mjs +0 -906
  85. package/backends/arm64/src/runtime.c +0 -744
  86. package/backends/arm64/tests/integration.sh +0 -112
  87. package/backends/arm64/tests/test-arm64.mjs +0 -240
  88. package/backends/llvm/bin/k-llvm-jit.mjs +0 -160
  89. package/harness/adapters/arm64.mjs +0 -105
@@ -51,6 +51,9 @@ const tests = [
51
51
  ["tests/test-arithmetics.mjs", node, ["tests/test-arithmetics.mjs"]],
52
52
  ["tests/test-karatsuba.mjs", node, ["tests/test-karatsuba.mjs"]],
53
53
  ["tests/test-poly.mjs", node, ["tests/test-poly.mjs"]],
54
+ ["tests/test-polymorphic-tdd.mjs", node, ["tests/test-polymorphic-tdd.mjs"]],
55
+ ["tests/test-access-table.mjs", node, ["tests/test-access-table.mjs"]],
56
+ ["tests/test-pkir.mjs", node, ["tests/test-pkir.mjs"]],
54
57
  ["tests/test-ieee-arithmetic.mjs", node, ["tests/test-ieee-arithmetic.mjs"]],
55
58
  ["tests/integration.sh", path.join(root, "tests/integration.sh"), []]
56
59
  ];
@@ -12,8 +12,8 @@ const INT_PATTERN = [
12
12
  ];
13
13
 
14
14
  const script = `
15
- int = ?< <bits 0, bits 1, {} _>=bits "+", bits "-" >;
16
- {}|_|0|1|+ int
15
+ int? = ?< <bits 0, bits 1, {} _>=bits "+", bits "-" >;
16
+ {}|_|0|1|+ int?
17
17
  `;
18
18
 
19
19
  const result = k.compile(script)(Value.product({}));
@@ -75,8 +75,8 @@ assert.throws(
75
75
  );
76
76
 
77
77
  const projectionScript = `
78
- int = ?< <bits 0, bits 1, {} _>=bits "+", bits "-" >;
79
- int /+
78
+ int? = ?< <bits 0, bits 1, {} _>=bits "+", bits "-" >;
79
+ int? /+
80
80
  `;
81
81
  const annotated = k.annotate(projectionScript);
82
82
  run.defs = annotated;
@@ -0,0 +1,213 @@
1
+ import assert from "node:assert/strict";
2
+ import { buildAccessTable } from "../access-table.mjs";
3
+
4
+ console.log("==> Running Access Table Tests (tests/test-access-table.mjs)");
5
+
6
+ // --------------------------------------------------------------------
7
+ // Test 1: Access Table for 'search' on Disparate Schema
8
+ // --------------------------------------------------------------------
9
+ {
10
+ console.log("--> Test 1: Access Table for 'search' on Disparate Schema");
11
+
12
+ // Input Schema S: list of { data, flag, id }
13
+ const S_list = [
14
+ ["closed-union", [["cons", 1], ["nil", 2]]],
15
+ ["closed-product", [["car", 3], ["cdr", 0]]],
16
+ ["closed-product", []],
17
+ ["closed-product", [["data", 4], ["flag", 5], ["id", 6]]],
18
+ ["any", []],
19
+ ["closed-union", [["false", 2], ["true", 2]]],
20
+ ["any", []]
21
+ ];
22
+
23
+ // Function Pattern P: list of { flag: <true, ...> }
24
+ const P_search = [
25
+ ["closed-union", [["cons", 1], ["nil", 2]]],
26
+ ["closed-product", [["car", 3], ["cdr", 0]]],
27
+ ["closed-product", []],
28
+ ["open-product", [["flag", 4]]],
29
+ ["open-union", [["true", 2]]],
30
+ ];
31
+
32
+ const table = buildAccessTable(S_list, P_search, { wordSize: 8 });
33
+ assert.equal(table.stateCount, 7);
34
+
35
+ // 1a: Check list union resolution (State 0)
36
+ const consVariant = table.resolveVariant(0, "cons");
37
+ assert.equal(consVariant.tagId, 0);
38
+ assert.equal(consVariant.branchId, 0);
39
+ assert.equal(consVariant.childState, 1);
40
+
41
+ const nilVariant = table.resolveVariant(0, "nil");
42
+ assert.equal(nilVariant.tagId, 1);
43
+ assert.equal(nilVariant.branchId, 1);
44
+ assert.equal(nilVariant.childState, 2);
45
+
46
+ // 1b: Check cons product resolution (State 1)
47
+ const carField = table.resolveField(1, "car");
48
+ assert.equal(carField.physicalSlot, 0);
49
+ assert.equal(carField.byteOffset, 0);
50
+ assert.equal(carField.childState, 3);
51
+
52
+ const cdrField = table.resolveField(1, "cdr");
53
+ assert.equal(cdrField.physicalSlot, 1);
54
+ assert.equal(cdrField.byteOffset, 8);
55
+ assert.equal(cdrField.childState, 0);
56
+
57
+ // 1c: Check item product resolution (State 3: { data, flag, id })
58
+ // In alphabetical order: data = 0, flag = 1, id = 2
59
+ const flagField = table.resolveField(3, "flag");
60
+ assert.equal(flagField.physicalSlot, 1);
61
+ assert.equal(flagField.byteOffset, 8);
62
+ assert.equal(flagField.skipCount, 1);
63
+ assert.equal(flagField.childState, 5); // points to boolean union
64
+
65
+ // Logical slot access (by numeric slot 0)
66
+ const flagBySlot = table.resolveField(3, 0);
67
+ assert.equal(flagBySlot.byteOffset, 8);
68
+ assert.equal(flagBySlot.childState, 5);
69
+ assert.equal(flagBySlot.skipCount, 1);
70
+
71
+ console.log(" Passed: AccessTable correctly resolves fields and variants.");
72
+ }
73
+
74
+ // --------------------------------------------------------------------
75
+ // Test 2: Access Table for Multi-Variant Dispatch ('extract_id')
76
+ // --------------------------------------------------------------------
77
+ {
78
+ console.log("--> Test 2: Access Table for Multi-Variant Dispatch");
79
+
80
+ const P_extract = [
81
+ ["closed-union", [["click", 1], ["ping", 2], ["sensor", 3]]],
82
+ ["open-product", [["id", 4]]],
83
+ ["open-product", [["id", 4]]],
84
+ ["open-product", [["id", 4]]],
85
+ ["any", []]
86
+ ];
87
+
88
+ // Click: { active, id } -> id is at physical slot 1
89
+ const S_click = [
90
+ ["closed-union", [["click", 1]]],
91
+ ["closed-product", [["active", 2], ["id", 3]]],
92
+ ["any", []],
93
+ ["any", []]
94
+ ];
95
+
96
+ // Sensor: { battery_low, id, reading } -> id is at physical slot 1
97
+ const S_sensor = [
98
+ ["closed-union", [["sensor", 1]]],
99
+ ["closed-product", [["battery_low", 2], ["id", 3], ["reading", 4]]],
100
+ ["any", []],
101
+ ["any", []],
102
+ ["any", []]
103
+ ];
104
+
105
+ // Ping: { id } -> id is at physical slot 0
106
+ const S_ping = [
107
+ ["closed-union", [["ping", 1]]],
108
+ ["closed-product", [["id", 2]]],
109
+ ["any", []]
110
+ ];
111
+
112
+ const tClick = buildAccessTable(S_click, P_extract, { wordSize: 8 });
113
+ const tSensor = buildAccessTable(S_sensor, P_extract, { wordSize: 8 });
114
+ const tPing = buildAccessTable(S_ping, P_extract, { wordSize: 8 });
115
+
116
+ // In click, id is at offset 8 (after active)
117
+ assert.equal(tClick.resolveField(1, "id").byteOffset, 8);
118
+ assert.equal(tClick.resolveField(1, "id").skipCount, 1);
119
+
120
+ // In sensor, id is at offset 8 (after battery_low)
121
+ assert.equal(tSensor.resolveField(1, "id").byteOffset, 8);
122
+ assert.equal(tSensor.resolveField(1, "id").skipCount, 1);
123
+
124
+ // In ping, id is at offset 0
125
+ assert.equal(tPing.resolveField(1, "id").byteOffset, 0);
126
+ assert.equal(tPing.resolveField(1, "id").skipCount, 0);
127
+
128
+ console.log(" Passed: Variable offsets resolved per variant schema.");
129
+ }
130
+
131
+ // --------------------------------------------------------------------
132
+ // Test 3: Simulating In-Memory Payload Navigation via AccessTable
133
+ // --------------------------------------------------------------------
134
+ {
135
+ console.log("--> Test 3: Simulating In-Memory Payload Navigation");
136
+
137
+ // S: list of { data, flag, id }
138
+ const S = [
139
+ ["closed-union", [["cons", 1], ["nil", 2]]],
140
+ ["closed-product", [["car", 3], ["cdr", 0]]],
141
+ ["closed-product", []],
142
+ ["closed-product", [["data", 4], ["flag", 5], ["id", 6]]],
143
+ ["any", []],
144
+ ["closed-union", [["false", 2], ["true", 2]]],
145
+ ["any", []]
146
+ ];
147
+
148
+ const P = [
149
+ ["closed-union", [["cons", 1], ["nil", 2]]],
150
+ ["closed-product", [["car", 3], ["cdr", 0]]],
151
+ ["closed-product", []],
152
+ ["open-product", [["flag", 4]]],
153
+ ["open-union", [["true", 2]]],
154
+ ];
155
+
156
+ const table = buildAccessTable(S, P, { wordSize: 8 });
157
+
158
+ // Mock in-memory value representation:
159
+ // Node representation in word arrays:
160
+ // Item 1: { data: 'blob1', flag: 'true', id: 'alpha' }
161
+ // Sorted physical layout: slot 0 = data, slot 1 = flag, slot 2 = id
162
+ const item1 = {
163
+ tag: null,
164
+ words: [
165
+ { text: "blob1" }, // offset 0
166
+ { tag: 1, text: "true" }, // offset 8 (true is tag 1 in {false:0, true:1})
167
+ { text: "alpha" } // offset 16
168
+ ]
169
+ };
170
+
171
+ // Cons cell: slot 0 = car, slot 1 = cdr
172
+ const nilCell = { tag: 1, words: [] }; // tag 1 = nil
173
+ const consCell = {
174
+ tag: 0, // tag 0 = cons
175
+ words: [item1, nilCell]
176
+ };
177
+
178
+ // Navigate using table and word indices (zero string comparisons):
179
+ let state = table.rootState; // 0
180
+ assert.equal(state, 0);
181
+
182
+ // Step 1: Match union at root
183
+ const unionDesc = table.getDescriptor(state);
184
+ const tag = consCell.tag; // 0
185
+ const branch = unionDesc.branchMap[tag]; // 0 (cons)
186
+ assert.equal(branch, 0);
187
+ state = unionDesc.childStateMap[tag]; // state 1 (cons product)
188
+ assert.equal(state, 1);
189
+
190
+ // Step 2: Project .car (slot 0)
191
+ const carMeta = table.resolveField(state, 0);
192
+ assert.equal(carMeta.byteOffset, 0);
193
+ const carNode = consCell.words[carMeta.byteOffset / 8];
194
+ state = carMeta.childState; // state 3 (item product)
195
+ assert.equal(state, 3);
196
+
197
+ // Step 3: Project .flag (slot 0 in P's view of car)
198
+ const flagMeta = table.resolveField(state, 0);
199
+ assert.equal(flagMeta.byteOffset, 8); // correctly jumps to slot 1!
200
+ const flagVal = carNode.words[flagMeta.byteOffset / 8];
201
+ state = flagMeta.childState; // state 5 (boolean union)
202
+ assert.equal(state, 5);
203
+
204
+ // Step 4: Check if flag is 'true'
205
+ const boolDesc = table.getDescriptor(state);
206
+ const flagTag = flagVal.tag; // 1 ('true')
207
+ const flagBranch = boolDesc.branchMap[flagTag];
208
+ assert.equal(flagBranch, 0); // matches P's only branch ('true')
209
+
210
+ console.log(" Passed: Zero-string navigation simulation successful.");
211
+ }
212
+
213
+ console.log("\n==> All Access Table Tests Passed Successfully!");
@@ -91,8 +91,8 @@ console.log("==> Starting Polymorphic kVM & Specialization Tests");
91
91
  // Test 3: Type Error on Envelope Mismatch
92
92
  {
93
93
  const script = `
94
- check = ?< {} true, {} false >;
95
- check
94
+ check? = ?< {} true, {} false >;
95
+ check?
96
96
  `;
97
97
  const obj = decodeObject(compileObjectBuffer(script));
98
98
  const kvmArtifact = objectToKVMArtifact(obj);