@fraczak/k 6.10.6 → 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 +41 -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/vfs-data.mjs +11 -11
- 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 +123 -95
- 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 +8 -38
- 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 +5 -2
- package/tests/test-repl.mjs +38 -53
- package/tests/test.mjs +2 -3
|
@@ -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
|
`;
|
package/tests/test-repl-html.mjs
CHANGED
|
@@ -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.
|
|
612
|
-
assert.strictEqual(narrowNavbarCheck.
|
|
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");
|