@fraczak/k 3.1.0 → 4.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.
- package/BIG_PICTURE.md +37 -28
- package/Code-derivation-tests/vector.mjs +0 -3
- package/Filters/bug.k +3 -0
- package/Filters/composing.k +15 -0
- package/Filters/filter.k +9 -0
- package/README.md +19 -16
- package/TYPING.md +8 -11
- package/codes.mjs +2 -2
- package/index.mjs +5 -4
- package/k.mjs +1 -2
- package/package.json +1 -1
- package/parser.jison +8 -4
- package/parser.mjs +44 -41
- package/patterns.mjs +73 -14
- package/pretty.mjs +100 -23
- package/repl.mjs +152 -109
- package/run.mjs +7 -12
- package/symbol-table.mjs +1 -1
- package/typing.mjs +173 -12
- package/INTRO.md +0 -88
- package/aaa.txt +0 -203033
- package/bug.json +0 -419
- package/chatGPT.md +0 -235
- package/chatGPT.md~ +0 -119
- package/code-resolution.md +0 -121
- package/code-resolution.mjs +0 -51
- package/filters.mjs +0 -59
package/patterns.mjs
CHANGED
|
@@ -27,11 +27,17 @@ function relDefToString(relDef) {
|
|
|
27
27
|
case "dot":
|
|
28
28
|
case "code":
|
|
29
29
|
case "pipe":
|
|
30
|
-
|
|
30
|
+
case "filter":
|
|
31
|
+
return [...rel.patterns];
|
|
31
32
|
}
|
|
32
|
-
throw new Error("NOT EXPECTED OP:", rel);
|
|
33
|
+
throw new Error("NOT EXPECTED OP:", JSON.stringify(rel, null, 2));
|
|
33
34
|
};
|
|
34
35
|
|
|
36
|
+
// console.log("SIZE", relDef.typePatternGraph.size());
|
|
37
|
+
// console.log(relDef.typePatternGraph.patterns.nodes);
|
|
38
|
+
// console.log(relDef.typePatternGraph.edges);
|
|
39
|
+
// console.log(relDef.def);
|
|
40
|
+
|
|
35
41
|
return JSON.stringify(dumpPatterns(relDef.def).map((x) => {
|
|
36
42
|
const { pattern, fields, type} = relDef.typePatternGraph.get_pattern(x);
|
|
37
43
|
return {pattern, fields, type};
|
|
@@ -39,13 +45,11 @@ function relDefToString(relDef) {
|
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
function compactRel(relDef, name = "") {
|
|
48
|
+
// console.log("********************************* compacting", name);
|
|
42
49
|
const {def, typePatternGraph, varRefs } = relDef;
|
|
43
50
|
// console.log("COMPACTING typePatternGraph of size", typePatternGraph.size());
|
|
44
51
|
|
|
45
|
-
const newTypePatternGraph =
|
|
46
|
-
const renumbering = typePatternGraph.cloneAll(newTypePatternGraph);
|
|
47
|
-
|
|
48
|
-
newTypePatternGraph.turnSingletonPatternsIntoCodes();
|
|
52
|
+
const {typePatternGraph : newTypePatternGraph, remapping: renumbering} = typePatternGraph.getCompressed();
|
|
49
53
|
|
|
50
54
|
const copyRel = (rel) => {
|
|
51
55
|
const newRel = {...rel, patterns:[renumbering[rel.patterns[0]], renumbering[rel.patterns[1]]]};
|
|
@@ -72,9 +76,10 @@ function compactRel(relDef, name = "") {
|
|
|
72
76
|
case "dot":
|
|
73
77
|
case "code":
|
|
74
78
|
case "pipe":
|
|
79
|
+
case "filter":
|
|
75
80
|
break;
|
|
76
81
|
default:
|
|
77
|
-
console.error("NOT EXPECTED OP:", rel);
|
|
82
|
+
console.error("NOT EXPECTED OP:", JSON.stringify(rel, null, 2));
|
|
78
83
|
break;
|
|
79
84
|
};
|
|
80
85
|
return newRel;
|
|
@@ -90,8 +95,7 @@ function compactRel(relDef, name = "") {
|
|
|
90
95
|
return {def: newDef, typePatternGraph: newTypePatternGraph, varRefs: newVarRefs};
|
|
91
96
|
}
|
|
92
97
|
|
|
93
|
-
function patterns(
|
|
94
|
-
codes.register(usedCodes);
|
|
98
|
+
function patterns(representatives, rels) {
|
|
95
99
|
// INPUT:
|
|
96
100
|
// codes: {"BG": {"code": "product", "product": {}}, ...}
|
|
97
101
|
// representatives:{"{}": "BG", ...}
|
|
@@ -175,17 +179,68 @@ function patterns(usedCodes, representatives, rels) {
|
|
|
175
179
|
rel.patterns[1] = rootDef.typePatternGraph.addNewNode();
|
|
176
180
|
rel.patterns[0] = rootDef.typePatternGraph.addNewNode({pattern: '(...)'}, { [rel.dot]: [rel.patterns[1]] });
|
|
177
181
|
break;
|
|
178
|
-
|
|
182
|
+
case "filter":
|
|
183
|
+
rel.patterns = [];
|
|
184
|
+
rel.patterns[1] = rel.patterns[0] = filterToPattern(rel.filter, rootDef);
|
|
185
|
+
break;
|
|
179
186
|
default:
|
|
180
|
-
console.error("NOT EXPECTED OP:", rel);
|
|
187
|
+
console.error("NOT EXPECTED OP for aumentation:", JSON.stringify(rel, null, 2));
|
|
181
188
|
break;
|
|
182
189
|
}
|
|
183
190
|
} catch (e) {
|
|
184
|
-
|
|
191
|
+
e.message = `Type Error in '${rel.op}' (lines ${rel.start?.line}:${rel.start?.column}...${rel.end?.line}:${rel.end?.column})\n - ${e.message}`;
|
|
185
192
|
throw e;
|
|
186
193
|
}
|
|
187
194
|
}
|
|
188
195
|
|
|
196
|
+
function filterToPattern(filter, rootDef) {
|
|
197
|
+
const context = rootDef.patternVars;
|
|
198
|
+
const getFields = () =>
|
|
199
|
+
Object.keys(filter.fields || {}).reduce( (fields, label) => {
|
|
200
|
+
const patternId = filterToPattern(filter.fields[label], rootDef);
|
|
201
|
+
fields[label] = [patternId];
|
|
202
|
+
return fields;
|
|
203
|
+
}, {});
|
|
204
|
+
if (filter.name && ! (filter.name in context)) {
|
|
205
|
+
context[filter.name] = rootDef.typePatternGraph.addNewNode();
|
|
206
|
+
}
|
|
207
|
+
let newPatternId = null;
|
|
208
|
+
switch (filter.type) {
|
|
209
|
+
case "name":
|
|
210
|
+
newPatternId = context[filter.name];
|
|
211
|
+
break;
|
|
212
|
+
case "code":
|
|
213
|
+
newPatternId = rootDef.typePatternGraph.getTypeId(filter.code);
|
|
214
|
+
break;
|
|
215
|
+
case "union":
|
|
216
|
+
newPatternId = rootDef.typePatternGraph.addNewNode(
|
|
217
|
+
{pattern: filter.open ? '<...>' : '<>', fields:Object.keys(filter.fields || {})},
|
|
218
|
+
getFields());
|
|
219
|
+
break;
|
|
220
|
+
case "product":
|
|
221
|
+
newPatternId = rootDef.typePatternGraph.addNewNode(
|
|
222
|
+
{pattern: filter.open ? '{...}' : '{}', fields:Object.keys(filter.fields || {})},
|
|
223
|
+
getFields());
|
|
224
|
+
break;
|
|
225
|
+
case "vector": {
|
|
226
|
+
const vector = filterToPattern(filter.vector, rootDef);
|
|
227
|
+
newPatternId = rootDef.typePatternGraph.addNewNode(
|
|
228
|
+
{pattern: '[]', fields: ["vector-member"]},
|
|
229
|
+
{"vector-member": [vector]});
|
|
230
|
+
};
|
|
231
|
+
break;
|
|
232
|
+
default:
|
|
233
|
+
newPatternId = rootDef.typePatternGraph.addNewNode(
|
|
234
|
+
{pattern: filter.open ? '(...)' : '()'},
|
|
235
|
+
getFields());
|
|
236
|
+
}
|
|
237
|
+
if (filter.name) {
|
|
238
|
+
rootDef.typePatternGraph.unify(`filter: ${filter.name}`, newPatternId, context[filter.name]);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return newPatternId;
|
|
242
|
+
}
|
|
243
|
+
|
|
189
244
|
function augmentProduct(rel,rootDef) {
|
|
190
245
|
rel.patterns = [];
|
|
191
246
|
switch (rel.product.length) {
|
|
@@ -305,7 +360,7 @@ function patterns(usedCodes, representatives, rels) {
|
|
|
305
360
|
rel.patterns[0] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [rel.patterns[1]]});
|
|
306
361
|
break;
|
|
307
362
|
case "toVEC":
|
|
308
|
-
rel.patterns[0] = rootDef.typePatternGraph.
|
|
363
|
+
rel.patterns[0] = rootDef.typePatternGraph.getTypeId('string')
|
|
309
364
|
rel.patterns[1] = rootDef.typePatternGraph.addNewNode({pattern: '[]'}, {"vector-member": [rel.patterns[0]]});
|
|
310
365
|
break;
|
|
311
366
|
case "toDateMsec":
|
|
@@ -357,7 +412,9 @@ function patterns(usedCodes, representatives, rels) {
|
|
|
357
412
|
const rootDef = rels[relName];
|
|
358
413
|
rootDef.typePatternGraph = new TypePatternGraph();
|
|
359
414
|
rootDef.varRefs = []; // the list of non-built references as pointers to AST nodes
|
|
415
|
+
rootDef.patternVars = {};
|
|
360
416
|
augment(rootDef.def, rootDef);
|
|
417
|
+
delete rootDef.patternVars;
|
|
361
418
|
}
|
|
362
419
|
|
|
363
420
|
|
|
@@ -429,7 +486,9 @@ function patterns(usedCodes, representatives, rels) {
|
|
|
429
486
|
relDef.typePatternGraph.unify(`ref:input ${relName}(${varName})`, varRel.inputPatternId, cloned[varInputPatternId]);
|
|
430
487
|
relDef.typePatternGraph.unify("ref:output", varRel.outputPatternId, cloned[varOutputPatternId]);
|
|
431
488
|
} catch (e) {
|
|
432
|
-
|
|
489
|
+
e.message =
|
|
490
|
+
`Type Error in definition of '${relName}' at call to '${varName}': lines ${varRel.start?.line}:${varRel.start?.column}...${varRel.end?.line}:${varRel.end?.column}):
|
|
491
|
+
- ${e.message}`;
|
|
433
492
|
throw e;
|
|
434
493
|
}
|
|
435
494
|
}
|
package/pretty.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { find } from "./codes.mjs";
|
|
2
|
+
import { TypePatternGraph } from "./typing.mjs";
|
|
3
|
+
|
|
1
4
|
function compareAs(fn) {
|
|
2
5
|
return function (a, b) {
|
|
3
6
|
[a, b] = [a, b].map(fn);
|
|
@@ -9,12 +12,12 @@ function compareAs(fn) {
|
|
|
9
12
|
|
|
10
13
|
const nameRE = /^[a-zA-Z0-9_][a-zA-Z0-9_?!]*$/;
|
|
11
14
|
|
|
12
|
-
function prettyCode_labels (
|
|
15
|
+
function prettyCode_labels (representatives, label_ref_map) {
|
|
13
16
|
return Object.keys(label_ref_map)
|
|
14
17
|
.sort( compareAs((x) => x) )
|
|
15
18
|
.map( (label) => {
|
|
16
19
|
const plabel = nameRE.test(label) ? label : `'${label}'`;
|
|
17
|
-
return `${prettyCode(
|
|
20
|
+
return `${prettyCode(representatives, {
|
|
18
21
|
code: "ref",
|
|
19
22
|
ref: label_ref_map[label],
|
|
20
23
|
})} ${plabel}`;
|
|
@@ -22,21 +25,21 @@ function prettyCode_labels (codes, representatives, label_ref_map) {
|
|
|
22
25
|
.join(", ");
|
|
23
26
|
};
|
|
24
27
|
|
|
25
|
-
function prettyCode (
|
|
28
|
+
function prettyCode (representatives, codeExp) {
|
|
26
29
|
switch (codeExp.code) {
|
|
27
30
|
case "ref":
|
|
28
31
|
const name = representatives[codeExp.ref] || codeExp.ref;
|
|
29
32
|
if (name.startsWith(":")) {
|
|
30
|
-
return prettyCode(
|
|
33
|
+
return prettyCode(representatives, find(name));
|
|
31
34
|
} else {
|
|
32
35
|
return name;
|
|
33
36
|
}
|
|
34
37
|
case "product":
|
|
35
|
-
return `{${prettyCode_labels(
|
|
38
|
+
return `{${prettyCode_labels(representatives, codeExp.product)}}`;
|
|
36
39
|
case "union":
|
|
37
|
-
return `< ${prettyCode_labels(
|
|
40
|
+
return `< ${prettyCode_labels(representatives, codeExp.union)} >`;
|
|
38
41
|
case "vector":
|
|
39
|
-
return `[${prettyCode(
|
|
42
|
+
return `[${prettyCode(representatives, {code:'ref', ref:codeExp.vector})}]`;
|
|
40
43
|
// return `[${representatives[codeExp.vector] || codeExp.vector}]`;
|
|
41
44
|
default:
|
|
42
45
|
return ":error";
|
|
@@ -44,28 +47,31 @@ function prettyCode (codes, representatives, codeExp) {
|
|
|
44
47
|
};
|
|
45
48
|
|
|
46
49
|
function prettyFilter (prettyCode, filter) {
|
|
47
|
-
const fieldsStr = (
|
|
48
|
-
Object.keys(
|
|
49
|
-
`${
|
|
50
|
-
)
|
|
50
|
+
const fieldsStr = () => {
|
|
51
|
+
const fields = Object.keys(filter.fields).map( (key) =>
|
|
52
|
+
`${prettyFilter(prettyCode, filter.fields[key])} ${key}`
|
|
53
|
+
);
|
|
54
|
+
if (filter.open) fields.push("...");
|
|
55
|
+
return fields.join(", ");
|
|
56
|
+
}
|
|
51
57
|
switch (filter.type) {
|
|
58
|
+
|
|
59
|
+
case "code":
|
|
60
|
+
return `$${prettyCode({code: "ref",ref: filter.code,})}`;
|
|
52
61
|
case "name":
|
|
53
62
|
return filter.name;
|
|
54
|
-
case "code":
|
|
55
|
-
return `$${prettyCode({
|
|
56
|
-
code: "ref",
|
|
57
|
-
ref: filter.code,
|
|
58
|
-
})}`;
|
|
59
63
|
case "vector":
|
|
60
|
-
return `[${prettyFilter(prettyCode, filter.vector)}]`;
|
|
64
|
+
return `[${prettyFilter(prettyCode, filter.vector)}]${filter.name ? "=" + filter.name : ""}`;
|
|
61
65
|
case null:
|
|
62
|
-
|
|
66
|
+
if (filter.name && Object.keys(filter.fields).length == 0)
|
|
67
|
+
return filter.name;
|
|
68
|
+
return `(${fieldsStr()})${filter.name ? "=" + filter.name : ""}`;
|
|
63
69
|
case "union":
|
|
64
|
-
return `<${fieldsStr(
|
|
70
|
+
return `<${fieldsStr()}>${filter.name ? "=" + filter.name : ""}`;
|
|
65
71
|
case "product":
|
|
66
|
-
return `{${fieldsStr(
|
|
72
|
+
return `{${fieldsStr()}}${filter.name ? "=" + filter.name : ""}`;
|
|
67
73
|
}
|
|
68
|
-
throw new Error(
|
|
74
|
+
throw new Error(`Unknown filter type ${filter.type} in ${JSON.stringify(filter)}`);
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
function prettyRel (prettyCode, exp) {
|
|
@@ -123,5 +129,76 @@ function prettyRel (prettyCode, exp) {
|
|
|
123
129
|
return pretty(exp);
|
|
124
130
|
};
|
|
125
131
|
|
|
126
|
-
|
|
127
|
-
|
|
132
|
+
|
|
133
|
+
function patterns2filters(typePatternGraph, ...patternIds) {
|
|
134
|
+
const newTypePatternGraph = new TypePatternGraph();
|
|
135
|
+
const renamed = typePatternGraph.clone(patternIds, newTypePatternGraph);
|
|
136
|
+
const newPatternIds = patternIds.map((id) => newTypePatternGraph.find(renamed[id]));
|
|
137
|
+
|
|
138
|
+
// inDegree - all open patterns, i.e. (...), {...}, <...>,
|
|
139
|
+
// with inDegree > 1 are variables
|
|
140
|
+
const inDegree = newTypePatternGraph.patterns.nodes.map((x) => 0);
|
|
141
|
+
newPatternIds.forEach( id => inDegree[id]++);
|
|
142
|
+
newTypePatternGraph.edges.forEach( outEdges =>
|
|
143
|
+
Object.values( outEdges ).forEach( destMap =>
|
|
144
|
+
Object.values(destMap).forEach( dst =>
|
|
145
|
+
inDegree[dst]++ )
|
|
146
|
+
)
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// variables - variables which will have to be added as extra filters
|
|
150
|
+
const variables = inDegree.reduce( (variables, degree, i) => {
|
|
151
|
+
if (degree > 1) variables[i] = "fresh";
|
|
152
|
+
return variables;
|
|
153
|
+
}, {});
|
|
154
|
+
|
|
155
|
+
const buildFilter = (path, patternId, i) => {
|
|
156
|
+
let named_filter = {};
|
|
157
|
+
const pattern = newTypePatternGraph.get_pattern(patternId);
|
|
158
|
+
if (variables[patternId] && pattern.pattern != 'type') {
|
|
159
|
+
const name = `X${patternId}`;
|
|
160
|
+
if (variables[patternId] == "done")
|
|
161
|
+
return { type: 'name', name: name };
|
|
162
|
+
variables[patternId] = "done";
|
|
163
|
+
named_filter = { name: name };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
const edges = newTypePatternGraph.edges[patternId];
|
|
168
|
+
const fields = () =>
|
|
169
|
+
Object.keys(edges).reduce( (fields, key) =>{
|
|
170
|
+
fields[key] = buildFilter([...path, key], Object.values(edges[key])[0], i);
|
|
171
|
+
return fields;
|
|
172
|
+
}, {});
|
|
173
|
+
|
|
174
|
+
switch (pattern.pattern) {
|
|
175
|
+
case 'type':
|
|
176
|
+
return {type: "code", code: pattern.type, ...named_filter};
|
|
177
|
+
case '[]':
|
|
178
|
+
return {
|
|
179
|
+
type: "vector",
|
|
180
|
+
vector: buildFilter([...path, "vector-member"], Object.values(edges["vector-member"])[0], i),
|
|
181
|
+
...named_filter
|
|
182
|
+
};
|
|
183
|
+
case '(...)':
|
|
184
|
+
return { type: null, open: true, fields: fields(), ...named_filter };
|
|
185
|
+
case '{...}':
|
|
186
|
+
return { type: 'product', open: true, fields: fields(), ...named_filter };
|
|
187
|
+
case '<...>':
|
|
188
|
+
return { type: 'union', open: true, fields: fields(), ...named_filter };
|
|
189
|
+
case '()':
|
|
190
|
+
return { type: null, fields: fields(), ...named_filter };
|
|
191
|
+
case '{}':
|
|
192
|
+
return { type: 'product', fields: fields(), ...named_filter };
|
|
193
|
+
case '<>':
|
|
194
|
+
return { type: 'union', fields: fields(), ...named_filter };
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const filters = newPatternIds.map( (id, i) => buildFilter([], id, i) );
|
|
199
|
+
return filters;
|
|
200
|
+
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export default { prettyCode, prettyRel, patterns2filters };
|
|
204
|
+
export { prettyCode, prettyRel, patterns2filters };
|
package/repl.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import readline from "node:readline";
|
|
3
|
+
import fs from "node:fs";
|
|
2
4
|
|
|
3
5
|
import k from "./index.mjs";
|
|
4
6
|
import {run, closeVector } from "./run.mjs";
|
|
5
|
-
import { prettyCode, prettyRel } from "./pretty.mjs";
|
|
7
|
+
import { prettyCode, prettyRel, patterns2filters } from "./pretty.mjs";
|
|
8
|
+
import { find } from "./codes.mjs";
|
|
6
9
|
|
|
7
|
-
import fs from "node:fs";
|
|
8
10
|
|
|
9
11
|
const splice = [].splice;
|
|
10
12
|
|
|
@@ -13,14 +15,16 @@ console.log("Very! experimental repl shell for 'k-language'...");
|
|
|
13
15
|
const help = function () {
|
|
14
16
|
console.log(" --h print help");
|
|
15
17
|
console.log(" --a print codes and relations");
|
|
16
|
-
console.log(" --c print codes");
|
|
18
|
+
console.log(" --c print aliased codes");
|
|
19
|
+
console.log(" --C code print code definition");
|
|
17
20
|
console.log(" --r print rels");
|
|
18
21
|
console.log(" --p pretty-print last value");
|
|
19
|
-
console.log(" --pp
|
|
22
|
+
console.log(" --pp print last value via node.js 'console.log'");
|
|
20
23
|
console.log(" --s reg store the last value in register 'reg'");
|
|
21
24
|
console.log(" --g reg get the value from register 'reg'");
|
|
22
25
|
console.log(" --regs print registers names");
|
|
23
26
|
console.log(" --l file.k load 'file.k'");
|
|
27
|
+
console.log(" --x rel print out the type pattern of 'rel'");
|
|
24
28
|
};
|
|
25
29
|
|
|
26
30
|
help();
|
|
@@ -28,114 +32,153 @@ help();
|
|
|
28
32
|
const re__l = /^[ \n\t]*(?:--l[ ]+)(.+)[ ]*?$/;
|
|
29
33
|
const re__s = /^[ \n\t]*(?:--s[ ]+)(.+)[ ]*?$/;
|
|
30
34
|
const re__g = /^[ \n\t]*(?:--g[ ]+)(.+)[ ]*?$/;
|
|
35
|
+
const re__x = /^[ \n\t]*(?:--x[ ]+)(.+)[ ]*?$/;
|
|
36
|
+
const re__C = /^[ \n\t]*(?:--C[ ]+)(.+)[ ]*?$/;
|
|
31
37
|
|
|
32
|
-
const
|
|
38
|
+
const rl = readline.createInterface({
|
|
39
|
+
input: process.stdin,
|
|
40
|
+
output: process.stdout,
|
|
41
|
+
prompt: ''
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
rl.prompt();
|
|
45
|
+
|
|
46
|
+
rl.on('line', (line) => {
|
|
47
|
+
// console.log(`Received: ${line}`);
|
|
48
|
+
evaluate(line);
|
|
49
|
+
rl.prompt();
|
|
50
|
+
}).on('close', () => {
|
|
51
|
+
console.log('REPL closed');
|
|
52
|
+
process.exit(0);
|
|
53
|
+
});
|
|
33
54
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
);
|
|
87
|
-
})(run.defs, {}));
|
|
88
|
-
} else if (line.match(/^[ \n\t]*(?:--c)?$/)) {
|
|
89
|
-
console.log(
|
|
90
|
-
(function (defs, result) {
|
|
91
|
-
var codeExp, codeName, ref1;
|
|
92
|
-
if (defs == null) {
|
|
93
|
-
return result;
|
|
94
|
-
}
|
|
95
|
-
ref1 = defs.codes;
|
|
96
|
-
for (codeName in ref1) {
|
|
97
|
-
codeExp = ref1[codeName];
|
|
98
|
-
result[codeName] = prettyCode(
|
|
99
|
-
defs.codes,
|
|
100
|
-
defs.representatives,
|
|
101
|
-
codeExp
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
return result;
|
|
105
|
-
})(run.defs, {})
|
|
55
|
+
let val = {};
|
|
56
|
+
const registers = {};
|
|
57
|
+
const buffer = [];
|
|
58
|
+
function evaluate(line) {
|
|
59
|
+
if (line.trim().endsWith('\\')) {
|
|
60
|
+
buffer.push(line.slice(0, -1));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
line = [...buffer, line].join('\n');
|
|
64
|
+
buffer.length = 0;
|
|
65
|
+
try {
|
|
66
|
+
if (val === void 0) {
|
|
67
|
+
val = {};
|
|
68
|
+
}
|
|
69
|
+
if (line.match(/^[ \n\t]*(?:--h)?$/)) {
|
|
70
|
+
// --h
|
|
71
|
+
help();
|
|
72
|
+
} else if (line.match(/^[ \n\t]*\^$/)) {
|
|
73
|
+
val = closeVector(val);
|
|
74
|
+
console.log(`=> ${JSON.stringify(val)}`);
|
|
75
|
+
} else if (line.match(re__l)) {
|
|
76
|
+
// --l
|
|
77
|
+
const file = line.match(re__l)[1];
|
|
78
|
+
console.log(` -- loading file: ${file} ...`);
|
|
79
|
+
const kScript = fs.readFileSync(file).toString();
|
|
80
|
+
console.log(` ----------------------------- compiling file: ${file} ...`);
|
|
81
|
+
// console.log(kScript);
|
|
82
|
+
val = k.compile("+++\n" + kScript + "\n()")(val);
|
|
83
|
+
console.log(`=> ${JSON.stringify(val)}`);
|
|
84
|
+
} else if (line.match(/^[ \n\t]*(?:--a)?$/)) {
|
|
85
|
+
// --a
|
|
86
|
+
val = run.defs;
|
|
87
|
+
console.log(val);
|
|
88
|
+
// --r
|
|
89
|
+
} else if (line.match(/^[ \n\t]*(?:--r)?$/)) {
|
|
90
|
+
console.log(
|
|
91
|
+
(function (defs, result) {
|
|
92
|
+
if (defs == null) {
|
|
93
|
+
return result;
|
|
94
|
+
}
|
|
95
|
+
return (function (prettyRel) {
|
|
96
|
+
let ref1, relName;
|
|
97
|
+
ref1 = defs.rels;
|
|
98
|
+
for (relName in ref1) {
|
|
99
|
+
result[relName] = prettyRel(ref1[relName].def);
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
})(
|
|
103
|
+
prettyRel.bind(
|
|
104
|
+
null,
|
|
105
|
+
prettyCode.bind(null, defs.representatives)
|
|
106
|
+
)
|
|
106
107
|
);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
let reg = line.match(re__s)[1];
|
|
119
|
-
registers[reg] = val;
|
|
120
|
-
console.log(` -- current value stored in register: '${reg}'`);
|
|
121
|
-
// --g
|
|
122
|
-
} else if (line.match(re__g)) {
|
|
123
|
-
console.log(" -- getting value from register...");
|
|
124
|
-
let reg = line.match(re__g)[1];
|
|
125
|
-
val = registers[reg];
|
|
126
|
-
console.log(val);
|
|
127
|
-
// ------ k code
|
|
128
|
-
} else if (!line.match(/^[ \n\t]*(?:#.*)?$/)) {
|
|
129
|
-
try {
|
|
130
|
-
val = k.run(`+++ ${line} ()`, val);
|
|
131
|
-
console.log(`=> ${JSON.stringify(val)}`);
|
|
132
|
-
} catch (error) {
|
|
133
|
-
e = error;
|
|
134
|
-
console.error("ERROR:");
|
|
135
|
-
console.error(e);
|
|
108
|
+
})(run.defs, {}));
|
|
109
|
+
// --c
|
|
110
|
+
} else if (line.match(/^[ \n\t]*(?:--c)?$/)) {
|
|
111
|
+
console.log(
|
|
112
|
+
(function (defs, result) {
|
|
113
|
+
for (const codeName of Object.keys(defs.representatives || {})) {
|
|
114
|
+
const codeExp = find(defs.representatives[codeName] || codeName);
|
|
115
|
+
result[codeName] = prettyCode(
|
|
116
|
+
defs.representatives,
|
|
117
|
+
codeExp
|
|
118
|
+
);
|
|
136
119
|
}
|
|
137
|
-
|
|
120
|
+
return result;
|
|
121
|
+
})(run.defs || {}, {})
|
|
122
|
+
);
|
|
123
|
+
// --C
|
|
124
|
+
} else if (line.match(re__C)) {
|
|
125
|
+
let codeName = line.match(re__C)[1];
|
|
126
|
+
if (codeName.startsWith("?"))
|
|
127
|
+
codeName = codeName.slice(1);
|
|
128
|
+
if (codeName.startsWith("$"))
|
|
129
|
+
codeName = codeName.slice(1);
|
|
130
|
+
const canonicalName = run.defs.representatives[codeName] || codeName;
|
|
131
|
+
const codeExp = find( canonicalName );
|
|
132
|
+
console.log(` $ ${canonicalName} = ${prettyCode(run.defs.representatives, codeExp)}; -- ${codeExp.def}`);
|
|
133
|
+
// --pp
|
|
134
|
+
} else if (line.match(/^[ \n\t]*(?:--pp)?$/)) {
|
|
135
|
+
console.log(val);
|
|
136
|
+
// --p
|
|
137
|
+
} else if (line.match(/^[ \n\t]*(?:--p)?$/)) {
|
|
138
|
+
console.log(JSON.stringify(val, null, 2));
|
|
139
|
+
// --regs
|
|
140
|
+
} else if (line.match(/^[ \n\t]*(?:--regs)?$/)) {
|
|
141
|
+
console.log(` -- registers: ${Object.keys(registers).join(", ")}`);
|
|
142
|
+
// --s
|
|
143
|
+
} else if (line.match(re__s)) {
|
|
144
|
+
let reg = line.match(re__s)[1];
|
|
145
|
+
registers[reg] = val;
|
|
146
|
+
console.log(` -- current value stored in register: '${reg}'`);
|
|
147
|
+
// --g
|
|
148
|
+
} else if (line.match(re__g)) {
|
|
149
|
+
console.log(" -- getting value from register...");
|
|
150
|
+
let reg = line.match(re__g)[1];
|
|
151
|
+
val = registers[reg];
|
|
152
|
+
console.log(val);
|
|
153
|
+
// --x
|
|
154
|
+
} else if (line.match(re__x)) {
|
|
155
|
+
const relName = line.match(re__x)[1];
|
|
156
|
+
const rel = run.defs?.rels[relName];
|
|
157
|
+
if (!rel) {
|
|
158
|
+
console.log(` -- relation '${relName}' not found`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const filters = patterns2filters(rel.typePatternGraph, ...rel.def.patterns);
|
|
162
|
+
// console.log(filters);
|
|
163
|
+
// console.log(" variables:", JSON.stringify(variables));
|
|
164
|
+
// console.log(JSON.stringify({filters, variables}, null, 2));
|
|
165
|
+
// for (const filter of filters) {
|
|
166
|
+
const pcodef= prettyCode.bind(null, run.defs.representatives);
|
|
167
|
+
const filtersStr = filters.map( x => prettyRel(pcodef, {op: "filter", filter: x}));
|
|
168
|
+
console.log(` ${relName} : ${filtersStr[0]} --> ${filtersStr[1]}`);
|
|
169
|
+
// }
|
|
170
|
+
// ------ k code
|
|
171
|
+
} else if (!line.match(/^[ \n\t]*(?:#.*)?$/)) {
|
|
172
|
+
try {
|
|
173
|
+
val = k.run(`+++\n${line}\n()`, val);
|
|
174
|
+
console.log(`=> ${JSON.stringify(val)}`);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
e = error;
|
|
177
|
+
console.error("ERROR:");
|
|
178
|
+
console.error(e);
|
|
138
179
|
}
|
|
139
180
|
}
|
|
140
|
-
})
|
|
141
|
-
|
|
181
|
+
} catch (e) {
|
|
182
|
+
console.error(e.message);
|
|
183
|
+
}
|
|
184
|
+
}
|
package/run.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import assert from "assert";
|
|
2
|
+
import { find } from "./codes.mjs";
|
|
2
3
|
|
|
3
4
|
const modulo = (a, b) => ((+a % (b = +b)) + b) % b;
|
|
4
5
|
const valid = (x) => (isNaN(x) ? undefined : x);
|
|
@@ -54,7 +55,7 @@ const builtin = {
|
|
|
54
55
|
},
|
|
55
56
|
FDIV: ([x, y]) => x / y,
|
|
56
57
|
CONCAT: (strs) => strs.join(""),
|
|
57
|
-
toVEC: (str) => [
|
|
58
|
+
toVEC: (str) => [...`${str}`],
|
|
58
59
|
true: () => true,
|
|
59
60
|
false: () => false,
|
|
60
61
|
null: () => null,
|
|
@@ -73,12 +74,9 @@ const codes = {
|
|
|
73
74
|
};
|
|
74
75
|
|
|
75
76
|
function verify(code, value) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
// console.log {code,value, representatives, defCodes}
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
77
|
+
"use strict";
|
|
78
|
+
if (code == null) return false;
|
|
79
|
+
code = find(code);
|
|
82
80
|
switch (code.code) {
|
|
83
81
|
case "vector":
|
|
84
82
|
if (!Array.isArray(value)) return false;
|
|
@@ -99,11 +97,8 @@ function verify(code, value) {
|
|
|
99
97
|
if (fields.length !== 1) return false;
|
|
100
98
|
return verify(code.union[fields[0]], value[fields[0]]);
|
|
101
99
|
}
|
|
102
|
-
default:
|
|
103
|
-
|
|
104
|
-
if (c != null) return verify(c, value);
|
|
105
|
-
return codes[code](value);
|
|
106
|
-
}
|
|
100
|
+
default:
|
|
101
|
+
return codes[code.code](value);
|
|
107
102
|
}
|
|
108
103
|
}
|
|
109
104
|
|
package/symbol-table.mjs
CHANGED
|
@@ -124,7 +124,7 @@ class SymbolTable {
|
|
|
124
124
|
|
|
125
125
|
add_rel(name, rel) {
|
|
126
126
|
if (this.rels[name] != undefined)
|
|
127
|
-
console.error(`SymbolTable: rel ${name}
|
|
127
|
+
console.error(`SymbolTable: rel '${name}' is redefined (lines ${rel.start?.line}:${rel.start?.column}...${rel.end?.line}:${rel.end?.column})`);
|
|
128
128
|
|
|
129
129
|
this.rels[name] = {def: rel};
|
|
130
130
|
}
|