@fraczak/k 7.0.2 → 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.
- package/CHANGELOG.md +42 -0
- package/DOCS/FILE_FORMATS.md +238 -15
- package/DOCS/POLYMORPHIC_IR.md +104 -0
- package/JOURNAL.md +288 -0
- package/README.md +10 -2
- package/access-table.mjs +343 -0
- package/backend-api.mjs +18 -0
- package/backends/llvm/README.md +20 -21
- package/backends/llvm/bin/k-llvm-build.mjs +105 -32
- package/backends/llvm/bin/k-llvm-compile.mjs +63 -24
- package/backends/llvm/bin/k-llvm.mjs +292 -0
- package/backends/llvm/runtime/krt.c +8 -0
- package/backends/llvm/runtime/krt.h +1 -0
- package/backends/llvm/src/cli.mjs +95 -17
- package/backends/llvm/src/executable.mjs +128 -11
- package/backends/llvm/src/kvm2llvm.mjs +10 -5
- package/backends/llvm/src/llvm.mjs +121 -9
- package/backends/llvm/tests/integration.sh +11 -11
- package/backends/llvm/{bin → tests}/k-llvm-run.mjs +48 -22
- package/backends/llvm/tests/perf-support.mjs +24 -3
- package/backends/llvm/tests/test-llvm.mjs +22 -1
- package/backends/wasm/bin/k-wasm-compile.mjs +46 -20
- package/backends/wasm/bin/k-wasm-run.mjs +61 -20
- package/backends/wasm/bin/k-wasm.mjs +47 -13
- package/backends/wasm/src/cli.mjs +141 -19
- package/backends/wasm/src/wasm.mjs +130 -23
- package/browser/repl-browser.mjs +16 -5
- package/codecs/k-parse.mjs +29 -8
- package/codecs/k-print.mjs +22 -6
- package/codecs/runtime/codec-sdk.mjs +8 -4
- package/codecs/show.mjs +20 -6
- package/k.mjs +56 -16
- package/kir.mjs +58 -19
- package/kvm.mjs +49 -12
- package/objects/compile.mjs +37 -23
- package/objects/decompile.mjs +40 -10
- package/objects/extract-aliases.mjs +44 -14
- package/objects/inspect.mjs +19 -14
- package/objects/validate.mjs +18 -11
- package/package.json +10 -3
- package/pkir.mjs +772 -0
- package/repl.mjs +36 -18
- package/scripts/build-repl-html.mjs +14 -2
- package/scripts/perf-ieee.mjs +264 -13
- package/scripts/perf-int.mjs +315 -22
- package/scripts/perf-multiplication.mjs +58 -7
- package/scripts/perf-poly.mjs +306 -24
- package/scripts/run-tests.mjs +3 -0
- package/tests/test-access-table.mjs +213 -0
- package/tests/test-pkir.mjs +530 -0
- package/tests/test-polymorphic-tdd.mjs +196 -0
- package/tests/test-repl-html.mjs +15 -2
- package/tests/test-repl.mjs +30 -1
- package/backends/llvm/bin/k-llvm-jit.mjs +0 -160
|
@@ -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!");
|