@fraczak/k 3.0.2 → 4.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/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
@@ -2,7 +2,8 @@
2
2
 
3
3
  import k from "./index.mjs";
4
4
  import {run, closeVector } from "./run.mjs";
5
- import { prettyCode, prettyRel } from "./pretty.mjs";
5
+ import { prettyCode, prettyRel, patterns2filters } from "./pretty.mjs";
6
+ import { find } from "./codes.mjs";
6
7
 
7
8
  import fs from "node:fs";
8
9
 
@@ -13,13 +14,16 @@ console.log("Very! experimental repl shell for 'k-language'...");
13
14
  const help = function () {
14
15
  console.log(" --h print help");
15
16
  console.log(" --a print codes and relations");
16
- console.log(" --c print codes");
17
+ console.log(" --c print aliased codes");
18
+ console.log(" --C CODE print code definition");
17
19
  console.log(" --r print rels");
18
- console.log(" --pp pretty-print last value");
20
+ console.log(" --p pretty-print last value");
21
+ console.log(" --pp print last value via node.js 'console.log'");
19
22
  console.log(" --s reg store the last value in register 'reg'");
20
23
  console.log(" --g reg get the value from register 'reg'");
21
24
  console.log(" --regs print registers names");
22
25
  console.log(" --l file.k load 'file.k'");
26
+ console.log(" --x rel Print out the type of 'rel'");
23
27
  };
24
28
 
25
29
  help();
@@ -27,6 +31,8 @@ help();
27
31
  const re__l = /^[ \n\t]*(?:--l[ ]+)(.+)[ ]*?$/;
28
32
  const re__s = /^[ \n\t]*(?:--s[ ]+)(.+)[ ]*?$/;
29
33
  const re__g = /^[ \n\t]*(?:--g[ ]+)(.+)[ ]*?$/;
34
+ const re__x = /^[ \n\t]*(?:--x[ ]+)(.+)[ ]*?$/;
35
+ const re__C = /^[ \n\t]*(?:--C[ ]+)(.+)[ ]*?$/;
30
36
 
31
37
  const registers = {};
32
38
 
@@ -41,93 +47,125 @@ const registers = {};
41
47
  buffer = [last];
42
48
  todo = [todo, ...rest];
