@fraczak/k 1.3.3 → 2.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/INTRO.md +19 -5
- package/README.md +3 -2
- package/codes.mjs +104 -0
- package/index.mjs +35 -0
- package/k.mjs +92 -0
- package/package.json +6 -9
- package/parser.jison +24 -4
- package/{parser.js → parser.mjs} +33 -21
- package/pretty.mjs +95 -0
- package/repl.mjs +112 -0
- package/run.mjs +142 -0
- package/symbol-table.mjs +133 -0
- package/test.mjs +143 -0
- package/codes.coffee +0 -81
- package/codes.js +0 -134
- package/index.coffee +0 -28
- package/index.js +0 -49
- package/k.coffee +0 -59
- package/k.js +0 -93
- package/k.sh +0 -94
- package/pretty.coffee +0 -74
- package/pretty.js +0 -106
- package/repl.coffee +0 -62
- package/repl.js +0 -101
- package/repl.sh +0 -102
- package/run.coffee +0 -117
- package/run.js +0 -229
- package/symbol-table.coffee +0 -90
- package/symbol-table.js +0 -165
- package/test.coffee +0 -68
- package/test.js +0 -161
package/run.mjs
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
const modulo = (a, b) => ((+a % (b = +b)) + b) % b;
|
|
2
|
+
const valid = (x) => (isNaN(x) ? undefined : x);
|
|
3
|
+
|
|
4
|
+
const builtin = {
|
|
5
|
+
"_log!": (arg) => {
|
|
6
|
+
console.error(`_log!: ${JSON.stringify(arg)}`);
|
|
7
|
+
return arg;
|
|
8
|
+
},
|
|
9
|
+
GT: (args) => {
|
|
10
|
+
const [last, ...rest] = args;
|
|
11
|
+
const [ok, _] = rest.reduce(
|
|
12
|
+
([ok, last], x) => [ok && last > x, x],
|
|
13
|
+
[true, last]
|
|
14
|
+
);
|
|
15
|
+
if (ok) return args;
|
|
16
|
+
},
|
|
17
|
+
EQ: (args) => {
|
|
18
|
+
const [first, ...rest] = args;
|
|
19
|
+
const ok = rest.reduce((ok, x) => ok && first === x, true);
|
|
20
|
+
if (ok) return args;
|
|
21
|
+
},
|
|
22
|
+
PLUS: (args) => valid(args.reduce((res, x) => res + x, 0)),
|
|
23
|
+
TIMES: (args) => valid(args.reduce((res, x) => res * x, 1)),
|
|
24
|
+
DIV: ([x, y]) => {
|
|
25
|
+
const div = Math.floor(x / y);
|
|
26
|
+
const rem = modulo(x, y);
|
|
27
|
+
if (x === div * y + rem) return { div, rem };
|
|
28
|
+
},
|
|
29
|
+
FDIV: ([x, y]) => x / y,
|
|
30
|
+
CONCAT: (strs) => strs.join(""),
|
|
31
|
+
true: () => true,
|
|
32
|
+
false: () => false,
|
|
33
|
+
null: () => null,
|
|
34
|
+
toJSON: (x) => JSON.stringify(x),
|
|
35
|
+
fromJSON: (x) => JSON.parse(x),
|
|
36
|
+
CONS: ([x, y]) => [x, ...y],
|
|
37
|
+
SNOC: (x) => (x.length > 1 ? [x[0], x.slice(1)] : undefined),
|
|
38
|
+
toDateMsec: (x) => new Date(x).getTime(),
|
|
39
|
+
toDateStr: (x) => new Date(x).toISOString(),
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const codes = {
|
|
43
|
+
int: (x) => Number.isInteger(x),
|
|
44
|
+
string: (x) => x instanceof String || "string" === typeof x,
|
|
45
|
+
bool: (x) => x === true || x === false,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
function verify(code, value) {
|
|
49
|
+
if (code == null) {
|
|
50
|
+
// representatives = run.defs.representatives
|
|
51
|
+
// defCodes = JSON.stringify run.defs.codes
|
|
52
|
+
// console.log {code,value, representatives, defCodes}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
switch (code.code) {
|
|
56
|
+
case "vector":
|
|
57
|
+
if (!Array.isArray(value)) return false;
|
|
58
|
+
return value.every((x) => verify(code.vector, x));
|
|
59
|
+
case "product":
|
|
60
|
+
if ("object" !== typeof value) return false;
|
|
61
|
+
else {
|
|
62
|
+
const fields = Object.keys(value);
|
|
63
|
+
if (fields.length !== Object.keys(code.product).length) return false;
|
|
64
|
+
return fields.every((label) =>
|
|
65
|
+
verify(code.product[label], value[label])
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
case "union":
|
|
69
|
+
if ("object" !== typeof value) return false;
|
|
70
|
+
else {
|
|
71
|
+
const fields = Object.keys(value);
|
|
72
|
+
if (fields.length !== 1) return false;
|
|
73
|
+
return verify(code.union[fields[0]], value[fields[0]]);
|
|
74
|
+
}
|
|
75
|
+
default: {
|
|
76
|
+
const c = run.defs.codes[run.defs.representatives[code]];
|
|
77
|
+
if (c != null) return verify(c, value);
|
|
78
|
+
return codes[code](value);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function run(exp, value) {
|
|
84
|
+
"use strict";
|
|
85
|
+
if (value === undefined) return;
|
|
86
|
+
switch (exp.op) {
|
|
87
|
+
case "code":
|
|
88
|
+
if (verify(exp.code, value)) {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
92
|
+
case "identity":
|
|
93
|
+
return value;
|
|
94
|
+
case "str":
|
|
95
|
+
case "int":
|
|
96
|
+
return exp[exp.op];
|
|
97
|
+
case "ref":
|
|
98
|
+
const defn = run.defs.rels[exp.ref];
|
|
99
|
+
if (defn != null) {
|
|
100
|
+
return run(defn[defn.length - 1], value);
|
|
101
|
+
}
|
|
102
|
+
return builtin[exp.ref](value);
|
|
103
|
+
case "dot":
|
|
104
|
+
return value[exp.dot];
|
|
105
|
+
case "comp":
|
|
106
|
+
return exp.comp.reduce((value, exp) => {
|
|
107
|
+
if (value !== undefined) return run(exp, value);
|
|
108
|
+
}, value);
|
|
109
|
+
case "union":
|
|
110
|
+
for (let i = 0, len = exp.union.length; i < len; i++) {
|
|
111
|
+
const result = run(exp.union[i], value);
|
|
112
|
+
if (result !== undefined) {
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
117
|
+
case "vector": {
|
|
118
|
+
const result = [];
|
|
119
|
+
for (let i = 0, len = exp.vector.length; i < len; i++) {
|
|
120
|
+
const r = run(exp.vector[i], value);
|
|
121
|
+
if (r === undefined) return;
|
|
122
|
+
result.push(r);
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
case "product": {
|
|
127
|
+
const result = {};
|
|
128
|
+
for (let i = 0, len = exp.product.length; i < len; i++) {
|
|
129
|
+
const { label, exp: e } = exp.product[i];
|
|
130
|
+
const r = run(e, value);
|
|
131
|
+
if (r === undefined) return;
|
|
132
|
+
result[label] = r;
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
default:
|
|
137
|
+
return console.error(exp.op);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export default run;
|
|
142
|
+
export { run };
|
package/symbol-table.mjs
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
const rels = {};
|
|
2
|
+
const codes = {
|
|
3
|
+
"{}": {
|
|
4
|
+
code: "product",
|
|
5
|
+
product: {},
|
|
6
|
+
},
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const identity = {
|
|
10
|
+
op: "identity",
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
function is_identity_rel(rel) {
|
|
14
|
+
return rel.op === "identity";
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function is_constant_rel(rel) {
|
|
18
|
+
switch (rel.op) {
|
|
19
|
+
case "int":
|
|
20
|
+
case "str":
|
|
21
|
+
return true;
|
|
22
|
+
case "vector":
|
|
23
|
+
return Object.values(rel[rel.op]).every(is_constant_rel);
|
|
24
|
+
case "product":
|
|
25
|
+
return Object.values(rel[rel.op]).every(({ exp }) =>
|
|
26
|
+
is_constant_rel(exp)
|
|
27
|
+
);
|
|
28
|
+
default:
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function is_empty_rel(rel) {
|
|
34
|
+
return rel.op === "union" && rel.union.length === 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function is_full_rel(rel) {
|
|
38
|
+
if (is_constant_rel(rel)) return true;
|
|
39
|
+
switch (rel.op) {
|
|
40
|
+
case "int":
|
|
41
|
+
case "str":
|
|
42
|
+
case "identity":
|
|
43
|
+
return true;
|
|
44
|
+
case "comp":
|
|
45
|
+
return rel.comp.every(is_full_rel);
|
|
46
|
+
case "vector":
|
|
47
|
+
return Object.values(rel[rel.op]).every(is_full_rel);
|
|
48
|
+
case "product":
|
|
49
|
+
return Object.values(rel[rel.op]).every(({ exp }) => is_full_rel(exp));
|
|
50
|
+
default:
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function comp_first(e1, e2) {
|
|
56
|
+
if (is_identity_rel(e1)) return e2;
|
|
57
|
+
if (is_identity_rel(e2)) return e1;
|
|
58
|
+
if (is_empty_rel(e1)) return e1;
|
|
59
|
+
if (is_empty_rel(e2)) return e2;
|
|
60
|
+
if (e1.op === "comp" && e2.op === "comp")
|
|
61
|
+
return {
|
|
62
|
+
op: "comp",
|
|
63
|
+
comp: [].concat(e1.comp, e2.comp),
|
|
64
|
+
};
|
|
65
|
+
if (e1.op === "comp")
|
|
66
|
+
return {
|
|
67
|
+
op: "comp",
|
|
68
|
+
comp: [].concat(e1.comp, [e2]),
|
|
69
|
+
};
|
|
70
|
+
if (e2.op === "comp")
|
|
71
|
+
return {
|
|
72
|
+
op: "comp",
|
|
73
|
+
comp: [].concat([e1], e2.comp),
|
|
74
|
+
};
|
|
75
|
+
return {
|
|
76
|
+
op: "comp",
|
|
77
|
+
comp: [e1, e2],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function comp (e1, e2) {
|
|
82
|
+
const result = comp_first(e1, e2);
|
|
83
|
+
if (result.op !== "comp") return result;
|
|
84
|
+
result.comp = result.comp.reduceRight(
|
|
85
|
+
(c, e) => (c[0] && is_constant_rel(c[0]) && is_full_rel(e) ? c : [e, ...c]),
|
|
86
|
+
[]
|
|
87
|
+
);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function union (rels) {
|
|
92
|
+
const list = [];
|
|
93
|
+
label: for (const rel of rels) {
|
|
94
|
+
const new_rels = rel.op === "union" ? rel.union : [rel];
|
|
95
|
+
for (const new_rel of new_rels) {
|
|
96
|
+
list.push(new_rel);
|
|
97
|
+
if (is_full_rel(new_rel)) break label;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (list.length === 1) return list[0];
|
|
101
|
+
return {
|
|
102
|
+
op: "union",
|
|
103
|
+
union: list,
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
function as_ref (codeExp) {
|
|
108
|
+
if (codeExp.code === "ref") return codeExp.ref;
|
|
109
|
+
const newName = `:${Object.keys(codes).length}`;
|
|
110
|
+
codes[newName] = codeExp;
|
|
111
|
+
return newName;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
function add_rel (name, rel) {
|
|
115
|
+
if (rels[name] == null) rels[name] = [];
|
|
116
|
+
rels[name].push(rel);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
function add_code (name, code) {
|
|
120
|
+
codes[name] = code;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export default {
|
|
124
|
+
identity,
|
|
125
|
+
comp,
|
|
126
|
+
union,
|
|
127
|
+
rels,
|
|
128
|
+
codes,
|
|
129
|
+
add_rel,
|
|
130
|
+
add_code,
|
|
131
|
+
as_ref,
|
|
132
|
+
};
|
|
133
|
+
export { identity, comp, union, rels, codes, add_rel, add_code, as_ref };
|
package/test.mjs
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import k from "./index.mjs";
|
|
2
|
+
|
|
3
|
+
[
|
|
4
|
+
["ANYTHING...", "()"],
|
|
5
|
+
["ANYTHING...", '{"ala" name, 23 age}'],
|
|
6
|
+
[
|
|
7
|
+
{
|
|
8
|
+
year: 2002,
|
|
9
|
+
age: 19,
|
|
10
|
+
},
|
|
11
|
+
"[.year, .age]",
|
|
12
|
+
],
|
|
13
|
+
["duplicate me", "[(), ()]"],
|
|
14
|
+
["nesting", "[[[()]]]"],
|
|
15
|
+
["nesting and accessing", "[[()]] {() nested, .0.0 val}"],
|
|
16
|
+
[
|
|
17
|
+
{
|
|
18
|
+
test: "parse integer",
|
|
19
|
+
},
|
|
20
|
+
"0000",
|
|
21
|
+
],
|
|
22
|
+
[
|
|
23
|
+
{
|
|
24
|
+
x: 3,
|
|
25
|
+
y: 4,
|
|
26
|
+
},
|
|
27
|
+
"[.y,.x] PLUS",
|
|
28
|
+
],
|
|
29
|
+
].map(function ([data, script]) {
|
|
30
|
+
console.log(`k_expression = '${script}';`);
|
|
31
|
+
console.log(`k.run(k_expression,${JSON.stringify(data)});`);
|
|
32
|
+
console.log(`// RETURNS: ${JSON.stringify(k.run(script, data))}`);
|
|
33
|
+
return console.log("");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
let k_expression =
|
|
37
|
+
'{.name nom, <[.age, 18] GT .0, [.age, 12] GT "ado", "enfant"> age}';
|
|
38
|
+
|
|
39
|
+
let k_fn = k.compile(k_expression);
|
|
40
|
+
|
|
41
|
+
console.log(`var k_fn = k.compile('${k_expression}');`);
|
|
42
|
+
|
|
43
|
+
console.log("");
|
|
44
|
+
|
|
45
|
+
[
|
|
46
|
+
{
|
|
47
|
+
age: 23,
|
|
48
|
+
name: "Emily",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
age: 16,
|
|
52
|
+
name: "Katrina",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
age: 2,
|
|
56
|
+
name: "Mark",
|
|
57
|
+
},
|
|
58
|
+
].map(function (data) {
|
|
59
|
+
console.log(`k_fn(${JSON.stringify(data)});`);
|
|
60
|
+
console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
|
|
61
|
+
return console.log("");
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
k_expression = "$t = < i: int, t: [ t ] > ; <$t, $int>";
|
|
65
|
+
|
|
66
|
+
k_fn = k.compile(k_expression);
|
|
67
|
+
|
|
68
|
+
console.log(`var k_fn = k.compile('${k_expression}');`);
|
|
69
|
+
|
|
70
|
+
console.log("");
|
|
71
|
+
|
|
72
|
+
[
|
|
73
|
+
1,
|
|
74
|
+
{
|
|
75
|
+
i: 1,
|
|
76
|
+
},
|
|
77
|
+
[
|
|
78
|
+
{
|
|
79
|
+
i: 2,
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
i: 3,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
t: [],
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
{
|
|
89
|
+
t: [
|
|
90
|
+
{
|
|
91
|
+
i: 2,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
i: 3,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
t: [],
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
].map(function (data) {
|
|
102
|
+
console.log(`k_fn(${JSON.stringify(data)});`);
|
|
103
|
+
console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
|
|
104
|
+
return console.log("");
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
k_expression = "$ < < [ int ] ints, [ bool ] bools > list, string None>";
|
|
108
|
+
|
|
109
|
+
k_fn = k.compile(k_expression);
|
|
110
|
+
|
|
111
|
+
console.log(`var k_fn = k.compile('${k_expression}');`);
|
|
112
|
+
|
|
113
|
+
console.log("");
|
|
114
|
+
|
|
115
|
+
[
|
|
116
|
+
{
|
|
117
|
+
None: "None",
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
list: {
|
|
121
|
+
ints: [],
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
list: {
|
|
126
|
+
ints: [1, 2, 3],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
list: {
|
|
131
|
+
bools: [true, false],
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
list: {
|
|
136
|
+
bools: [true, 0],
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
].map(function (data) {
|
|
140
|
+
console.log(`k_fn(${JSON.stringify(data)});`);
|
|
141
|
+
console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
|
|
142
|
+
return console.log("");
|
|
143
|
+
});
|
package/codes.coffee
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
are_different = (classes, representatives, name1, name2, codes) ->
|
|
3
|
-
# console.log {classes, representatives, name1, name2, codes}
|
|
4
|
-
return false if name1 is name2
|
|
5
|
-
code1 = codes[name1]
|
|
6
|
-
code2 = codes[name2]
|
|
7
|
-
# console.log {name1, code1, name2, code2}
|
|
8
|
-
return true unless code1.code is code2.code
|
|
9
|
-
switch code1.code
|
|
10
|
-
when "union", "product"
|
|
11
|
-
[fields1,fields2] = [code1, code2]. map (code) ->
|
|
12
|
-
do (arg = code[code.code]) ->
|
|
13
|
-
Object.keys(arg).reduce (fields, label) ->
|
|
14
|
-
fields[label] = representatives[arg[label]] ? arg[label]
|
|
15
|
-
fields
|
|
16
|
-
, {}
|
|
17
|
-
return true unless Object.keys(fields1).length is Object.keys(fields2).length
|
|
18
|
-
for field,rep of fields1
|
|
19
|
-
# console.log {field,rep1:rep,rep2:fields2[field]}
|
|
20
|
-
return true unless fields2[field] is rep
|
|
21
|
-
when "vector"
|
|
22
|
-
[arg1,arg2] = [code1, code2]. map ({vector}) ->
|
|
23
|
-
representatives[vector] ? vector
|
|
24
|
-
return true unless arg1 is arg2
|
|
25
|
-
false
|
|
26
|
-
|
|
27
|
-
minimize = (codes) ->
|
|
28
|
-
names = Object.keys codes
|
|
29
|
-
classes = {}
|
|
30
|
-
classes["{}"] = names
|
|
31
|
-
representatives = names.reduce (representatives, name) ->
|
|
32
|
-
representatives[name] = "{}"
|
|
33
|
-
representatives
|
|
34
|
-
, {}
|
|
35
|
-
changed = true
|
|
36
|
-
while changed
|
|
37
|
-
changed = false
|
|
38
|
-
for name1, eq_names of classes
|
|
39
|
-
code = codes[name1]
|
|
40
|
-
[eq_names, dif_names] = eq_names.reduce ([eq_names, dif_names], name2) ->
|
|
41
|
-
if are_different(classes, representatives, name1, name2, codes)
|
|
42
|
-
dif_names.push name2
|
|
43
|
-
else
|
|
44
|
-
eq_names.push name2
|
|
45
|
-
[eq_names,dif_names]
|
|
46
|
-
, [[],[]]
|
|
47
|
-
classes[name1] = eq_names
|
|
48
|
-
do (new_rep = dif_names[0]) ->
|
|
49
|
-
if new_rep?
|
|
50
|
-
changed = true
|
|
51
|
-
classes[new_rep] = dif_names
|
|
52
|
-
for x in dif_names
|
|
53
|
-
representatives[x] = new_rep
|
|
54
|
-
{classes,representatives}
|
|
55
|
-
|
|
56
|
-
normalize = (label_ref_map, representatives) ->
|
|
57
|
-
# console.log {label_ref_map, representatives}
|
|
58
|
-
Object.keys(label_ref_map).reduce (result, label) ->
|
|
59
|
-
result[label] = do (name = label_ref_map[label]) ->
|
|
60
|
-
representatives[name] ? name
|
|
61
|
-
result
|
|
62
|
-
, {}
|
|
63
|
-
|
|
64
|
-
normalizeAll = (codes,representatives) ->
|
|
65
|
-
names = Object.keys codes
|
|
66
|
-
normalized = names.reduce (normalized, name) ->
|
|
67
|
-
if name is representatives[name]
|
|
68
|
-
do (code = codes[name]) ->
|
|
69
|
-
switch code.code
|
|
70
|
-
when "union", "product"
|
|
71
|
-
normalized[name] = { code: code.code }
|
|
72
|
-
normalized[name][code.code] = normalize code[code.code], representatives
|
|
73
|
-
when "vector"
|
|
74
|
-
normalized[name] = {code:"vector", vector: representatives[code.vector] ? code.vector}
|
|
75
|
-
|
|
76
|
-
normalized
|
|
77
|
-
, {}
|
|
78
|
-
|
|
79
|
-
module.exports = {minimize,normalize,normalizeAll}
|
|
80
|
-
|
|
81
|
-
|
package/codes.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
(function() {
|
|
3
|
-
var are_different, minimize, normalize, normalizeAll;
|
|
4
|
-
|
|
5
|
-
are_different = function(classes, representatives, name1, name2, codes) {
|
|
6
|
-
var arg1, arg2, code1, code2, field, fields1, fields2, rep;
|
|
7
|
-
if (name1 === name2) {
|
|
8
|
-
// console.log {classes, representatives, name1, name2, codes}
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
code1 = codes[name1];
|
|
12
|
-
code2 = codes[name2];
|
|
13
|
-
if (code1.code !== code2.code) {
|
|
14
|
-
// console.log {name1, code1, name2, code2}
|
|
15
|
-
return true;
|
|
16
|
-
}
|
|
17
|
-
switch (code1.code) {
|
|
18
|
-
case "union":
|
|
19
|
-
case "product":
|
|
20
|
-
[fields1, fields2] = [code1, code2].map(function(code) {
|
|
21
|
-
return (function(arg) {
|
|
22
|
-
return Object.keys(arg).reduce(function(fields, label) {
|
|
23
|
-
var ref;
|
|
24
|
-
fields[label] = (ref = representatives[arg[label]]) != null ? ref : arg[label];
|
|
25
|
-
return fields;
|
|
26
|
-
}, {});
|
|
27
|
-
})(code[code.code]);
|
|
28
|
-
});
|
|
29
|
-
if (Object.keys(fields1).length !== Object.keys(fields2).length) {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
for (field in fields1) {
|
|
33
|
-
rep = fields1[field];
|
|
34
|
-
if (fields2[field] !== rep) {
|
|
35
|
-
|
|
36
|
-
// console.log {field,rep1:rep,rep2:fields2[field]}
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
break;
|
|
41
|
-
case "vector":
|
|
42
|
-
[arg1, arg2] = [code1, code2].map(function({vector}) {
|
|
43
|
-
var ref;
|
|
44
|
-
return (ref = representatives[vector]) != null ? ref : vector;
|
|
45
|
-
});
|
|
46
|
-
if (arg1 !== arg2) {
|
|
47
|
-
return true;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return false;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
minimize = function(codes) {
|
|
54
|
-
var changed, classes, code, dif_names, eq_names, name1, names, representatives;
|
|
55
|
-
names = Object.keys(codes);
|
|
56
|
-
classes = {};
|
|
57
|
-
classes["{}"] = names;
|
|
58
|
-
representatives = names.reduce(function(representatives, name) {
|
|
59
|
-
representatives[name] = "{}";
|
|
60
|
-
return representatives;
|
|
61
|
-
}, {});
|
|
62
|
-
changed = true;
|
|
63
|
-
while (changed) {
|
|
64
|
-
changed = false;
|
|
65
|
-
for (name1 in classes) {
|
|
66
|
-
eq_names = classes[name1];
|
|
67
|
-
code = codes[name1];
|
|
68
|
-
[eq_names, dif_names] = eq_names.reduce(function([eq_names, dif_names], name2) {
|
|
69
|
-
if (are_different(classes, representatives, name1, name2, codes)) {
|
|
70
|
-
dif_names.push(name2);
|
|
71
|
-
} else {
|
|
72
|
-
eq_names.push(name2);
|
|
73
|
-
}
|
|
74
|
-
return [eq_names, dif_names];
|
|
75
|
-
}, [[], []]);
|
|
76
|
-
classes[name1] = eq_names;
|
|
77
|
-
(function(new_rep) {
|
|
78
|
-
var i, len, results, x;
|
|
79
|
-
if (new_rep != null) {
|
|
80
|
-
changed = true;
|
|
81
|
-
classes[new_rep] = dif_names;
|
|
82
|
-
results = [];
|
|
83
|
-
for (i = 0, len = dif_names.length; i < len; i++) {
|
|
84
|
-
x = dif_names[i];
|
|
85
|
-
results.push(representatives[x] = new_rep);
|
|
86
|
-
}
|
|
87
|
-
return results;
|
|
88
|
-
}
|
|
89
|
-
})(dif_names[0]);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return {classes, representatives};
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
normalize = function(label_ref_map, representatives) {
|
|
96
|
-
// console.log {label_ref_map, representatives}
|
|
97
|
-
return Object.keys(label_ref_map).reduce(function(result, label) {
|
|
98
|
-
result[label] = (function(name) {
|
|
99
|
-
var ref;
|
|
100
|
-
return (ref = representatives[name]) != null ? ref : name;
|
|
101
|
-
})(label_ref_map[label]);
|
|
102
|
-
return result;
|
|
103
|
-
}, {});
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
normalizeAll = function(codes, representatives) {
|
|
107
|
-
var names, normalized;
|
|
108
|
-
names = Object.keys(codes);
|
|
109
|
-
return normalized = names.reduce(function(normalized, name) {
|
|
110
|
-
if (name === representatives[name]) {
|
|
111
|
-
(function(code) {
|
|
112
|
-
var ref;
|
|
113
|
-
switch (code.code) {
|
|
114
|
-
case "union":
|
|
115
|
-
case "product":
|
|
116
|
-
normalized[name] = {
|
|
117
|
-
code: code.code
|
|
118
|
-
};
|
|
119
|
-
return normalized[name][code.code] = normalize(code[code.code], representatives);
|
|
120
|
-
case "vector":
|
|
121
|
-
return normalized[name] = {
|
|
122
|
-
code: "vector",
|
|
123
|
-
vector: (ref = representatives[code.vector]) != null ? ref : code.vector
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
})(codes[name]);
|
|
127
|
-
}
|
|
128
|
-
return normalized;
|
|
129
|
-
}, {});
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
module.exports = {minimize, normalize, normalizeAll};
|
|
133
|
-
|
|
134
|
-
}).call(this);
|
package/index.coffee
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{parse} = require "./parser.js"
|
|
2
|
-
run = require "./run"
|
|
3
|
-
t = require "./codes"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
finalize = (codes) ->
|
|
7
|
-
representatives = t.minimize(codes).representatives
|
|
8
|
-
codes = t.normalizeAll codes, representatives
|
|
9
|
-
|
|
10
|
-
{codes, representatives}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
compile = (script) ->
|
|
14
|
-
do ({defs,exp} = parse script) ->
|
|
15
|
-
# console.log defs
|
|
16
|
-
{codes, representatives} = finalize defs.codes
|
|
17
|
-
# console.log {codes, representatives}
|
|
18
|
-
run.defs = {codes, representatives, rels: defs.rels}
|
|
19
|
-
|
|
20
|
-
(data) -> run exp, data
|
|
21
|
-
|
|
22
|
-
compile.doc = "Transforms k-script (string) into a function"
|
|
23
|
-
|
|
24
|
-
runScriptOnData = (script, data) ->
|
|
25
|
-
compile(script) data
|
|
26
|
-
runScriptOnData.doc = "Run 'script' (string) on 'data': (script,data) -> data"
|
|
27
|
-
|
|
28
|
-
module.exports = {compile, run: runScriptOnData, parse}
|
package/index.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
(function() {
|
|
3
|
-
var compile, finalize, parse, run, runScriptOnData, t;
|
|
4
|
-
|
|
5
|
-
({parse} = require("./parser.js"));
|
|
6
|
-
|
|
7
|
-
run = require("./run");
|
|
8
|
-
|
|
9
|
-
t = require("./codes");
|
|
10
|
-
|
|
11
|
-
finalize = function(codes) {
|
|
12
|
-
var representatives;
|
|
13
|
-
representatives = t.minimize(codes).representatives;
|
|
14
|
-
codes = t.normalizeAll(codes, representatives);
|
|
15
|
-
return {codes, representatives};
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
compile = function(script) {
|
|
19
|
-
return (function({defs, exp}) {
|
|
20
|
-
var codes, representatives;
|
|
21
|
-
// console.log defs
|
|
22
|
-
({codes, representatives} = finalize(defs.codes));
|
|
23
|
-
// console.log {codes, representatives}
|
|
24
|
-
run.defs = {
|
|
25
|
-
codes,
|
|
26
|
-
representatives,
|
|
27
|
-
rels: defs.rels
|
|
28
|
-
};
|
|
29
|
-
return function(data) {
|
|
30
|
-
return run(exp, data);
|
|
31
|
-
};
|
|
32
|
-
})(parse(script));
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
compile.doc = "Transforms k-script (string) into a function";
|
|
36
|
-
|
|
37
|
-
runScriptOnData = function(script, data) {
|
|
38
|
-
return compile(script)(data);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
runScriptOnData.doc = "Run 'script' (string) on 'data': (script,data) -> data";
|
|
42
|
-
|
|
43
|
-
module.exports = {
|
|
44
|
-
compile,
|
|
45
|
-
run: runScriptOnData,
|
|
46
|
-
parse
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
}).call(this);
|