@fraczak/k 2.1.0 → 2.1.3
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 +10 -1
- package/package.json +1 -1
- package/parser.jison +2 -2
- package/parser.mjs +24 -24
- package/repl.mjs +45 -52
- package/run.mjs +145 -120
- package/symbol-table.mjs +6 -3
package/README.md
CHANGED
|
@@ -205,7 +205,7 @@ by `[ codeExp ]`. All members of the vector are the same code. E.g.,
|
|
|
205
205
|
-- of integers and a vector of strings
|
|
206
206
|
---
|
|
207
207
|
|
|
208
|
-
### List comprehension on vectors
|
|
208
|
+
### List comprehension on vectors (experimental!)
|
|
209
209
|
|
|
210
210
|
A vector can be "open" by PIPE (`|`) operator so the following partial function is applied to
|
|
211
211
|
each element of the vector one by one, yielding another open value. An open value can be "closed",
|
|
@@ -241,6 +241,15 @@ times value `x` appears in the list. (see `Examples/list-comprehension.k` for a
|
|
|
241
241
|
$ int;
|
|
242
242
|
```
|
|
243
243
|
|
|
244
|
+
**WARNING**: The `CARET` operator makes composition not associative, i.e., if you use
|
|
245
|
+
nested _list comprehension_ you cannot drop paranthesis anymore.
|
|
246
|
+
E.g., `| (| PLUS ^ .0) ^` and `| | PLUS ^ .0 ^` are two different functions:
|
|
247
|
+
|
|
248
|
+
```k
|
|
249
|
+
{ |(| PLUS ^ .0) ^ x, | | PLUS ^ .0 ^ y }:
|
|
250
|
+
[[[1,2],[3,4]],[[5,6],[7,8]]] --> {"x":[3,11],"y":[3,7]}
|
|
251
|
+
```
|
|
252
|
+
|
|
244
253
|
---
|
|
245
254
|
|
|
246
255
|
## Examples
|
package/package.json
CHANGED
package/parser.jison
CHANGED
|
@@ -54,7 +54,7 @@ function fromEscString(escString) {
|
|
|
54
54
|
/lex
|
|
55
55
|
|
|
56
56
|
%token NAME STRING INT
|
|
57
|
-
%token LA LC LB LP RA RP RB RC EQ DOT COMMA SC COL DOLLAR PIPE CARET
|
|
57
|
+
%token LA LC LB LP RA RP RB RC EQ DOT COMMA SC COL DOLLAR PIPE CARET
|
|
58
58
|
%token EOF
|
|
59
59
|
|
|
60
60
|
%start input_with_eof
|
|
@@ -113,6 +113,7 @@ code_label
|
|
|
113
113
|
comp
|
|
114
114
|
: exp { $$ = $1; }
|
|
115
115
|
| comp exp { $$ = s.comp($1, $2); }
|
|
116
|
+
| comp CARET { $$ = {op: 'caret', caret: $1}; }
|
|
116
117
|
;
|
|
117
118
|
|
|
118
119
|
exp
|
|
@@ -129,7 +130,6 @@ exp
|
|
|
129
130
|
| DOT name { $$ = {op: "dot", dot: $2}; }
|
|
130
131
|
| DOLLAR code { $$ = {op: "code", code: s.as_ref($2)}; }
|
|
131
132
|
| PIPE { $$ = {op: "pipe"}; }
|
|
132
|
-
| CARET { $$ = {op: "caret"}; }
|
|
133
133
|
;
|
|
134
134
|
|
|
135
135
|
labelled
|
package/parser.mjs
CHANGED
|
@@ -100,12 +100,12 @@ function fromEscString(escString) {
|
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
var parser = (function(){
|
|
103
|
-
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[4,6,8,15,18,21,23,
|
|
103
|
+
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[4,6,8,15,18,21,23,33,35,36],$V1=[1,7],$V2=[1,16],$V3=[1,17],$V4=[1,8],$V5=[1,9],$V6=[1,10],$V7=[1,11],$V8=[1,14],$V9=[1,15],$Va=[1,22],$Vb=[1,20],$Vc=[4,6,8,12,15,18,21,23,30,33,35,36],$Vd=[2,29],$Ve=[1,27],$Vf=[1,28],$Vg=[1,29],$Vh=[4,6,8,12,14,15,18,20,21,22,23,24,27,30,33,34,35,36],$Vi=[2,49],$Vj=[2,32],$Vk=[2,33],$Vl=[4,6,8,12,14,15,18,20,21,22,23,24,27,28,30,33,34,35,36],$Vm=[2,8],$Vn=[2,13],$Vo=[20,27],$Vp=[4,6,8,15,18,21,23,30,33,35,36],$Vq=[22,24,27],$Vr=[20,24,27],$Vs=[2,43],$Vt=[2,44],$Vu=[2,45];
|
|
104
104
|
var parser = {trace: function trace () { },
|
|
105
105
|
yy: {},
|
|
106
|
-
symbols_: {"error":2,"name":3,"NAME":4,"str":5,"STRING":6,"int":7,"INT":8,"input_with_eof":9,"defs":10,"comp":11,"EOF":12,"EQ":13,"SC":14,"DOLLAR":15,"codeDef":16,"code":17,"LC":18,"labelled_codes":19,"RC":20,"LB":21,"RB":22,"LA":23,"RA":24,"non_empty_labelled_codes":25,"code_label":26,"COMMA":27,"COL":28,"exp":29,"
|
|
107
|
-
terminals_: {2:"error",4:"NAME",6:"STRING",8:"INT",12:"EOF",13:"EQ",14:"SC",15:"DOLLAR",18:"LC",20:"RC",21:"LB",22:"RB",23:"LA",24:"RA",27:"COMMA",28:"COL",
|
|
108
|
-
productions_: [0,[3,1],[5,1],[7,1],[9,3],[10,0],[10,5],[10,6],[17,1],[17,1],[16,3],[16,3],[16,3],[19,0],[19,1],[25,1],[25,3],[26,2],[26,2],[26,2],[26,3],[26,3],[26,3],[11,1],[11,2],[29,3],[29,3],[29,3],[29,1],[29,2],[29,3],[29,1],[29,1],[29,2],[29,2],[29,2],[29,2],[29,1],[
|
|
106
|
+
symbols_: {"error":2,"name":3,"NAME":4,"str":5,"STRING":6,"int":7,"INT":8,"input_with_eof":9,"defs":10,"comp":11,"EOF":12,"EQ":13,"SC":14,"DOLLAR":15,"codeDef":16,"code":17,"LC":18,"labelled_codes":19,"RC":20,"LB":21,"RB":22,"LA":23,"RA":24,"non_empty_labelled_codes":25,"code_label":26,"COMMA":27,"COL":28,"exp":29,"CARET":30,"labelled":31,"list":32,"LP":33,"RP":34,"DOT":35,"PIPE":36,"non_empty_labelled":37,"comp_label":38,"non_empty_list":39,"$accept":0,"$end":1},
|
|
107
|
+
terminals_: {2:"error",4:"NAME",6:"STRING",8:"INT",12:"EOF",13:"EQ",14:"SC",15:"DOLLAR",18:"LC",20:"RC",21:"LB",22:"RB",23:"LA",24:"RA",27:"COMMA",28:"COL",30:"CARET",33:"LP",34:"RP",35:"DOT",36:"PIPE"},
|
|
108
|
+
productions_: [0,[3,1],[5,1],[7,1],[9,3],[10,0],[10,5],[10,6],[17,1],[17,1],[16,3],[16,3],[16,3],[19,0],[19,1],[25,1],[25,3],[26,2],[26,2],[26,2],[26,3],[26,3],[26,3],[11,1],[11,2],[11,2],[29,3],[29,3],[29,3],[29,1],[29,2],[29,3],[29,1],[29,1],[29,2],[29,2],[29,2],[29,2],[29,1],[31,0],[31,1],[37,1],[37,3],[38,2],[38,2],[38,2],[38,3],[38,3],[38,3],[32,0],[32,1],[39,1],[39,3]],
|
|
109
109
|
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
|
|
110
110
|
/* this == yyval */
|
|
111
111
|
|
|
@@ -176,40 +176,40 @@ case 24:
|
|
|
176
176
|
this.$ = s.comp($$[$0-1], $$[$0]);
|
|
177
177
|
break;
|
|
178
178
|
case 25:
|
|
179
|
-
this.$ = $$[$0-1];
|
|
179
|
+
this.$ = {op: 'caret', caret: $$[$0-1]};
|
|
180
180
|
break;
|
|
181
181
|
case 26:
|
|
182
|
-
this.$ =
|
|
182
|
+
this.$ = $$[$0-1];
|
|
183
183
|
break;
|
|
184
184
|
case 27:
|
|
185
|
-
this.$ =
|
|
185
|
+
this.$ = {op: "vector", vector: $$[$0-1]};
|
|
186
186
|
break;
|
|
187
187
|
case 28:
|
|
188
|
-
this.$ =
|
|
188
|
+
this.$ = s.union($$[$0-1]);
|
|
189
189
|
break;
|
|
190
190
|
case 29:
|
|
191
|
-
this.$ =
|
|
191
|
+
this.$ = {op: "ref", ref: $$[$0]};
|
|
192
192
|
break;
|
|
193
193
|
case 30:
|
|
194
|
-
this.$ =
|
|
194
|
+
this.$ = s.identity;
|
|
195
195
|
break;
|
|
196
196
|
case 31:
|
|
197
|
-
this.$ =
|
|
197
|
+
this.$ = $$[$0-1];
|
|
198
198
|
break;
|
|
199
199
|
case 32:
|
|
200
|
+
this.$ = {op: "str", str: $$[$0]};
|
|
201
|
+
break;
|
|
202
|
+
case 33:
|
|
200
203
|
this.$ = {op: "int", int: $$[$0]};
|
|
201
204
|
break;
|
|
202
|
-
case
|
|
205
|
+
case 34: case 35: case 36:
|
|
203
206
|
this.$ = {op: "dot", dot: $$[$0]};
|
|
204
207
|
break;
|
|
205
|
-
case 36:
|
|
206
|
-
this.$ = {op: "code", code: s.as_ref($$[$0])};
|
|
207
|
-
break;
|
|
208
208
|
case 37:
|
|
209
|
-
this.$ = {op: "
|
|
209
|
+
this.$ = {op: "code", code: s.as_ref($$[$0])};
|
|
210
210
|
break;
|
|
211
211
|
case 38:
|
|
212
|
-
this.$ = {op: "
|
|
212
|
+
this.$ = {op: "pipe"};
|
|
213
213
|
break;
|
|
214
214
|
case 39:
|
|
215
215
|
this.$ = {op: "product", product: []};
|
|
@@ -231,8 +231,8 @@ case 49:
|
|
|
231
231
|
break;
|
|
232
232
|
}
|
|
233
233
|
},
|
|
234
|
-
table: [o($V0,[2,5],{9:1,10:2}),{1:[3]},{3:4,4:$V1,5:12,6:$V2,7:13,8:$V3,11:3,15:[1,5],18:$V4,21:$V5,23:$V6,29:6,
|
|
235
|
-
defaultActions: {
|
|
234
|
+
table: [o($V0,[2,5],{9:1,10:2}),{1:[3]},{3:4,4:$V1,5:12,6:$V2,7:13,8:$V3,11:3,15:[1,5],18:$V4,21:$V5,23:$V6,29:6,33:$V7,35:$V8,36:$V9},{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,12:[1,18],15:$Va,18:$V4,21:$V5,23:$V6,29:19,30:$Vb,33:$V7,35:$V8,36:$V9},o($Vc,$Vd,{13:[1,23]}),{3:24,4:$V1,16:26,17:25,18:$Ve,21:$Vf,23:$Vg},o($Vh,[2,23]),o([4,6,8,12,13,14,15,18,20,21,22,23,24,27,28,30,33,34,35,36],[2,1]),{3:34,4:$V1,5:35,6:$V2,7:36,8:$V3,11:33,15:$Va,18:$V4,20:[2,39],21:$V5,23:$V6,29:6,31:30,33:$V7,35:$V8,36:$V9,37:31,38:32},{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,11:39,15:$Va,18:$V4,21:$V5,22:$Vi,23:$V6,29:6,32:37,33:$V7,35:$V8,36:$V9,39:38},{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,11:39,15:$Va,18:$V4,21:$V5,23:$V6,24:$Vi,29:6,32:40,33:$V7,35:$V8,36:$V9,39:38},{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,11:42,15:$Va,18:$V4,21:$V5,23:$V6,29:6,33:$V7,34:[1,41],35:$V8,36:$V9},o($Vh,$Vj),o($Vh,$Vk),{3:45,4:$V1,5:44,6:$V2,7:43,8:$V3},o($Vh,[2,38]),o($Vl,[2,2]),o($Vl,[2,3]),{1:[2,4]},o($Vh,[2,24]),o($Vh,[2,25]),o($Vh,$Vd),{3:46,4:$V1,16:26,17:25,18:$Ve,21:$Vf,23:$Vg},{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,11:47,15:$Va,18:$V4,21:$V5,23:$V6,29:6,33:$V7,35:$V8,36:$V9},o($Vc,$Vm,{13:[1,48]}),o($Vh,[2,37]),o($Vh,[2,9]),{3:53,4:$V1,5:54,6:$V2,7:55,8:$V3,16:26,17:52,18:$Ve,19:49,20:$Vn,21:$Vf,23:$Vg,25:50,26:51},{3:46,4:$V1,16:26,17:56,18:$Ve,21:$Vf,23:$Vg},{3:53,4:$V1,5:54,6:$V2,7:55,8:$V3,16:26,17:52,18:$Ve,19:57,21:$Vf,23:$Vg,24:$Vn,25:50,26:51},{20:[1,58]},{20:[2,40],27:[1,59]},o($Vo,[2,41]),{3:60,4:$V1,5:61,6:$V2,7:62,8:$V3,15:$Va,18:$V4,21:$V5,23:$V6,29:19,30:$Vb,33:$V7,35:$V8,36:$V9},o($Vp,$Vd,{28:[1,63]}),o($Vp,$Vj,{28:[1,64]}),o($Vp,$Vk,{28:[1,65]}),{22:[1,66]},o([22,24],[2,50],{27:[1,67]}),o($Vq,[2,51],{5:12,7:13,29:19,3:21,4:$V1,6:$V2,8:$V3,15:$Va,18:$V4,21:$V5,23:$V6,30:$Vb,33:$V7,35:$V8,36:$V9}),{24:[1,68]},o($Vh,[2,30]),{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,15:$Va,18:$V4,21:$V5,23:$V6,29:19,30:$Vb,33:$V7,34:[1,69],35:$V8,36:$V9},o($Vh,[2,34]),o($Vh,[2,35]),o($Vh,[2,36]),o($Vh,$Vm),{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,14:[1,70],15:$Va,18:$V4,21:$V5,23:$V6,29:19,30:$Vb,33:$V7,35:$V8,36:$V9},{16:71,18:$Ve,21:$Vf,23:$Vg},{20:[1,72]},o([20,24],[2,14],{27:[1,73]}),o($Vr,[2,15]),{3:74,4:$V1,5:75,6:$V2,7:76,8:$V3},o([4,6,8],$Vm,{28:[1,77]}),{28:[1,78]},{28:[1,79]},{22:[1,80]},{24:[1,81]},o($Vh,[2,26]),{3:34,4:$V1,5:35,6:$V2,7:36,8:$V3,11:33,15:$Va,18:$V4,21:$V5,23:$V6,29:6,33:$V7,35:$V8,36:$V9,38:82},o($Vp,$Vd,{20:$Vs,27:$Vs}),o($Vp,$Vj,{20:$Vt,27:$Vt}),o($Vp,$Vk,{20:$Vu,27:$Vu}),{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,11:83,15:$Va,18:$V4,21:$V5,23:$V6,29:6,33:$V7,35:$V8,36:$V9},{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,11:84,15:$Va,18:$V4,21:$V5,23:$V6,29:6,33:$V7,35:$V8,36:$V9},{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,11:85,15:$Va,18:$V4,21:$V5,23:$V6,29:6,33:$V7,35:$V8,36:$V9},o($Vh,[2,27]),{3:21,4:$V1,5:12,6:$V2,7:13,8:$V3,11:86,15:$Va,18:$V4,21:$V5,23:$V6,29:6,33:$V7,35:$V8,36:$V9},o($Vh,[2,28]),o($Vh,[2,31]),o($V0,[2,6]),{14:[1,87]},o($Vh,[2,10]),{3:53,4:$V1,5:54,6:$V2,7:55,8:$V3,16:26,17:52,18:$Ve,21:$Vf,23:$Vg,26:88},o($Vr,[2,17]),o($Vr,[2,18]),o($Vr,[2,19]),{3:46,4:$V1,16:26,17:89,18:$Ve,21:$Vf,23:$Vg},{3:46,4:$V1,16:26,17:90,18:$Ve,21:$Vf,23:$Vg},{3:46,4:$V1,16:26,17:91,18:$Ve,21:$Vf,23:$Vg},o($Vh,[2,11]),o($Vh,[2,12]),o($Vo,[2,42]),o($Vo,[2,46],{5:12,7:13,29:19,3:21,4:$V1,6:$V2,8:$V3,15:$Va,18:$V4,21:$V5,23:$V6,30:$Vb,33:$V7,35:$V8,36:$V9}),o($Vo,[2,47],{5:12,7:13,29:19,3:21,4:$V1,6:$V2,8:$V3,15:$Va,18:$V4,21:$V5,23:$V6,30:$Vb,33:$V7,35:$V8,36:$V9}),o($Vo,[2,48],{5:12,7:13,29:19,3:21,4:$V1,6:$V2,8:$V3,15:$Va,18:$V4,21:$V5,23:$V6,30:$Vb,33:$V7,35:$V8,36:$V9}),o($Vq,[2,52],{5:12,7:13,29:19,3:21,4:$V1,6:$V2,8:$V3,15:$Va,18:$V4,21:$V5,23:$V6,30:$Vb,33:$V7,35:$V8,36:$V9}),o($V0,[2,7]),o($Vr,[2,16]),o($Vr,[2,20]),o($Vr,[2,21]),o($Vr,[2,22])],
|
|
235
|
+
defaultActions: {18:[2,4]},
|
|
236
236
|
parseError: function parseError (str, hash) {
|
|
237
237
|
if (hash.recoverable) {
|
|
238
238
|
this.trace(str);
|
|
@@ -718,7 +718,7 @@ case 4:return 18;
|
|
|
718
718
|
break;
|
|
719
719
|
case 5:return 21;
|
|
720
720
|
break;
|
|
721
|
-
case 6:return
|
|
721
|
+
case 6:return 33;
|
|
722
722
|
break;
|
|
723
723
|
case 7:return 24;
|
|
724
724
|
break;
|
|
@@ -726,11 +726,11 @@ case 8:return 20;
|
|
|
726
726
|
break;
|
|
727
727
|
case 9:return 22;
|
|
728
728
|
break;
|
|
729
|
-
case 10:return
|
|
729
|
+
case 10:return 34;
|
|
730
730
|
break;
|
|
731
731
|
case 11:return 13;
|
|
732
732
|
break;
|
|
733
|
-
case 12:return
|
|
733
|
+
case 12:return 35;
|
|
734
734
|
break;
|
|
735
735
|
case 13:return 27;
|
|
736
736
|
break;
|
|
@@ -740,9 +740,9 @@ case 15:return 28;
|
|
|
740
740
|
break;
|
|
741
741
|
case 16:return 15;
|
|
742
742
|
break;
|
|
743
|
-
case 17:return
|
|
743
|
+
case 17:return 36;
|
|
744
744
|
break;
|
|
745
|
-
case 18:return
|
|
745
|
+
case 18:return 30;
|
|
746
746
|
break;
|
|
747
747
|
case 19:return 6;
|
|
748
748
|
break;
|
package/repl.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import k from "./index.mjs";
|
|
4
|
-
import run from "./run.mjs";
|
|
4
|
+
import {run, closeVector } from "./run.mjs";
|
|
5
5
|
import { prettyCode, prettyRel } from "./pretty.mjs";
|
|
6
6
|
|
|
7
7
|
import fs from "node:fs";
|
|
@@ -24,7 +24,7 @@ const re = /^[ \n\t]*(?:--l[ ]+)(.+[^ ])[ ]*?$/;
|
|
|
24
24
|
|
|
25
25
|
(function (val, buffer) {
|
|
26
26
|
return process.stdin.on("data", function (data) {
|
|
27
|
-
var e, file, first, i, kScript, last, len, line, ref, rest,
|
|
27
|
+
var e, file, first, i, kScript, last, len, line, ref, rest, todo;
|
|
28
28
|
[first, ...rest] = data.toString("utf8").split("\n");
|
|
29
29
|
buffer.push(first);
|
|
30
30
|
if (rest.length > 0) {
|
|
@@ -32,81 +32,74 @@ const re = /^[ \n\t]*(?:--l[ ]+)(.+[^ ])[ ]*?$/;
|
|
|
32
32
|
(ref = rest), ([...rest] = ref), ([last] = splice.call(rest, -1));
|
|
33
33
|
buffer = [last];
|
|
34
34
|
todo = [todo, ...rest];
|
|
35
|
-
results = [];
|
|
36
35
|
for (i = 0, len = todo.length; i < len; i++) {
|
|
37
36
|
line = todo[i];
|
|
38
37
|
if (val === void 0) {
|
|
39
38
|
val = {};
|
|
40
39
|
}
|
|
41
40
|
if (line.match(/^[ \n\t]*(?:--h)?$/)) {
|
|
42
|
-
|
|
41
|
+
help();
|
|
42
|
+
} else if (line.match(/^[ \n\t]*\^$/)) {
|
|
43
|
+
val = closeVector(val);
|
|
44
|
+
console.log(`=> ${JSON.stringify(val)}`);
|
|
43
45
|
} else if (line.match(re)) {
|
|
44
46
|
file = line.match(re)[1];
|
|
45
47
|
console.log(`-- loading file: ${file} ...`);
|
|
46
48
|
kScript = fs.readFileSync(file).toString();
|
|
47
49
|
val = k.compile(kScript)(val);
|
|
48
|
-
|
|
50
|
+
console.log(`=> ${JSON.stringify(val)}`);
|
|
49
51
|
} else if (line.match(/^[ \n\t]*(?:--a)?$/)) {
|
|
50
|
-
|
|
52
|
+
console.log(JSON.stringify(run.defs, " ", 2));
|
|
51
53
|
} else if (line.match(/^[ \n\t]*(?:--r)?$/)) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
);
|
|
72
|
-
})(run.defs, {})
|
|
73
|
-
)
|
|
74
|
-
);
|
|
54
|
+
(function (defs, result) {
|
|
55
|
+
if (defs == null) {
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
return (function (prettyRel) {
|
|
59
|
+
var ref1, relExps, relName;
|
|
60
|
+
ref1 = defs.rels;
|
|
61
|
+
for (relName in ref1) {
|
|
62
|
+
relExps = ref1[relName];
|
|
63
|
+
result[relName] = relExps.map(prettyRel);
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
})(
|
|
67
|
+
prettyRel.bind(
|
|
68
|
+
null,
|
|
69
|
+
prettyCode.bind(null, defs.codes, defs.representatives)
|
|
70
|
+
)
|
|
71
|
+
);
|
|
72
|
+
})(run.defs, {})
|
|
75
73
|
} else if (line.match(/^[ \n\t]*(?:--c)?$/)) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (defs == null) {
|
|
81
|
-
return result;
|
|
82
|
-
}
|
|
83
|
-
ref1 = defs.codes;
|
|
84
|
-
for (codeName in ref1) {
|
|
85
|
-
codeExp = ref1[codeName];
|
|
86
|
-
result[codeName] = prettyCode(
|
|
87
|
-
defs.codes,
|
|
88
|
-
defs.representatives,
|
|
89
|
-
codeExp
|
|
90
|
-
);
|
|
91
|
-
}
|
|
74
|
+
console.log(
|
|
75
|
+
(function (defs, result) {
|
|
76
|
+
var codeExp, codeName, ref1;
|
|
77
|
+
if (defs == null) {
|
|
92
78
|
return result;
|
|
93
|
-
}
|
|
94
|
-
|
|
79
|
+
}
|
|
80
|
+
ref1 = defs.codes;
|
|
81
|
+
for (codeName in ref1) {
|
|
82
|
+
codeExp = ref1[codeName];
|
|
83
|
+
result[codeName] = prettyCode(
|
|
84
|
+
defs.codes,
|
|
85
|
+
defs.representatives,
|
|
86
|
+
codeExp
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
})(run.defs, {})
|
|
95
91
|
);
|
|
96
92
|
} else if (!line.match(/^[ \n\t]*(?:#.*)?$/)) {
|
|
97
93
|
try {
|
|
98
94
|
val = k.run(`${line} ()`, val);
|
|
99
|
-
|
|
95
|
+
console.log(`=> ${JSON.stringify(val)}`);
|
|
100
96
|
} catch (error) {
|
|
101
97
|
e = error;
|
|
102
98
|
console.error("ERROR:");
|
|
103
|
-
|
|
99
|
+
console.error(e);
|
|
104
100
|
}
|
|
105
|
-
} else {
|
|
106
|
-
results.push(void 0);
|
|
107
101
|
}
|
|
108
102
|
}
|
|
109
|
-
return results;
|
|
110
103
|
}
|
|
111
104
|
});
|
|
112
105
|
})({}, []);
|
package/run.mjs
CHANGED
|
@@ -10,7 +10,23 @@ function isOpen(x) {
|
|
|
10
10
|
function isClosed(x) {
|
|
11
11
|
return (Array.isArray(x) && !x.open);
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
Array.prototype.toJSON = function () {
|
|
15
|
+
if (this.open) {
|
|
16
|
+
// throw new Error(`Cannot serialize open vector: ${JSON.stringify([...this])}.`);
|
|
17
|
+
return {"OPEN VECTOR": [...this]};
|
|
18
|
+
}
|
|
19
|
+
return this;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function closeVector(val) {
|
|
23
|
+
if (isOpen(val)) {
|
|
24
|
+
return [...val];
|
|
25
|
+
}
|
|
26
|
+
console.error("Can close only an open vector.");
|
|
27
|
+
return val;
|
|
28
|
+
}
|
|
29
|
+
|
|
14
30
|
const builtin = {
|
|
15
31
|
"_log!": (arg) => {
|
|
16
32
|
console.error(`_log!: ${JSON.stringify(arg)}`);
|
|
@@ -43,7 +59,7 @@ const builtin = {
|
|
|
43
59
|
null: () => null,
|
|
44
60
|
toJSON: (x) => JSON.stringify(x),
|
|
45
61
|
fromJSON: (x) => JSON.parse(x),
|
|
46
|
-
CONS: ([x, y]) => [x, ...y],
|
|
62
|
+
CONS: ([x, y]) => { try { return [x, ...y]; } catch (e) { return undefined; } },
|
|
47
63
|
SNOC: (x) => (x.length > 1 ? [x[0], x.slice(1)] : undefined),
|
|
48
64
|
toDateMsec: (x) => new Date(x).getTime(),
|
|
49
65
|
toDateStr: (x) => new Date(x).toISOString(),
|
|
@@ -93,10 +109,9 @@ function verify(code, value) {
|
|
|
93
109
|
function run(exp, value) {
|
|
94
110
|
"use strict";
|
|
95
111
|
if (value === undefined) return;
|
|
96
|
-
|
|
97
|
-
if (
|
|
98
|
-
return [...value];
|
|
99
|
-
} else {
|
|
112
|
+
while (true) {
|
|
113
|
+
if (isOpen(value)) {
|
|
114
|
+
if (exp.op === "caret2") return [...value];
|
|
100
115
|
const result = [];
|
|
101
116
|
result.open = true
|
|
102
117
|
for (const v of value) {
|
|
@@ -105,135 +120,145 @@ function run(exp, value) {
|
|
|
105
120
|
}
|
|
106
121
|
return result;
|
|
107
122
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
return;
|
|
115
|
-
case "identity":
|
|
116
|
-
return value;
|
|
117
|
-
case "str":
|
|
118
|
-
case "int":
|
|
119
|
-
return exp[exp.op];
|
|
120
|
-
case "ref":
|
|
121
|
-
const defn = run.defs.rels[exp.ref];
|
|
122
|
-
if (defn != null) {
|
|
123
|
-
return run(defn[defn.length - 1], value);
|
|
124
|
-
}
|
|
125
|
-
const builtin_func = builtin[exp.ref];
|
|
126
|
-
if (builtin_func != null) {
|
|
127
|
-
return builtin_func(value);
|
|
128
|
-
}
|
|
129
|
-
throw(`Unknown ref: '${exp.ref}'`);
|
|
130
|
-
case "dot":
|
|
131
|
-
// a hack to allow something like 'null . null' or '0 . 0' to work by returning unit
|
|
132
|
-
if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
133
|
-
if (`${value}` === `${exp.dot}`) return {};
|
|
123
|
+
switch (exp.op) {
|
|
124
|
+
case "code":
|
|
125
|
+
if (verify(exp.code, value)) {
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
134
128
|
return;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
129
|
+
case "identity":
|
|
130
|
+
return value;
|
|
131
|
+
case "str":
|
|
132
|
+
case "int":
|
|
133
|
+
return exp[exp.op];
|
|
134
|
+
case "ref":
|
|
135
|
+
const defn = run.defs.rels[exp.ref];
|
|
136
|
+
if (defn != null) {
|
|
137
|
+
exp = defn[defn.length - 1];
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const builtin_func = builtin[exp.ref];
|
|
141
|
+
if (builtin_func != null) {
|
|
142
|
+
return builtin_func(value);
|
|
143
|
+
}
|
|
144
|
+
throw(`Unknown ref: '${exp.ref}'`);
|
|
145
|
+
case "dot":
|
|
146
|
+
// a hack to allow something like 'null . null' or '0 . 0' to work by returning unit
|
|
147
|
+
if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
148
|
+
if (`${value}` === `${exp.dot}`) return {};
|
|
149
|
+
return;
|
|
152
150
|
}
|
|
151
|
+
return value[exp.dot];
|
|
152
|
+
case "pipe": {
|
|
153
|
+
assert(isClosed(value), `PIPE (|): Only a regular vector value can be "open".`);
|
|
154
|
+
const result = [...value];
|
|
155
|
+
result.open = true;
|
|
156
|
+
return result;
|
|
153
157
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
158
|
+
case "comp":
|
|
159
|
+
for (let i = 0, len = exp.comp.length - 1; i < len; i++) {
|
|
160
|
+
const result = run(exp.comp[i], value);
|
|
161
|
+
if (result === undefined) return;
|
|
162
|
+
value = result;
|
|
163
|
+
}
|
|
164
|
+
exp = exp.comp[exp.comp.length - 1];
|
|
165
|
+
continue;
|
|
166
|
+
case "union":
|
|
167
|
+
for (let i = 0, len = exp.union.length -1; i < len; i++) {
|
|
168
|
+
const result = run(exp.union[i], value);
|
|
169
|
+
if (result !== undefined) {
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
exp = exp.union[exp.union.length - 1];
|
|
174
|
+
continue;
|
|
175
|
+
case "vector": {
|
|
176
|
+
let result = [];
|
|
177
|
+
let open = false;
|
|
178
|
+
for (let i = 0, len = exp.vector.length; i < len; i++) {
|
|
179
|
+
const r = run(exp.vector[i], value);
|
|
180
|
+
if (r === undefined) return;
|
|
181
|
+
if (open) {
|
|
182
|
+
if (isOpen(r)) {
|
|
183
|
+
const newResult = [];
|
|
184
|
+
newResult.open = true;
|
|
185
|
+
for (const x of result) {
|
|
186
|
+
for (const y of r) {
|
|
187
|
+
newResult.push([...x, y]);
|
|
188
|
+
}
|
|
168
189
|
}
|
|
190
|
+
result = newResult;
|
|
191
|
+
} else {
|
|
192
|
+
for (const x of result) x.push(r);
|
|
169
193
|
}
|
|
170
|
-
result = newResult;
|
|
171
|
-
} else {
|
|
172
|
-
for (const x of result) x.push(r);
|
|
173
|
-
}
|
|
174
|
-
} else {
|
|
175
|
-
if (isOpen(r)) {
|
|
176
|
-
open = true;
|
|
177
|
-
const newResult = [];
|
|
178
|
-
newResult.open = true;
|
|
179
|
-
for (const x of r) {
|
|
180
|
-
newResult.push([...result, x]);
|
|
181
|
-
}
|
|
182
|
-
result = newResult;
|
|
183
194
|
} else {
|
|
184
|
-
|
|
195
|
+
if (isOpen(r)) {
|
|
196
|
+
open = true;
|
|
197
|
+
const newResult = [];
|
|
198
|
+
newResult.open = true;
|
|
199
|
+
for (const x of r) {
|
|
200
|
+
newResult.push([...result, x]);
|
|
201
|
+
}
|
|
202
|
+
result = newResult;
|
|
203
|
+
} else {
|
|
204
|
+
result.push(r);
|
|
205
|
+
}
|
|
185
206
|
}
|
|
186
207
|
}
|
|
208
|
+
return result;
|
|
187
209
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
210
|
+
case "product": {
|
|
211
|
+
let result = {};
|
|
212
|
+
let open = false;
|
|
213
|
+
for (let i = 0, len = exp.product.length; i < len; i++) {
|
|
214
|
+
const { label, exp: e } = exp.product[i];
|
|
215
|
+
const r = run(e, value);
|
|
216
|
+
if (r === undefined) return;
|
|
217
|
+
if (open) {
|
|
218
|
+
if (isOpen(r)) {
|
|
219
|
+
let newResult = [];
|
|
220
|
+
newResult.open = true;
|
|
221
|
+
for (const v of r) {
|
|
222
|
+
for (const x of result) {
|
|
223
|
+
newResult.push({...x, [label]: v});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
result = newResult;
|
|
227
|
+
} else {
|
|
228
|
+
let newResult = [];
|
|
229
|
+
newResult.open = true;
|
|
202
230
|
for (const x of result) {
|
|
203
|
-
newResult.push({...x, [label]:
|
|
231
|
+
newResult.push({...x, [label]: r});
|
|
204
232
|
}
|
|
205
|
-
|
|
206
|
-
|
|
233
|
+
result = newResult;
|
|
234
|
+
}
|
|
207
235
|
} else {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
newResult.
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
let newResult = [];
|
|
219
|
-
newResult.open = true;
|
|
220
|
-
for (const v of r.values()) {
|
|
221
|
-
newResult.push({...result, [label]: v});
|
|
236
|
+
if (isOpen(r)) {
|
|
237
|
+
open = true;
|
|
238
|
+
let newResult = [];
|
|
239
|
+
newResult.open = true;
|
|
240
|
+
for (const v of r.values()) {
|
|
241
|
+
newResult.push({...result, [label]: v});
|
|
242
|
+
}
|
|
243
|
+
result = newResult;
|
|
244
|
+
} else {
|
|
245
|
+
result[label] = r;
|
|
222
246
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}
|
|
227
|
-
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return result
|
|
228
250
|
}
|
|
229
|
-
|
|
251
|
+
case "caret": {
|
|
252
|
+
const result = run(exp.caret, value);
|
|
253
|
+
assert(isOpen(result), "CARET (^): Only an 'open' vector can be closed.");
|
|
254
|
+
return [...result];
|
|
255
|
+
}
|
|
256
|
+
default:
|
|
257
|
+
assert(false,`Unknown operation: '${exp.op}'`);
|
|
258
|
+
|
|
230
259
|
}
|
|
231
|
-
|
|
232
|
-
assert(false, "CARET (^): Only an 'open' vector can be closed.");
|
|
233
|
-
default:
|
|
234
|
-
assert(false,`Unknown operation: '${exp.op}'`);
|
|
235
|
-
}
|
|
260
|
+
};
|
|
236
261
|
}
|
|
237
262
|
|
|
238
263
|
export default run;
|
|
239
|
-
export { run };
|
|
264
|
+
export { run , closeVector };
|
package/symbol-table.mjs
CHANGED
|
@@ -57,21 +57,24 @@ function comp_first(e1, e2) {
|
|
|
57
57
|
if (is_identity_rel(e2)) return e1;
|
|
58
58
|
if (is_empty_rel(e1)) return e1;
|
|
59
59
|
if (is_empty_rel(e2)) return e2;
|
|
60
|
-
if (e1.op === "comp" && e2.op === "comp")
|
|
60
|
+
if (e1.op === "comp" && e2.op === "comp") {
|
|
61
61
|
return {
|
|
62
62
|
op: "comp",
|
|
63
63
|
comp: [].concat(e1.comp, e2.comp),
|
|
64
64
|
};
|
|
65
|
-
|
|
65
|
+
}
|
|
66
|
+
if (e1.op === "comp") {
|
|
66
67
|
return {
|
|
67
68
|
op: "comp",
|
|
68
69
|
comp: [].concat(e1.comp, [e2]),
|
|
69
70
|
};
|
|
70
|
-
|
|
71
|
+
}
|
|
72
|
+
if (e2.op === "comp") {
|
|
71
73
|
return {
|
|
72
74
|
op: "comp",
|
|
73
75
|
comp: [].concat([e1], e2.comp),
|
|
74
76
|
};
|
|
77
|
+
}
|
|
75
78
|
return {
|
|
76
79
|
op: "comp",
|
|
77
80
|
comp: [e1, e2],
|