@fraczak/k 7.0.2 → 7.2.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 +75 -0
- package/DOCS/CODECS.md +37 -2
- package/DOCS/CODEC_ARCHITECTURE.md +12 -5
- package/DOCS/FILE_FORMATS.md +238 -15
- package/DOCS/POLYMORPHIC_IR.md +104 -0
- package/DOCS/REPL.md +11 -3
- package/DOCS/WEB_REPL_REQUIREMENTS.md +1 -1
- package/JOURNAL.md +288 -0
- package/README.md +12 -3
- package/Value.mjs +28 -3
- package/access-table.mjs +343 -0
- package/backend-api.mjs +23 -1
- 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/browser/tree-view.mjs +47 -8
- package/browser/vfs-data.mjs +6 -5
- package/codecs/README.md +1 -0
- package/codecs/djson.mjs +270 -0
- package/codecs/int.mjs +2 -1
- package/codecs/json.mjs +7 -2
- package/codecs/k-parse.mjs +36 -9
- package/codecs/k-print.mjs +26 -6
- package/codecs/runtime/codec-sdk.mjs +24 -6
- package/codecs/runtime/pattern-json.mjs +80 -1
- package/codecs/runtime/prefix-codec.mjs +629 -67
- package/codecs/runtime/show-value.mjs +93 -51
- package/codecs/runtime/unicode-string.mjs +29 -6
- package/codecs/show.mjs +24 -6
- package/codecs/utf16.mjs +2 -1
- 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 +11 -3
- package/pkir.mjs +772 -0
- package/repl.mjs +92 -23
- package/scripts/build-repl-html.mjs +22 -3
- 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-codecs.mjs +168 -0
- package/tests/test-pkir.mjs +530 -0
- package/tests/test-polymorphic-tdd.mjs +196 -0
- package/tests/test-repl-html.mjs +16 -2
- package/tests/test-repl.mjs +63 -1
- package/backends/llvm/bin/k-llvm-jit.mjs +0 -160
package/repl.mjs
CHANGED
|
@@ -50,7 +50,7 @@ const NAME_RE = /^[a-zA-Z0-9_+-][a-zA-Z0-9_?!+-]*$/;
|
|
|
50
50
|
const COMMAND_NAMES = [
|
|
51
51
|
"help", "rel",
|
|
52
52
|
"codecs", "rels", "codec", "input", "reset", "klib", "ko", "load",
|
|
53
|
-
"engine", "wasm", "js",
|
|
53
|
+
"engine", "wasm", "pkir", "js", "limit",
|
|
54
54
|
"quit", "exit"
|
|
55
55
|
];
|
|
56
56
|
const CODEC_COMMAND_NAMES = ["load", "unload", "list"];
|
|
@@ -76,8 +76,10 @@ function emptyValue() {
|
|
|
76
76
|
function createState(options = {}) {
|
|
77
77
|
codes.load(cloneJSON(initialCodes));
|
|
78
78
|
const engine = (options.engine || "wasm").toLowerCase();
|
|
79
|
-
if (engine !== "wasm" && engine !== "js") {
|
|
80
|
-
throw new Error(
|
|
79
|
+
if (engine !== "wasm" && engine !== "pkir" && engine !== "js") {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`Invalid engine '${options.engine}'. Valid engines: wasm, pkir, js`
|
|
82
|
+
);
|
|
81
83
|
}
|
|
82
84
|
return {
|
|
83
85
|
engine,
|
|
@@ -93,7 +95,8 @@ function createState(options = {}) {
|
|
|
93
95
|
lastResult: null,
|
|
94
96
|
lastMain: null,
|
|
95
97
|
lastTiming: null,
|
|
96
|
-
showTiming: true
|
|
98
|
+
showTiming: true,
|
|
99
|
+
printLimit: options.printLimit ?? Infinity
|
|
97
100
|
};
|
|
98
101
|
}
|
|
99
102
|
|
|
@@ -352,7 +355,8 @@ function formatCodecOutput(output) {
|
|
|
352
355
|
}
|
|
353
356
|
|
|
354
357
|
function printValue(value, state = null) {
|
|
355
|
-
const
|
|
358
|
+
const limit = state?.printLimit ?? Infinity;
|
|
359
|
+
const lines = [valueWithEnvelopeToK(value, limit)];
|
|
356
360
|
if (!state || value === undefined) return lines[0];
|
|
357
361
|
|
|
358
362
|
const store = state.codecs || {};
|
|
@@ -361,7 +365,11 @@ function printValue(value, state = null) {
|
|
|
361
365
|
try {
|
|
362
366
|
const output = codec.print(value, { state });
|
|
363
367
|
if (output != null) {
|
|
364
|
-
|
|
368
|
+
let text = formatCodecOutput(output);
|
|
369
|
+
if (Number.isFinite(limit) && text.length > limit) {
|
|
370
|
+
text = text.slice(0, limit) + "...";
|
|
371
|
+
}
|
|
372
|
+
lines.push(`${codec.name}: ${text}`);
|
|
365
373
|
}
|
|
366
374
|
} catch {
|
|
367
375
|
// Codec cannot format this value; silently skip
|
|
@@ -768,7 +776,7 @@ function completeCommandArgument(line, state) {
|
|
|
768
776
|
}
|
|
769
777
|
|
|
770
778
|
if (command === "engine") {
|
|
771
|
-
return completeCommandWord(line, argStart, arg, ["wasm", "js"]);
|
|
779
|
+
return completeCommandWord(line, argStart, arg, ["wasm", "pkir", "js"]);
|
|
772
780
|
}
|
|
773
781
|
|
|
774
782
|
if (command === "input") {
|
|
@@ -1003,7 +1011,8 @@ async function executeExpressionWithWasm(annotated, state, lineOffset = 0) {
|
|
|
1003
1011
|
|
|
1004
1012
|
const wasmCompileStart = performance.now();
|
|
1005
1013
|
const wasmBytes = await compileWasmArtifactFromObject(obj, {
|
|
1006
|
-
inputEnvelopePattern: inputValue?.pattern
|
|
1014
|
+
inputEnvelopePattern: inputValue?.pattern,
|
|
1015
|
+
usePKIR: state.engine === "pkir" || state.usePKIR
|
|
1007
1016
|
});
|
|
1008
1017
|
const runner = await instantiateWasmArtifact(wasmBytes);
|
|
1009
1018
|
const wasmCompileMs = performance.now() - wasmCompileStart;
|
|
@@ -1242,8 +1251,10 @@ async function evaluateCommand(line, state) {
|
|
|
1242
1251
|
if (!mode) {
|
|
1243
1252
|
return [`Current engine: ${state.engine}`];
|
|
1244
1253
|
}
|
|
1245
|
-
if (mode !== "wasm" && mode !== "js") {
|
|
1246
|
-
throw new Error(
|
|
1254
|
+
if (mode !== "wasm" && mode !== "pkir" && mode !== "js") {
|
|
1255
|
+
throw new Error(
|
|
1256
|
+
`Invalid engine '${arg.trim()}'. Valid engines: wasm, pkir, js`
|
|
1257
|
+
);
|
|
1247
1258
|
}
|
|
1248
1259
|
state.engine = mode;
|
|
1249
1260
|
return [`engine set to ${mode}`];
|
|
@@ -1252,13 +1263,42 @@ async function evaluateCommand(line, state) {
|
|
|
1252
1263
|
state.engine = "wasm";
|
|
1253
1264
|
return ["engine set to wasm"];
|
|
1254
1265
|
}
|
|
1266
|
+
case "pkir": {
|
|
1267
|
+
state.engine = "pkir";
|
|
1268
|
+
return ["engine set to pkir"];
|
|
1269
|
+
}
|
|
1255
1270
|
case "js": {
|
|
1256
1271
|
state.engine = "js";
|
|
1257
1272
|
return ["engine set to js"];
|
|
1258
1273
|
}
|
|
1274
|
+
case "limit": {
|
|
1275
|
+
const mode = (arg || "").trim().toLowerCase();
|
|
1276
|
+
if (!mode) {
|
|
1277
|
+
const current = Number.isFinite(state.printLimit)
|
|
1278
|
+
? state.printLimit
|
|
1279
|
+
: "none";
|
|
1280
|
+
return [`Current output limit: ${current}`];
|
|
1281
|
+
}
|
|
1282
|
+
if (mode === "none" || mode === "infinity" || mode === "off") {
|
|
1283
|
+
state.printLimit = Infinity;
|
|
1284
|
+
return ["output limit disabled"];
|
|
1285
|
+
}
|
|
1286
|
+
const n = parseInt(mode, 10);
|
|
1287
|
+
if (Number.isNaN(n) || n < 0) {
|
|
1288
|
+
throw new Error(
|
|
1289
|
+
`Invalid limit '${arg.trim()}'. Usage: :limit [num|none]`
|
|
1290
|
+
);
|
|
1291
|
+
}
|
|
1292
|
+
state.printLimit = n;
|
|
1293
|
+
return [`output limit set to ${n}`];
|
|
1294
|
+
}
|
|
1259
1295
|
case "reset": {
|
|
1260
1296
|
const currentEngine = state.engine;
|
|
1261
|
-
const
|
|
1297
|
+
const currentLimit = state.printLimit;
|
|
1298
|
+
const fresh = createState({
|
|
1299
|
+
engine: currentEngine,
|
|
1300
|
+
printLimit: currentLimit
|
|
1301
|
+
});
|
|
1262
1302
|
Object.assign(state, fresh);
|
|
1263
1303
|
return ["reset"];
|
|
1264
1304
|
}
|
|
@@ -1290,9 +1330,10 @@ async function evaluateCommand(line, state) {
|
|
|
1290
1330
|
|
|
1291
1331
|
function helpText() {
|
|
1292
1332
|
return [
|
|
1293
|
-
":engine [wasm|js]
|
|
1333
|
+
":engine [wasm|pkir|js] display or switch evaluation engine",
|
|
1294
1334
|
":rel name show relation definition",
|
|
1295
1335
|
":rels list relation aliases",
|
|
1336
|
+
":limit [num|none] set maximum characters for value output",
|
|
1296
1337
|
":codec load file load a codec module from file (e.g. :codec load codecs/int.mjs)",
|
|
1297
1338
|
":codec unload name unload a registered codec",
|
|
1298
1339
|
":codec list list loaded codecs (or simply :codecs)",
|
|
@@ -1316,15 +1357,19 @@ function promptForState(state) {
|
|
|
1316
1357
|
}
|
|
1317
1358
|
|
|
1318
1359
|
function cliUsage() {
|
|
1319
|
-
console.log("
|
|
1360
|
+
console.log("Start the interactive k interpreter.");
|
|
1361
|
+
console.log("Type :help inside the REPL for commands.");
|
|
1320
1362
|
console.log("");
|
|
1321
|
-
console.log("
|
|
1363
|
+
console.log("Usage: k-repl [options]");
|
|
1322
1364
|
console.log("");
|
|
1323
1365
|
console.log("Options:");
|
|
1324
|
-
console.log(" --engine=<wasm|js> Select
|
|
1325
|
-
console.log("
|
|
1326
|
-
console.log(" --
|
|
1327
|
-
console.log("
|
|
1366
|
+
console.log(" --engine=<wasm|pkir|js> Select engine: wasm, pkir, js");
|
|
1367
|
+
console.log(" (default: wasm).");
|
|
1368
|
+
console.log(" --pkir Shortcut for --engine=pkir.");
|
|
1369
|
+
console.log(" --wasm Shortcut for --engine=wasm.");
|
|
1370
|
+
console.log(" --js Shortcut for --engine=js.");
|
|
1371
|
+
console.log(" --limit=<num> Set maximum characters for output.");
|
|
1372
|
+
console.log(" -h, --help Show this help.");
|
|
1328
1373
|
}
|
|
1329
1374
|
|
|
1330
1375
|
function startRepl(options = {}) {
|
|
@@ -1419,6 +1464,7 @@ function startRepl(options = {}) {
|
|
|
1419
1464
|
if (isMainEntrypoint()) {
|
|
1420
1465
|
const args = argv.slice(2);
|
|
1421
1466
|
let engine = "wasm";
|
|
1467
|
+
let printLimit = Infinity;
|
|
1422
1468
|
for (let i = 0; i < args.length; i++) {
|
|
1423
1469
|
const arg = args[i];
|
|
1424
1470
|
if (arg === "-h" || arg === "--help") {
|
|
@@ -1428,28 +1474,51 @@ if (isMainEntrypoint()) {
|
|
|
1428
1474
|
engine = "js";
|
|
1429
1475
|
} else if (arg === "--wasm") {
|
|
1430
1476
|
engine = "wasm";
|
|
1477
|
+
} else if (arg === "--pkir") {
|
|
1478
|
+
engine = "pkir";
|
|
1431
1479
|
} else if (arg.startsWith("--engine=")) {
|
|
1432
1480
|
const val = arg.slice("--engine=".length).toLowerCase();
|
|
1433
|
-
if (val !== "wasm" && val !== "js") {
|
|
1434
|
-
console.error(
|
|
1481
|
+
if (val !== "wasm" && val !== "pkir" && val !== "js") {
|
|
1482
|
+
console.error(
|
|
1483
|
+
`Invalid engine '${val}'. Valid engines: wasm, pkir, js`
|
|
1484
|
+
);
|
|
1435
1485
|
exit(1);
|
|
1436
1486
|
}
|
|
1437
1487
|
engine = val;
|
|
1438
1488
|
} else if (arg === "--engine") {
|
|
1439
1489
|
i++;
|
|
1440
1490
|
const val = (args[i] || "").toLowerCase();
|
|
1441
|
-
if (val !== "wasm" && val !== "js") {
|
|
1442
|
-
console.error(
|
|
1491
|
+
if (val !== "wasm" && val !== "pkir" && val !== "js") {
|
|
1492
|
+
console.error(
|
|
1493
|
+
`Invalid engine '${val}'. Valid engines: wasm, pkir, js`
|
|
1494
|
+
);
|
|
1443
1495
|
exit(1);
|
|
1444
1496
|
}
|
|
1445
1497
|
engine = val;
|
|
1498
|
+
} else if (arg.startsWith("--limit=")) {
|
|
1499
|
+
const val = parseInt(arg.slice("--limit=".length), 10);
|
|
1500
|
+
if (Number.isNaN(val) || val < 0) {
|
|
1501
|
+
console.error(
|
|
1502
|
+
`Invalid limit '${arg.slice("--limit=".length)}'.`
|
|
1503
|
+
);
|
|
1504
|
+
exit(1);
|
|
1505
|
+
}
|
|
1506
|
+
printLimit = val;
|
|
1507
|
+
} else if (arg === "--limit") {
|
|
1508
|
+
i++;
|
|
1509
|
+
const val = parseInt(args[i] || "", 10);
|
|
1510
|
+
if (Number.isNaN(val) || val < 0) {
|
|
1511
|
+
console.error(`Invalid limit '${args[i]}'.`);
|
|
1512
|
+
exit(1);
|
|
1513
|
+
}
|
|
1514
|
+
printLimit = val;
|
|
1446
1515
|
} else {
|
|
1447
1516
|
console.error(`Unknown option '${arg}'.`);
|
|
1448
1517
|
cliUsage();
|
|
1449
1518
|
exit(1);
|
|
1450
1519
|
}
|
|
1451
1520
|
}
|
|
1452
|
-
startRepl({ engine });
|
|
1521
|
+
startRepl({ engine, printLimit });
|
|
1453
1522
|
}
|
|
1454
1523
|
|
|
1455
1524
|
export {
|
|
@@ -91,7 +91,14 @@ for (const filename of verifiedExamples) {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// Bundle verified codecs for browser VFS as 100% self-contained ES modules
|
|
94
|
-
const verifiedCodecs = [
|
|
94
|
+
const verifiedCodecs = [
|
|
95
|
+
"json.mjs",
|
|
96
|
+
"djson.mjs",
|
|
97
|
+
"utf8.mjs",
|
|
98
|
+
"int.mjs",
|
|
99
|
+
"unit.mjs",
|
|
100
|
+
"ieee.mjs"
|
|
101
|
+
];
|
|
95
102
|
const codecsDir = path.join(projectRoot, "codecs");
|
|
96
103
|
|
|
97
104
|
const browserCodecSdkShim = `
|
|
@@ -284,6 +291,17 @@ const htmlContent = `<!DOCTYPE html>
|
|
|
284
291
|
border-color: rgba(240, 180, 41, 0.7);
|
|
285
292
|
}
|
|
286
293
|
|
|
294
|
+
.engine-badge.pkir-mode {
|
|
295
|
+
background: rgba(187, 128, 255, 0.15);
|
|
296
|
+
color: #d2a8ff;
|
|
297
|
+
border-color: rgba(187, 128, 255, 0.4);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.engine-badge.pkir-mode:hover {
|
|
301
|
+
background: rgba(187, 128, 255, 0.3);
|
|
302
|
+
border-color: rgba(187, 128, 255, 0.7);
|
|
303
|
+
}
|
|
304
|
+
|
|
287
305
|
.status-indicator {
|
|
288
306
|
display: flex;
|
|
289
307
|
align-items: center;
|
|
@@ -1644,7 +1662,7 @@ const htmlContent = `<!DOCTYPE html>
|
|
|
1644
1662
|
<div class="nav-left">
|
|
1645
1663
|
<div class="brand">
|
|
1646
1664
|
<span class="brand-name">k repl</span>
|
|
1647
|
-
<span id="engine-badge" class="engine-badge" title="Click to toggle engine (wasm/js)">wasm-in-process</span>
|
|
1665
|
+
<span id="engine-badge" class="engine-badge" title="Click to toggle engine (wasm/pkir/js)">wasm-in-process</span>
|
|
1648
1666
|
</div>
|
|
1649
1667
|
<div class="status-indicator">
|
|
1650
1668
|
<span id="status-dot" class="status-dot ready"></span>
|
|
@@ -1673,6 +1691,7 @@ const htmlContent = `<!DOCTYPE html>
|
|
|
1673
1691
|
<option value="expr::rels">:rels (list relations)</option>
|
|
1674
1692
|
<option value="expr::engine">:engine (show engine)</option>
|
|
1675
1693
|
<option value="expr::engine wasm">:engine wasm</option>
|
|
1694
|
+
<option value="expr::engine pkir">:engine pkir</option>
|
|
1676
1695
|
<option value="expr::engine js">:engine js</option>
|
|
1677
1696
|
</optgroup>
|
|
1678
1697
|
<optgroup label="Codecs & Format Adapters">
|
|
@@ -1867,7 +1886,7 @@ const htmlContent = `<!DOCTYPE html>
|
|
|
1867
1886
|
<div class="help-section">
|
|
1868
1887
|
<h4>REPL Commands</h4>
|
|
1869
1888
|
<table class="help-table">
|
|
1870
|
-
<tr><td><code>:engine [wasm|js]</code></td><td>Display or switch evaluation engine (<code>wasm</code> or <code>js</code>)</td></tr>
|
|
1889
|
+
<tr><td><code>:engine [wasm|pkir|js]</code></td><td>Display or switch evaluation engine (<code>wasm</code>, <code>pkir</code>, or <code>js</code>)</td></tr>
|
|
1871
1890
|
<tr><td><code>:load <file></code></td><td>Load a <code>.k</code> source or <code>.klib</code> library into current state</td></tr>
|
|
1872
1891
|
<tr><td><code>:rel <name></code></td><td>Display definition of relation <code><name></code></td></tr>
|
|
1873
1892
|
<tr><td><code>:rels</code></td><td>List all relation aliases</td></tr>
|