@fraczak/k 6.10.5 → 7.0.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 (71) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/CLAUDE.md +1 -1
  3. package/DOCS/BIG_PICTURE.md +156 -172
  4. package/DOCS/BINARY_CODEC_STATUS_AND_TODO.md +3 -3
  5. package/DOCS/CODEC_ARCHITECTURE.md +2 -2
  6. package/DOCS/DICTIONARY.md +243 -250
  7. package/DOCS/DIVERGENCE_DETECTION.md +0 -1
  8. package/DOCS/FILE_FORMATS.md +5 -5
  9. package/DOCS/KIR_SPECIALIZATION_DESIGN.md +1 -1
  10. package/DOCS/OBJECT_FILE_AND_PATTERN.md +12 -12
  11. package/DOCS/PATTERNS.md +17 -17
  12. package/DOCS/PATTERNS_AND_TYPED_VALUES.md +1 -1
  13. package/DOCS/REPL.md +9 -19
  14. package/DOCS/TYPE_DERIVATION.md +2 -8
  15. package/DOCS/WEB_REPL_REQUIREMENTS.md +8 -8
  16. package/DOCS/book/01-introduction.md +8 -11
  17. package/DOCS/book/02-syntax-and-values.md +19 -20
  18. package/DOCS/book/03-types-as-finite-automata.md +42 -43
  19. package/DOCS/book/04-partial-functions-and-composition.md +2 -3
  20. package/DOCS/book/05-typing-filters-and-normalization.md +44 -46
  21. package/DOCS/book/06-values-in-memory.md +10 -10
  22. package/DOCS/book/08-operational-semantics-and-execution.md +21 -26
  23. package/DOCS/book/09-compiler-architecture.md +11 -11
  24. package/DOCS/book/10-from-ast-to-intermediate-representation.md +6 -7
  25. package/DOCS/book/14-canonical-serialization.md +2 -2
  26. package/DOCS/book/appendix-b-incorporating-external-predefined-types-and-functions.md +17 -17
  27. package/DOCS/book.md +5 -5
  28. package/Examples/arithmetics.k +49 -153
  29. package/Examples/bnat.k +13 -13
  30. package/Examples/byte.k +2 -50
  31. package/Examples/ieee.k +408 -423
  32. package/Examples/karatsuba-mult.k +30 -34
  33. package/Examples/nat.k +5 -6
  34. package/README.md +54 -49
  35. package/TODO.md +13 -18
  36. package/browser/repl-browser.mjs +40 -22
  37. package/browser/shims/fs.mjs +7 -10
  38. package/browser/vfs-data.mjs +12 -12
  39. package/codecs/BINARY_FORMAT.md +4 -4
  40. package/codecs/POLYMORPHIC_BINARY_FORMAT.md +4 -4
  41. package/codecs/README.md +6 -6
  42. package/codecs/ieee.mjs +15 -11
  43. package/codecs/int.mjs +9 -5
  44. package/codecs/string-codec.mjs +46 -47
  45. package/core.k +124 -175
  46. package/object.mjs +0 -7
  47. package/package.json +5 -2
  48. package/parser.jison +2 -41
  49. package/parser.mjs +55 -95
  50. package/pretty.mjs +11 -4
  51. package/repl.mjs +8 -63
  52. package/scripts/build-repl-html.mjs +18 -49
  53. package/tests/code-derivation/blowup.mjs +2 -4
  54. package/tests/code-derivation/bnat.mjs +2 -3
  55. package/tests/code-derivation/dot.mjs +5 -11
  56. package/tests/code-derivation/nat.mjs +2 -2
  57. package/tests/code-derivation/not-not.mjs +6 -6
  58. package/tests/code-derivation/pattern-envelope.mjs +4 -6
  59. package/tests/code-derivation/product.mjs +3 -6
  60. package/tests/code-derivation/rlz.mjs +4 -5
  61. package/tests/test-codecs.mjs +1 -1
  62. package/tests/test-fingerprint.mjs +36 -41
  63. package/tests/test-hash-normalization.mjs +4 -6
  64. package/tests/test-ieee-arithmetic.mjs +6 -7
  65. package/tests/test-k-object.mjs +11 -15
  66. package/tests/test-kir.mjs +0 -1
  67. package/tests/test-kvm-polymorphic.mjs +1 -2
  68. package/tests/test-kvm.mjs +8 -11
  69. package/tests/test-repl-html.mjs +86 -9
  70. package/tests/test-repl.mjs +38 -53
  71. package/tests/test.mjs +2 -3
