@fraczak/k 4.0.4 → 5.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 +106 -48
- package/Code-derivation-tests/bnat.mjs +1 -1
- package/TODO.md +18 -0
- package/TYPING.md +2 -2
- package/export.mjs +185 -0
- package/index.mjs +3 -15
- package/package.json +1 -1
- package/parser.jison +1 -1
- package/parser.mjs +1 -1
- package/patterns.mjs +25 -11
- package/pretty.mjs +26 -41
- package/repl.mjs +50 -27
- package/run.mjs +2 -0
- package/k-repl.cast~ +0 -1939
package/pretty.mjs
CHANGED
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
import { find } from "./codes.mjs";
|
|
2
2
|
import { TypePatternGraph } from "./typing.mjs";
|
|
3
3
|
|
|
4
|
-
function compareAs(fn) {
|
|
5
|
-
return function (a, b) {
|
|
6
|
-
[a, b] = [a, b].map(fn);
|
|
7
|
-
if (a < b) return -1;
|
|
8
|
-
if (a > b) return 1;
|
|
9
|
-
return 0;
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
4
|
const nameRE = /^[a-zA-Z0-9_][a-zA-Z0-9_?!]*$/;
|
|
5
|
+
function pLabel_(label) {
|
|
6
|
+
return nameRE.test(label) ? ` ${label}` : `${JSON.stringify(label)}`;
|
|
7
|
+
}
|
|
8
|
+
function pLabel(label) {
|
|
9
|
+
return nameRE.test(label) ? `${label}` : `${JSON.stringify(label)}`;
|
|
10
|
+
}
|
|
14
11
|
|
|
15
12
|
function prettyCode_labels (representatives, label_ref_map) {
|
|
16
13
|
return Object.keys(label_ref_map)
|
|
17
|
-
.sort(
|
|
14
|
+
.sort()
|
|
18
15
|
.map( (label) => {
|
|
19
|
-
const plabel = nameRE.test(label) ? label : `'${label}'`;
|
|
20
16
|
return `${prettyCode(representatives, {
|
|
21
17
|
code: "ref",
|
|
22
18
|
ref: label_ref_map[label],
|
|
23
|
-
})}
|
|
19
|
+
})}${pLabel_(label)}`;
|
|
24
20
|
})
|
|
25
21
|
.join(", ");
|
|
26
22
|
};
|
|
@@ -46,10 +42,10 @@ function prettyCode (representatives, codeExp) {
|
|
|
46
42
|
}
|
|
47
43
|
};
|
|
48
44
|
|
|
49
|
-
function prettyFilter (
|
|
45
|
+
function prettyFilter ( filter ) {
|
|
50
46
|
const fieldsStr = () => {
|
|
51
47
|
const fields = Object.keys(filter.fields).map( (key) =>
|
|
52
|
-
`${prettyFilter(
|
|
48
|
+
`${prettyFilter(filter.fields[key])}${pLabel_(key)}`
|
|
53
49
|
);
|
|
54
50
|
if (filter.open) fields.push("...");
|
|
55
51
|
return fields.join(", ");
|
|
@@ -57,11 +53,11 @@ function prettyFilter (prettyCode, filter) {
|
|
|
57
53
|
switch (filter.type) {
|
|
58
54
|
|
|
59
55
|
case "code":
|
|
60
|
-
return `$${
|
|
56
|
+
return `$${filter.code}`;
|
|
61
57
|
case "name":
|
|
62
58
|
return filter.name;
|
|
63
59
|
case "vector":
|
|
64
|
-
return `[${prettyFilter(
|
|
60
|
+
return `[${prettyFilter(filter.vector)}]${filter.name ? "=" + filter.name : ""}`;
|
|
65
61
|
case null:
|
|
66
62
|
if (filter.name && Object.keys(filter.fields).length == 0)
|
|
67
63
|
return filter.name;
|
|
@@ -74,12 +70,13 @@ function prettyFilter (prettyCode, filter) {
|
|
|
74
70
|
throw new Error(`Unknown filter type ${filter.type} in ${JSON.stringify(filter)}`);
|
|
75
71
|
}
|
|
76
72
|
|
|
77
|
-
function prettyRel (
|
|
73
|
+
function prettyRel (exp) {
|
|
78
74
|
"use strict";
|
|
79
75
|
const pretty = (exp) => {
|
|
80
76
|
switch (exp.op) {
|
|
81
77
|
case "filter":
|
|
82
|
-
return
|
|
78
|
+
if (exp.filter.type == 'code') return `$${exp.filter.code}`;
|
|
79
|
+
return `?${prettyFilter(exp.filter)}`;
|
|
83
80
|
case "pipe":
|
|
84
81
|
return `|`;
|
|
85
82
|
case "caret":
|
|
@@ -101,27 +98,16 @@ function prettyRel (prettyCode, exp) {
|
|
|
101
98
|
case "dot":
|
|
102
99
|
if ("number" === typeof exp.dot) {
|
|
103
100
|
return `.${exp.dot}`;
|
|
104
|
-
} else
|
|
105
|
-
return `.${exp.dot}`;
|
|
106
|
-
} else {
|
|
107
|
-
return `'${exp.dot}'`;
|
|
108
|
-
}
|
|
109
|
-
break;
|
|
101
|
+
} else
|
|
102
|
+
return `.${pLabel(exp.dot)}`;
|
|
110
103
|
case "code":
|
|
111
|
-
return `$${
|
|
112
|
-
code: "ref",
|
|
113
|
-
ref: exp.code,
|
|
114
|
-
})}`;
|
|
104
|
+
return `$${exp.code}`;
|
|
115
105
|
case "product":
|
|
116
106
|
return (function (labelled) {
|
|
117
107
|
return `{${labelled.join(", ")}}`;
|
|
118
108
|
})(
|
|
119
109
|
exp.product.map(function ({ label, exp }) {
|
|
120
|
-
|
|
121
|
-
return `${pretty(exp)} ${label}`;
|
|
122
|
-
} else {
|
|
123
|
-
return `${pretty(exp)} '${label}'`;
|
|
124
|
-
}
|
|
110
|
+
return `${pretty(exp)}${pLabel_(label)}`;
|
|
125
111
|
})
|
|
126
112
|
);
|
|
127
113
|
}
|
|
@@ -148,25 +134,24 @@ function patterns2filters(typePatternGraph, ...patternIds) {
|
|
|
148
134
|
|
|
149
135
|
// variables - variables which will have to be added as extra filters
|
|
150
136
|
const variables = inDegree.reduce( (variables, degree, i) => {
|
|
151
|
-
if (degree > 1) variables[i] =
|
|
137
|
+
if (degree > 1) variables[i] = true;
|
|
152
138
|
return variables;
|
|
153
139
|
}, {});
|
|
154
140
|
|
|
141
|
+
const filterVars = {};
|
|
155
142
|
const buildFilter = (path, patternId, i) => {
|
|
156
143
|
let named_filter = {};
|
|
157
144
|
const pattern = newTypePatternGraph.get_pattern(patternId);
|
|
158
145
|
if (variables[patternId] && pattern.pattern != 'type') {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
named_filter = { name: name };
|
|
146
|
+
if (filterVars[patternId])
|
|
147
|
+
return { type: 'name', name: filterVars[patternId] };
|
|
148
|
+
filterVars[patternId] = `X${Object.keys(filterVars).length}`;
|
|
149
|
+
named_filter = { name: filterVars[patternId] };
|
|
164
150
|
}
|
|
165
151
|
|
|
166
|
-
|
|
167
152
|
const edges = newTypePatternGraph.edges[patternId];
|
|
168
153
|
const fields = () =>
|
|
169
|
-
Object.keys(edges).reduce( (fields, key) =>{
|
|
154
|
+
Object.keys(edges).sort().reduce( (fields, key) =>{
|
|
170
155
|
fields[key] = buildFilter([...path, key], Object.values(edges[key])[0], i);
|
|
171
156
|
return fields;
|
|
172
157
|
}, {});
|
package/repl.mjs
CHANGED
|
@@ -6,14 +6,17 @@ import k from "./index.mjs";
|
|
|
6
6
|
import {run, closeVector } from "./run.mjs";
|
|
7
7
|
import { prettyCode, prettyRel, patterns2filters } from "./pretty.mjs";
|
|
8
8
|
import { find } from "./codes.mjs";
|
|
9
|
+
import { exportRelation } from "./export.mjs";
|
|
9
10
|
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
let DEBUG_FLAG = false;
|
|
12
13
|
|
|
13
14
|
console.log("Very! experimental repl shell for 'k-language'...");
|
|
14
15
|
|
|
15
16
|
const help = function () {
|
|
16
|
-
|
|
17
|
+
console.log(` --debug toggle debug flag: [${DEBUG_FLAG?'ON':'OFF'}]`);
|
|
18
|
+
if (DEBUG_FLAG)
|
|
19
|
+
console.log(" --load loads codes and relations as value");
|
|
17
20
|
console.log(" --c print aliased codes");
|
|
18
21
|
console.log(" --C code print 'code' definition");
|
|
19
22
|
console.log(" --r print relations");
|
|
@@ -48,8 +51,8 @@ rl.on('line', (line) => {
|
|
|
48
51
|
process.exit(0);
|
|
49
52
|
});
|
|
50
53
|
|
|
51
|
-
let old_val = {};
|
|
52
|
-
let val =
|
|
54
|
+
let old_val = k.compile("{}")({});
|
|
55
|
+
let val = old_val;
|
|
53
56
|
const printVal = function (v = val) {
|
|
54
57
|
if (v === undefined)
|
|
55
58
|
console.log("...",v);
|
|
@@ -88,40 +91,42 @@ function evaluate(line) {
|
|
|
88
91
|
// console.log(kScript);
|
|
89
92
|
val = k.compile("+++\n" + kScript + "\n()")(val);
|
|
90
93
|
printVal();
|
|
91
|
-
} else if (line.match(/^[ \n\t]*--debug$/)) {
|
|
92
94
|
// --debug
|
|
95
|
+
} else if (line.match(/^[ \n\t]*--debug$/)) {
|
|
96
|
+
DEBUG_FLAG = ! DEBUG_FLAG;
|
|
97
|
+
// --load
|
|
98
|
+
} else if (line.match(/^[ \n\t]*--load$/)) {
|
|
93
99
|
val = run.defs;
|
|
94
100
|
console.log(val);
|
|
95
101
|
// --r
|
|
96
102
|
} else if (line.match(/^[ \n\t]*(?:--r)?$/)) {
|
|
97
|
-
console.log(
|
|
103
|
+
console.log("BUILT-IN:", run.builtin);
|
|
104
|
+
console.log("USER-DEFINED:",
|
|
98
105
|
(function (defs, result) {
|
|
99
106
|
if (defs == null) {
|
|
100
107
|
return result;
|
|
101
108
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
})(
|
|
109
|
-
prettyRel.bind(
|
|
110
|
-
null,
|
|
111
|
-
prettyCode.bind(null, defs.representatives)
|
|
112
|
-
)
|
|
113
|
-
);
|
|
109
|
+
|
|
110
|
+
for (const relName in defs.rels) {
|
|
111
|
+
if (relName != "__main__")
|
|
112
|
+
result[relName] = prettyRel(defs.rels[relName].def);
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
114
115
|
})(run.defs, {}));
|
|
115
116
|
// --c
|
|
116
117
|
} else if (line.match(/^[ \n\t]*(?:--c)?$/)) {
|
|
117
118
|
console.log(
|
|
118
119
|
(function (defs, result) {
|
|
119
120
|
for (const codeName of Object.keys(defs.representatives || {})) {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
const codeRep = defs.representatives[codeName] || codeName;
|
|
122
|
+
if (codeName == codeRep) {
|
|
123
|
+
result[codeName] = prettyCode(
|
|
124
|
+
defs.representatives,
|
|
125
|
+
find(codeRep)
|
|
126
|
+
);
|
|
127
|
+
} else if (! codeName.startsWith(":")) {
|
|
128
|
+
result[codeName] = codeRep;
|
|
129
|
+
}
|
|
125
130
|
}
|
|
126
131
|
return result;
|
|
127
132
|
})(run.defs || {}, {})
|
|
@@ -135,6 +140,9 @@ function evaluate(line) {
|
|
|
135
140
|
codeName = codeName.slice(1);
|
|
136
141
|
const canonicalName = run.defs.representatives[codeName] || codeName;
|
|
137
142
|
const codeExp = find( canonicalName );
|
|
143
|
+
if (codeExp.def == "builtin") {
|
|
144
|
+
return console.log(` $ ${canonicalName} = :builtin;`);
|
|
145
|
+
}
|
|
138
146
|
console.log(` $ ${canonicalName} = ${prettyCode(run.defs.representatives, codeExp)}; -- ${codeExp.def}`);
|
|
139
147
|
// --pp
|
|
140
148
|
} else if (line.match(/^[ \n\t]*(?:--pp)?$/)) {
|
|
@@ -161,18 +169,33 @@ function evaluate(line) {
|
|
|
161
169
|
const relName = line.match(re__R)[1];
|
|
162
170
|
const rel = run.defs?.rels[relName];
|
|
163
171
|
if (!rel) {
|
|
172
|
+
if (relName in run.builtin) {
|
|
173
|
+
console.log(` -- builtin relation: ${relName}\n ${relName} = ${run.builtin[relName]}`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
164
176
|
console.log(` -- relation '${relName}' not found`);
|
|
165
177
|
return;
|
|
166
178
|
}
|
|
179
|
+
const canonicalRelName = run.defs.relAlias[relName];
|
|
167
180
|
const filters = patterns2filters(rel.typePatternGraph, ...rel.def.patterns);
|
|
168
181
|
// console.log(filters);
|
|
169
182
|
// console.log(" variables:", JSON.stringify(variables));
|
|
170
183
|
// console.log(JSON.stringify({filters, variables}, null, 2));
|
|
171
184
|
// for (const filter of filters) {
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
console.log(` ${relName} : ${filtersStr[0]} --> ${filtersStr[1]}`);
|
|
175
|
-
console.log(` ${relName} = ${prettyRel(
|
|
185
|
+
const filtersStr = filters.map( x => prettyRel( {op: "filter", filter: x}));
|
|
186
|
+
// console.log(` -- canonical relation name: ${canonicalRelName} --`);
|
|
187
|
+
// console.log(` ${relName} : ${filtersStr[0]} --> ${filtersStr[1]}`);
|
|
188
|
+
// console.log(` ${relName} = ${prettyRel(rel.def)};`);
|
|
189
|
+
// console.log(` ${relName} = ${prettyRel(rel.simplified)};`);
|
|
190
|
+
console.log({
|
|
191
|
+
name: canonicalRelName,
|
|
192
|
+
type: `${filtersStr[0]} --> ${filtersStr[1]}`,
|
|
193
|
+
def: prettyRel(rel.def)
|
|
194
|
+
});
|
|
195
|
+
if (DEBUG_FLAG) {
|
|
196
|
+
val = exportRelation(run.defs.rels, run.defs.relAlias, relName);
|
|
197
|
+
console.log(val);
|
|
198
|
+
}
|
|
176
199
|
// }
|
|
177
200
|
// ------ k code
|
|
178
201
|
} else if (!line.match(/^[ \n\t]*(?:#.*)?$/)) {
|