@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/patterns.mjs CHANGED
@@ -27,11 +27,17 @@ function relDefToString(relDef) {
27
27
  case "dot":
28
28
  case "code":
29
29
  case "pipe":
30
- return [...rel.patterns];
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 = new TypePatternGraph();
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(usedCodes, representatives, rels) {
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
- console.error(`Code Derivation Error for '${rel.op}' (lines ${rel.start?.line}:${rel.start?.column}...${rel.end?.line}:${rel.end?.column}): ${e.message}.`);
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.addNewNode();
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
- console.error(`Type Error in call to ${varName} in definition of ${relName}: lines ${varRel.start?.line}:${varRel.start?.column}...${varRel.end?.line}:${varRel.end?.column}): ${e.message}.`);
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 (codes, representatives, label_ref_map) {
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(codes, representatives, {
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 (codes, representatives, codeExp) {
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(codes, representatives, codes[name]);
33
+ return prettyCode(representatives, find(name));
31
34
  } else {
32
35
  return name;
33
36
  }
34
37
  case "product":
35
- return `{${prettyCode_labels(codes, representatives, codeExp.product)}}`;
38
+ return `{${prettyCode_labels(representatives, codeExp.product)}}`;
36
39
  case "union":
37
- return `< ${prettyCode_labels(codes, representatives, codeExp.union)} >`;
40
+ return `< ${prettyCode_labels(representatives, codeExp.union)} >`;
38
41
  case "vector":
39
- return `[${prettyCode(codes,representatives, {code:'ref', ref:codeExp.vector})}]`;
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 = (f) =>
48
- Object.keys(f.fields).map( (key) =>
49
- `${key}: ${prettyFilter(prettyCode, f.fields[key])}`
50
- ).join(", ") + (f.open ? ", ..." : "");
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
- return `(${fieldsStr(filter)})`;
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(filter)}>`;
70
+ return `<${fieldsStr()}>${filter.name ? "=" + filter.name : ""}`;
65
71
  case "product":
66
- return `{${fieldsStr(filter)}}`;
72
+ return `{${fieldsStr()}}${filter.name ? "=" + filter.name : ""}`;
67
73
  }
68
- throw new Error("unreachable");
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
- export default { prettyCode, prettyRel };
127
- export { prettyCode, prettyRel };
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 pretty-print last value (abrevaited)");
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 registers = {};
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
- (function (val, buffer) {
35
- return process.stdin.on("data", function (data) {
36
- var e, file, first, i, kScript, last, len, line, ref, rest, todo;
37
- [first, ...rest] = data.toString("utf8").split("\n");
38
- buffer.push(first);
39
- if (rest.length > 0) {
40
- todo = buffer.join("");
41
- (ref = rest), ([...rest] = ref), ([last] = splice.call(rest, -1));
42
- buffer = [last];
43
- todo = [todo, ...rest];
44
- for (i = 0, len = todo.length; i < len; i++) {
45
- line = todo[i];
46
- if (val === void 0) {
47
- val = {};
48
- }
49
- if (line.match(/^[ \n\t]*(?:--h)?$/)) {
50
- // --h
51
- help();
52
- } else if (line.match(/^[ \n\t]*\^$/)) {
53
- val = closeVector(val);
54
- console.log(`=> ${JSON.stringify(val)}`);
55
- } else if (line.match(re__l)) {
56
- // --l
57
- file = line.match(re__l)[1];
58
- console.log(` -- loading file: ${file} ...`);
59
- kScript = fs.readFileSync(file).toString();
60
- console.log(` ----------------------------- compiling file: ${file} ...`);
61
- // console.log(kScript);
62
- val = k.compile("+++" + kScript + "\n()")(val);
63
- console.log(`=> ${JSON.stringify(val)}`);
64
- } else if (line.match(/^[ \n\t]*(?:--a)?$/)) {
65
- // --a
66
- val = run.defs;
67
- console.log(val);
68
- } else if (line.match(/^[ \n\t]*(?:--r)?$/)) {
69
- console.log(
70
- (function (defs, result) {
71
- if (defs == null) {
72
- return result;
73
- }
74
- return (function (prettyRel) {
75
- var ref1, relName;
76
- ref1 = defs.rels;
77
- for (relName in ref1) {
78
- result[relName] = prettyRel(ref1[relName].def);
79
- }
80
- return result;
81
- })(
82
- prettyRel.bind(
83
- null,
84
- prettyCode.bind(null, defs.codes, defs.representatives)
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
- // --pp
108
- } else if (line.match(/^[ \n\t]*(?:--pp)?$/)) {
109
- console.log(val);
110
- // --s
111
- // --p
112
- } else if (line.match(/^[ \n\t]*(?:--p)?$/)) {
113
- console.log(JSON.stringify(val, null, 2));
114
- // --s
115
- } else if (line.match(/^[ \n\t]*(?:--regs)?$/)) {
116
- console.log(` -- registers: ${Object.keys(registers).join(", ")}`);
117
- } else if (line.match(re__s)) {
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) => [...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
- if (code == null) {
77
- // representatives = run.defs.representatives
78
- // defCodes = JSON.stringify run.defs.codes
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
- const c = run.defs.codes[run.defs.representatives[code]];
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} already defined (lines ${rel.start?.line}:${rel.start?.column}...${rel.end?.line}:${rel.end?.column})`);
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
  }