@fraczak/k 5.1.2 → 6.0.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.
Files changed (115) hide show
  1. package/.codex +0 -0
  2. package/Code-derivation-tests/blowup.mjs +3 -3
  3. package/Code-derivation-tests/bnat.mjs +2 -2
  4. package/Code-derivation-tests/codec-witness-pattern.mjs +50 -0
  5. package/Code-derivation-tests/convergence-strategy.mjs +24 -0
  6. package/Code-derivation-tests/dot.mjs +12 -9
  7. package/Code-derivation-tests/filter-syntax.mjs +21 -0
  8. package/Code-derivation-tests/loop.mjs +8 -2
  9. package/Code-derivation-tests/nat.mjs +1 -1
  10. package/Code-derivation-tests/not-not.mjs +3 -3
  11. package/Code-derivation-tests/pattern-envelope.mjs +68 -0
  12. package/Code-derivation-tests/rlz.mjs +2 -2
  13. package/{BIG_PICTURE.md → DOCS/BIG_PICTURE.md} +103 -50
  14. package/DOCS/REPL.md +191 -0
  15. package/DOCS/a.html +398 -0
  16. package/DOCS/book/01-introduction.md +51 -0
  17. package/DOCS/book/02-syntax-and-values.md +111 -0
  18. package/DOCS/book/03-types-as-finite-automata.md +156 -0
  19. package/DOCS/book/04-partial-functions-and-composition.md +146 -0
  20. package/DOCS/book/05-typing-filters-and-normalization.md +111 -0
  21. package/DOCS/book-combined.html +3798 -0
  22. package/DOCS/book-combined.md +3745 -0
  23. package/DOCS/book-combined.pdf +0 -0
  24. package/DOCS/book-combined.tex +5682 -0
  25. package/DOCS/book.html +65 -0
  26. package/DOCS/book.md +54 -0
  27. package/DOCS/book.pdf +0 -0
  28. package/DOCS/book.tex +150 -0
  29. package/NAT.k~ +452 -0
  30. package/README.md +204 -508
  31. package/TypeGraph.mjs +43 -0
  32. package/TypePatternGraph.mjs +251 -0
  33. package/Value.mjs +192 -0
  34. package/augmentation.mjs +198 -0
  35. package/codecs/BINARY_FORMAT.html +471 -0
  36. package/codecs/BINARY_FORMAT.md +53 -0
  37. package/codecs/POLYMORPHIC_BINARY_FORMAT.html +355 -0
  38. package/codecs/POLYMORPHIC_BINARY_FORMAT.md +303 -0
  39. package/codecs/README.md +215 -0
  40. package/codecs/example-pipeline.mjs +149 -0
  41. package/codecs/ieee.mjs +140 -0
  42. package/codecs/int.mjs +104 -0
  43. package/codecs/json-codec.mjs +215 -0
  44. package/codecs/json.mjs +40 -0
  45. package/codecs/k-parse.mjs +90 -0
  46. package/codecs/k-pattern.mjs +75 -0
  47. package/codecs/k-print.mjs +46 -0
  48. package/codecs/runtime/codec.mjs +768 -0
  49. package/codecs/runtime/ieee-pattern.mjs +30 -0
  50. package/codecs/runtime/pattern-json.mjs +96 -0
  51. package/codecs/runtime/prefix-codec.mjs +425 -0
  52. package/codecs/runtime/show-value.mjs +68 -0
  53. package/codecs/runtime/typeFromValue.mjs +34 -0
  54. package/codecs/runtime/unicode-string.mjs +220 -0
  55. package/codecs/show.mjs +41 -0
  56. package/codecs/string-codec.mjs +80 -0
  57. package/codecs/unit.mjs +51 -0
  58. package/codecs/utf16.mjs +66 -0
  59. package/codecs/utf8.mjs +37 -0
  60. package/codes.mjs +146 -44
  61. package/compiler.mjs +111 -0
  62. package/convergence.mjs +197 -0
  63. package/core.k +197 -0
  64. package/export.mjs +22 -32
  65. package/hash.mjs +29 -31
  66. package/ieee.klib +0 -0
  67. package/index.mjs +41 -15
  68. package/k-vscode/.vscode/launch.json +14 -0
  69. package/k-vscode/README.md +65 -0
  70. package/k-vscode/language-configuration.json +42 -0
  71. package/k-vscode/package-lock.json +4176 -0
  72. package/k-vscode/package.json +57 -0
  73. package/k-vscode/snippets/k.json +92 -0
  74. package/k-vscode/syntaxes/k.tmLanguage.json +243 -0
  75. package/k.mjs +56 -54
  76. package/object.mjs +517 -0
  77. package/objects/README.md +38 -0
  78. package/objects/compile-lib.mjs +42 -0
  79. package/objects/compile.mjs +42 -0
  80. package/objects/decompile.mjs +32 -0
  81. package/package.json +13 -6
  82. package/parser.jison +27 -46
  83. package/parser.mjs +68 -100
  84. package/pretty.mjs +21 -40
  85. package/repl2.mjs +662 -0
  86. package/run.mjs +264 -231
  87. package/symbol-table.mjs +3 -17
  88. package/test-fingerprint.mjs +7 -7
  89. package/test-hash-fuzz.mjs +107 -0
  90. package/test-hash-normalization.mjs +134 -0
  91. package/test-k-object.mjs +74 -0
  92. package/test-repl2.mjs +106 -0
  93. package/test.mjs +45 -70
  94. package/tests.sh +10 -1
  95. package/type_registry/registry.mjs~ +105 -0
  96. package/type_registry/typeParser.jison~ +132 -0
  97. package/typing.mjs +129 -676
  98. package/unification.mjs +157 -0
  99. package/valueIO.mjs +54 -0
  100. package/valueParser.jison +143 -0
  101. package/valueParser.mjs +713 -0
  102. package/Code-derivation-tests/built-in.mjs +0 -19
  103. package/Code-derivation-tests/vector.mjs +0 -19
  104. package/Filters/bug.k +0 -3
  105. package/Filters/composing.k +0 -15
  106. package/Filters/filter.k +0 -9
  107. package/TODO.md +0 -53
  108. package/TYPING.md +0 -365
  109. package/k-repl.cast +0 -1913
  110. package/k.cast +0 -618
  111. package/my-objects.json +0 -6
  112. package/patterns.mjs +0 -543
  113. package/repl.mjs +0 -213
  114. package/test-filters.mjs +0 -45
  115. package/typing-test.mjs +0 -40