43
49
  for (i = 0, len = todo.length; i < len; i++) {
44
- line = todo[i];
45
- if (val === void 0) {
46
- val = {};
47
- }
48
- if (line.match(/^[ \n\t]*(?:--h)?$/)) {
49
- // --h
50
- help();
51
- } else if (line.match(/^[ \n\t]*\^$/)) {
52
- val = closeVector(val);
53
- console.log(`=> ${JSON.stringify(val)}`);
54
- } else if (line.match(re__l)) {
55
- // --l
56
- file = line.match(re__l)[1];
57
- console.log(` -- loading file: ${file} ...`);
58
- kScript = fs.readFileSync(file).toString();
59
- val = k.compile(kScript + "\n()")(val);
60
- console.log(`=> ${JSON.stringify(val)}`);
61
- } else if (line.match(/^[ \n\t]*(?:--a)?$/)) {
62
- // --a
63
- val = run.defs;
64
- console.log(val);
65
- } else if (line.match(/^[ \n\t]*(?:--r)?$/)) {
66
- console.log(
67
- (function (defs, result) {
68
- if (defs == null) {
69
- return result;
70
- }
71
- return (function (prettyRel) {
72
- var ref1, relExps, relName;
73
- ref1 = defs.rels;
74
- for (relName in ref1) {
75
- relExps = ref1[relName];
76
- result[relName] = relExps.map(prettyRel);
50
+ try {
51
+ line = todo[i];
52
+ if (val === void 0) {
53
+ val = {};
54
+ }
55
+ if (line.match(/^[ \n\t]*(?:--h)?$/)) {
56
+ // --h
57
+ help();
58
+ } else if (line.match(/^[ \n\t]*\^$/)) {
59
+ val = closeVector(val);
60
+ console.log(`=> ${JSON.stringify(val)}`);
61
+ } else if (line.match(re__l)) {
62
+ // --l
63
+ file = line.match(re__l)[1];
64
+ console.log(` -- loading file: ${file} ...`);
65
+ kScript = fs.readFileSync(file).toString();
66
+ console.log(` ----------------------------- compiling file: ${file} ...`);
67
+ // console.log(kScript);
68
+ val = k.compile("+++" + kScript + "\n()")(val);
69
+ console.log(`=> ${JSON.stringify(val)}`);
70
+ } else if (line.match(/^[ \n\t]*(?:--a)?$/)) {
71
+ // --a
72
+ val = run.defs;
73
+ console.log(val);
74
+ // --r
75
+ } else if (line.match(/^[ \n\t]*(?:--r)?$/)) {
76
+ console.log(
77
+ (function (defs, result) {
78
+ if (defs == null) {
79
+ return result;
77
80
  }
78
- return result;
79
- })(
80
- prettyRel.bind(
81
- null,
82
- prettyCode.bind(null, defs.codes, defs.representatives)
83
- )
84
- );
85
- })(run.defs, {}));
86
- } else if (line.match(/^[ \n\t]*(?:--c)?$/)) {
87
- console.log(
88
- (function (defs, result) {
89
- var codeExp, codeName, ref1;
90
- if (defs == null) {
91
- return result;
92
- }
93
- ref1 = defs.codes;
94
- for (codeName in ref1) {
95
- codeExp = ref1[codeName];
96
- result[codeName] = prettyCode(
97
- defs.codes,
98
- defs.representatives,
99
- codeExp
81
+ return (function (prettyRel) {
82
+ var ref1, relName;
83
+ ref1 = defs.rels;
84
+ for (relName in ref1) {
85
+ result[relName] = prettyRel(ref1[relName].def);
86
+ }
87
+ return result;
88
+ })(
89
+ prettyRel.bind(
90
+ null,
91
+ prettyCode.bind(null, defs.representatives)
92
+ )
100
93
  );
101
- }
102
- return result;
103
- })(run.defs, {})
104
- );
94
+ })(run.defs, {}));
95
+ // --c
96
+ } else if (line.match(/^[ \n\t]*(?:--c)?$/)) {
97
+ console.log(
98
+ (function (defs, result) {
99
+ for (const codeName of Object.keys(defs.representatives || {})) {
100
+ const codeExp = find(defs.representatives[codeName] || codeName);
101
+ result[codeName] = prettyCode(
102
+ defs.representatives,
103
+ codeExp
104
+ );
105
+ }
106
+ return result;
107
+ })(run.defs || {}, {})
108
+ );
109
+ // --C
110
+ } else if (line.match(re__C)) {
111
+ let codeName = line.match(re__C)[1];
112
+ if (codeName.startsWith("?"))
113
+ codeName = codeName.slice(1);
114
+ if (codeName.startsWith("$"))
115
+ codeName = codeName.slice(1);
116
+ const canonicalName = run.defs.representatives[codeName] || codeName;
117
+ const codeExp = find( canonicalName );
118
+ console.log(` $ ${canonicalName} = ${prettyCode(run.defs.representatives, codeExp)}; -- ${codeExp.def}`);
119
+ // --pp
120
+ } else if (line.match(/^[ \n\t]*(?:--pp)?$/)) {
121
+ console.log(val);
105
122
  // --p
106
- } else if (line.match(/^[ \n\t]*(?:--pp)?$/)) {
107
- console.log(val);
108
- // --s
109
- } else if (line.match(/^[ \n\t]*(?:--regs)?$/)) {
110
- console.log(` -- registers: ${Object.keys(registers).join(", ")}`);
111
- } else if (line.match(re__s)) {
112
- let reg = line.match(re__s)[1];
113
- registers[reg] = val;
114
- console.log(` -- current value stored in register: '${reg}'`);
115
- // --g
116
- } else if (line.match(re__g)) {
117
- console.log(" -- getting value from register...");
118
- let reg = line.match(re__g)[1];
119
- val = registers[reg];
120
- console.log(val);
121
- // ------ k code
122
- } else if (!line.match(/^[ \n\t]*(?:#.*)?$/)) {
123
- try {
124
- val = k.run(`${line} ()`, val);
125
- console.log(`=> ${JSON.stringify(val)}`);
126
- } catch (error) {
127
- e = error;
128
- console.error("ERROR:");
129
- console.error(e);
123
+ } else if (line.match(/^[ \n\t]*(?:--p)?$/)) {
124
+ console.log(JSON.stringify(val, null, 2));
125
+ // --regs
126
+ } else if (line.match(/^[ \n\t]*(?:--regs)?$/)) {
127
+ console.log(` -- registers: ${Object.keys(registers).join(", ")}`);
128
+ // --s
129
+ } else if (line.match(re__s)) {
130
+ let reg = line.match(re__s)[1];
131
+ registers[reg] = val;
132
+ console.log(` -- current value stored in register: '${reg}'`);
133
+ // --g
134
+ } else if (line.match(re__g)) {
135
+ console.log(" -- getting value from register...");
136
+ let reg = line.match(re__g)[1];
137
+ val = registers[reg];
138
+ console.log(val);
139
+ // --x
140
+ } else if (line.match(re__x)) {
141
+ const relName = line.match(re__x)[1];
142
+ const rel = run.defs?.rels[relName];
143
+ if (!rel) {
144
+ console.log(` -- relation '${relName}' not found`);
145
+ continue;
146
+ }
147
+ const filters = patterns2filters(rel.typePatternGraph, ...rel.def.patterns);
148
+ // console.log(filters);
149
+ // console.log(" variables:", JSON.stringify(variables));
150
+ // console.log(JSON.stringify({filters, variables}, null, 2));
151
+ // for (const filter of filters) {
152
+ const pcodef= prettyCode.bind(null, run.defs.representatives);
153
+ const filtersStr = filters.map( x => prettyRel(pcodef, {op: "filter", filter: x}));
154
+ console.log(` ${relName} : ${filtersStr[0]} --> ${filtersStr[1]}`);
155
+ // }
156
+ // ------ k code
157
+ } else if (!line.match(/^[ \n\t]*(?:#.*)?$/)) {
158
+ try {
159
+ val = k.run(`+++ ${line}\n ()`, val);
160
+ console.log(`=> ${JSON.stringify(val)}`);
161
+ } catch (error) {
162
+ e = error;
163
+ console.error("ERROR:");
164
+ console.error(e);
165
+ }
130
166
  }
167
+ } catch (e) {
168
+ console.error(e.message);
131
169
  }
132
170
  }
133
171
  }
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,13 +55,14 @@ const builtin = {
54
55
  },
55
56
  FDIV: ([x, y]) => x / y,
56
57
  CONCAT: (strs) => strs.join(""),
58
+ toVEC: (str) => [...str],
57
59
  true: () => true,
58
60
  false: () => false,
59
61
  null: () => null,
60
62
  toJSON: (x) => JSON.stringify(x),
61
63
  fromJSON: (x) => JSON.parse(x),
62
- CONS: (arg) => { try { return [arg[0], ...arg[1]]; } catch (e) { return undefined; } },
63
- SNOC: (x) => (x.length > 1 ? [x[0], x.slice(1)] : undefined),
64
+ CONS: ({car, cdr}) => { try { return [car, ...cdr]; } catch (e) { return undefined; } },
65
+ SNOC: (x) => (x.length > 1 ? {car: x[0], cdr: x.slice(1)} : undefined),
64
66
  toDateMsec: (x) => new Date(x).getTime(),
65
67
  toDateStr: (x) => new Date(x).toISOString(),
66
68
  };
@@ -72,12 +74,9 @@ const codes = {
72
74
  };
73
75
 
74
76
  function verify(code, value) {
75
- if (code == null) {
76
- // representatives = run.defs.representatives
77
- // defCodes = JSON.stringify run.defs.codes
78
- // console.log {code,value, representatives, defCodes}
79
- return false;
80
- }
77
+ "use strict";
78
+ if (code == null) return false;
79
+ code = find(code);
81
80
  switch (code.code) {
82
81
  case "vector":
83
82
  if (!Array.isArray(value)) return false;
@@ -98,11 +97,8 @@ function verify(code, value) {
98
97
  if (fields.length !== 1) return false;
99
98
  return verify(code.union[fields[0]], value[fields[0]]);
100
99
  }
101
- default: {
102
- const c = run.defs.codes[run.defs.representatives[code]];
103
- if (c != null) return verify(c, value);
104
- return codes[code](value);
105
- }
100
+ default:
101
+ return codes[code.code](value);
106
102
  }
107
103
  }
108
104
 
@@ -131,10 +127,10 @@ function run(exp, value) {
131
127
  case "str":
132
128
  case "int":
133
129
  return exp[exp.op];
134
- case "ref":
130
+ case "ref": {
135
131
  const defn = run.defs.rels[exp.ref];
136
- if (defn != null) {
137
- exp = defn[defn.length - 1];
132
+ if (defn != undefined) {
133
+ exp = defn.def;
138
134
  continue;
139
135
  }
140
136
  const builtin_func = builtin[exp.ref];
@@ -142,6 +138,7 @@ function run(exp, value) {
142
138
  return builtin_func(value);
143
139
  }
144
140
  throw(`Unknown ref: '${exp.ref}'`);
141
+ }
145
142
  case "dot":
146
143
  // a hack to allow something like 'null . null' or '0 . 0' to work by returning unit
147
144
  if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
package/symbol-table.mjs CHANGED
@@ -1,14 +1,8 @@
1
- const rels = {};
2
- const codes = {
3
- "{}": {
4
- code: "product",
5
- product: {},
6
- },
7
- };
8
-
9
- const identity = {
10
- op: "identity",
11
- };
1
+ import hash from "./hash.mjs";
2
+
3
+ const unitCode = hash('$C0={};');
4
+
5
+ const identity = {op: "identity"}
12
6
 
13
7
  function is_identity_rel(rel) {
14
8
  return rel.op === "identity";
@@ -46,7 +40,9 @@ function is_full_rel(rel) {
46
40
  case "vector":
47
41
  return Object.values(rel[rel.op]).every(is_full_rel);
48
42
  case "product":
49
- return Object.values(rel[rel.op]).every(({ exp }) => is_full_rel(exp));
43
+ return Object.values(rel[rel.op]).every(({ exp }) =>
44
+ is_full_rel(exp)
45
+ );
50
46
  default:
51
47
  return false;
52
48
  }
@@ -81,7 +77,7 @@ function comp_first(e1, e2) {
81
77
  };
82
78
  }
83
79
 
84
- function comp (e1, e2) {
80
+ function comp(e1, e2) {
85
81
  const result = comp_first(e1, e2);
86
82
  if (result.op !== "comp") return result;
87
83
  result.comp = result.comp.reduceRight(
@@ -91,7 +87,8 @@ function comp (e1, e2) {
91
87
  return result;
92
88
  }
93
89
 
94
- function union (rels) {
90
+
91
+ function union(rels) {
95
92
  const list = [];
96
93
  label: for (const rel of rels) {
97
94
  const new_rels = rel.op === "union" ? rel.union : [rel];
@@ -105,32 +102,38 @@ function union (rels) {
105
102
  op: "union",
106
103
  union: list,
107
104
  };
108
- };
109
-
110
- function as_ref (codeExp) {
111
- if (codeExp.code === "ref") return codeExp.ref;
112
- const newName = `:${Object.keys(codes).length}`;
113
- codes[newName] = codeExp;
114
- return newName;
115
- };
116
-
117
- function add_rel (name, rel) {
118
- if (rels[name] == null) rels[name] = [];
119
- rels[name].push(rel);
120
- };
121
-
122
- function add_code (name, code) {
123
- codes[name] = code;
124
105
  }
125
106
 
126
- export default {
127
- identity,
128
- comp,
129
- union,
130
- rels,
131
- codes,
132
- add_rel,
133
- add_code,
134
- as_ref,
135
- };
136
- export { identity, comp, union, rels, codes, add_rel, add_code, as_ref };
107
+ class SymbolTable {
108
+ constructor() {
109
+ this.rels = {}; // name -> {def: rel_exp}
110
+ this.codes = {
111
+ [unitCode]: {
112
+ code: "product",
113
+ product: {},
114
+ },
115
+ };
116
+ }
117
+
118
+ as_ref(codeExp) {
119
+ if (codeExp.code === "ref") return codeExp.ref;
120
+ const newName = `:${Object.keys(this.codes).length}`;
121
+ this.codes[newName] = codeExp;
122
+ return newName;
123
+ }
124
+
125
+ add_rel(name, rel) {
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})`);
128
+
129
+ this.rels[name] = {def: rel};
130
+ }
131
+
132
+ add_code(name, code) {
133
+ this.codes[name] = code;
134
+ }
135
+ }
136
+
137
+ export default { SymbolTable, comp, union, identity };
138
+ export { SymbolTable, comp, union, identity };
139
+
package/test-filters.mjs CHANGED
@@ -23,7 +23,7 @@ const annotated = k.annotate(`
23
23
  const test1 = unify_with_code(
24
24
  annotated.codes,
25
25
  annotated.representatives["pair"],
26
- annotated.rels['f1'][0].filter,
26
+ annotated.rels['f1'].def.filter,
27
27
  {}
28
28
  );
29
29
  console.log(JSON.stringify(test1, null, 2));
@@ -31,7 +31,7 @@ console.log(JSON.stringify(test1, null, 2));
31
31
  const test2 = unify_with_code(
32
32
  annotated.codes,
33
33
  annotated.representatives["pair"],
34
- annotated.rels['f2'][0].filter,
34
+ annotated.rels['f2'].def.filter,
35
35
  {}
36
36
  );
37
37
  console.log(JSON.stringify(test2, null, 2));
@@ -39,7 +39,7 @@ console.log(JSON.stringify(test2, null, 2));
39
39
  const test3 = unify_with_code(
40
40
  annotated.codes,
41
41
  annotated.representatives["list"],
42
- annotated.rels['f3'][0].filter,
42
+ annotated.rels['f3'].def.filter,
43
43
  {}
44
44
  );
45
45
  console.log(JSON.stringify(test3, null, 2));
@@ -0,0 +1,40 @@
1
+ import t from './typing.mjs';
2
+ // const t = await import('./typing.mjs');
3
+ const g = new t.typePatternGraph();
4
+
5
+ const pu = {pattern: '(...)', fields: []};
6
+
7
+ // x = .x; { { 5 x } x i, { true x } x b }
8
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
9
+
10
+ for (var i = 0; i < 16; i++) { g.addNewNode(pu); }
11
+
12
+ g.addNewNode({pattern: '(...)'}, {x: [1]}); // 16
13
+ g.unify("y:input", 0,16); // 17
14
+
15
+ //
16
+ g.unify('main:input',2,3,4,9,10); // 18
17
+
18
+ g.addNewNode({pattern: '{}'}, {i: [8], b: [14]}); // 19
19
+ g.unify("main:output", 15,19); // 20
20
+
21
+ g.unify('comp:chain',6,7); // 21
22
+ g.unify('comp:chain',12,13); // 22
23
+
24
+
25
+ // {5 x}
26
+ g.addNewNode({pattern: '<...>'}, {x: [5]}); // 23
27
+ g.unify('variant:output',6,23); // 24
28
+
29
+ // {true x}
30
+ g.addNewNode({pattern: '<...>'}, {x: [11]}); // 25
31
+ g.unify('variant:output',12,25); // 26
32
+
33
+
34
+ // 5
35
+ g.addNewNode({pattern: 'type', type: 'int'}); // 27
36
+ g.unify('5:outout',5,27); // 28
37
+
38
+ // true
39
+ g.addNewNode({pattern: 'type', type: 'bool'}); // 29
40
+ g.unify('true:output',11,29); // 30