@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
@@ -130,7 +130,7 @@ for (const filename of verifiedCodecs) {
130
130
  }]
131
131
  });
132
132
  const bundledContent = buildRes.outputFiles[0].text;
133
- vfsFiles[`codecs/${filename}`] = bundledContent;
133
+ vfsFiles[filename] = bundledContent;
134
134
  }
135
135
  }
136
136
 
@@ -1666,13 +1666,10 @@ const htmlContent = `<!DOCTYPE html>
1666
1666
  </optgroup>
1667
1667
  <optgroup label="Quick Expressions">
1668
1668
  <option value="expr:{} | ok">{} | ok</option>
1669
- <option value="expr:()">()</option>
1670
- <option value="expr:$ bool = &lt; {} true, {} false &gt;; not = $ bool &lt; / true | false, {} | true &gt; $ bool; {} | true not">not (boolean relation with fallback)</option>
1671
- <option value="expr:{10 x, 5 y} plus">{10 x, 5 y} plus (bits)</option>
1669
+ <option value="expr:not = &lt; / true | false, / false | true &gt;; {} | true not">not (boolean relation)</option>
1672
1670
  <option value="expr:1 succ">1 succ</option>
1673
1671
  <option value="expr:{10 int x, 5 int y} plus">{10 int x, 5 int y} plus (int)</option>
1674
1672
  <option value="expr:{10 int x, 5 int y} karatsuba">{10 int x, 5 int y} karatsuba</option>
1675
- <option value="expr::types">:types (list types)</option>
1676
1673
  <option value="expr::rels">:rels (list relations)</option>
1677
1674
  <option value="expr::engine">:engine (show engine)</option>
1678
1675
  <option value="expr::engine wasm">:engine wasm</option>
@@ -1681,21 +1678,21 @@ const htmlContent = `<!DOCTYPE html>
1681
1678
  <optgroup label="Codecs &amp; Format Adapters">
1682
1679
  <option value="expr::codecs">:codecs</option>
1683
1680
  <option value="expr::input">:input (interactive dialog)</option>
1684
- <option value="expr::codec load codecs/int.mjs">:codec load codecs/int.mjs</option>
1685
- <option value="expr::codec load codecs/utf8.mjs">:codec load codecs/utf8.mjs</option>
1686
- <option value="expr::codec load codecs/json.mjs">:codec load codecs/json.mjs</option>
1687
- <option value="expr::codec load codecs/ieee.mjs">:codec load codecs/ieee.mjs</option>
1688
- <option value="expr::codec load codecs/unit.mjs">:codec load codecs/unit.mjs</option>
1689
- <option value="expr::input codecs/json.mjs {&quot;a&quot;:12,&quot;b&quot;:&quot;hello&quot;}">:input codecs/json.mjs {"a":12,"b":"hello"}</option>
1690
- <option value="expr::input codecs/int.mjs [0,1,2]">:input codecs/int.mjs [0,1,2]</option>
1681
+ <option value="expr::codec load int.mjs">:codec load int.mjs</option>
1682
+ <option value="expr::codec load utf8.mjs">:codec load utf8.mjs</option>
1683
+ <option value="expr::codec load json.mjs">:codec load json.mjs</option>
1684
+ <option value="expr::codec load ieee.mjs">:codec load ieee.mjs</option>
1685
+ <option value="expr::codec load unit.mjs">:codec load unit.mjs</option>
1686
+ <option value="expr::input json.mjs {&quot;a&quot;:12,&quot;b&quot;:&quot;hello&quot;}">:input json.mjs {"a":12,"b":"hello"}</option>
1687
+ <option value="expr::input int.mjs [0,1,2]">:input int.mjs [0,1,2]</option>
1691
1688
  </optgroup>
1692
1689
  </select>
1693
1690
  <button id="btn-load-example" class="btn btn-primary">Load</button>
1694
1691
  </div>
1695
1692
 
1696
1693
  <!-- File Upload -->
1697
- <label class="btn btn-secondary btn-file" title="Upload local .k or .klib file into VFS">
1698
- <input type="file" id="file-upload" accept=".k,.klib,.wat,.ko" style="display:none;">
1694
+ <label class="btn btn-secondary btn-file" title="Upload local file into VFS">
1695
+ <input type="file" id="file-upload" accept=".k,.klib,.wat,.ko,.mjs,.js,.json" style="display:none;">
1699
1696
  <span>📁 Upload</span>
