@fraczak/k 1.0.1 → 1.1.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/README.md +54 -14
- package/bnat.k +121 -0
- package/code.k +18 -0
- package/codes.coffee +107 -0
- package/codes.js +167 -0
- package/factorial.k +11 -0
- package/fib.k +15 -0
- package/index.coffee +16 -1
- package/index.js +20 -2
- package/k.coffee +34 -20
- package/k.js +51 -30
- package/k.sh +51 -30
- package/package.json +4 -3
- package/parser.jison +54 -8
- package/parser.js +99 -46
- package/pow.k +7 -0
- package/run.coffee +46 -4
- package/run.js +81 -10
- package/symbol-table.coffee +53 -3
- package/symbol-table.js +90 -4
- package/test.coffee +16 -0
- package/test.js +43 -0
- package/{test.t → test.k} +1 -1
package/run.coffee
CHANGED
|
@@ -2,7 +2,10 @@ valid = (x) ->
|
|
|
2
2
|
return undefined if isNaN x
|
|
3
3
|
return x if x?
|
|
4
4
|
|
|
5
|
-
builtin =
|
|
5
|
+
builtin =
|
|
6
|
+
"_log!": (arg) ->
|
|
7
|
+
console.log "_log!: #{JSON.stringify arg}"
|
|
8
|
+
arg
|
|
6
9
|
"GT": (args) ->
|
|
7
10
|
[ok,_] = do ([last,args...] = args) ->
|
|
8
11
|
args.reduce ([ok,last], x) ->
|
|
@@ -32,20 +35,57 @@ builtin =
|
|
|
32
35
|
"null": -> null
|
|
33
36
|
"toJSON": (x) -> JSON.stringify x
|
|
34
37
|
"fromJSON": (x) -> JSON.parse x
|
|
38
|
+
"CONS": ([x,y]) -> [x,y...]
|
|
39
|
+
"SNOC": (x) ->
|
|
40
|
+
return [x[0],x.slice 1] if x.length > 1
|
|
35
41
|
|
|
42
|
+
codes =
|
|
43
|
+
"int": (x) ->
|
|
44
|
+
Number.isInteger x
|
|
45
|
+
"string": (x) ->
|
|
46
|
+
(x instanceof String) or ('string' is typeof x)
|
|
47
|
+
"bool": (x) ->
|
|
48
|
+
x is true or x is false
|
|
49
|
+
|
|
50
|
+
verify = (code, value) ->
|
|
51
|
+
# console.log {code,value}
|
|
52
|
+
switch code.code
|
|
53
|
+
when "vector"
|
|
54
|
+
value.every (x) ->
|
|
55
|
+
verify code.vector, x
|
|
56
|
+
when "product"
|
|
57
|
+
do (fields = Object.keys(value)) ->
|
|
58
|
+
return false unless fields.length is Object.keys(code.product).length
|
|
59
|
+
fields.every (label) ->
|
|
60
|
+
verify code.product[label], value[label]
|
|
61
|
+
when "union"
|
|
62
|
+
do (fields = Object.keys(value)) ->
|
|
63
|
+
return false unless fields.length is 1
|
|
64
|
+
verify code.union[fields[0]], value[fields[0]]
|
|
65
|
+
else
|
|
66
|
+
do (c = run.defs.codes[run.defs.representatives[code]]) ->
|
|
67
|
+
return verify c, value if c?
|
|
68
|
+
codes[code] value
|
|
36
69
|
|
|
37
70
|
run = (exp, value) ->
|
|
71
|
+
# console.log {exp,value}
|
|
38
72
|
return undefined if value is undefined
|
|
39
73
|
try
|
|
40
74
|
switch exp.op
|
|
75
|
+
when "code"
|
|
76
|
+
return value if verify exp.code, value
|
|
41
77
|
when "identity"
|
|
42
78
|
return value
|
|
43
79
|
when "str", "int"
|
|
44
80
|
return exp[exp.op]
|
|
45
81
|
when "ref"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
82
|
+
do (defn = run.defs.rels[exp.ref]?[0]) ->
|
|
83
|
+
if defn?
|
|
84
|
+
run defn, value
|
|
85
|
+
else
|
|
86
|
+
do ( value = builtin[exp.ref] value ) ->
|
|
87
|
+
throw new Error "Undefined" if value is undefined
|
|
88
|
+
value
|
|
49
89
|
when "dot"
|
|
50
90
|
return value[exp.dot]
|
|
51
91
|
when "comp"
|
|
@@ -71,6 +111,8 @@ run = (exp, value) ->
|
|
|
71
111
|
result[label] = value
|
|
72
112
|
result
|
|
73
113
|
, {}
|
|
114
|
+
else
|
|
115
|
+
console.log exp.op
|
|
74
116
|
|
|
75
117
|
|
|
76
118
|
module.exports = run
|
package/run.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
|
2
2
|
(function() {
|
|
3
|
-
var builtin, run, valid,
|
|
3
|
+
var builtin, codes, run, valid, verify,
|
|
4
4
|
modulo = function(a, b) { return (+a % (b = +b) + b) % b; };
|
|
5
5
|
|
|
6
6
|
valid = function(x) {
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
builtin = {
|
|
16
|
+
"_log!": function(arg) {
|
|
17
|
+
console.log(`_log!: ${JSON.stringify(arg)}`);
|
|
18
|
+
return arg;
|
|
19
|
+
},
|
|
16
20
|
"GT": function(args) {
|
|
17
21
|
var _, ok;
|
|
18
22
|
[ok, _] = (function([last, ...args]) {
|
|
@@ -83,28 +87,93 @@
|
|
|
83
87
|
},
|
|
84
88
|
"fromJSON": function(x) {
|
|
85
89
|
return JSON.parse(x);
|
|
90
|
+
},
|
|
91
|
+
"CONS": function([x, y]) {
|
|
92
|
+
return [x, ...y];
|
|
93
|
+
},
|
|
94
|
+
"SNOC": function(x) {
|
|
95
|
+
if (x.length > 1) {
|
|
96
|
+
return [x[0], x.slice(1)];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
codes = {
|
|
102
|
+
"int": function(x) {
|
|
103
|
+
return Number.isInteger(x);
|
|
104
|
+
},
|
|
105
|
+
"string": function(x) {
|
|
106
|
+
return (x instanceof String) || ('string' === typeof x);
|
|
107
|
+
},
|
|
108
|
+
"bool": function(x) {
|
|
109
|
+
return x === true || x === false;
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
verify = function(code, value) {
|
|
114
|
+
// console.log {code,value}
|
|
115
|
+
switch (code.code) {
|
|
116
|
+
case "vector":
|
|
117
|
+
return value.every(function(x) {
|
|
118
|
+
return verify(code.vector, x);
|
|
119
|
+
});
|
|
120
|
+
case "product":
|
|
121
|
+
return (function(fields) {
|
|
122
|
+
if (fields.length !== Object.keys(code.product).length) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
return fields.every(function(label) {
|
|
126
|
+
return verify(code.product[label], value[label]);
|
|
127
|
+
});
|
|
128
|
+
})(Object.keys(value));
|
|
129
|
+
case "union":
|
|
130
|
+
return (function(fields) {
|
|
131
|
+
if (fields.length !== 1) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return verify(code.union[fields[0]], value[fields[0]]);
|
|
135
|
+
})(Object.keys(value));
|
|
136
|
+
default:
|
|
137
|
+
return (function(c) {
|
|
138
|
+
if (c != null) {
|
|
139
|
+
return verify(c, value);
|
|
140
|
+
}
|
|
141
|
+
return codes[code](value);
|
|
142
|
+
})(run.defs.codes[run.defs.representatives[code]]);
|
|
86
143
|
}
|
|
87
144
|
};
|
|
88
145
|
|
|
89
146
|
run = function(exp, value) {
|
|
90
|
-
var e, i, len, ref, result;
|
|
147
|
+
var e, i, len, ref, ref1, result;
|
|
91
148
|
if (value === void 0) {
|
|
149
|
+
// console.log {exp,value}
|
|
92
150
|
return void 0;
|
|
93
151
|
}
|
|
94
152
|
try {
|
|
95
153
|
switch (exp.op) {
|
|
154
|
+
case "code":
|
|
155
|
+
if (verify(exp.code, value)) {
|
|
156
|
+
return value;
|
|
157
|
+
}
|
|
158
|
+
break;
|
|
96
159
|
case "identity":
|
|
97
160
|
return value;
|
|
98
161
|
case "str":
|
|
99
162
|
case "int":
|
|
100
163
|
return exp[exp.op];
|
|
101
164
|
case "ref":
|
|
102
|
-
return (function(
|
|
103
|
-
if (
|
|
104
|
-
|
|
165
|
+
return (function(defn) {
|
|
166
|
+
if (defn != null) {
|
|
167
|
+
return run(defn, value);
|
|
168
|
+
} else {
|
|
169
|
+
return (function(value) {
|
|
170
|
+
if (value === void 0) {
|
|
171
|
+
throw new Error("Undefined");
|
|
172
|
+
}
|
|
173
|
+
return value;
|
|
174
|
+
})(builtin[exp.ref](value));
|
|
105
175
|
}
|
|
106
|
-
|
|
107
|
-
})(builtin[exp.ref](value));
|
|
176
|
+
})((ref = run.defs.rels[exp.ref]) != null ? ref[0] : void 0);
|
|
108
177
|
case "dot":
|
|
109
178
|
return value[exp.dot];
|
|
110
179
|
case "comp":
|
|
@@ -125,9 +194,9 @@
|
|
|
125
194
|
return result;
|
|
126
195
|
});
|
|
127
196
|
case "union":
|
|
128
|
-
|
|
129
|
-
for (i = 0, len =
|
|
130
|
-
e =
|
|
197
|
+
ref1 = exp.union;
|
|
198
|
+
for (i = 0, len = ref1.length; i < len; i++) {
|
|
199
|
+
e = ref1[i];
|
|
131
200
|
result = (function() {
|
|
132
201
|
try {
|
|
133
202
|
return run(e, value);
|
|
@@ -148,6 +217,8 @@
|
|
|
148
217
|
return result;
|
|
149
218
|
})(run(exp, value));
|
|
150
219
|
}, {});
|
|
220
|
+
default:
|
|
221
|
+
return console.log(exp.op);
|
|
151
222
|
}
|
|
152
223
|
} catch (error) {}
|
|
153
224
|
};
|
package/symbol-table.coffee
CHANGED
|
@@ -1,8 +1,31 @@
|
|
|
1
|
+
rels = Object.create null
|
|
2
|
+
codes = Object.create null
|
|
3
|
+
codes["{}"] = {code: "product", product: {}}
|
|
4
|
+
|
|
1
5
|
identity = op: "identity"
|
|
2
6
|
|
|
7
|
+
is_identity_rel = (rel) ->
|
|
8
|
+
rel.op is "identity"
|
|
9
|
+
|
|
10
|
+
is_empty_rel = (rel) ->
|
|
11
|
+
rel.op is "union" and rel.union.length is 0
|
|
12
|
+
|
|
13
|
+
is_full_rel = (rel) ->
|
|
14
|
+
switch rel.op
|
|
15
|
+
when "int", "str", "identity"
|
|
16
|
+
true
|
|
17
|
+
when "comp"
|
|
18
|
+
rel.comp.every is_full_rel
|
|
19
|
+
when "product", "vector"
|
|
20
|
+
Object.values(rel[rel.op]).every is_full_rel
|
|
21
|
+
else
|
|
22
|
+
false
|
|
23
|
+
|
|
3
24
|
comp = (e1, e2) ->
|
|
4
|
-
return e2 if e1
|
|
5
|
-
return e1 if e2
|
|
25
|
+
return e2 if is_identity_rel e1
|
|
26
|
+
return e1 if is_identity_rel e2
|
|
27
|
+
return e1 if is_empty_rel e1
|
|
28
|
+
return e2 if is_empty_rel e2
|
|
6
29
|
if e1.op is "comp" and e2.op is "comp"
|
|
7
30
|
return {op: "comp", comp: [].concat(e1.comp,e2.comp)}
|
|
8
31
|
if e1.op is "comp"
|
|
@@ -11,4 +34,31 @@ comp = (e1, e2) ->
|
|
|
11
34
|
return {op: "comp", comp: [].concat([e1],e2.comp)}
|
|
12
35
|
{op: "comp", comp: [e1,e2]}
|
|
13
36
|
|
|
14
|
-
|
|
37
|
+
union = (rels) ->
|
|
38
|
+
list = []
|
|
39
|
+
do ->
|
|
40
|
+
for rel in rels
|
|
41
|
+
new_rels = if rel.op is "union"
|
|
42
|
+
rel.union
|
|
43
|
+
else
|
|
44
|
+
[rel]
|
|
45
|
+
for rel in new_rels
|
|
46
|
+
list.push rel
|
|
47
|
+
return if is_full_rel rel
|
|
48
|
+
return list[0] if list.length is 1
|
|
49
|
+
{op: "union", union: list}
|
|
50
|
+
|
|
51
|
+
as_ref = (codeExp) ->
|
|
52
|
+
return codeExp.ref if codeExp.code is "ref"
|
|
53
|
+
newName = ":#{Object.keys(codes).length}"
|
|
54
|
+
codes[newName] = codeExp
|
|
55
|
+
return newName
|
|
56
|
+
|
|
57
|
+
add_rel = (name, rel) ->
|
|
58
|
+
rels[name] ?= []
|
|
59
|
+
rels[name].push rel
|
|
60
|
+
|
|
61
|
+
add_code = (name, code) ->
|
|
62
|
+
codes[name] = code
|
|
63
|
+
|
|
64
|
+
module.exports = {identity, comp, union, rels, codes, add_rel, add_code, as_ref};
|
package/symbol-table.js
CHANGED
|
@@ -1,18 +1,57 @@
|
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
|
2
2
|
(function() {
|
|
3
|
-
var comp, identity;
|
|
3
|
+
var add_code, add_rel, as_ref, codes, comp, identity, is_empty_rel, is_full_rel, is_identity_rel, rels, union;
|
|
4
|
+
|
|
5
|
+
rels = Object.create(null);
|
|
6
|
+
|
|
7
|
+
codes = Object.create(null);
|
|
8
|
+
|
|
9
|
+
codes["{}"] = {
|
|
10
|
+
code: "product",
|
|
11
|
+
product: {}
|
|
12
|
+
};
|
|
4
13
|
|
|
5
14
|
identity = {
|
|
6
15
|
op: "identity"
|
|
7
16
|
};
|
|
8
17
|
|
|
18
|
+
is_identity_rel = function(rel) {
|
|
19
|
+
return rel.op === "identity";
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
is_empty_rel = function(rel) {
|
|
23
|
+
return rel.op === "union" && rel.union.length === 0;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
is_full_rel = function(rel) {
|
|
27
|
+
switch (rel.op) {
|
|
28
|
+
case "int":
|
|
29
|
+
case "str":
|
|
30
|
+
case "identity":
|
|
31
|
+
return true;
|
|
32
|
+
case "comp":
|
|
33
|
+
return rel.comp.every(is_full_rel);
|
|
34
|
+
case "product":
|
|
35
|
+
case "vector":
|
|
36
|
+
return Object.values(rel[rel.op]).every(is_full_rel);
|
|
37
|
+
default:
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
9
42
|
comp = function(e1, e2) {
|
|
10
|
-
if (e1
|
|
43
|
+
if (is_identity_rel(e1)) {
|
|
11
44
|
return e2;
|
|
12
45
|
}
|
|
13
|
-
if (e2
|
|
46
|
+
if (is_identity_rel(e2)) {
|
|
14
47
|
return e1;
|
|
15
48
|
}
|
|
49
|
+
if (is_empty_rel(e1)) {
|
|
50
|
+
return e1;
|
|
51
|
+
}
|
|
52
|
+
if (is_empty_rel(e2)) {
|
|
53
|
+
return e2;
|
|
54
|
+
}
|
|
16
55
|
if (e1.op === "comp" && e2.op === "comp") {
|
|
17
56
|
return {
|
|
18
57
|
op: "comp",
|
|
@@ -37,6 +76,53 @@
|
|
|
37
76
|
};
|
|
38
77
|
};
|
|
39
78
|
|
|
40
|
-
|
|
79
|
+
union = function(rels) {
|
|
80
|
+
var list;
|
|
81
|
+
list = [];
|
|
82
|
+
(function() {
|
|
83
|
+
var i, j, len, len1, new_rels, rel;
|
|
84
|
+
for (i = 0, len = rels.length; i < len; i++) {
|
|
85
|
+
rel = rels[i];
|
|
86
|
+
new_rels = rel.op === "union" ? rel.union : [rel];
|
|
87
|
+
for (j = 0, len1 = new_rels.length; j < len1; j++) {
|
|
88
|
+
rel = new_rels[j];
|
|
89
|
+
list.push(rel);
|
|
90
|
+
if (is_full_rel(rel)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
})();
|
|
96
|
+
if (list.length === 1) {
|
|
97
|
+
return list[0];
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
op: "union",
|
|
101
|
+
union: list
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
as_ref = function(codeExp) {
|
|
106
|
+
var newName;
|
|
107
|
+
if (codeExp.code === "ref") {
|
|
108
|
+
return codeExp.ref;
|
|
109
|
+
}
|
|
110
|
+
newName = `:${Object.keys(codes).length}`;
|
|
111
|
+
codes[newName] = codeExp;
|
|
112
|
+
return newName;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
add_rel = function(name, rel) {
|
|
116
|
+
if (rels[name] == null) {
|
|
117
|
+
rels[name] = [];
|
|
118
|
+
}
|
|
119
|
+
return rels[name].push(rel);
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
add_code = function(name, code) {
|
|
123
|
+
return codes[name] = code;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
module.exports = {identity, comp, union, rels, codes, add_rel, add_code, as_ref};
|
|
41
127
|
|
|
42
128
|
}).call(this);
|
package/test.coffee
CHANGED
|
@@ -32,3 +32,19 @@ console.log ""
|
|
|
32
32
|
console.log "k_fn(#{JSON.stringify(data)});"
|
|
33
33
|
console.log "// RETURNS: #{JSON.stringify k_fn data}"
|
|
34
34
|
console.log ""
|
|
35
|
+
|
|
36
|
+
k_expression = "$t = < i: int, t: [ t ] > ; <$t, $int>"
|
|
37
|
+
k_fn = k.compile k_expression
|
|
38
|
+
|
|
39
|
+
console.log "var k_fn = k.compile('#{k_expression}');"
|
|
40
|
+
console.log ""
|
|
41
|
+
|
|
42
|
+
[
|
|
43
|
+
1
|
|
44
|
+
{i:1}
|
|
45
|
+
[{i:2},{i:3},{t:[]}]
|
|
46
|
+
{"t":[{"i":2},{"i":3},{"t":[]}]}
|
|
47
|
+
].map (data) ->
|
|
48
|
+
console.log "k_fn(#{JSON.stringify(data)});"
|
|
49
|
+
console.log "// RETURNS: #{JSON.stringify k_fn data}"
|
|
50
|
+
console.log ""
|
package/test.js
CHANGED
|
@@ -73,4 +73,47 @@
|
|
|
73
73
|
return console.log("");
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
k_expression = "$t = < i: int, t: [ t ] > ; <$t, $int>";
|
|
77
|
+
|
|
78
|
+
k_fn = k.compile(k_expression);
|
|
79
|
+
|
|
80
|
+
console.log(`var k_fn = k.compile('${k_expression}');`);
|
|
81
|
+
|
|
82
|
+
console.log("");
|
|
83
|
+
|
|
84
|
+
[
|
|
85
|
+
1,
|
|
86
|
+
{
|
|
87
|
+
i: 1
|
|
88
|
+
},
|
|
89
|
+
[
|
|
90
|
+
{
|
|
91
|
+
i: 2
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
i: 3
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
t: []
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
{
|
|
101
|
+
"t": [
|
|
102
|
+
{
|
|
103
|
+
"i": 2
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"i": 3
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"t": []
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
].map(function(data) {
|
|
114
|
+
console.log(`k_fn(${JSON.stringify(data)});`);
|
|
115
|
+
console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
|
|
116
|
+
return console.log("");
|
|
117
|
+
});
|
|
118
|
+
|
|
76
119
|
}).call(this);
|
package/{test.t → test.k}
RENAMED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
< -- merge of 4 partial functions...
|
|
3
3
|
["x=", .x, " & y=", .y], -- produces a vector of 4 values, if fields 'x' and 'y' are present
|
|
4
4
|
["only x=", .x], -- produces a pair '["only x=", "value-of-x"]', for input like {"x":"value-of-x"}
|
|
5
|
-
|
|
5
|
+
-- it is defined only if field 'x' is present
|
|
6
6
|
["only y=", .y],
|
|
7
7
|
["no x nor y"] -- defined for all input, returns always the same one element vector
|
|
8
8
|
>
|