@@ -139,15 +139,15 @@ if (chromiumBin) {
139
139
  const vfsList = await evaluateAsync(`window.kRepl.getAllVfsFiles().sort()`);
140
140
  const expectedFiles = [
141
141
  "arithmetics.k",
142
- "codecs/ieee.mjs",
143
- "codecs/int.mjs",
144
- "codecs/json.mjs",
145
- "codecs/unit.mjs",
146
- "codecs/utf8.mjs",
147
142
  "core.k",
148
143
  "ieee.k",
144
+ "ieee.mjs",
145
+ "int.mjs",
146
+ "json.mjs",
149
147
  "karatsuba-mult.k",
150
- "poly.k"
148
+ "poly.k",
149
+ "unit.mjs",
150
+ "utf8.mjs"
151
151
  ].sort();
152
152
  assert.deepStrictEqual(vfsList, expectedFiles, `getAllVfsFiles() must match curated files list, got: ${JSON.stringify(vfsList)}`);
153
153
 
@@ -581,6 +581,7 @@ if (chromiumBin) {
581
581
  const hasTime = modalText.includes(":time");
582
582
  const hasT = modalText.includes(":t <name>");
583
583
  const hasCodecDefine = modalText.includes(":codec define");
584
+ const hasRels = modalText.includes(":rels");
584
585
  const hasType = modalText.includes(":type <name>");
585
586
  const hasTypes = modalText.includes(":types");
586
587
  const hasCodes = modalText.includes(":codes");
@@ -592,6 +593,7 @@ if (chromiumBin) {
592
593
  rect: { left: rect.left, right: rect.right, top: rect.top, bottom: rect.bottom },
593
594
  helpModalOpen,
594
595
  hasRel,
596
+ hasRels,
595
597
  hasVal,
596
598
  hasTiming,
597
599
  hasTime,
@@ -608,8 +610,9 @@ if (chromiumBin) {
608
610
  assert.strictEqual(narrowNavbarCheck.isVisible, true, "#btn-help should be visible within narrow viewport");
609
611
  assert.strictEqual(narrowNavbarCheck.helpModalOpen, true, "Clicking #btn-help in narrow viewport should open help modal");
610
612
  assert.strictEqual(narrowNavbarCheck.hasRel, true, "Help modal should contain :rel <name>");
611
- assert.strictEqual(narrowNavbarCheck.hasType, true, "Help modal should contain :type <name>");
612
- assert.strictEqual(narrowNavbarCheck.hasTypes, true, "Help modal should contain :types");
613
+ assert.strictEqual(narrowNavbarCheck.hasRels, true, "Help modal should contain :rels");
614
+ assert.strictEqual(narrowNavbarCheck.hasType, false, "Help modal should not contain :type <name>");
615
+ assert.strictEqual(narrowNavbarCheck.hasTypes, false, "Help modal should not contain :types");
613
616
  assert.strictEqual(narrowNavbarCheck.hasEngine, true, "Help modal should contain :engine");
614
617
  assert.strictEqual(narrowNavbarCheck.hasCodes, false, "Help modal should not contain :codes");
615
618
  assert.strictEqual(narrowNavbarCheck.hasTime, false, "Help modal should not contain :time");
@@ -635,7 +638,81 @@ if (chromiumBin) {
635
638
  assert.strictEqual(engineCheck.jsEngine, "js");
636
639
  assert.strictEqual(engineCheck.badgeJsText, "js-in-process");
637
640
  assert.strictEqual(engineCheck.wasmEngine, "wasm");
638
- assert.strictEqual(engineCheck.badgeWasmText, "wasm-in-process");
641
+ // 7. Test uploading a file (adds to VFS without auto-loading)
642
+ const uploadCheck = await evaluateAsync(`(async () => {
643
+ const codecCode = \`export default {
644
+ name: "custom.mjs",
645
+ target: "(...)",
646
+ format: "custom",
647
+ parse: (raw) => raw,
648
+ print: (v) => "CUSTOM_VAL"
649
+ };\`;
650
+ const file = new File(
651
+ [codecCode],
652
+ "custom.mjs",
653
+ { type: "text/javascript" }
654
+ );
655
+ await window.kRepl.handleFileUpload(file);
656
+
657
+ const vfsContent = window.kRepl.getVfsFile("custom.mjs");
658
+ const inVfsList = window.kRepl.getAllVfsFiles().includes("custom.mjs");
659
+
660
+ // Verify system message showed upload confirmation
661
+ const systemMessages = Array.from(
662
+ document.querySelectorAll(".system-msg")
663
+ ).map(el => el.textContent);
664
+ const hasUploadedMsg = systemMessages.some(
665
+ m => m.includes("Uploaded custom.mjs into VFS")
666
+ );
667
+
668
+ // Verify it was NOT auto-loaded (:codecs does not list it)
669
+ await window.kRepl.executeCommand(":codecs");
670
+ const linesBefore = Array.from(
671
+ document.querySelectorAll(".entry-line")
672
+ ).map(el => el.textContent);
673
+ const codecsBefore = linesBefore[linesBefore.length - 1];
674
+
675
+ // Explicitly load it to prove it can be loaded as a codec
676
+ await window.kRepl.executeCommand(":codec load custom.mjs");
677
+ const linesAfter = Array.from(
678
+ document.querySelectorAll(".entry-line")
679
+ ).map(el => el.textContent);
680
+ const codecsAfter = linesAfter[linesAfter.length - 1];
681
+
682
+ return {
683
+ hasVfsContent: typeof vfsContent === "string" &&
684
+ vfsContent.includes("custom.mjs"),
685
+ inVfsList,
686
+ hasUploadedMsg,
687
+ codecsBefore,
688
+ codecsAfter
689
+ };
690
+ })()`);
691
+ assert.strictEqual(
692
+ uploadCheck.hasVfsContent,
693
+ true,
694
+ "Uploaded file must be present in VFS"
695
+ );
696
+ assert.strictEqual(
697
+ uploadCheck.inVfsList,
698
+ true,
699
+ "Uploaded file must be in getAllVfsFiles()"
700
+ );
701
+ assert.strictEqual(
702
+ uploadCheck.hasUploadedMsg,
703
+ true,
704
+ "Upload confirmation message must be displayed"
705
+ );
706
+ assert.strictEqual(
707
+ uploadCheck.codecsBefore.includes("custom.mjs"),
708
+ false,
709
+ "Upload must NOT auto-load the file"
710
+ );
711
+ assert.strictEqual(
712
+ uploadCheck.codecsAfter.includes("custom.mjs"),
713
+ true,
714
+ "Explicit :codec load of uploaded file must succeed"
715
+ );
639
716
 
640
717
  ws.close();
641
718
  console.log(" Browser execution verified successfully!");
@@ -24,18 +24,16 @@ import { Value } from "../Value.mjs";
24
24
 
25
25
  const state = createState();
26
26
 
27
- let output = await evaluateInput("$ nat = < {} zero, nat succ >;", state);
28
- output = await evaluateInput(":type nat", state);
29
- assert.match(output[0], /^\$ nat = /);
27
+ let output = await evaluateInput("zero = {} | zero;", state);
28
+ output = await evaluateInput(":rel zero", state);
29
+ assert.match(output[0], /^zero = /);
30
30
 
31
31
  output = await evaluateInput("succ = | succ;", state);
32
32
  output = await evaluateInput(":rel succ", state);
33
33
  assert.match(output[0], /^succ = /);
34
34
 
35
- output = await evaluateInput(":types", state);
36
- assert.match(output[0], /^nat = @/m);
37
-
38
35
  output = await evaluateInput(":rels", state);
36
+ assert.match(output[0], /^zero = @/m);
39
37
  assert.match(output[0], /^succ = @/m);
40
38
 
41
39
  output = await evaluateInput("succ", state);
@@ -54,18 +52,18 @@ assert.match(output[0], /^succ = /);
54
52
  let completions = completeInput(":he", state)[0];
55
53
  assert.deepEqual(completions, [":help"]);
56
54
 
57
- const canonicalPartial = state.typeAliases.nat.slice(0, 8);
55
+ const canonicalPartial = state.relAliases.zero.slice(0, 8);
58
56
  completions = completeInput(`:rel ${canonicalPartial}`, state)[0];
59
- assert(completions.some((line) => line.endsWith(state.typeAliases.nat)));
57
+ assert(completions.some((line) => line.endsWith(state.relAliases.zero)));
60
58
 
61
59
  completions = completeInput(`(${canonicalPartial}`, state)[0];
62
- assert(completions.includes(`(${state.typeAliases.nat}`));
60
+ assert(completions.includes(`(${state.relAliases.zero}`));
63
61
 
64
62
  completions = completeInput(":rel su", state)[0];
65
63
  assert(completions.includes(":rel succ"));
66
- completions = completeInput(":ty", state)[0];
67
- assert(completions.includes(":types"));
68
- assert(completions.includes(":type"));
64
+ completions = completeInput(":re", state)[0];
65
+ assert(completions.includes(":rels"));
66
+ assert(completions.includes(":rel"));
69
67
 
70
68
  await assert.rejects(
71
69
  () => evaluateInput(":run succ", state),
@@ -83,27 +81,26 @@ await assert.rejects(
83
81
  completions = completeInput(":co", state)[0];
84
82
  assert(completions.includes(":codec"));
85
83
 
86
- completions = completeInput("$na", state)[0];
87
- assert(completions.includes("$nat"));
84
+ completions = completeInput("ze", state)[0];
85
+ assert(completions.includes("zero"));
88
86
 
89
- assert.deepEqual(aliasNames(state), ["nat", "succ"]);
87
+ assert.deepEqual(aliasNames(state), ["succ", "zero"]);
90
88
  assert.equal(lineTerminatesSnippet(";"), true);
91
89
  assert.equal(lineTerminatesSnippet(" ; "), true);
92
90
  assert.equal(lineTerminatesSnippet(" ; -- comment"), false);
93
91
  assert.equal(lineTerminatesSnippet("succ"), false);
94
- assert.equal(explicitSnippetTerminated("$ bool = <{} true, {} false>;"), true);
92
+ assert.equal(explicitSnippetTerminated("bool = <{} true, {} false>;"), true);
95
93
  assert.equal(lineHasExplicitContinuation("succ \\"), true);
96
- assert.equal(analyzeRawSnippet("$ bool = <{} true, {} false>").kind, "incomplete");
97
- assert.equal(analyzeAcceptedSnippet("$ bool = <{} true, {} false>;", true).kind, "definitionsOnly");
94
+ assert.equal(analyzeRawSnippet("bool = <{} true, {} false>").kind, "incomplete");
95
+ assert.equal(analyzeAcceptedSnippet("bool = <{} true, {} false>;", true).kind, "definitionsOnly");
98
96
  assert.equal(analyzeRawSnippet("a =").kind, "incomplete");
99
97
  assert.equal(analyzeRawSnippet("{} | succ").kind, "withMain");
100
98
 
101
99
  const offsetState = createState();
102
- await evaluateInput("$ ab = < {} 1, {} 2 >;", offsetState);
103
- await evaluateInput("$ bool = < {} true, {} false >;", offsetState);
100
+ await evaluateInput("zero = {} | zero;\nsucc = | succ;", offsetState);
104
101
  await assert.rejects(
105
- () => evaluateInput("$ab", offsetState),
106
- /Type Error in 'filter' \(lines 1:1\.\.\.1:4\)/
102
+ () => evaluateInput("{} .x", offsetState),
103
+ /Type Error in 'comp' \(lines 1:1\.\.\.1:6\)/
107
104
  );
108
105
 
109
106
  const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "k-repl-"));
@@ -117,13 +114,12 @@ output = await evaluateInput(`:klib ${libPath}`, state);
117
114
  assert.equal(output[0], `saved ${libPath}`);
118
115
 
119
116
  const recursiveState = createState();
120
- await evaluateInput("$ nat = < {} _, nat 0, nat 1 >;", recursiveState);
121
- await evaluateInput("0? = $ nat < / _ {} | 0, / 0 0? >;", recursiveState);
117
+ await evaluateInput("0? = ?< {} _, X 0, X 1 > = X < / _ {} | 0, / 0 0? >;", recursiveState);
122
118
  const staleZeroHash = recursiveState.relAliases["0?"];
123
- await evaluateInput("0? = $ nat < / _ {} | _, / 0 0? >;", recursiveState);
119
+ await evaluateInput("0? = ?< {} _, X 0, X 1 > = X < / _ {} | _, / 0 0? >;", recursiveState);
124
120
  const zeroHash = recursiveState.relAliases["0?"];
125
121
  assert.notEqual(zeroHash, staleZeroHash);
126
- await evaluateInput("{}|_|0|0 $nat", recursiveState);
122
+ await evaluateInput("{}|_|0|0 0?", recursiveState);
127
123
  assert.deepEqual(
128
124
  Object.keys(recursiveState.rels).sort(),
129
125
  [staleZeroHash, zeroHash].sort()
@@ -144,28 +140,21 @@ const objectFn = objectToFunction(decodeObject(fs.readFileSync(koPath)));
144
140
  const objectResult = objectFn(Value.product({}, [["closed-product", []]]));
145
141
  assert.equal(objectResult.toJSON(), "succ");
146
142
 
147
- fs.writeFileSync(sourcePath, "$ nat = <{} zero, nat succ>;\nsucc = $nat |succ $nat;\ntwice = succ succ;\n");
143
+ fs.writeFileSync(sourcePath, "succ = |succ;\ntwice = succ succ;\n");
148
144
  const loadedSource = createState();
149
145
  output = await evaluateInput(`:load ${sourcePath}`, loadedSource);
150
146
  assert.equal(output[0], `loaded ${sourcePath}`);
151
- output = await evaluateInput(":types", loadedSource);
152
- assert.match(output[0], /^nat = @/m);
153
147
  output = await evaluateInput(":rels", loadedSource);
154
148
  assert.match(output[0], /^succ = @/m);
155
149
  output = await evaluateInput(":rel twice", loadedSource);
156
- assert.match(output[0], /^twice = \$nat succ succ \$nat; -- @/);
157
- output = await evaluateInput(":C nat", loadedSource);
158
- assert.match(output[0], /^\$ nat = < nat succ, @[^ ]+ zero >; -- @/);
150
+ assert.match(output[0], /^twice = .*succ succ.*; -- @/);
159
151
 
160
152
  const codecState = createState();
161
- output = await evaluateInput("$ bool = < {} true, {} false >;", codecState);
162
- const boolHash = codecState.typeAliases.bool;
163
153
  const valueModuleUrl = pathToFileURL(path.resolve("Value.mjs")).href;
164
154
  fs.writeFileSync(codecPath, `
165
155
  import { Value } from ${JSON.stringify(valueModuleUrl)};
166
156
 
167
157
  export const name = "yn";
168
- export const codes = [${JSON.stringify(boolHash)}];
169
158
 
170
159
  export function parse(text) {
171
160
  const tag = text.trim();
@@ -249,11 +238,9 @@ const reloaded = createState();
249
238
  output = await evaluateInput(`:load ${libPath}`, reloaded);
250
239
  assert.equal(output[0], `loaded ${libPath}`);
251
240
 
252
- output = await evaluateInput(":types", reloaded);
253
- assert.match(output[0], /^nat = @/m);
254
-
255
241
  output = await evaluateInput(":rels", reloaded);
256
242
  assert.match(output[0], /^succ = @/m);
243
+ assert.match(output[0], /^zero = @/m);
257
244
 
258
245
  output = await evaluateInput("succ", reloaded);
259
246
  assert.equal(output[0], "{}|succ ?<{} succ, ...>");
@@ -261,25 +248,22 @@ assert.equal(output[0], "{}|succ ?<{} succ, ...>");
261
248
  const noAliasReloaded = createState();
262
249
  output = await evaluateInput(`:load --no-alias ${libPath}`, noAliasReloaded);
263
250
  assert.equal(output[0], `loaded ${libPath}`);
264
- output = await evaluateInput(":types", noAliasReloaded);
265
- assert.equal(output[0], "(none)");
266
251
  output = await evaluateInput(":rels", noAliasReloaded);
267
252
  assert.equal(output[0], "(none)");
268
253
 
269
254
  const shorthand = createState();
270
- output = await evaluateInput("$ nat = <{} zero, nat succ>\n; succ = |succ\n;", shorthand);
255
+ output = await evaluateInput("zero = {} | zero\n; succ = |succ\n;", shorthand);
271
256
  assert.match(output[0], /\/\* comp: .* \*\//);
272
- output = await evaluateInput(":types", shorthand);
273
- assert.match(output[0], /^nat = @/m);
274
257
  output = await evaluateInput(":rels", shorthand);
258
+ assert.match(output[0], /^zero = @/m);
275
259
  assert.match(output[0], /^succ = @/m);
276
- output = await evaluateInput("$ bool = <{} true, {} false>\n; not = $bool </true | false, {} | true >\n; {} | true not", shorthand);
260
+ output = await evaluateInput("not = </true | false, /false | true >\n; {} | true not", shorthand);
277
261
  assert.match(output[0], /^\{\}\|false \?</);
278
262
  assert.match(output[0], / false/);
279
263
  assert.match(output[0], / true/);
280
- output = await evaluateInput("$ maybe = <{} none, {} some>;", shorthand);
264
+ output = await evaluateInput("maybe = < /none {} | none, /some | some >;", shorthand);
281
265
  assert.match(output[0], /\/\* comp: .* \*\//);
282
- output = await evaluateInput(":types", shorthand);
266
+ output = await evaluateInput(":rels", shorthand);
283
267
  assert.match(output[0], /^maybe = @/m);
284
268
  output = await evaluateInput("{} | true not", shorthand);
285
269
  assert.match(output[0], /^\{\}\|false \?</);
@@ -291,8 +275,7 @@ await assert.rejects(
291
275
 
292
276
  // Verify WebAssembly in-process backend supports TCO / stack safety on deep recursion
293
277
  const tcoState = createState();
294
- await evaluateInput("$ nat = < {} zero, nat succ >;", tcoState);
295
- await evaluateInput("countdown = $ nat < / zero {} | zero, / succ countdown >;", tcoState);
278
+ await evaluateInput("countdown = ?< {} zero, X succ > = X < / zero {} | zero, / succ countdown >;", tcoState);
296
279
 
297
280
  let deepNat = Value.variant("zero", Value.product({}, [["closed-product", []]]), [["open-union", [["zero", 1]]], ["closed-product", []]]);
298
281
  for (let i = 0; i < 5000; i++) {
@@ -336,7 +319,7 @@ assert.equal(output[0], "unloaded codec int.mjs");
336
319
  output = await evaluateInput(":codecs", codecTestState);
337
320
  assert.equal(output[0], "(none)");
338
321
 
339
- output = await evaluateInput("$ bool = < {} true, {} false >;", codecTestState);
322
+ output = await evaluateInput("bool = < /true {} | true, /false {} | false >;", codecTestState);
340
323
  registerCodec(codecTestState, {
341
324
  name: "yn.mjs",
342
325
  parse: (text) => Value.variant(text.trim() === "yes" ? "true" : "false", Value.product({})),
@@ -390,7 +373,9 @@ const ieeeAutoState = createState();
390
373
  await evaluateInput(":load Examples/ieee.k", ieeeAutoState);
391
374
  output = await evaluateInput(":codec load ./codecs/ieee.mjs", ieeeAutoState);
392
375
  assert.match(output[0], /^loaded codec ieee\.mjs/);
393
- assert.ok(ieeeAutoState.typeAliases.ieee, "ieee type alias should be registered");
376
+ assert.ok(ieeeAutoState.codecs["ieee.mjs"], "ieee codec should be registered");
377
+ output = await evaluateInput(":input ieee.mjs 1.5", ieeeAutoState);
378
+ assert.match(output[0], /ieee\.mjs: 1\.5/);
394
379
 
395
380
  const jsonInputState = createState();
396
381
  await evaluateInput(":load core.k", jsonInputState);
@@ -453,7 +438,7 @@ const polyAutoState = createState();
453
438
  output = await evaluateInput(":load Examples/poly.k", polyAutoState);
454
439
  assert.equal(output[0], "loaded Examples/poly.k");
455
440
  assert.ok(polyAutoState.relAliases.reverse, "poly relations should be loaded");
456
- assert.ok(polyAutoState.typeAliases.int, "arithmetics int should be auto-loaded");
441
+ assert.ok(polyAutoState.relAliases.int, "arithmetics int should be auto-loaded");
457
442
 
458
443
  // Verify timing reporting is always on and reflects active engine
459
444
  const timingState = createState();
@@ -510,11 +495,11 @@ assert(completions.includes(":engine js"));
510
495
  const jsState = createState({ engine: "js" });
511
496
  assert.equal(jsState.engine, "js");
512
497
 
513
- output = await evaluateInput("$ nat = < {} zero, nat succ >;\nsucc = | succ;\n{} | zero succ succ", jsState);
498
+ output = await evaluateInput("succ = | succ;\n{} | zero succ succ", jsState);
514
499
  assert.match(output[0], /^\{\}\|zero\|succ\|succ/);
515
500
  assert.match(output[1], /\(js\)/);
516
501
 
517
- output = await evaluateInput("$ bool = < {} true, {} false >;\nnot = $bool </true | false, {} | true >;\n{} | true not", jsState);
502
+ output = await evaluateInput("not = </true | false, /false | true >;\n{} | true not", jsState);
518
503
  assert.match(output[0], /^\{\}\|false/);
519
504
  assert.match(output[1], /\(js\)/);
520
505
 
package/tests/test.mjs CHANGED
@@ -22,9 +22,8 @@ import k from "../index.mjs";
22
22
 
23
23
 
24
24
  let k_expression = `
25
- $ bool = < {} true, {} false >;
26
- true = {} | true $bool;
27
- false = {} | false $bool;
25
+ true = {} | true;
26
+ false = {} | false;
28
27
 
29
28
  list? = ?< {} nil, {X car, Y cdr} cons > = Y;
30
29
  nil = {}|nil list?;