1700
1697
  </label>
1701
1698
 
@@ -1804,10 +1801,10 @@ const htmlContent = `<!DOCTYPE html>
1804
1801
  <div class="help-section">
1805
1802
  <h4>Language Overview</h4>
1806
1803
  <p style="margin-bottom: 8px; color: var(--text-muted); line-height: 1.45;">
1807
- <b>k</b> is a concise language of <b>types</b> and <b>relations</b> (functions) over tree-like (JSON-like) documents. Every expression denotes a relation that transforms an input document into an output document.
1804
+ <b>k</b> is a concise language of <b>relations</b> (functions) over tree-like (JSON-like) documents. Every expression denotes a relation that transforms an input document into an output document.
1808
1805
  </p>
1809
1806
  <p style="margin-bottom: 10px; color: var(--text-muted); line-height: 1.45;">
1810
- <b>Content-Addressed:</b> Functions and types are identified by their canonical content hash (<code>@...</code>) derived directly from their structure. Local names are just temporary aliases used for recursion and readability.
1807
+ <b>Content-Addressed:</b> Relations are identified by their canonical content hash (<code>@...</code>) derived directly from their structure. Local names are just temporary aliases used for recursion and readability.
1811
1808
  </p>
1812
1809
 
1813
1810
  <div class="help-category-title">1. Definitions (Local Aliases)</div>
@@ -1821,36 +1818,10 @@ const htmlContent = `<!DOCTYPE html>
1821
1818
  <td><code>name = relExpr;</code></td>
1822
1819
  <td><b>Relation Alias:</b> Defines a local alias for a relation expression.<br><i>e.g.</i> <code>swap = { . y x, . x y };</code></td>
1823
1820
  </tr>
1824
- <tr>
1825
- <td><code>$ name = typeExpr;</code></td>
1826
- <td><b>Type Alias:</b> Defines a local alias for a type schema.<br><i>e.g.</i> <code>$ bool = &lt; {} true, {} false &gt;;</code></td>
1827
- </tr>
1828
- </tbody>
1829
- </table>
1830
-
1831
- <div class="help-category-title">2. Type Expressions (<code>typeExpr</code>)</div>
1832
- <p style="margin-bottom: 6px; color: var(--text-muted); font-size: 12px;">Schemas describing tree-like documents:</p>
1833
- <table class="help-table">
1834
- <thead>
1835
- <tr><th style="width: 45%;">Syntax</th><th>Description</th></tr>
1836
- </thead>
1837
- <tbody>
1838
- <tr>
1839
- <td><code>{ Type_1 label_1, ..., Type_k label_k }</code></td>
1840
- <td><b>Product Type:</b> Labeled record of arity <i>k</i> (e.g. <code>{float64 x, string n}</code>; special case: <code>{}</code> is the 0-ary product)</td>
1841
- </tr>
1842
- <tr>
1843
- <td><code>&lt; Type_1 tag_1, ..., Type_k tag_k &gt;</code></td>
1844
- <td><b>Union Type:</b> Tagged sum of <i>k</i> variants (e.g. <code>&lt;int ok, string err&gt;</code>)</td>
1845
- </tr>
1846
- <tr>
1847
- <td><code>name</code> / <code>@hash</code></td>
1848
- <td><b>Type Reference:</b> References a type by local alias or canonical content hash</td>
1849
- </tr>
1850
1821
  </tbody>
1851
1822
  </table>
1852
1823
 
1853
- <div class="help-category-title">3. Relation Expressions (<code>relExpr</code>)</div>
1824
+ <div class="help-category-title">2. Relation Expressions (<code>relExpr</code>)</div>
1854
1825
  <p style="margin-bottom: 6px; color: var(--text-muted); font-size: 12px;">Functions transforming an input document to an output document:</p>
1855
1826
  <table class="help-table">
1856
1827
  <thead>
