@fraczak/k 6.8.0 → 6.10.1
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 +40 -0
- package/CLAUDE.md +1 -1
- package/DOCS/BIG_PICTURE.md +3 -5
- package/DOCS/CODECS.md +80 -181
- package/DOCS/CODEC_ARCHITECTURE.md +194 -0
- package/DOCS/REPL.md +69 -51
- package/Examples/arithmetics.k +1 -0
- package/Examples/poly.k +46 -0
- package/backends/llvm/runtime/krt.c +4 -0
- package/backends/llvm/src/kvm2llvm.mjs +2 -2
- package/backends/llvm/tests/test-llvm.mjs +19 -0
- package/backends/wasm/src/kvm2wasm.mjs +4 -0
- package/backends/wasm/tests/test-wasm.mjs +4 -0
- package/browser/repl-browser.mjs +131 -779
- package/browser/shims/process.mjs +7 -0
- package/browser/tree-view.mjs +5 -2
- package/browser/vfs-data.mjs +14 -14
- package/codecs/README.md +7 -0
- package/codecs/ieee.mjs +50 -75
- package/codecs/int.mjs +83 -62
- package/codecs/json-codec.mjs +5 -77
- package/codecs/json.mjs +12 -56
- package/codecs/k-parse.mjs +3 -19
- package/codecs/runtime/codec-sdk.mjs +94 -0
- package/codecs/runtime/pattern-k.mjs +45 -0
- package/codecs/string-codec.mjs +48 -74
- package/codecs/unit.mjs +13 -61
- package/codecs/utf16.mjs +13 -56
- package/codecs/utf8.mjs +11 -55
- package/package.json +1 -1
- package/patterns/from-k.mjs +2 -22
- package/repl-codecs.mjs +69 -196
- package/repl.mjs +177 -281
- package/scripts/build-repl-html.mjs +114 -385
- package/scripts/run-tests.mjs +1 -0
- package/tests/test-codecs.mjs +186 -0
- package/tests/test-poly.mjs +44 -0
- package/tests/test-repl-html.mjs +163 -68
- package/tests/test-repl.mjs +210 -156
- package/tests/test-structural-values.mjs +17 -0
- package/tests/test-tree-view.mjs +3 -0
- package/codecs/example-pipeline.mjs +0 -163
- package/codecs/runtime/ieee-pattern.mjs +0 -30
- package/codecs/runtime/test-codec.mjs +0 -89
- package/codecs/runtime/typeFromValue.mjs +0 -34
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Example: Demonstrating the codec pipeline
|
|
4
|
-
*
|
|
5
|
-
* Shows how to:
|
|
6
|
-
* 1. Define types with canonical names
|
|
7
|
-
* 2. Create values
|
|
8
|
-
* 3. Encode to binary
|
|
9
|
-
* 4. Pass through "compiled program" (identity)
|
|
10
|
-
* 5. Decode from binary
|
|
11
|
-
* 6. Print result
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { deriveClosedPattern } from './runtime/codec.mjs';
|
|
15
|
-
import { encodeToWire, decodeWire } from './runtime/prefix-codec.mjs';
|
|
16
|
-
import { patternToPropertyList } from './runtime/pattern-json.mjs';
|
|
17
|
-
import { Value, isVariant } from '../Value.mjs';
|
|
18
|
-
import hash from '../hash.mjs';
|
|
19
|
-
import { argv, exit } from 'node:process';
|
|
20
|
-
|
|
21
|
-
function usage() {
|
|
22
|
-
console.log(`Usage: ${argv[1]}`);
|
|
23
|
-
console.log(" Run a self-contained demonstration of the codec pipeline.");
|
|
24
|
-
console.log("");
|
|
25
|
-
console.log("Options:");
|
|
26
|
-
console.log(" -h, --help Show this help.");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (argv.slice(2).includes("-h") || argv.slice(2).includes("--help")) {
|
|
30
|
-
usage();
|
|
31
|
-
exit(0);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
console.log('=== K Codec Pipeline Example ===\n');
|
|
35
|
-
|
|
36
|
-
// ============================================================================
|
|
37
|
-
// Step 1: Define types (normally from compiler)
|
|
38
|
-
// ============================================================================
|
|
39
|
-
|
|
40
|
-
const types = {};
|
|
41
|
-
|
|
42
|
-
// Unit: {}
|
|
43
|
-
const unitDef = { code: 'product', product: {} };
|
|
44
|
-
const unitName = hash('$C0={};');
|
|
45
|
-
types[unitName] = unitDef;
|
|
46
|
-
|
|
47
|
-
// Bool: <{} false, {} true>
|
|
48
|
-
const boolDef = {
|
|
49
|
-
code: 'union',
|
|
50
|
-
union: { false: unitName, true: unitName }
|
|
51
|
-
};
|
|
52
|
-
const boolName = hash(`$C0=<${unitName}"false",${unitName}"true">;`);
|
|
53
|
-
types[boolName] = boolDef;
|
|
54
|
-
|
|
55
|
-
// Maybe: <{} nothing, Bool something>
|
|
56
|
-
const maybeDef = {
|
|
57
|
-
code: 'union',
|
|
58
|
-
union: { nothing: unitName, something: boolName }
|
|
59
|
-
};
|
|
60
|
-
const maybeName = hash(
|
|
61
|
-
`$C0=<${unitName}"nothing",${boolName}"something">;`
|
|
62
|
-
);
|
|
63
|
-
types[maybeName] = maybeDef;
|
|
64
|
-
|
|
65
|
-
console.log('Types defined:');
|
|
66
|
-
console.log(' unit:', unitName);
|
|
67
|
-
console.log(' bool:', boolName);
|
|
68
|
-
console.log(' maybe:', maybeName);
|
|
69
|
-
console.log();
|
|
70
|
-
|
|
71
|
-
// ============================================================================
|
|
72
|
-
// Step 2: Type resolver
|
|
73
|
-
// ============================================================================
|
|
74
|
-
|
|
75
|
-
function resolveType(typeName) {
|
|
76
|
-
const def = types[typeName];
|
|
77
|
-
if (!def) {
|
|
78
|
-
throw new Error(`Unknown type: ${typeName}`);
|
|
79
|
-
}
|
|
80
|
-
return def;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// ============================================================================
|
|
84
|
-
// Step 3: Create input value: Maybe Bool = something(true)
|
|
85
|
-
// ============================================================================
|
|
86
|
-
|
|
87
|
-
const inputValue = Value.variant(
|
|
88
|
-
'something',
|
|
89
|
-
Value.variant('true', Value.product({}))
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
console.log('Input value:', inputValue.toString());
|
|
93
|
-
console.log();
|
|
94
|
-
|
|
95
|
-
const maybePattern = patternToPropertyList(
|
|
96
|
-
deriveClosedPattern(maybeName, maybeDef, resolveType)
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
// ============================================================================
|
|
100
|
-
// Step 4: Parse (TEXT → BINARY)
|
|
101
|
-
// ============================================================================
|
|
102
|
-
|
|
103
|
-
console.log('--- PARSE (text → binary) ---');
|
|
104
|
-
const binaryInput = encodeToWire(inputValue, maybePattern);
|
|
105
|
-
console.log('Binary size:', binaryInput.length, 'bytes');
|
|
106
|
-
console.log(' Bytes:', binaryInput.toString('hex'));
|
|
107
|
-
console.log();
|
|
108
|
-
|
|
109
|
-
// ============================================================================
|
|
110
|
-
// Step 5: Compiled k-program (BINARY → BINARY)
|
|
111
|
-
// ============================================================================
|
|
112
|
-
|
|
113
|
-
console.log('--- COMPILED PROGRAM (binary → binary) ---');
|
|
114
|
-
|
|
115
|
-
// Simulate a compiled k-program: decode → transform → encode
|
|
116
|
-
const { value: programInput } = decodeWire(binaryInput);
|
|
117
|
-
|
|
118
|
-
console.log('Program sees value:', programInput.toString());
|
|
119
|
-
|
|
120
|
-
// Example transformation: NOT operation (flip bool inside Maybe)
|
|
121
|
-
let programOutput;
|
|
122
|
-
if (isVariant(programInput) && programInput.tag === 'something') {
|
|
123
|
-
const innerBool = programInput.value;
|
|
124
|
-
if (isVariant(innerBool)) {
|
|
125
|
-
const flipped = Value.variant(
|
|
126
|
-
innerBool.tag === 'true' ? 'false' : 'true',
|
|
127
|
-
innerBool.value
|
|
128
|
-
);
|
|
129
|
-
programOutput = Value.variant('something', flipped);
|
|
130
|
-
}
|
|
131
|
-
} else {
|
|
132
|
-
programOutput = programInput; // nothing → nothing
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
console.log('Program output value:', programOutput.toString());
|
|
136
|
-
|
|
137
|
-
// Encode output
|
|
138
|
-
const binaryOutput = encodeToWire(programOutput, maybePattern);
|
|
139
|
-
|
|
140
|
-
console.log('Binary output size:', binaryOutput.length, 'bytes');
|
|
141
|
-
console.log(' Bytes:', binaryOutput.toString('hex'));
|
|
142
|
-
console.log();
|
|
143
|
-
|
|
144
|
-
// ============================================================================
|
|
145
|
-
// Step 6: Print (BINARY → TEXT)
|
|
146
|
-
// ============================================================================
|
|
147
|
-
|
|
148
|
-
console.log('--- PRINT (binary → text) ---');
|
|
149
|
-
const { value: finalValue } = decodeWire(binaryOutput);
|
|
150
|
-
|
|
151
|
-
console.log('Output value:', finalValue.toString());
|
|
152
|
-
console.log();
|
|
153
|
-
|
|
154
|
-
// ============================================================================
|
|
155
|
-
// Summary
|
|
156
|
-
// ============================================================================
|
|
157
|
-
|
|
158
|
-
console.log('=== Pipeline Summary ===');
|
|
159
|
-
console.log('Input: ', inputValue.toString(), '(true inside Maybe)');
|
|
160
|
-
console.log('Transform: NOT operation on inner bool');
|
|
161
|
-
console.log('Output: ', finalValue.toString(), '(false inside Maybe)');
|
|
162
|
-
console.log();
|
|
163
|
-
console.log('Binary representations are canonical and type-safe!');
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import { parse as parseScript } from "../../parser.mjs";
|
|
3
|
-
import codes from "../../codes.mjs";
|
|
4
|
-
import { deriveClosedPattern } from "./codec.mjs";
|
|
5
|
-
import { patternToPropertyList } from "./pattern-json.mjs";
|
|
6
|
-
|
|
7
|
-
const IEEE_SCRIPT = fs.readFileSync(new URL("../../Examples/ieee.k", import.meta.url), "utf8");
|
|
8
|
-
|
|
9
|
-
function loadFloat64Pattern() {
|
|
10
|
-
const { defs } = parseScript(IEEE_SCRIPT);
|
|
11
|
-
const { codes: finalizedCodes, representatives } = codes.finalize(defs.codes);
|
|
12
|
-
const typeName = representatives.float64 || "float64";
|
|
13
|
-
const typeInfo = finalizedCodes[typeName];
|
|
14
|
-
if (!typeInfo) {
|
|
15
|
-
throw new Error("Could not resolve float64 type from Examples/ieee.k");
|
|
16
|
-
}
|
|
17
|
-
const resolveType = (name) => {
|
|
18
|
-
const type = finalizedCodes[name];
|
|
19
|
-
if (!type) {
|
|
20
|
-
throw new Error(`Unknown IEEE helper type '${name}'`);
|
|
21
|
-
}
|
|
22
|
-
return type;
|
|
23
|
-
};
|
|
24
|
-
return patternToPropertyList(deriveClosedPattern(typeName, typeInfo, resolveType));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const FLOAT64_PATTERN = loadFloat64Pattern();
|
|
28
|
-
|
|
29
|
-
export { FLOAT64_PATTERN, loadFloat64Pattern };
|
|
30
|
-
export default { FLOAT64_PATTERN, loadFloat64Pattern };
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Test the binary codec with basic k types
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { deriveClosedPattern } from './codec.mjs';
|
|
7
|
-
import { encodeToWire, decodeWire } from './prefix-codec.mjs';
|
|
8
|
-
import { patternToPropertyList } from './pattern-json.mjs';
|
|
9
|
-
import { Value, isProduct, isVariant } from '../../Value.mjs';
|
|
10
|
-
import hash from '../../hash.mjs';
|
|
11
|
-
|
|
12
|
-
// Type repository
|
|
13
|
-
const types = {};
|
|
14
|
-
|
|
15
|
-
// Define unit type: {}
|
|
16
|
-
const unitTypeDef = { code: 'product', product: {} };
|
|
17
|
-
const unitTypeStr = '$C0={};';
|
|
18
|
-
const unitTypeName = hash(unitTypeStr);
|
|
19
|
-
types[unitTypeName] = unitTypeDef;
|
|
20
|
-
|
|
21
|
-
console.log('Unit type name:', unitTypeName);
|
|
22
|
-
|
|
23
|
-
// Define bool type: <{} false, {} true>
|
|
24
|
-
const boolTypeDef = {
|
|
25
|
-
code: 'union',
|
|
26
|
-
union: {
|
|
27
|
-
false: unitTypeName,
|
|
28
|
-
true: unitTypeName
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
const boolTypeStr = `$C0=<${unitTypeName}"false",${unitTypeName}"true">;`;
|
|
32
|
-
const boolTypeName = hash(boolTypeStr);
|
|
33
|
-
types[boolTypeName] = boolTypeDef;
|
|
34
|
-
|
|
35
|
-
console.log('Bool type name:', boolTypeName);
|
|
36
|
-
|
|
37
|
-
// Resolver function
|
|
38
|
-
function resolveType(typeName) {
|
|
39
|
-
if (!types[typeName]) {
|
|
40
|
-
throw new Error(`Unknown type: ${typeName}`);
|
|
41
|
-
}
|
|
42
|
-
return types[typeName];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Test 1: Unit value
|
|
46
|
-
console.log('\n=== Test 1: Unit ===');
|
|
47
|
-
const unitValue = Value.product({});
|
|
48
|
-
console.log('Encoding unit:', unitValue.toString());
|
|
49
|
-
|
|
50
|
-
const unitPattern = patternToPropertyList(deriveClosedPattern(unitTypeName, unitTypeDef, resolveType));
|
|
51
|
-
const unitEncoded = encodeToWire(unitValue, unitPattern);
|
|
52
|
-
console.log('Encoded bytes:', unitEncoded.length, 'bytes');
|
|
53
|
-
console.log('Hex:', unitEncoded.toString('hex'));
|
|
54
|
-
|
|
55
|
-
const unitDecoded = decodeWire(unitEncoded);
|
|
56
|
-
console.log('Decoded value:', unitDecoded.value.toString());
|
|
57
|
-
console.log('Match:', isProduct(unitDecoded.value) &&
|
|
58
|
-
Object.keys(unitDecoded.value.product).length === 0);
|
|
59
|
-
|
|
60
|
-
// Test 2: Bool false
|
|
61
|
-
console.log('\n=== Test 2: Bool (false) ===');
|
|
62
|
-
const falseValue = Value.variant('false', Value.product({}));
|
|
63
|
-
console.log('Encoding false:', falseValue.toString());
|
|
64
|
-
|
|
65
|
-
const boolPattern = patternToPropertyList(deriveClosedPattern(boolTypeName, boolTypeDef, resolveType));
|
|
66
|
-
const falseEncoded = encodeToWire(falseValue, boolPattern);
|
|
67
|
-
console.log('Encoded bytes:', falseEncoded.length, 'bytes');
|
|
68
|
-
console.log('Hex:', falseEncoded.toString('hex'));
|
|
69
|
-
|
|
70
|
-
const falseDecoded = decodeWire(falseEncoded);
|
|
71
|
-
console.log('Decoded value:', falseDecoded.value.toString());
|
|
72
|
-
console.log('Match:', isVariant(falseDecoded.value) &&
|
|
73
|
-
falseDecoded.value.tag === 'false');
|
|
74
|
-
|
|
75
|
-
// Test 3: Bool true
|
|
76
|
-
console.log('\n=== Test 3: Bool (true) ===');
|
|
77
|
-
const trueValue = Value.variant('true', Value.product({}));
|
|
78
|
-
console.log('Encoding true:', trueValue.toString());
|
|
79
|
-
|
|
80
|
-
const trueEncoded = encodeToWire(trueValue, boolPattern);
|
|
81
|
-
console.log('Encoded bytes:', trueEncoded.length, 'bytes');
|
|
82
|
-
console.log('Hex:', trueEncoded.toString('hex'));
|
|
83
|
-
|
|
84
|
-
const trueDecoded = decodeWire(trueEncoded);
|
|
85
|
-
console.log('Decoded value:', trueDecoded.value.toString());
|
|
86
|
-
console.log('Match:', isVariant(trueDecoded.value) &&
|
|
87
|
-
trueDecoded.value.tag === 'true');
|
|
88
|
-
|
|
89
|
-
console.log('\n=== All tests complete ===');
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { isProduct, isVariant } from "../../Value.mjs";
|
|
2
|
-
|
|
3
|
-
function typeDefsFromValue(value) {
|
|
4
|
-
let nextId = 0;
|
|
5
|
-
const defs = {};
|
|
6
|
-
|
|
7
|
-
function visit(node) {
|
|
8
|
-
const name = `:auto${nextId++}`;
|
|
9
|
-
if (isProduct(node)) {
|
|
10
|
-
const labels = Object.keys(node.product).sort();
|
|
11
|
-
const product = {};
|
|
12
|
-
for (const label of labels) {
|
|
13
|
-
product[label] = visit(node.product[label]);
|
|
14
|
-
}
|
|
15
|
-
defs[name] = { code: "product", product };
|
|
16
|
-
return name;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (isVariant(node)) {
|
|
20
|
-
const childName = visit(node.value);
|
|
21
|
-
defs[name] = { code: "union", union: { [node.tag]: childName } };
|
|
22
|
-
return name;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
throw new Error(`Unsupported runtime value node: ${node?.constructor?.name || typeof node}`);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const root = visit(value);
|
|
29
|
-
defs.__root__ = { code: "ref", ref: `@${root}` };
|
|
30
|
-
return { defs, root };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export { typeDefsFromValue };
|
|
34
|
-
export default { typeDefsFromValue };
|