@fraczak/k 1.2.2 → 1.3.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 +131 -0
- package/README.md +17 -16
- package/codes.coffee +1 -32
- package/codes.js +2 -49
- package/package.json +1 -1
- package/parser.jison +4 -0
- package/parser.js +25 -25
- package/pretty.coffee +74 -0
- package/pretty.js +106 -0
- package/repl.coffee +14 -1
- package/repl.js +32 -6
- package/repl.sh +32 -6
- package/run.coffee +6 -8
- package/run.js +21 -19
- package/test.coffee +2 -0
- package/test.js +12 -0
- package/Benchmark/range1000 +0 -1000
- package/Benchmark/range200 +0 -200
package/INTRO.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# k - the way of building and manipulating JSON-like data
|
|
2
|
+
|
|
3
|
+
Technically: notation for defining __first-order partial functions__.
|
|
4
|
+
|
|
5
|
+
An example of a _partial function_ is "`.toto`", which maps an object
|
|
6
|
+
to its property named `toto`, or it is not defined if the property
|
|
7
|
+
doesn't exist. E.g.,
|
|
8
|
+
|
|
9
|
+
.toto :
|
|
10
|
+
{"toto": 5, "titi": 10} --> 5
|
|
11
|
+
{"titi": 10} ... undefined // it is not a value!
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Combining "partial functions"
|
|
16
|
+
|
|
17
|
+
There are three ways of combining functions:
|
|
18
|
+
|
|
19
|
+
1. __composition__: `(f1 f2 ...)`, e.g. `(.toto .titi)` extracts
|
|
20
|
+
nested field.
|
|
21
|
+
|
|
22
|
+
(.toto .titi) :
|
|
23
|
+
{"toto": {"titi": 10}} --> 10
|
|
24
|
+
{"toto": 10 } ... undefined
|
|
25
|
+
{} ... undefined
|
|
26
|
+
|
|
27
|
+
2. __merge__: `< f1, f2,... >`, e.g., `<.toto, .titi>` extracts field
|
|
28
|
+
`toto` if present; otherwise extracts `titi`.
|
|
29
|
+
|
|
30
|
+
<.toto, .titi> :
|
|
31
|
+
{"toto": 5, "titi": 10} --> 5
|
|
32
|
+
{"titi": 10 } --> 10
|
|
33
|
+
{} ... undefined
|
|
34
|
+
|
|
35
|
+
3. __product__: `{ f1 label1, f2 label2, ...}`, e.g., `{.toto TOTO,
|
|
36
|
+
.titi TITI}` extracts two fields and builds a record out of them.
|
|
37
|
+
|
|
38
|
+
{.toto TOTO, .titi TITI} :
|
|
39
|
+
{"toto": 5, "titi": 10} --> {"TOTO": 5, "TITI": 10}
|
|
40
|
+
{"titi": 10 } ... undefined
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
__QUIZ__: What is:
|
|
45
|
+
|
|
46
|
+
- empty composition: `()` ?
|
|
47
|
+
- empty merge: `<>` ?
|
|
48
|
+
- empty product: `{}` ?
|
|
49
|
+
- `{{{{} s} s} s}` ?
|
|
50
|
+
- `({{{() a} b} c} .c .b .a)` ?
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Basic extensions
|
|
55
|
+
|
|
56
|
+
### Constants, i.e., literals for `strings`, `integers`, `booleans`, and `null`
|
|
57
|
+
|
|
58
|
+
A constant defines a function which ignores its argument and produces
|
|
59
|
+
the constant value. E.g.:
|
|
60
|
+
|
|
61
|
+
{123 int, "kScript" str, true bool, null null} :
|
|
62
|
+
<any> --> {"int":123,"str":"kScript","bool":true,"null":null}
|
|
63
|
+
|
|
64
|
+
### Vector product
|
|
65
|
+
|
|
66
|
+
Vector product can be used as an abbreviation for product whose field
|
|
67
|
+
names are integers starting from zero. E.g., `{.toto "0", .titi "1",
|
|
68
|
+
123 "2"}` can be written as `[.toto, .titi, 123]`.
|
|
69
|
+
|
|
70
|
+
[.toto, .titi, 12] :
|
|
71
|
+
{"toto": 5, "titi": 10 } --> [5, 10, 12] // {"0":5,"1":10,"2":12}
|
|
72
|
+
|
|
73
|
+
.1 :
|
|
74
|
+
["A","B","C"] --> "B"
|
|
75
|
+
["a"] ... undefined
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Pragmatic extensions, aka "standard library"
|
|
79
|
+
|
|
80
|
+
- `GT` :
|
|
81
|
+
|
|
82
|
+
[4,3,0] --> [4,3,0]
|
|
83
|
+
[5,8] - undefined
|
|
84
|
+
|
|
85
|
+
- `EQ` :
|
|
86
|
+
|
|
87
|
+
[4,4,4] --> [4,4,4]
|
|
88
|
+
[5,8] - undefined
|
|
89
|
+
|
|
90
|
+
- `[PLUS, TIMES, MINUS]` :
|
|
91
|
+
|
|
92
|
+
[2,2,2] --> [6,8,-2]
|
|
93
|
+
|
|
94
|
+
- `CONCAT` :
|
|
95
|
+
|
|
96
|
+
["a","bc","d"] --> "abcd"
|
|
97
|
+
|
|
98
|
+
- `toJSON` :
|
|
99
|
+
|
|
100
|
+
{a: 12} --> "{\"a\":12}"
|
|
101
|
+
|
|
102
|
+
- `fromJSON` :
|
|
103
|
+
|
|
104
|
+
"{\"a\":12}" --> {a: 12}
|
|
105
|
+
|
|
106
|
+
- `DIV`, `FDIV`, `CONS`, `SNOC`, `_log!`
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Recursive definitions
|
|
111
|
+
|
|
112
|
+
-- factorial.k
|
|
113
|
+
dec = ([(),-1] PLUS);
|
|
114
|
+
zero? = ([(),0] EQ 0);
|
|
115
|
+
factorial = <
|
|
116
|
+
(zero? 1),
|
|
117
|
+
([(dec factorial), ()] TIMES)
|
|
118
|
+
>;
|
|
119
|
+
{ () x, factorial "x!" }
|
|
120
|
+
|
|
121
|
+
## Codes (_types_)
|
|
122
|
+
|
|
123
|
+
_Codes_ (prefixed by `$`) can be defined by taged union and product. E.g.:
|
|
124
|
+
|
|
125
|
+
$nat = <nat s, {} z>; -- e.g., {{{{} z} s} s}
|
|
126
|
+
$pair = {nat x, nat y}; -- e.g., {{{} z} x, {{{{} z} s} s} y}
|
|
127
|
+
|
|
128
|
+
s = ($nat {() s} $nat);
|
|
129
|
+
add = ($pair <{(.x .s) x, (.y s) y} add, .y> $nat);
|
|
130
|
+
|
|
131
|
+
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# k-language
|
|
2
2
|
|
|
3
|
-
npm install @fraczak/k
|
|
3
|
+
npm install '@fraczak/k'
|
|
4
4
|
|
|
5
5
|
From javascript:
|
|
6
6
|
|
|
@@ -72,20 +72,21 @@ the field (or a vector with the index).
|
|
|
72
72
|
|
|
73
73
|
`k`-expression can be prefixed by function definitions. E.g.:
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
dec = [(),-1] PLUS;
|
|
76
|
+
zero? = [(),0] EQ 0;
|
|
77
|
+
factorial = <
|
|
78
|
+
zero? 1,
|
|
79
|
+
[dec factorial, ()] TIMES
|
|
80
|
+
>;
|
|
81
|
+
{ () x, factorial "x!" }
|
|
81
82
|
|
|
82
83
|
Another example could be finding the biggest (max) value in a vector:
|
|
83
84
|
|
|
84
85
|
max = <
|
|
85
86
|
SNOC -- [x0, x1, x2, ...] -> [x0, [x1, x2, ...]]
|
|
86
87
|
[.0, .1 max] -- [x0, [x1, x2, ...]] -> [x0, max(x1,x2,...)], i.e., recursive call
|
|
87
|
-
<GT.0
|
|
88
|
-
|
|
88
|
+
<GT .0, .1>, -- if x0 > max(x1,x2,...) then x0 else max(x1,x2,...)
|
|
89
|
+
-- when SNOC is not defined, e.g. the argument is a singleton vector [x0]
|
|
89
90
|
.0 -- [x0] -> x0,
|
|
90
91
|
>;
|
|
91
92
|
max
|
|
@@ -102,7 +103,7 @@ There are three predefined value encodings: `int`, `string`, and
|
|
|
102
103
|
|
|
103
104
|
One can define recursive codes. E.g.:
|
|
104
105
|
|
|
105
|
-
$
|
|
106
|
+
$tree = <string leaf, {tree left, tree right} tree>;
|
|
106
107
|
|
|
107
108
|
Each _code_ definition starts with a `$`.
|
|
108
109
|
The above example defines new code called _tree_.
|
|
@@ -143,8 +144,8 @@ run the language from command line.
|
|
|
143
144
|
> ./node_modules/.bin/k '<["x=",.x," & y=",.y],["only x=",.x],["only y=",.y],["no x nor y"]>{CONCAT "x&y"}'
|
|
144
145
|
|
|
145
146
|
{"y": 123, "x": 432,"others": "..."} --> {"x&y":"x=432 & y=123"}
|
|
146
|
-
{"x":987}
|
|
147
|
-
{"z":123}
|
|
147
|
+
{"x": 987} --> {"x&y":"only x=987"}
|
|
148
|
+
{"z": 123} --> {"x&y":"no x nor y"}
|
|
148
149
|
^D - to interrupt
|
|
149
150
|
|
|
150
151
|
3. If the `k`-expression is long, it can be put in a file, e.g.:
|
|
@@ -172,7 +173,7 @@ run the language from command line.
|
|
|
172
173
|
|
|
173
174
|
> ./node_modules/.bin/k -k test.k my-objects.json
|
|
174
175
|
{"x&y":"x=432 & y=123"}
|
|
175
|
-
{"x&y":"
|
|
176
|
+
{"x&y":"only x=987"}
|
|
176
177
|
{"x&y":"no x nor y"}
|
|
177
178
|
|
|
178
179
|
where:
|
|
@@ -181,8 +182,8 @@ run the language from command line.
|
|
|
181
182
|
####################################################
|
|
182
183
|
# empty lines and lines starting with # are ignored
|
|
183
184
|
{"y": 123, "x": 432,"others": "..."}
|
|
184
|
-
{"x":987}
|
|
185
|
-
{"z":123}
|
|
185
|
+
{"x": 987}
|
|
186
|
+
{"z": 123}
|
|
186
187
|
####################################################
|
|
187
188
|
|
|
188
189
|
### k-REPL (Read-Evaluate-Print Loop)
|
|
@@ -194,7 +195,7 @@ shell for the language. E.g.:
|
|
|
194
195
|
{'a' a, 'b' b} toJSON
|
|
195
196
|
=> "{\"a\":\"a\",\"b\":\"b\"}"
|
|
196
197
|
{"a" a} toJSON fromJSON
|
|
197
|
-
=> {"a":"a"}
|
|
198
|
+
=> {"a": "a"}
|
|
198
199
|
inc = [(),1] PLUS; 1 inc inc
|
|
199
200
|
=> 3
|
|
200
201
|
inc inc inc inc
|
package/codes.coffee
CHANGED
|
@@ -53,37 +53,6 @@ minimize = (codes) ->
|
|
|
53
53
|
representatives[x] = new_rep
|
|
54
54
|
{classes,representatives}
|
|
55
55
|
|
|
56
|
-
compareAs = (fn) ->
|
|
57
|
-
(a,b) ->
|
|
58
|
-
[a,b] = [a,b].map fn
|
|
59
|
-
return -1 if a < b
|
|
60
|
-
return 1 if a > b
|
|
61
|
-
0
|
|
62
|
-
|
|
63
|
-
pretty_labels = (label_ref_map, codes, representatives) ->
|
|
64
|
-
labels = Object.keys(label_ref_map)
|
|
65
|
-
.sort compareAs (x) -> x
|
|
66
|
-
.map (label) ->
|
|
67
|
-
"#{pretty {code:"ref",ref:label_ref_map[label]}, codes, representatives} #{label}"
|
|
68
|
-
.join ", "
|
|
69
|
-
|
|
70
|
-
pretty = (codeExp, codes, representatives) ->
|
|
71
|
-
switch codeExp.code
|
|
72
|
-
when "ref"
|
|
73
|
-
name = representatives[codeExp.ref] ? codeExp.ref
|
|
74
|
-
if name.startsWith ":"
|
|
75
|
-
pretty codes[name], codes, representatives
|
|
76
|
-
else
|
|
77
|
-
name
|
|
78
|
-
when "product"
|
|
79
|
-
"{#{pretty_labels codeExp.product, codes, representatives}}"
|
|
80
|
-
when "union"
|
|
81
|
-
"<#{pretty_labels codeExp.union, codes, representatives}>"
|
|
82
|
-
when "vector"
|
|
83
|
-
"[#{representatives[codeExp.ref] ? codeExp.ref}]"
|
|
84
|
-
else
|
|
85
|
-
":error"
|
|
86
|
-
|
|
87
56
|
normalize = (label_ref_map, representatives) ->
|
|
88
57
|
# console.log {label_ref_map, representatives}
|
|
89
58
|
Object.keys(label_ref_map).reduce (result, label) ->
|
|
@@ -107,6 +76,6 @@ normalizeAll = (codes,representatives) ->
|
|
|
107
76
|
normalized
|
|
108
77
|
, {}
|
|
109
78
|
|
|
110
|
-
module.exports = {minimize,
|
|
79
|
+
module.exports = {minimize,normalize,normalizeAll}
|
|
111
80
|
|
|
112
81
|
|
package/codes.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
|
2
2
|
(function() {
|
|
3
|
-
var are_different,
|
|
3
|
+
var are_different, minimize, normalize, normalizeAll;
|
|
4
4
|
|
|
5
5
|
are_different = function(classes, representatives, name1, name2, codes) {
|
|
6
6
|
var arg1, arg2, code1, code2, field, fields1, fields2, rep;
|
|
@@ -92,53 +92,6 @@
|
|
|
92
92
|
return {classes, representatives};
|
|
93
93
|
};
|
|
94
94
|
|
|
95
|
-
compareAs = function(fn) {
|
|
96
|
-
return function(a, b) {
|
|
97
|
-
[a, b] = [a, b].map(fn);
|
|
98
|
-
if (a < b) {
|
|
99
|
-
return -1;
|
|
100
|
-
}
|
|
101
|
-
if (a > b) {
|
|
102
|
-
return 1;
|
|
103
|
-
}
|
|
104
|
-
return 0;
|
|
105
|
-
};
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
pretty_labels = function(label_ref_map, codes, representatives) {
|
|
109
|
-
var labels;
|
|
110
|
-
return labels = Object.keys(label_ref_map).sort(compareAs(function(x) {
|
|
111
|
-
return x;
|
|
112
|
-
})).map(function(label) {
|
|
113
|
-
return `${pretty({
|
|
114
|
-
code: "ref",
|
|
115
|
-
ref: label_ref_map[label]
|
|
116
|
-
}, codes, representatives)} ${label}`;
|
|
117
|
-
}).join(", ");
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
pretty = function(codeExp, codes, representatives) {
|
|
121
|
-
var name, ref, ref1;
|
|
122
|
-
switch (codeExp.code) {
|
|
123
|
-
case "ref":
|
|
124
|
-
name = (ref = representatives[codeExp.ref]) != null ? ref : codeExp.ref;
|
|
125
|
-
if (name.startsWith(":")) {
|
|
126
|
-
return pretty(codes[name], codes, representatives);
|
|
127
|
-
} else {
|
|
128
|
-
return name;
|
|
129
|
-
}
|
|
130
|
-
break;
|
|
131
|
-
case "product":
|
|
132
|
-
return `{${pretty_labels(codeExp.product, codes, representatives)}}`;
|
|
133
|
-
case "union":
|
|
134
|
-
return `<${pretty_labels(codeExp.union, codes, representatives)}>`;
|
|
135
|
-
case "vector":
|
|
136
|
-
return `[${(ref1 = representatives[codeExp.ref]) != null ? ref1 : codeExp.ref}]`;
|
|
137
|
-
default:
|
|
138
|
-
return ":error";
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
95
|
normalize = function(label_ref_map, representatives) {
|
|
143
96
|
// console.log {label_ref_map, representatives}
|
|
144
97
|
return Object.keys(label_ref_map).reduce(function(result, label) {
|
|
@@ -176,6 +129,6 @@
|
|
|
176
129
|
}, {});
|
|
177
130
|
};
|
|
178
131
|
|
|
179
|
-
module.exports = {minimize,
|
|
132
|
+
module.exports = {minimize, normalize, normalizeAll};
|
|
180
133
|
|
|
181
134
|
}).call(this);
|
package/package.json
CHANGED
package/parser.jison
CHANGED
|
@@ -82,8 +82,10 @@ non_empty_labelled_codes
|
|
|
82
82
|
code_label
|
|
83
83
|
: code name { $$ = {label: $2, code: $1}; }
|
|
84
84
|
| code str { $$ = {label: $2, code: $1}; }
|
|
85
|
+
| code int { $$ = {label: $2, code: $1}; }
|
|
85
86
|
| name COL code { $$ = {label: $1, code: $3}; }
|
|
86
87
|
| str COL code { $$ = {label: $1, code: $3}; }
|
|
88
|
+
| int COL code { $$ = {label: $1, code: $3}; }
|
|
87
89
|
;
|
|
88
90
|
|
|
89
91
|
comp
|
|
@@ -121,8 +123,10 @@ non_empty_labelled
|
|
|
121
123
|
comp_label
|
|
122
124
|
: comp name { $$ = {label: $2, exp: $1}; }
|
|
123
125
|
| comp str { $$ = {label: $2, exp: $1}; }
|
|
126
|
+
| comp int { $$ = {label: $2, exp: $1}; }
|
|
124
127
|
| name COL comp { $$ = {label: $1, exp: $3}; }
|
|
125
128
|
| str COL comp { $$ = {label: $1, exp: $3}; }
|
|
129
|
+
| int COL comp { $$ = {label: $1, exp: $3}; }
|
|
126
130
|
;
|
|
127
131
|
|
|
128
132
|
list
|
package/parser.js
CHANGED
|
@@ -72,12 +72,12 @@
|
|
|
72
72
|
}
|
|
73
73
|
*/
|
|
74
74
|
var parser = (function(){
|
|
75
|
-
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,32,34],$V1=[1,7],$V2=[1,15],$V3=[1,16],$V4=[1,8],$V5=[1,9],$V6=[1,10],$V7=[1,11],$V8=[1,14],$V9=[1,20],$Va=[4,6,8,12,15,18,21,23,32,34],$Vb=[2,
|
|
75
|
+
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,32,34],$V1=[1,7],$V2=[1,15],$V3=[1,16],$V4=[1,8],$V5=[1,9],$V6=[1,10],$V7=[1,11],$V8=[1,14],$V9=[1,20],$Va=[4,6,8,12,15,18,21,23,32,34],$Vb=[2,28],$Vc=[1,25],$Vd=[1,26],$Ve=[1,27],$Vf=[4,6,8,12,14,15,18,20,21,22,23,24,27,32,33,34],$Vg=[2,47],$Vh=[2,31],$Vi=[2,32],$Vj=[4,6,8,12,14,15,18,20,21,22,23,24,27,28,32,33,34],$Vk=[2,8],$Vl=[2,13],$Vm=[20,27],$Vn=[22,24,27],$Vo=[20,24,27],$Vp=[2,41],$Vq=[2,42],$Vr=[2,43];
|
|
76
76
|
var parser = {trace: function trace () { },
|
|
77
77
|
yy: {},
|
|
78
78
|
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,"labelled":30,"list":31,"LP":32,"RP":33,"DOT":34,"non_empty_labelled":35,"comp_label":36,"non_empty_list":37,"$accept":0,"$end":1},
|
|
79
79
|
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",32:"LP",33:"RP",34:"DOT"},
|
|
80
|
-
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,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],[30,0],[30,1],[35,1],[35,3],[36,2],[36,2],[36,3],[36,3],[31,0],[31,1],[37,1],[37,3]],
|
|
80
|
+
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],[30,0],[30,1],[35,1],[35,3],[36,2],[36,2],[36,2],[36,3],[36,3],[36,3],[31,0],[31,1],[37,1],[37,3]],
|
|
81
81
|
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
|
|
82
82
|
/* this == yyval */
|
|
83
83
|
|
|
@@ -111,7 +111,7 @@ break;
|
|
|
111
111
|
case 8:
|
|
112
112
|
this.$ = {code: "ref", ref: $$[$0]};
|
|
113
113
|
break;
|
|
114
|
-
case 9: case
|
|
114
|
+
case 9: case 23: case 38: case 48:
|
|
115
115
|
this.$ = $$[$0];
|
|
116
116
|
break;
|
|
117
117
|
case 10:
|
|
@@ -132,72 +132,72 @@ case 14:
|
|
|
132
132
|
return r }
|
|
133
133
|
, {});
|
|
134
134
|
break;
|
|
135
|
-
case 15: case
|
|
135
|
+
case 15: case 49:
|
|
136
136
|
this.$ = [$$[$0]];
|
|
137
137
|
break;
|
|
138
|
-
case 16: case
|
|
138
|
+
case 16: case 50:
|
|
139
139
|
this.$ = [].concat($$[$0-2],$$[$0]);
|
|
140
140
|
break;
|
|
141
|
-
case 17: case 18:
|
|
141
|
+
case 17: case 18: case 19:
|
|
142
142
|
this.$ = {label: $$[$0], code: $$[$0-1]};
|
|
143
143
|
break;
|
|
144
|
-
case
|
|
144
|
+
case 20: case 21: case 22:
|
|
145
145
|
this.$ = {label: $$[$0-2], code: $$[$0]};
|
|
146
146
|
break;
|
|
147
|
-
case
|
|
147
|
+
case 24:
|
|
148
148
|
this.$ = s.comp($$[$0-1], $$[$0]);
|
|
149
149
|
break;
|
|
150
|
-
case
|
|
150
|
+
case 25:
|
|
151
151
|
this.$ = $$[$0-1];
|
|
152
152
|
break;
|
|
153
|
-
case
|
|
153
|
+
case 26:
|
|
154
154
|
this.$ = {op: "vector", vector: $$[$0-1]};
|
|
155
155
|
break;
|
|
156
|
-
case
|
|
156
|
+
case 27:
|
|
157
157
|
this.$ = s.union($$[$0-1]);
|
|
158
158
|
break;
|
|
159
|
-
case
|
|
159
|
+
case 28:
|
|
160
160
|
this.$ = {op: "ref", ref: $$[$0]};
|
|
161
161
|
break;
|
|
162
|
-
case
|
|
162
|
+
case 29:
|
|
163
163
|
this.$ = s.identity;
|
|
164
164
|
break;
|
|
165
|
-
case
|
|
165
|
+
case 30:
|
|
166
166
|
this.$ = $$[$0-1];
|
|
167
167
|
break;
|
|
168
|
-
case
|
|
168
|
+
case 31:
|
|
169
169
|
this.$ = {op: "str", str: $$[$0]};
|
|
170
170
|
break;
|
|
171
|
-
case
|
|
171
|
+
case 32:
|
|
172
172
|
this.$ = {op: "int", int: $$[$0]};
|
|
173
173
|
break;
|
|
174
|
-
case
|
|
174
|
+
case 33: case 34: case 35:
|
|
175
175
|
this.$ = {op: "dot", dot: $$[$0]};
|
|
176
176
|
break;
|
|
177
|
-
case
|
|
177
|
+
case 36:
|
|
178
178
|
this.$ = {op: "code", code: s.as_ref($$[$0])};
|
|
179
179
|
break;
|
|
180
|
-
case
|
|
180
|
+
case 37:
|
|
181
181
|
this.$ = {op: "product", product: []};
|
|
182
182
|
break;
|
|
183
|
-
case
|
|
183
|
+
case 39:
|
|
184
184
|
this.$ = {op: "product", product: [$$[$0]]};
|
|
185
185
|
break;
|
|
186
|
-
case
|
|
186
|
+
case 40:
|
|
187
187
|
$$[$0-2].product = [].concat($$[$0-2].product,$$[$0]); this.$ = $$[$0-2];
|
|
188
188
|
break;
|
|
189
|
-
case
|
|
189
|
+
case 41: case 42: case 43:
|
|
190
190
|
this.$ = {label: $$[$0], exp: $$[$0-1]};
|
|
191
191
|
break;
|
|
192
|
-
case
|
|
192
|
+
case 44: case 45: case 46:
|
|
193
193
|
this.$ = {label: $$[$0-2], exp: $$[$0]};
|
|
194
194
|
break;
|
|
195
|
-
case
|
|
195
|
+
case 47:
|
|
196
196
|
this.$ = [];
|
|
197
197
|
break;
|
|
198
198
|
}
|
|
199
199
|
},
|
|
200
|
-
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,32:$V7,34:$V8},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,12:[1,17],15:$V9,18:$V4,21:$V5,23:$V6,29:18,32:$V7,34:$V8},o($Va,$Vb,{13:[1,21]}),{3:22,4:$V1,16:24,17:23,18:$Vc,21:$Vd,23:$Ve},o($Vf,[2,
|
|
200
|
+
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,32:$V7,34:$V8},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,12:[1,17],15:$V9,18:$V4,21:$V5,23:$V6,29:18,32:$V7,34:$V8},o($Va,$Vb,{13:[1,21]}),{3:22,4:$V1,16:24,17:23,18:$Vc,21:$Vd,23:$Ve},o($Vf,[2,23]),o([4,6,8,12,13,14,15,18,20,21,22,23,24,27,28,32,33,34],[2,1]),{3:32,4:$V1,5:33,6:$V2,7:34,8:$V3,11:31,15:$V9,18:$V4,20:[2,37],21:$V5,23:$V6,29:6,30:28,32:$V7,34:$V8,35:29,36:30},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:37,15:$V9,18:$V4,21:$V5,22:$Vg,23:$V6,29:6,31:35,32:$V7,34:$V8,37:36},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:37,15:$V9,18:$V4,21:$V5,23:$V6,24:$Vg,29:6,31:38,32:$V7,34:$V8,37:36},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:40,15:$V9,18:$V4,21:$V5,23:$V6,29:6,32:$V7,33:[1,39],34:$V8},o($Vf,$Vh),o($Vf,$Vi),{3:43,4:$V1,5:42,6:$V2,7:41,8:$V3},o($Vj,[2,2]),o($Vj,[2,3]),{1:[2,4]},o($Vf,[2,24]),o($Vf,$Vb),{3:44,4:$V1,16:24,17:23,18:$Vc,21:$Vd,23:$Ve},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:45,15:$V9,18:$V4,21:$V5,23:$V6,29:6,32:$V7,34:$V8},o($Va,$Vk,{13:[1,46]}),o($Vf,[2,36]),o($Vf,[2,9]),{3:51,4:$V1,5:52,6:$V2,7:53,8:$V3,16:24,17:50,18:$Vc,19:47,20:$Vl,21:$Vd,23:$Ve,25:48,26:49},{3:44,4:$V1,16:24,17:54,18:$Vc,21:$Vd,23:$Ve},{3:51,4:$V1,5:52,6:$V2,7:53,8:$V3,16:24,17:50,18:$Vc,19:55,21:$Vd,23:$Ve,24:$Vl,25:48,26:49},{20:[1,56]},{20:[2,38],27:[1,57]},o($Vm,[2,39]),{3:58,4:$V1,5:59,6:$V2,7:60,8:$V3,15:$V9,18:$V4,21:$V5,23:$V6,29:18,32:$V7,34:$V8},o($V0,$Vb,{28:[1,61]}),o($V0,$Vh,{28:[1,62]}),o($V0,$Vi,{28:[1,63]}),{22:[1,64]},o([22,24],[2,48],{27:[1,65]}),o($Vn,[2,49],{5:12,7:13,29:18,3:19,4:$V1,6:$V2,8:$V3,15:$V9,18:$V4,21:$V5,23:$V6,32:$V7,34:$V8}),{24:[1,66]},o($Vf,[2,29]),{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,15:$V9,18:$V4,21:$V5,23:$V6,29:18,32:$V7,33:[1,67],34:$V8},o($Vf,[2,33]),o($Vf,[2,34]),o($Vf,[2,35]),o($Vf,$Vk),{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,14:[1,68],15:$V9,18:$V4,21:$V5,23:$V6,29:18,32:$V7,34:$V8},{16:69,18:$Vc,21:$Vd,23:$Ve},{20:[1,70]},o([20,24],[2,14],{27:[1,71]}),o($Vo,[2,15]),{3:72,4:$V1,5:73,6:$V2,7:74,8:$V3},o([4,6,8],$Vk,{28:[1,75]}),{28:[1,76]},{28:[1,77]},{22:[1,78]},{24:[1,79]},o($Vf,[2,25]),{3:32,4:$V1,5:33,6:$V2,7:34,8:$V3,11:31,15:$V9,18:$V4,21:$V5,23:$V6,29:6,32:$V7,34:$V8,36:80},o($V0,$Vb,{20:$Vp,27:$Vp}),o($V0,$Vh,{20:$Vq,27:$Vq}),o($V0,$Vi,{20:$Vr,27:$Vr}),{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:81,15:$V9,18:$V4,21:$V5,23:$V6,29:6,32:$V7,34:$V8},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:82,15:$V9,18:$V4,21:$V5,23:$V6,29:6,32:$V7,34:$V8},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:83,15:$V9,18:$V4,21:$V5,23:$V6,29:6,32:$V7,34:$V8},o($Vf,[2,26]),{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:84,15:$V9,18:$V4,21:$V5,23:$V6,29:6,32:$V7,34:$V8},o($Vf,[2,27]),o($Vf,[2,30]),o($V0,[2,6]),{14:[1,85]},o($Vf,[2,10]),{3:51,4:$V1,5:52,6:$V2,7:53,8:$V3,16:24,17:50,18:$Vc,21:$Vd,23:$Ve,26:86},o($Vo,[2,17]),o($Vo,[2,18]),o($Vo,[2,19]),{3:44,4:$V1,16:24,17:87,18:$Vc,21:$Vd,23:$Ve},{3:44,4:$V1,16:24,17:88,18:$Vc,21:$Vd,23:$Ve},{3:44,4:$V1,16:24,17:89,18:$Vc,21:$Vd,23:$Ve},o($Vf,[2,11]),o($Vf,[2,12]),o($Vm,[2,40]),o($Vm,[2,44],{5:12,7:13,29:18,3:19,4:$V1,6:$V2,8:$V3,15:$V9,18:$V4,21:$V5,23:$V6,32:$V7,34:$V8}),o($Vm,[2,45],{5:12,7:13,29:18,3:19,4:$V1,6:$V2,8:$V3,15:$V9,18:$V4,21:$V5,23:$V6,32:$V7,34:$V8}),o($Vm,[2,46],{5:12,7:13,29:18,3:19,4:$V1,6:$V2,8:$V3,15:$V9,18:$V4,21:$V5,23:$V6,32:$V7,34:$V8}),o($Vn,[2,50],{5:12,7:13,29:18,3:19,4:$V1,6:$V2,8:$V3,15:$V9,18:$V4,21:$V5,23:$V6,32:$V7,34:$V8}),o($V0,[2,7]),o($Vo,[2,16]),o($Vo,[2,20]),o($Vo,[2,21]),o($Vo,[2,22])],
|
|
201
201
|
defaultActions: {17:[2,4]},
|
|
202
202
|
parseError: function parseError (str, hash) {
|
|
203
203
|
if (hash.recoverable) {
|
package/pretty.coffee
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
|
|
2
|
+
compareAs = (fn) ->
|
|
3
|
+
(a,b) ->
|
|
4
|
+
[a,b] = [a,b].map fn
|
|
5
|
+
return -1 if a < b
|
|
6
|
+
return 1 if a > b
|
|
7
|
+
0
|
|
8
|
+
|
|
9
|
+
nameRE = /^[a-zA-Z_][a-zA-Z0-9_?!]*$/
|
|
10
|
+
prettyCode_labels = ( codes, representatives, label_ref_map) ->
|
|
11
|
+
labels = Object.keys(label_ref_map)
|
|
12
|
+
.sort compareAs (x) -> x
|
|
13
|
+
.map (label) ->
|
|
14
|
+
plabel = if /^[a-zA-Z_][a-zA-Z0-9_?!]*$/.test label
|
|
15
|
+
label
|
|
16
|
+
else
|
|
17
|
+
"'#{label}'"
|
|
18
|
+
"#{prettyCode codes, representatives, {code:"ref",ref:label_ref_map[label]}} #{plabel}"
|
|
19
|
+
.join ", "
|
|
20
|
+
|
|
21
|
+
prettyCode = (codes, representatives, codeExp) ->
|
|
22
|
+
switch codeExp.code
|
|
23
|
+
when "ref"
|
|
24
|
+
name = representatives[codeExp.ref] ? codeExp.ref
|
|
25
|
+
if name.startsWith ":"
|
|
26
|
+
prettyCode codes, representatives, codes[name]
|
|
27
|
+
else
|
|
28
|
+
name
|
|
29
|
+
when "product"
|
|
30
|
+
"{#{prettyCode_labels codes, representatives, codeExp.product}}"
|
|
31
|
+
when "union"
|
|
32
|
+
"<#{prettyCode_labels codes, representatives, codeExp.union}>"
|
|
33
|
+
when "vector"
|
|
34
|
+
"[#{representatives[codeExp.vector] ? codeExp.vector}]"
|
|
35
|
+
else
|
|
36
|
+
":error"
|
|
37
|
+
|
|
38
|
+
prettyRel = (prettyCode, exp) ->
|
|
39
|
+
"use strict"
|
|
40
|
+
pretty = (exp) ->
|
|
41
|
+
switch exp.op
|
|
42
|
+
when 'vector'
|
|
43
|
+
"[#{exp.vector.map(pretty).join(", ")}]"
|
|
44
|
+
when 'union'
|
|
45
|
+
"<#{exp.union.map(pretty).join(", ")}>"
|
|
46
|
+
when 'ref'
|
|
47
|
+
exp.ref
|
|
48
|
+
when 'identity'
|
|
49
|
+
"()"
|
|
50
|
+
when 'comp'
|
|
51
|
+
exp.comp.map(pretty).join(" ")
|
|
52
|
+
when 'str'
|
|
53
|
+
"'#{exp.str}'"
|
|
54
|
+
when 'int'
|
|
55
|
+
exp.int
|
|
56
|
+
when 'dot'
|
|
57
|
+
if 'number' is typeof exp.dot
|
|
58
|
+
".#{exp.dot}"
|
|
59
|
+
else if nameRE.test exp.dot
|
|
60
|
+
".#{exp.dot}"
|
|
61
|
+
else
|
|
62
|
+
"'#{exp.dot}'"
|
|
63
|
+
when 'code'
|
|
64
|
+
"$#{prettyCode {code:"ref",ref:exp.code}}"
|
|
65
|
+
when 'product'
|
|
66
|
+
do (labelled = exp.product.map ({label,exp}) ->
|
|
67
|
+
if /^[a-zA-Z_][a-zA-Z0-9_?!]*$/.test label
|
|
68
|
+
"#{pretty exp} #{label}"
|
|
69
|
+
else
|
|
70
|
+
"#{pretty exp} '#{label}'") ->
|
|
71
|
+
"{#{labelled.join(", ")}}"
|
|
72
|
+
pretty exp
|
|
73
|
+
|
|
74
|
+
module.exports = { prettyCode, prettyRel }
|
package/pretty.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Generated by CoffeeScript 2.7.0
|
|
2
|
+
(function() {
|
|
3
|
+
var compareAs, nameRE, prettyCode, prettyCode_labels, prettyRel;
|
|
4
|
+
|
|
5
|
+
compareAs = function(fn) {
|
|
6
|
+
return function(a, b) {
|
|
7
|
+
[a, b] = [a, b].map(fn);
|
|
8
|
+
if (a < b) {
|
|
9
|
+
return -1;
|
|
10
|
+
}
|
|
11
|
+
if (a > b) {
|
|
12
|
+
return 1;
|
|
13
|
+
}
|
|
14
|
+
return 0;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
nameRE = /^[a-zA-Z_][a-zA-Z0-9_?!]*$/;
|
|
19
|
+
|
|
20
|
+
prettyCode_labels = function(codes, representatives, label_ref_map) {
|
|
21
|
+
var labels;
|
|
22
|
+
return labels = Object.keys(label_ref_map).sort(compareAs(function(x) {
|
|
23
|
+
return x;
|
|
24
|
+
})).map(function(label) {
|
|
25
|
+
var plabel;
|
|
26
|
+
plabel = /^[a-zA-Z_][a-zA-Z0-9_?!]*$/.test(label) ? label : `'${label}'`;
|
|
27
|
+
return `${prettyCode(codes, representatives, {
|
|
28
|
+
code: "ref",
|
|
29
|
+
ref: label_ref_map[label]
|
|
30
|
+
})} ${plabel}`;
|
|
31
|
+
}).join(", ");
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
prettyCode = function(codes, representatives, codeExp) {
|
|
35
|
+
var name, ref, ref1;
|
|
36
|
+
switch (codeExp.code) {
|
|
37
|
+
case "ref":
|
|
38
|
+
name = (ref = representatives[codeExp.ref]) != null ? ref : codeExp.ref;
|
|
39
|
+
if (name.startsWith(":")) {
|
|
40
|
+
return prettyCode(codes, representatives, codes[name]);
|
|
41
|
+
} else {
|
|
42
|
+
return name;
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
45
|
+
case "product":
|
|
46
|
+
return `{${prettyCode_labels(codes, representatives, codeExp.product)}}`;
|
|
47
|
+
case "union":
|
|
48
|
+
return `<${prettyCode_labels(codes, representatives, codeExp.union)}>`;
|
|
49
|
+
case "vector":
|
|
50
|
+
return `[${(ref1 = representatives[codeExp.vector]) != null ? ref1 : codeExp.vector}]`;
|
|
51
|
+
default:
|
|
52
|
+
return ":error";
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
prettyRel = function(prettyCode, exp) {
|
|
57
|
+
"use strict";
|
|
58
|
+
var pretty;
|
|
59
|
+
pretty = function(exp) {
|
|
60
|
+
switch (exp.op) {
|
|
61
|
+
case 'vector':
|
|
62
|
+
return `[${exp.vector.map(pretty).join(", ")}]`;
|
|
63
|
+
case 'union':
|
|
64
|
+
return `<${exp.union.map(pretty).join(", ")}>`;
|
|
65
|
+
case 'ref':
|
|
66
|
+
return exp.ref;
|
|
67
|
+
case 'identity':
|
|
68
|
+
return "()";
|
|
69
|
+
case 'comp':
|
|
70
|
+
return exp.comp.map(pretty).join(" ");
|
|
71
|
+
case 'str':
|
|
72
|
+
return `'${exp.str}'`;
|
|
73
|
+
case 'int':
|
|
74
|
+
return exp.int;
|
|
75
|
+
case 'dot':
|
|
76
|
+
if ('number' === typeof exp.dot) {
|
|
77
|
+
return `.${exp.dot}`;
|
|
78
|
+
} else if (nameRE.test(exp.dot)) {
|
|
79
|
+
return `.${exp.dot}`;
|
|
80
|
+
} else {
|
|
81
|
+
return `'${exp.dot}'`;
|
|
82
|
+
}
|
|
83
|
+
break;
|
|
84
|
+
case 'code':
|
|
85
|
+
return `$${prettyCode({
|
|
86
|
+
code: "ref",
|
|
87
|
+
ref: exp.code
|
|
88
|
+
})}`;
|
|
89
|
+
case 'product':
|
|
90
|
+
return (function(labelled) {
|
|
91
|
+
return `{${labelled.join(", ")}}`;
|
|
92
|
+
})(exp.product.map(function({label, exp}) {
|
|
93
|
+
if (/^[a-zA-Z_][a-zA-Z0-9_?!]*$/.test(label)) {
|
|
94
|
+
return `${pretty(exp)} ${label}`;
|
|
95
|
+
} else {
|
|
96
|
+
return `${pretty(exp)} '${label}'`;
|
|
97
|
+
}
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
return pretty(exp);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
module.exports = {prettyCode, prettyRel};
|
|
105
|
+
|
|
106
|
+
}).call(this);
|