@@ -1882,8 +1853,8 @@ const htmlContent = `<!DOCTYPE html>
1882
1853
  <td><b>Variant Constructor:</b> Wraps document into variant <code>tag</code></td>
1883
1854
  </tr>
1884
1855
  <tr>
1885
- <td><code>$ typeExpr</code></td>
1886
- <td><b>Type Constraint:</b> Asserts input matches <code>typeExpr</code> (compile-time Type Error on mismatch)</td>
1856
+ <td><code>? filterExpr</code></td>
1857
+ <td><b>Pattern Filter:</b> Asserts input matches pattern; acts as partial identity and inductive termination witness (<i>e.g.</i> <code>?&lt; {} true, {} false &gt;</code>)</td>
1887
1858
  </tr>
1888
1859
  <tr>
1889
1860
  <td><code>name</code> / <code>@hash</code></td>
@@ -1899,8 +1870,6 @@ const htmlContent = `<!DOCTYPE html>
1899
1870
  <tr><td><code>:engine [wasm|js]</code></td><td>Display or switch evaluation engine (<code>wasm</code> or <code>js</code>)</td></tr>
1900
1871
  <tr><td><code>:load &lt;file&gt;</code></td><td>Load a <code>.k</code> source or <code>.klib</code> library into current state</td></tr>
1901
1872
  <tr><td><code>:rel &lt;name&gt;</code></td><td>Display definition of relation <code>&lt;name&gt;</code></td></tr>
1902
- <tr><td><code>:type &lt;name&gt;</code></td><td>Display definition of type <code>&lt;name&gt;</code></td></tr>
1903
- <tr><td><code>:types</code></td><td>List all type aliases and canonical hashes</td></tr>
1904
1873
  <tr><td><code>:rels</code></td><td>List all relation aliases</td></tr>
1905
1874
  <tr><td><code>:codecs</code></td><td>List all loaded format codecs</td></tr>
1906
1875
  <tr><td><code>:codec load &lt;file.mjs&gt;</code></td><td>Load a codec from file (or load through Files)</td></tr>
@@ -1919,8 +1888,8 @@ const htmlContent = `<!DOCTYPE html>
1919
1888
  <li><code>{} | ok</code> &mdash; Constant relation producing variant <code>ok</code> with empty document payload <code>{}</code></li>
1920
1889
  <li><code>not = &lt; / true | false, / false | true &gt;;</code> &mdash; Polymorphic negation via branch projections and ordered choice</li>
1921
1890
  <li><code>{} | true not</code> &mdash; Compose constant relation <code>{} | true</code> with <code>not</code> (evaluates to <code>{} | false</code>)</li>
1922
- <li><code>$ bool = &lt; {} true, {} false &gt;;</code> &mdash; Define a boolean union type schema</li>
1923
- <li><code>not = $ bool &lt; / true | false, {} | true &gt; $ bool;</code> &mdash; Typed boolean negation: guarded by <code>$ bool</code>, defaulting to <code>{} | true</code></li>
1891
+ <li><code>bool = ?&lt; {} true, {} false &gt;;</code> &mdash; Define a boolean pattern filter relation</li>
1892
+ <li><code>not = bool ?X &lt; / true | false, {} | true &gt; ?X;</code> &mdash; Filtered boolean negation: guarded by <code>bool</code>, defaulting to <code>{} | true</code></li>
1924
1893
  <li><code>swap = { . y x, . x y };</code> &mdash; Define a product field-swapping relation</li>
1925
1894
  <li><code>{ {} | ok x, {} | nil y } swap</code> &mdash; Construct a product and pass it through <code>swap</code></li>
1926
1895
  </ul>
@@ -19,9 +19,7 @@ t(`
19
19
  `, (annotated) => {
20
20
  // console.log(JSON.stringify(annotated,null,2));
21
21
  const {input,output} = in_out(annotated);
22
- console.log(input);
23
- console.log(output);
24
- assert.equal(output.type, annotated.representatives["bnat"]);
25
- assert.equal(input.type, annotated.representatives["pair"]);
22
+ assert.equal(output.pattern, '(...)');
23
+ assert.equal(input.pattern, '<...>');
26
24
  console.log("OK");
27
25
  });
@@ -5,8 +5,7 @@ import assert from 'assert';
5
5
  t(fs.readFileSync("./Examples/bnat.k", "utf8"), (annotated) => {
6
6
  // console.log(JSON.stringify(annotated,null,2));
7
7
  const {input,output} = in_out(annotated);
8
- // console.log(output);
9
- assert.equal(output.type, annotated.representatives["bnat"]);
10
- assert.equal(input.type, annotated.representatives["pair"]);
8
+ assert.equal(output.type, "@VtPHxGf5GNMzzyVFxtv7gegFfJRYapBGtCeyV56bs5Zb");
9
+ assert.equal(input.type, "@R7RD2sgu6yPqpCQBBcJqkzxHQMZfEJLcNW4UKBcTiC3m");
11
10
  console.log("OK");
12
11
  });
@@ -3,24 +3,18 @@ import { hash } from '../../hash.mjs';
3
3
  import assert from 'assert';
4
4
 
5
5
  t(`