@@ -0,0 +1,157 @@
1
+ function subsetP(v1,v2) {
2
+ const v2Set = new Set(v2);
3
+ return v1.every(x => v2Set.has(x));
4
+ }
5
+
6
+ function eqsetP(v1,v2) {
7
+ const v1Set = new Set(v1);
8
+ const v2Set = new Set(v2);
9
+ if (v1Set.size != v2Set.size) return false;
10
+
11
+ for (const value of v1Set) {
12
+ if (!v2Set.has(value)) {
13
+ return false;
14
+ }
15
+ }
16
+ return true;
17
+ }
18
+
19
+ function setUnion(...vectors) {
20
+ const unionSet = new Set();
21
+ for (const v of vectors) {
22
+ for (const element of v) {
23
+ unionSet.add(element);
24
+ }
25
+ }
26
+ return Array.from(unionSet);
27
+ }
28
+
29
+ export function unify_two_patterns(findCode, p1, p2) {
30
+ // console.log(`unify_two_patterns(${JSON.stringify(p1)}, ${JSON.stringify(p2)})`);
31
+ if (p1.pattern === '()' || p2.pattern === '()') {
32
+ throw new Error("Closed unknown pattern '()' is not supported. Use '{}' or '<>' to choose product or union.");
33
+ }
34
+ if ((p1.pattern === '(...)' && (p1.fields || []).length !== 0) || (p2.pattern === '(...)' && (p2.fields || []).length !== 0)) {
35
+ throw new Error("Unknown-kind pattern '(...)' cannot have fields.");
36
+ }
37
+ switch (p1.pattern) {
38
+ case '(...)':
39
+ switch (p2.pattern) {
40
+ case '(...)':
41
+ return {...p2, fields: setUnion(p1.fields, p2.fields)};
42
+ case '{...}':
43
+ return {...p2, fields: setUnion(p1.fields, p2.fields)};
44
+ case '<...>':
45
+ return {...p2, fields: setUnion(p1.fields, p2.fields)};
46
+ case '{}':
47
+ if (subsetP(p1.fields, p2.fields)) return p2;
48
+ throw new Error(`Cannot unify (${p1.fields},...) with {${p2.fields}}`);
49
+ case '<>':
50
+ if (subsetP(p1.fields, p2.fields)) return p2;
51
+ throw new Error(`Cannot unify (${p1.fields},...) with <${p2.fields}>`);
52
+ case 'type': {
53
+ const code = findCode(p2.type);
54
+ // console.log(JSON.stringify({p1,p2,code}));
55
+ switch (code.code) {
56
+ case 'product':
57
+ case 'union': {
58
+ let p2_fields = Object.keys(code[code.code]);
59
+ if (subsetP(p1.fields, p2_fields)) return {...p2, fields: p2_fields};
60
+ }; break;
61
+ }
62
+ throw new Error(`Cannot unify ${JSON.stringify(p1)} with code ${p2.type}:${code.def}`);
63
+ }
64
+ } ;
65
+ break;
66
+ case '{...}':
67
+ switch (p2.pattern) {
68
+ case '{...}':
69
+ return {...p2, fields: setUnion(p1.fields, p2.fields)};
70
+ case '<...>':
71
+ throw new Error('Cannot unify {...} with <...>');
72
+ case '{}':
73
+ if (subsetP(p1.fields, p2.fields)) return p2;
74
+ throw new Error(`Cannot unify {${p1.fields},...} with {${p2.fields}}`);
75
+ case '<>':
76
+ throw new Error('Cannot unify {...} with <>');
77
+ case 'type': {
78
+ const code = findCode(p2.type);
79
+ switch (code.code) {
80
+ case 'product':{
81
+ let p2_fields = Object.keys(code[code.code]);
82
+ if (subsetP(p1.fields, p2_fields)) return {...p2, fields: p2_fields};
83
+ };
84
+ }
85
+ throw new Error(`Cannot unify ${JSON.stringify(p1)} with code ${p2.type}:${code.def}`);
86
+ }
87
+ };
88
+ break;
89
+ case '<...>':
90
+ switch (p2.pattern) {
91
+ case '<...>':
92
+ return {pattern: '<...>', fields: setUnion(p1.fields, p2.fields)};
93
+ case '{}':
94
+ throw new Error('Cannot unify <...> with {}');
95
+ case '<>':
96
+ if (subsetP(p1.fields, p2.fields)) return p2;
97
+ throw new Error(`Cannot unify <${p1.fields},...> with <${p2.fields}>`);
98
+ case 'type':{
99
+ const code = findCode(p2.type);
100
+ switch (code.code) {
101
+
102
+ case 'union': {
103
+ let p2_fields = Object.keys(code[code.code]);
104
+ if (subsetP(p1.fields, p2_fields)) return {...p2, fields: p2_fields};
105
+ }
106
+ }
107
+ throw new Error(`Cannot unify ${JSON.stringify(p1)} with code ${p2.type}:${code.def}`);
108
+ };
109
+ };
110
+ break;
111
+ case '{}':
112
+ switch (p2.pattern) {
113
+ case '{}':
114
+ if (eqsetP(p1.fields, p2.fields)) return p2;
115
+ throw new Error(`Cannot unify {${p1.fields}} with {${p2.fields}}`);
116
+ case '<>':
117
+ throw new Error('Cannot unify {} with <>');
118
+ case 'type': {
119
+ const code = findCode(p2.type);
120
+ switch (code.code) {
121
+ case 'product':{
122
+ let p2_fields = Object.keys(code[code.code]);
123
+ if (eqsetP(p1.fields, p2_fields)) return {...p2, fields: p2_fields};
124
+ };
125
+ }
126
+ throw new Error(`Cannot unify ${JSON.stringify(p1)} with code ${p2.type}:${code.def}`);
127
+ }
128
+ };
129
+ break;
130
+ case '<>':
131
+ switch (p2.pattern) {
132
+ case '<>':
133
+ if (eqsetP(p1.fields, p2.fields)) return p2;
134
+ throw new Error(`Cannot unify <${p1.fields}> with <${p2.fields}>`);
135
+ case 'type': {
136
+ const code = findCode(p2.type);
137
+ switch (code.code) {
138
+ case 'union':{
139
+ let p2_fields = Object.keys(code[code.code]);
140
+ if (eqsetP(p1.fields, p2_fields)) return {...p2, fields: p2_fields};
141
+ };
142
+ }
143
+ throw new Error(`Cannot unify ${JSON.stringify(p1)} with code ${p2.type}:${code.def}`);
144
+ }
145
+ };
146
+ break;
147
+ case 'type':
148
+ switch (p2.pattern) {
149
+ case 'type':
150
+ if (p1.type != p2.type)
151
+ throw new Error(`Cannot unify different types: ${p1.type}:${findCode(p1.type).def} and ${p2.type}:${findCode(p2.type).def}`);
152
+ return p2;
153
+ };
154
+ break;
155
+ }
156
+ return unify_two_patterns(findCode, p2, p1);
157
+ }
package/valueIO.mjs ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Value I/O with Type Information
3
+ *
4
+ * This module wraps the valueParser to support explicit type information.
5
+ *
6
+ * Migration strategy (2 steps):
7
+ * - Step 1 (current): Add type parameter to all parseValue calls, but keep text parsing
8
+ * - Step 2 (future): Replace implementation to use binary codec
9
+ */
10
+
11
+ import { parse as parseValueText } from "./valueParser.mjs";
12
+ import { Value, fromObject } from "./Value.mjs";
13
+
14
+ /**
15
+ * Parse a value from text with optional type information
16
+ *
17
+ * @param {string} text - JSON-like text representation
18
+ * @param {string|null} typeName - Canonical type name (e.g., "@ABC123...")
19
+ * @param {Object|null} typeInfo - Type definition (for validation/future use)
20
+ * @returns {Value} - Product or Variant
21
+ *
22
+ * Step 1: Type parameters are accepted but not yet used
23
+ * Step 2: Will validate against type and eventually parse binary format
24
+ */
25
+ export function parseValue(text, typeName = null, typeInfo = null) {
26
+ // Step 1: Ignore type for now, just parse text as before
27
+ // TODO Step 2: Validate parsed value against typeInfo if provided
28
+ return parseValueText(text);
29
+ }
30
+
31
+ /**
32
+ * Serialize a value to text
33
+ *
34
+ * @param {Value} value - Product or Variant
35
+ * @param {string|null} typeName - Canonical type name (optional)
36
+ * @param {Object|null} typeInfo - Type definition (optional)
37
+ * @returns {string} - JSON representation
38
+ *
39
+ * Step 1: Returns JSON, ignoring type
40
+ * Step 2: Will encode to binary format
41
+ */
42
+ export function printValue(value, typeName = null, typeInfo = null) {
43
+ // Step 1: Just serialize to JSON as before
44
+ // TODO Step 2: Encode to binary format using codec
45
+ return JSON.stringify(value);
46
+ }
47
+
48
+ /**
49
+ * Convert JavaScript object to k Value
50
+ * (No change needed - this is type-agnostic)
51
+ */
52
+ export { fromObject } from "./Value.mjs";
53
+
54
+ export default { parseValue, printValue, fromObject };
@@ -0,0 +1,143 @@
1
+ %{
2
+
3
+ import { Product, Variant } from "./Value.mjs";
4
+
5
+ //--------------------------
6
+
7
+ function anError(pos,msg) {
8
+ throw new Error(`Parse Error (lines ${pos.first_line}:${pos.first_column}...${pos.last_line}:${pos.last_column}): ${msg}`);
9
+ }
10
+
11
+ function getToken(yytext,yy,lstack) {
12
+ const yylloc = yy.lexer.yylloc;
13
+ const loc = lstack[lstack.length - 1]; // { first_line: 5, last_line: 5, first_column: 2, last_column: 3 };
14
+ const start = {line: loc.first_line, column: loc.first_column + 1};
15
+ const end = {line: start.line, column: start.column + yytext.length};
16
+ const result = {start,end,value: String(yytext)};
17
+ // console.log(result);
18
+ return result;
19
+ }
20
+
21
+ function fromEscString(escString) {
22
+ const isSingleQuoted = escString.startsWith("'");
23
+ let str = escString.substring(1, escString.length - 1);
24
+ if (isSingleQuoted) {
25
+ str = str.replace(/\\'/g, "'");
26
+ } else {
27
+ str = str.replace(/\\"/g, '"');
28
+ }
29
+ str = str.replace(/\\\\/g, '\\');
30
+ str = str.replace(/\\\//g, '/');
31
+ str = str.replace(/\\b/g, '\b');
32
+ str = str.replace(/\\f/g, '\f');
33
+ str = str.replace(/\\n/g, '\n');
34
+ str = str.replace(/\\r/g, '\r');
35
+ str = str.replace(/\\t/g, '\t');
36
+ str = str.replace(/\\u([\dA-F]{4})/gi, (match, p1) => String.fromCharCode(parseInt(p1, 16)));
37
+
38
+ return str;
39
+ }
40
+
41
+
42
+ %}
43
+
44
+ %lex
45
+
46
+ %%
47
+ [/][*]([^*]*[*]+[^*/])*[^*]*[*]+[/] /* c-comment */
48
+ ("//"|"#"|"%"|"--"|"\\")[^\n]* /* one line comment */
49
+ \s+ /* blanks */
50
+ "{" return 'LC';
51
+ "}" return 'RC';
52
+ "[" return 'LB';
53
+ "]" return 'RB';
54
+ "," return 'COMMA';
55
+ ":" return 'COL';
56
+ \"([^"\\]|\\(.|\n))*\"|\'([^'\\]|\\(.|\n))*\' return 'STRING';
57
+ [a-zA-Z0-9_][a-zA-Z0-9_?!]* return 'NAME';
58
+ <<EOF>> return 'EOF';
59
+
60
+ /lex
61
+
62
+ %token NAME STRING
63
+ %token LC RC LB RB COMMA COL
64
+ %token EOF
65
+
66
+ %start input_with_eof
67
+
68
+ %%
69
+
70
+ str : STRING { $$ = getToken(yytext,yy,_$); $$.value = fromEscString($$.value);}
71
+ | NAME { $$ = getToken(yytext,yy,_$); }
72
+ ;
73
+ lc: LC { $$ = getToken(yytext,yy,_$); };
74
+ rc: RC { $$ = getToken(yytext,yy,_$); };
75
+ lb: LB { $$ = getToken(yytext,yy,_$); };
76
+ rb: RB { $$ = getToken(yytext,yy,_$); };
77
+ comma: COMMA { $$ = getToken(yytext,yy,_$); };
78
+ col: COL { $$ = getToken(yytext,yy,_$); };
79
+
80
+ input_with_eof
81
+ : exp EOF {
82
+ // console.log(`Parsed: ${$1.value.toString()}`);
83
+ return $1.value;
84
+ }
85
+ ;
86
+
87
+ exp
88
+ : lc labelled rc { $$ = {value: $2.value, start: $1.start, end: $3.end}; }
89
+ | lb exps rb { $$ = {value: $2.value, start: $1.start, end: $3.end}; }
90
+ | str { $$ = {value: new Variant($1.value, new Product({})), start: $1.start, end: $1.end}; }
91
+ | name { $$ = {value: new Variant($1.value, new Product({})), start: $1.start, end: $1.end}; }
92
+ ;
93
+
94
+ exps
95
+ : /* empty */ { $$ = {value: new Product({})}; }
96
+ | non_empty_exps {
97
+ if ($1.list.length === 1) {
98
+ $$ = {value: new Variant('0', $1.list[0].value)};
99
+ } else {
100
+ const product = {};
101
+ $1.list.forEach( (e, i) => product[i] = e.value );
102
+ $$ = {value: new Product(product)};
103
+ };
104
+ }
105
+ ;
106
+
107
+ non_empty_exps
108
+ : exp { $$ = {list: [$1]} ; }
109
+ | non_empty_exps comma exp
110
+ { $$ = {list: [].concat($1.list,$3)}; }
111
+ ;
112
+
113
+ labelled
114
+ : /* empty */ { $$ = {value: new Product({})}; }
115
+ | non_empty_labelled {
116
+ if ($1.list.length === 1) {
117
+ $$ = {value: new Variant($1.list[0].label, $1.list[0].value)};
118
+ } else {
119
+ const product = {};
120
+ for (const {label, value} of $1.list) {
121
+ if (product.hasOwnProperty(label))
122
+ anError(@0,`Duplicate label '${label}'.`);
123
+ product[label] = value;
124
+ }
125
+ $$ = {value: new Product(product)};
126
+ };
127
+ }
128
+ ;
129
+
130
+ non_empty_labelled
131
+ : exp_label
132
+ { $$ = {list: [$1]} ; }
133
+ | non_empty_labelled comma exp_label
134
+ { $$ = {list: [].concat($1.list,$3)}; }
135
+ ;
136
+
137
+ exp_label
138
+ : exp str { $$ = {label: $2.value, value: $1.value}; }
139
+ | str col exp { $$ = {label: $1.value, value: $3.value}; }
140
+ | bits col exp { $$ = {label: $1.value, value: $3.value}; }
141
+ ;
142
+
143
+ %%