@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.
- package/CHANGELOG.md +70 -0
- package/CLAUDE.md +1 -1
- package/DOCS/BIG_PICTURE.md +156 -172
- package/DOCS/BINARY_CODEC_STATUS_AND_TODO.md +3 -3
- package/DOCS/CODEC_ARCHITECTURE.md +2 -2
- package/DOCS/DICTIONARY.md +243 -250
- package/DOCS/DIVERGENCE_DETECTION.md +0 -1
- package/DOCS/FILE_FORMATS.md +5 -5
- package/DOCS/KIR_SPECIALIZATION_DESIGN.md +1 -1
- package/DOCS/OBJECT_FILE_AND_PATTERN.md +12 -12
- package/DOCS/PATTERNS.md +17 -17
- package/DOCS/PATTERNS_AND_TYPED_VALUES.md +1 -1
- package/DOCS/REPL.md +9 -19
- package/DOCS/TYPE_DERIVATION.md +2 -8
- package/DOCS/WEB_REPL_REQUIREMENTS.md +8 -8
- package/DOCS/book/01-introduction.md +8 -11
- package/DOCS/book/02-syntax-and-values.md +19 -20
- package/DOCS/book/03-types-as-finite-automata.md +42 -43
- package/DOCS/book/04-partial-functions-and-composition.md +2 -3
- package/DOCS/book/05-typing-filters-and-normalization.md +44 -46
- package/DOCS/book/06-values-in-memory.md +10 -10
- package/DOCS/book/08-operational-semantics-and-execution.md +21 -26
- package/DOCS/book/09-compiler-architecture.md +11 -11
- package/DOCS/book/10-from-ast-to-intermediate-representation.md +6 -7
- package/DOCS/book/14-canonical-serialization.md +2 -2
- package/DOCS/book/appendix-b-incorporating-external-predefined-types-and-functions.md +17 -17
- package/DOCS/book.md +5 -5
- package/Examples/arithmetics.k +49 -153
- package/Examples/bnat.k +13 -13
- package/Examples/byte.k +2 -50
- package/Examples/ieee.k +408 -423
- package/Examples/karatsuba-mult.k +30 -34
- package/Examples/nat.k +5 -6
- package/README.md +54 -49
- package/TODO.md +13 -18
- package/browser/repl-browser.mjs +40 -22
- package/browser/shims/fs.mjs +7 -10
- package/browser/vfs-data.mjs +12 -12
- package/codecs/BINARY_FORMAT.md +4 -4
- package/codecs/POLYMORPHIC_BINARY_FORMAT.md +4 -4
- package/codecs/README.md +6 -6
- package/codecs/ieee.mjs +15 -11
- package/codecs/int.mjs +9 -5
- package/codecs/string-codec.mjs +46 -47
- package/core.k +124 -175
- package/object.mjs +0 -7
- package/package.json +5 -2
- package/parser.jison +2 -41
- package/parser.mjs +55 -95
- package/pretty.mjs +11 -4
- package/repl.mjs +8 -63
- package/scripts/build-repl-html.mjs +18 -49
- package/tests/code-derivation/blowup.mjs +2 -4
- package/tests/code-derivation/bnat.mjs +2 -3
- package/tests/code-derivation/dot.mjs +5 -11
- package/tests/code-derivation/nat.mjs +2 -2
- package/tests/code-derivation/not-not.mjs +6 -6
- package/tests/code-derivation/pattern-envelope.mjs +4 -6
- package/tests/code-derivation/product.mjs +3 -6
- package/tests/code-derivation/rlz.mjs +4 -5
- package/tests/test-codecs.mjs +1 -1
- package/tests/test-fingerprint.mjs +36 -41
- package/tests/test-hash-normalization.mjs +4 -6
- package/tests/test-ieee-arithmetic.mjs +6 -7
- package/tests/test-k-object.mjs +11 -15
- package/tests/test-kir.mjs +0 -1
- package/tests/test-kvm-polymorphic.mjs +1 -2
- package/tests/test-kvm.mjs +8 -11
- package/tests/test-repl-html.mjs +86 -9
- package/tests/test-repl.mjs +38 -53
- 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[
|
|
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:
|
|
1670
|
-
<option value="expr:$ bool = < {} true, {} false >; not = $ bool < / true | false, {} | true > $ 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 = < / true | false, / false | true >; {} | 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 & 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
|
|
1685
|
-
<option value="expr::codec load
|
|
1686
|
-
<option value="expr::codec load
|
|
1687
|
-
<option value="expr::codec load
|
|
1688
|
-
<option value="expr::codec load
|
|
1689
|
-
<option value="expr::input
|
|
1690
|
-
<option value="expr::input
|
|
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 {"a":12,"b":"hello"}">: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
|
|
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>
|
|
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>
|
|
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 = < {} true, {} false >;</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>< Type_1 tag_1, ..., Type_k tag_k ></code></td>
|
|
1844
|
-
<td><b>Union Type:</b> Tagged sum of <i>k</i> variants (e.g. <code><int ok, string err></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">
|
|
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
|
|
1886
|
-
<td><b>
|
|
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>?< {} true, {} false ></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 <file></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 <name></code></td><td>Display definition of relation <code><name></code></td></tr>
|
|
1902
|
-
<tr><td><code>:type <name></code></td><td>Display definition of type <code><name></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 <file.mjs></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> — Constant relation producing variant <code>ok</code> with empty document payload <code>{}</code></li>
|
|
1920
1889
|
<li><code>not = < / true | false, / false | true >;</code> — Polymorphic negation via branch projections and ordered choice</li>
|
|
1921
1890
|
<li><code>{} | true not</code> — Compose constant relation <code>{} | true</code> with <code>not</code> (evaluates to <code>{} | false</code>)</li>
|
|
1922
|
-
<li><code
|
|
1923
|
-
<li><code>not =
|
|
1891
|
+
<li><code>bool = ?< {} true, {} false >;</code> — Define a boolean pattern filter relation</li>
|
|
1892
|
+
<li><code>not = bool ?X < / true | false, {} | true > ?X;</code> — Filtered boolean negation: guarded by <code>bool</code>, defaulting to <code>{} | true</code></li>
|
|
1924
1893
|
<li><code>swap = { . y x, . x y };</code> — Define a product field-swapping relation</li>
|
|
1925
1894
|
<li><code>{ {} | ok x, {} | nil y } swap</code> — 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
|
-
|
|
23
|
-
|
|
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
|
-
|
|
9
|
-
assert.equal(
|
|
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
|
-
|
|
7
|
-
|
|
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
|
-
|
|
15
|
-
assert.equal(
|
|
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
|
-
|
|
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,
|
|
8
|
-
assert.equal(
|
|
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(
|
|
5
|
-
true = {} |true
|
|
6
|
-
false = {} |false
|
|
7
|
-
not =
|
|
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,
|
|
12
|
-
assert.equal(
|
|
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
|
-
|
|
16
|
-
|
|
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
|
-
|
|
80
|
-
|
|
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
|
-
|
|
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,
|
|
23
|
-
assert.equal(output.type,
|
|
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
|
-
|
|
6
|
-
|
|
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,
|
|
12
|
-
assert.equal(
|
|
10
|
+
assert.equal(output.type, input.type);
|
|
11
|
+
assert.equal(output.type, "@VtPHxGf5GNMzzyVFxtv7gegFfJRYapBGtCeyV56bs5Zb");
|
|
13
12
|
console.log("OK");
|
|
14
13
|
});
|
package/tests/test-codecs.mjs
CHANGED
|
@@ -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
|
-
'
|
|
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
|
|
2
|
-
import { encodeCodeToString, find } from '../codes.mjs';
|
|
1
|
+
import codes, { encodeCodeToString } from '../codes.mjs';
|
|
3
2
|
import hash from '../hash.mjs';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
71
|
-
|
|
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
|
-
|
|
78
|
-
|
|
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
|
|
17
|
-
const
|
|
16
|
+
const sampleFloat = parseFloat64("0");
|
|
17
|
+
const float64Hash = closedPatternToCodeHash(sampleFloat.pattern);
|
|
18
18
|
|
|
19
19
|
function float64(text) {
|
|
20
|
-
return
|
|
20
|
+
return parseFloat64(text);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function floatPair(x, y) {
|
|
24
|
-
return
|
|
24
|
+
return Value.product({
|
|
25
25
|
x: float64(x),
|
|
26
26
|
y: float64(y)
|
|
27
|
-
})
|
|
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
|
|
package/tests/test-k-object.mjs
CHANGED
|
@@ -51,9 +51,7 @@ const INT_PATTERN = [
|
|
|
51
51
|
];
|
|
52
52
|
|
|
53
53
|
const objectBuffer = compileObjectBuffer(`
|
|
54
|
-
|
|
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,
|
|
91
|
-
assert.match(decompiledSource,
|
|
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 =
|
|
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"), /
|
|
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 -----\
|
|
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("
|
|
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 === "
|
|
132
|
+
type === "rel" &&
|
|
137
133
|
origins.some((origin) =>
|
|
138
134
|
origin.source === "defs-only.k" &&
|
|
139
|
-
origin.name === "
|
|
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,
|
|
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;
|
package/tests/test-kir.mjs
CHANGED
|
@@ -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
|
-
|
|
95
|
-
check = $bool;
|
|
94
|
+
check = ?< {} true, {} false >;
|
|
96
95
|
check
|
|
97
96
|
`;
|
|
98
97
|
const obj = decodeObject(compileObjectBuffer(script));
|
package/tests/test-kvm.mjs
CHANGED
|
@@ -84,8 +84,7 @@ console.log("==> Starting kVM Tests");
|
|
|
84
84
|
// Test 7: Filters & Types
|
|
85
85
|
{
|
|
86
86
|
const script = `
|
|
87
|
-
|
|
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
|
-
|
|
102
|
-
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
`;
|