6
- $b = < {} true, {} false > ;
7
- $pair = { b one, b two } ;
8
- $bit = <{} 0, {} 1> ;
9
- 1 = {} |1 $bit;
10
- $b {1 one, () two, () c} .one
6
+ 1 = {} |1 ?< {} 0, {} 1 >;
7
+ ?< {} true, {} false > {1 one, () two, () c} .one
11
8
 
12
9
  `, (annotated) => {
13
10
  const {input,output} = in_out(annotated);
14
- // console.log({input,output});
15
- assert.equal(input.type, annotated.representatives["b"]);
16
- assert.equal(output.type, annotated.representatives["bit"]);
11
+ assert.equal(input.type, "@GWnxJCupZr96BZfdpDsfQQKxKjCbjyDh7Qaur7y9enCY");
12
+ assert.equal(output.type, "@MjusyRWZnVj8TR4BhFCCcMRrQbdKp9gPtC29LT9nZvjg");
17
13
  console.log("OK");
18
14
  });
19
15
 
20
16
  t(`
21
- $bit = <{} 0, {} 1> ;
22
- $a = < bit true, bit false > ;
23
- $a /true
17
+ ?< <{} 0, {} 1> true, <{} 0, {} 1> false > /true
24
18
  `, (annotated) => {
25
19
  const {input,output} = in_out(annotated);
26
20
  console.log({input,output});
@@ -4,7 +4,7 @@ import assert from 'assert';
4
4
 
5
5
  t(fs.readFileSync("./Examples/nat.k", "utf8"), (annotated) => {
6
6
  const {input,output} = in_out(annotated);
7
- assert.equal(output.type, annotated.representatives["nat"]);
8
- assert.equal(input.type, annotated.representatives["nat"]);
7
+ assert.equal(output.type, input.type);
8
+ assert.equal(output.type, "@e9WP6QX6URfgnd9hHYrrYUBhiL7UcvbWErVmyQJfFcr8");
9
9
  console.log("OK");
10
10
  });
@@ -1,14 +1,14 @@
1
1
  import { t, in_out } from './index.mjs';
2
2
  import assert from 'assert';
3
3
 
4
- t(`$b = < {} true, {} false > ;
5
- true = {} |true $b;
6
- false = {} |false $b;
7
- not = $b < /true false, /false true >;
4
+ t(`
5
+ true = {} |true;
6
+ false = {} |false;
7
+ not = ?< {} true, {} false > < /true false, /false true > ?< {} true, {} false >;
8
8
  not not
9
9
  `, (annotated) => {
10
10
  const {input,output} = in_out(annotated);
11
- assert.equal(input.type, annotated.representatives["b"]);
12
- assert.equal(output.type, annotated.representatives["b"]);
11
+ assert.equal(input.type, output.type);
12
+ assert.equal(input.type, "@GWnxJCupZr96BZfdpDsfQQKxKjCbjyDh7Qaur7y9enCY");
13
13
  console.log("OK");
14
14
  });
@@ -12,9 +12,8 @@ const INT_PATTERN = [
12
12
  ];
13
13
 
14
14
  const script = `
15
- $ bits = < {} _, bits 0, bits 1 >;
16
- $ int = < bits +, bits - >;
17
- {}|_|0|1|+ $int
15
+ int = ?< <bits 0, bits 1, {} _>=bits "+", bits "-" >;
16
+ {}|_|0|1|+ int
18
17
  `;
19
18
 
20
19
  const result = k.compile(script)(Value.product({}));
@@ -76,9 +75,8 @@ assert.throws(
76
75
  );
77
76
 
78
77
  const projectionScript = `
79
- $ bits = < {} _, bits 0, bits 1 >;
80
- $ int = < bits +, bits - >;
81
- $int /+
78
+ int = ?< <bits 0, bits 1, {} _>=bits "+", bits "-" >;
79
+ int /+
82
80
  `;
83
81
  const annotated = k.annotate(projectionScript);
84
82
  run.defs = annotated;
@@ -12,14 +12,11 @@ t('{}', (annotated) => {
12
12
  });
13
13
 
14
14
  t(`
15
- $b = < {} true, {} false > ;
16
- $pair = { b one, b two } ;
17
-
18
- {() one, () two} $pair
15
+ ?< {} true, {} false > {() one, () two} ?{ < {} true, {} false > one, < {} true, {} false > two }
19
16
  `, (annotated) => {
20
17
  const {input,output} = in_out(annotated);
21
18
 
22
- assert.equal(input.type, annotated.representatives["b"]);
23
- assert.equal(output.type, annotated.representatives["pair"]);
19
+ assert.equal(input.type, "@GWnxJCupZr96BZfdpDsfQQKxKjCbjyDh7Qaur7y9enCY");
20
+ assert.equal(output.type, "@ZR2yff4pdXTVqZdMu9x3t9GG5rwmhEfQuenbAwFnD2Nk");
24
21
  console.log("OK");
25
22
  });
@@ -2,13 +2,12 @@ import { t, in_out } from './index.mjs';
2
2
  import assert from 'assert';
3
3
 
4
4
  t(`
5
- $nat = < {} _, nat 0, nat 1>;
6
- zero = {}|_|0 $nat;
7
- rlz = </0/_ zero, /0 rlz, ()>;
5
+ zero = {}|_|0;
6
+ rlz = ?<X 0, X 1, {} _>=X </0/_ zero, /0 rlz, ()> ?X;
8
7
  rlz
9
8
  `, (annotated) => {
10
9
  const {input,output} = in_out(annotated);
11
- assert.equal(output.type, annotated.representatives["nat"]);
12
- assert.equal(input.type, annotated.representatives["nat"]);
10
+ assert.equal(output.type, input.type);
11
+ assert.equal(output.type, "@VtPHxGf5GNMzzyVFxtv7gegFfJRYapBGtCeyV56bs5Zb");
13
12
  console.log("OK");
14
13
  });
@@ -171,7 +171,7 @@ console.log("6. Verifying pattern derivation via k type system (patternFromFilte
171
171
  assert.deepEqual(UnitCodec.UNIT_PATTERN, unitPat);
172
172
 
173
173
  const listPat = SDK.patternFromFilter(
174
- '$ bits = < bits 0, bits 1, {} _ >; $ int = < bits "+", bits "-" >; ?< {} nil, { $int car, list cdr } cons > = list'
174
+ '?< {} nil, { < <bits 0, bits 1, {} _>=bits "+", bits "-" > car, list cdr } cons > = list'
175
175
  );
176
176
  assert.deepEqual(IntCodec.INT_LIST_PATTERN, listPat);
177
177
 
@@ -1,43 +1,38 @@
1
- import k from '../index.mjs';
2
- import { encodeCodeToString, find } from '../codes.mjs';
1
+ import codes, { encodeCodeToString } from '../codes.mjs';
3
2
  import hash from '../hash.mjs';
4
- [
5
- `
6
- $bits = < bits 0, bits 1, {} _ >;
7
- $nat = < {} zero, nat succ>;
8
- $pair = {nat x, nat y};
9
- $b = { bits"x", bits y};
10
- $tree = < {nat value, tree left, tree right} binary, nat leaf, {nat value, tree tree} unary >;
11
-
12
- succ = | succ $nat;
13
- plus = $pair <
14
- {.x/zero stop, .y result} .result,
15
- {.x/succ x, .y succ y } plus
16
- > $nat;
17
- {}|zero succ succ {() x, () y} plus
18
- `
19
- ].map(function (script) {
20
- console.log("test-fingerprint:");
21
- // console.log(`k_expression = '${script}';`);
22
- const annotated = k.annotate(script);
23
- // console.log(annotated);
24
- let ERRORS = 0;
25
- for (const code in annotated.representatives) {
26
- // console.log(`CODE: ${code}`);
27
- const s = encodeCodeToString(annotated.representatives[code]);
28
- // console.log(` - DEFS: ${s}`);;
29
- const annotated2 = k.annotate(s+" {}");;
30
- const s2 = encodeCodeToString(annotated2.representatives["C0"]);
31
- // console.log(` - reparsed FINGERPRINT: ${hash(s2)}`);
32
- if (!((s === s2) && (hash(s) === hash(s2)))) {
33
- ERRORS++;
34
- console.log(` ERROR - reparsed FINGERPRINT for ${code} is different`);
35
- }
36
- }
37
- if (ERRORS === 0) {
38
- console.log("OK");
39
- } else {
40
- console.log(" ----- ERRORS");
41
- }
42
- });
3
+ import assert from 'assert';
4
+
5
+ console.log("test-fingerprint:");
6
+ const codeDefs = {
7
+ bits: { code: "union", union: { "0": "bits", "1": "bits", "_": "{}" } },
8
+ nat: { code: "union", union: { zero: "{}", succ: "nat" } },
9
+ pair: { code: "product", product: { x: "nat", y: "nat" } },
10
+ b: { code: "product", product: { x: "bits", y: "bits" } },
11
+ tree: { code: "union", union: {
12
+ binary: "binNode",
13
+ leaf: "nat",
14
+ unary: "unNode"
15
+ } },
16
+ binNode: { code: "product", product: { value: "nat", left: "tree", right: "tree" } },
17
+ unNode: { code: "product", product: { value: "nat", tree: "tree" } },
18
+ "{}": { code: "product", product: {} }
19
+ };
20
+
21
+ const reps = codes.register(codeDefs);
22
+ let errors = 0;
23
+ for (const code in reps) {
24
+ const rep = reps[code];
25
+ const s = encodeCodeToString(rep);
26
+ const h = hash(s);
27
+ if (rep !== h) {
28
+ errors++;
29
+ console.log(` ERROR - fingerprint mismatch for ${code}: ${rep} !== ${h}`);
30
+ }
31
+ }
32
+
33
+ if (errors === 0) {
34
+ console.log("OK");
35
+ } else {
36
+ console.log(" ----- ERRORS");
37
+ }
43
38
 
@@ -67,16 +67,14 @@ f
67
67
  // SCC order should not change hash
68
68
  {
69
69
  const scriptA = `
70
- $bit = < {} 0, {} 1 >;
71
- f = $bit < /0 |0 g, /1 >;
72
- g = $bit < /0 |0 f, /1 >;
70
+ f = ?< {} 0, {} 1 > < /0 |0 g, /1 >;
71
+ g = ?< {} 0, {} 1 > < /0 |0 f, /1 >;
73
72
  f
74
73
  `;
75
74
 
76
75
  const scriptB = `
77
- $bit = < {} 0, {} 1 >;
78
- g = $bit < /0 |0 f, /1 >;
79
- f = $bit < /0 |0 g, /1 >;
76
+ g = ?< {} 0, {} 1 > < /0 |0 f, /1 >;
77
+ f = ?< {} 0, {} 1 > < /0 |0 g, /1 >;
80
78
  f
81
79
  `;
82
80
 
@@ -6,25 +6,25 @@ import codes from "../codes.mjs";
6
6
  import { parse as parseFloat64, print as printFloat64 } from "../codecs/ieee.mjs";
7
7
  import { closedPatternToCodeHash, valueForCode } from "../repl-codecs.mjs";
8
8
 
9
- const state = createState();
9
+ const state = createState({ engine: "js" });
10
10
  await evaluateInput(":load Examples/ieee.k", state);
11
11
 
12
12
  for (const name of ["add", "sub", "mul", "div"]) {
13
13
  assert.ok(state.relAliases[name], `Expected public IEEE relation '${name}'`);
14
14
  }
15
15
 
16
- const float64Hash = state.typeAliases.float64;
17
- const floatPairHash = state.typeAliases.float_pair;
16
+ const sampleFloat = parseFloat64("0");
17
+ const float64Hash = closedPatternToCodeHash(sampleFloat.pattern);
18
18
 
19
19
  function float64(text) {
20
- return valueForCode(parseFloat64(text), float64Hash, codes.find);
20
+ return parseFloat64(text);
21
21
  }
22
22
 
23
23
  function floatPair(x, y) {
24
- return valueForCode(Value.product({
24
+ return Value.product({
25
25
  x: float64(x),
26
26
  y: float64(y)
27
- }), floatPairHash, codes.find);
27
+ });
28
28
  }
29
29
 
30
30
  async function runOperation(op, x, y) {
@@ -40,7 +40,6 @@ async function runProjectedResult(op, x, y) {
40
40
  }
41
41
 
42
42
  function assertFloatResult(value, expected, label) {
43
- assert.equal(closedPatternToCodeHash(value.pattern), float64Hash, `${label}: result should keep float64 envelope`);
44
43
  assert.equal(printFloat64(value), expected, label);
45
44
  }
46
45
 
@@ -51,9 +51,7 @@ const INT_PATTERN = [
51
51
  ];
52
52
 
53
53
  const objectBuffer = compileObjectBuffer(`
54
- $ bits = < {} _, bits 0, bits 1 >;
55
- $ int = < bits +, bits - >;
56
- {}|_|0|1|+ $int
54
+ {}|_|0|1|+ ?< <bits 0, bits 1, {} _>=bits "+", bits "-">
57
55
  `);
58
56
  assert.equal(objectBuffer.subarray(0, 5).toString("utf8"), "KOBJ\n");
59
57
  const object = decodeObject(objectBuffer);
@@ -84,19 +82,17 @@ const decompiledSource = decompileObjectBuffer(objectBuffer);
84
82
  const decompiledResult = k.compile(decompiledSource)(Value.product({}));
85
83
  assert.deepEqual(decompiledResult.pattern, INT_PATTERN);
86
84
  assert.deepEqual(decompiledResult.toJSON(), objectResult.toJSON());
87
- assert.match(decompiledSource, /^----- codes -----$/m);
88
85
  assert.match(decompiledSource, /^----- rels -----$/m);
89
86
  assert.match(decompiledSource, /^----- main -----$/m);
90
- assert.match(decompiledSource, /\$ Nws3 =/);
91
- assert.match(decompiledSource, /^7jfi = /m);
92
- assert.match(decompiledSource, /^----- main -----\n\?\(\.\.\.\) 7jfi \$Nws3$/m);
87
+ assert.match(decompiledSource, /^[A-Za-z0-9_]+ = /m);
88
+ assert.match(decompiledSource, /^----- main -----\n\?\(\.\.\.\) [A-Za-z0-9_]+ \?<<X0 0, X0 1, {} _>=X0 \+, X0 ->$/m);
93
89
 
94
90
  const natLibraryBuffer = compileLibraryBuffer(fs.readFileSync("Examples/nat.k", "utf8"), { source: "Examples/nat.k" });
95
91
  const natDecompiledSource = decompileObjectBuffer(natLibraryBuffer);
96
92
  const natRoundTripSource = decompileObjectBuffer(
97
93
  compileLibraryBuffer(natDecompiledSource, { source: "Examples/nat.decompiled.k" })
98
94
  );
99
- const recursiveNatPattern = /\$dTww <\{\.x PgmQ x, \.y h4Wg y\} re64, \.y> \$e9WP;/;
95
+ const recursiveNatPattern = /\?\{<\{\} 0, X0 \+1>=X0 x, <X1 \+1, \.\.\.>=X1 y\} <\{\.x [A-Za-z0-9_]+ x, \.y [A-Za-z0-9_]+ y\} [A-Za-z0-9_]+, \.y> \?X1;/;
100
96
  assert.equal(natRoundTripSource, natDecompiledSource);
101
97
  assert.match(natDecompiledSource, recursiveNatPattern);
102
98
 
@@ -111,14 +107,14 @@ const arithmeticsRoundTripSource = decompileObjectBuffer(
111
107
  assert.equal(arithmeticsRoundTripSource, arithmeticsDecompiledSource);
112
108
 
113
109
  assert.throws(() => k.compile("@A = (); @A"), /Parse error/);
114
- assert.throws(() => k.compile("$ @A = {}; $@A"), /Parse error/);
110
+ assert.throws(() => k.compile("$ @A = {}; $@A"), /Lexical error/);
115
111
  assert.deepEqual(k.compile("7jfi = ?X0; 7jfi")(Value.product({})).toJSON(), {});
116
112
 
117
113
  const sccSource = decompileObjectBuffer(compileObjectBuffer("c = {}; b = c |x; a = b |y; a"));
118
- assert.match(sccSource, /----- rels -----\nPQgV = .+\n\naQAD = .+\n\nN9UH = /s);
114
+ assert.match(sccSource, /----- rels -----\n[A-Za-z0-9_]+ = .+\n\n[A-Za-z0-9_]+ = .+\n\n[A-Za-z0-9_]+ = /s);
119
115
  assert.deepEqual(k.compile(sccSource)(Value.product({})).toJSON(), { y: "x" });
120
116
 
121
- const libraryBuffer = compileLibraryBuffer("$ nat = <{} zero, nat succ>;\nsucc = |succ;\n", { source: "defs-only.k" });
117
+ const libraryBuffer = compileLibraryBuffer("zero = {}|zero;\nsucc = |succ;\n", { source: "defs-only.k" });
122
118
  assert.equal(libraryBuffer.subarray(0, 1).toString("utf8"), "{");
123
119
  const library = decodeObject(libraryBuffer);
124
120
  assert.equal("version" in library, false);
@@ -133,10 +129,10 @@ assert(Object.values(library.rels).every((rel) =>
133
129
  ));
134
130
  assert(Object.values(library.rels).every((rel) => rel.def.op !== "comp" || rel.def.comp[0]?.op !== "filter"));
135
131
  assert(Object.values(library.meta).some(({ type, origins }) =>
136
- type === "code" &&
132
+ type === "rel" &&
137
133
  origins.some((origin) =>
138
134
  origin.source === "defs-only.k" &&
139
- origin.name === "nat" &&
135
+ origin.name === "zero" &&
140
136
  typeof origin.compiledAt === "string" &&
141
137
  origin.start &&
142
138
  origin.end
@@ -158,11 +154,11 @@ const derivedLibrary = decodeObject(compileLibraryBuffer("other = |other;\n", {
158
154
  libraries: [library]
159
155
  }));
160
156
  const derivedAliases = extractAliasesFromObject(derivedLibrary);
161
- assert.match(derivedAliases, /^\$ nat = @/m);
157
+ assert.match(derivedAliases, /^zero = @/m);
162
158
  assert.match(derivedAliases, /^succ = @/m);
163
159
  assert.match(derivedAliases, /^other = @/m);
164
- assert(derivedAliases.indexOf("$ nat = @") < derivedAliases.indexOf("other = @"));
165
160
  assert(derivedAliases.indexOf("other = @") < derivedAliases.indexOf("succ = @"));
161
+ assert(derivedAliases.indexOf("succ = @") < derivedAliases.indexOf("zero = @"));
166
162
 
167
163
  {
168
164
  const warn = console.warn;
@@ -9,7 +9,6 @@ import {
9
9
  import { validateKIRP } from "../objects/validate.mjs";
10
10
 
11
11
  const object = decodeObject(compileObjectBuffer(`
12
- $ bit = < {} 0, {} 1 >;
13
12
  id = ();
14
13
  .x id
15
14
  `, { source: "kir-test.k" }));
@@ -91,8 +91,7 @@ console.log("==> Starting Polymorphic kVM & Specialization Tests");
91
91
  // Test 3: Type Error on Envelope Mismatch
92
92
  {
93
93
  const script = `
94
- $ bool = < {} true, {} false >;
95
- check = $bool;
94
+ check = ?< {} true, {} false >;
96
95
  check
97
96
  `;
98
97
  const obj = decodeObject(compileObjectBuffer(script));
@@ -84,8 +84,7 @@ console.log("==> Starting kVM Tests");
84
84
  // Test 7: Filters & Types
85
85
  {
86
86
  const script = `
87
- $ bool = < {} true, {} false >;
88
- $ bool
87
+ ?< {} true, {} false >
89
88
  `;
90
89
  const result1 = runKVM(script, { true: {} });
91
90
  assert.deepEqual(toJSON(result1), "true");
@@ -98,9 +97,8 @@ console.log("==> Starting kVM Tests");
98
97
  // Test 8: Recursive List traversal (Cons/Nil)
99
98
  {
100
99
  const script = `
101
- $ bool = < {} true, {} false >;
102
- true = {} | true $bool;
103
- false = {} | false $bool;
100
+ true = {} | true;
101
+ false = {} | false;
104
102
 
105
103
  list? = ?< {} nil, {X car, Y cdr} cons > = Y;
106
104
  nil = {}|nil list?;
@@ -130,12 +128,11 @@ console.log("==> Starting kVM Tests");
130
128
  // Test 9: Comparing KVM execution vs Native JS run (Envelope-aware and Envelope-free)
131
129
  {
132
130
  const script = `
133
- $ nat = < {} 0, nat +1 >;
134
- 0 = {} | 0 $ nat;
135
- inc = | +1 $ nat;
136
- dec = $ nat / +1;
137
- add = $ { nat x, nat y } <
138
- { . x dec x, . y inc y } add,
131
+ 0 = {} | 0;
132
+ inc = | +1;
133
+ dec = / +1;
134
+ add = ?{ < {} 0, N +1 > = N x, ... } = X <
135
+ { . x dec x, . y inc y } ?X add,
139
136
  . y
140
137
  >;
141
138
  `;