@fraczak/k 1.3.2 → 1.3.4
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 +50 -21
- package/README.md +4 -4
- package/package.json +2 -2
- package/parser.jison +23 -3
- package/parser.js +25 -5
- package/run.coffee +0 -5
- package/run.js +0 -13
- package/symbol-table.coffee +28 -2
- package/symbol-table.js +40 -3
- package/index.cjs +0 -49
- package/symbol-table.cjs +0 -128
- package/test.cjs +0 -162
package/INTRO.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# k - the way of building and manipulating JSON-like data
|
|
2
2
|
|
|
3
|
-
Technically
|
|
3
|
+
Technically, `k` is a notation for defining __first-order partial functions__.
|
|
4
4
|
|
|
5
|
-
An example of a _partial function_ is "`.toto`",
|
|
6
|
-
to its property named `toto`, or it is not defined if
|
|
7
|
-
doesn't exist. E.g.,
|
|
5
|
+
An example of a _partial function_ is the _projection_, e.g., "`.toto`",
|
|
6
|
+
which maps an object to its property named `toto`, or it is not defined if
|
|
7
|
+
the property doesn't exist. E.g.,
|
|
8
8
|
|
|
9
9
|
.toto :
|
|
10
10
|
{"toto": 5, "titi": 10} --> 5
|
|
@@ -51,6 +51,14 @@ __QUIZ__: What is:
|
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
+
#### Syntactic sugar:
|
|
55
|
+
|
|
56
|
+
- parenthesis can be omitted, except for the empty composition `()`,
|
|
57
|
+
- dot (`.`) in "projection" acts as a separator so the space around it can be omitted.
|
|
58
|
+
|
|
59
|
+
For example, `[(.toto .titi (.0 .1))]` can be written as `[.toto.titi.0.1]`.
|
|
60
|
+
|
|
61
|
+
|
|
54
62
|
## Basic extensions
|
|
55
63
|
|
|
56
64
|
### Constants, i.e., literals for `strings`, `integers`, `booleans`, and `null`
|
|
@@ -77,19 +85,25 @@ names are integers starting from zero. E.g., `{.toto "0", .titi "1",
|
|
|
77
85
|
|
|
78
86
|
## Pragmatic extensions, aka "standard library"
|
|
79
87
|
|
|
80
|
-
- `GT` :
|
|
88
|
+
- `GT` : -- identity for lists of decreasing elements; undefined otherwise
|
|
81
89
|
|
|
90
|
+
[4,3] --> [4,3]
|
|
91
|
+
[3,4] ... undefined
|
|
92
|
+
[] --> []
|
|
82
93
|
[4,3,0] --> [4,3,0]
|
|
83
|
-
[5,8] - undefined
|
|
84
94
|
|
|
85
|
-
- `EQ` :
|
|
95
|
+
- `EQ` : -- identity for lists of equal elements; undefined otherwise
|
|
86
96
|
|
|
97
|
+
[4,4] --> [4,4]
|
|
98
|
+
[4,5] ... undefined
|
|
87
99
|
[4,4,4] --> [4,4,4]
|
|
88
|
-
[
|
|
100
|
+
[] --> []
|
|
89
101
|
|
|
90
|
-
- `
|
|
102
|
+
- `{PLUS plus, TIMES times}` :
|
|
91
103
|
|
|
92
|
-
[
|
|
104
|
+
[1,2] --> {"plus":3,"times":2}
|
|
105
|
+
[2,2,2] --> {"plus":6,"times":8}
|
|
106
|
+
[] --> {"plus":0,"times":1}
|
|
93
107
|
|
|
94
108
|
- `CONCAT` :
|
|
95
109
|
|
|
@@ -97,24 +111,25 @@ names are integers starting from zero. E.g., `{.toto "0", .titi "1",
|
|
|
97
111
|
|
|
98
112
|
- `toJSON` :
|
|
99
113
|
|
|
100
|
-
{a: 12} --> "{\"a\":12}"
|
|
114
|
+
{"a": 12} --> "{\"a\":12}"
|
|
101
115
|
|
|
102
116
|
- `fromJSON` :
|
|
103
117
|
|
|
104
|
-
"{\"a\":12}" --> {a:
|
|
118
|
+
"{\"a\":12}" --> {"a":12}
|
|
105
119
|
|
|
106
|
-
- `DIV`, `FDIV`, `CONS`, `SNOC`, `
|
|
120
|
+
- other predefined parial functions are: `DIV`, `FDIV`, `CONS`, `SNOC`, `toDateMsec`,
|
|
121
|
+
`toDateStr`, and `_log!`.
|
|
107
122
|
|
|
108
123
|
---
|
|
109
124
|
|
|
110
125
|
## Recursive definitions
|
|
111
126
|
|
|
112
127
|
-- factorial.k
|
|
113
|
-
dec =
|
|
114
|
-
zero? =
|
|
128
|
+
dec = [(),-1] PLUS;
|
|
129
|
+
zero? = [(),0] EQ 0;
|
|
115
130
|
factorial = <
|
|
116
|
-
|
|
117
|
-
|
|
131
|
+
zero? 1,
|
|
132
|
+
[dec factorial, ()] TIMES
|
|
118
133
|
>;
|
|
119
134
|
{ () x, factorial "x!" }
|
|
120
135
|
|
|
@@ -122,10 +137,24 @@ names are integers starting from zero. E.g., `{.toto "0", .titi "1",
|
|
|
122
137
|
|
|
123
138
|
_Codes_ (prefixed by `$`) can be defined by taged union and product. E.g.:
|
|
124
139
|
|
|
125
|
-
$nat = <nat
|
|
126
|
-
$pair = {nat x, nat y};
|
|
140
|
+
$nat = <nat 1, {} 0>;
|
|
141
|
+
$pair = {nat x, nat y};
|
|
127
142
|
|
|
128
|
-
|
|
129
|
-
add =
|
|
143
|
+
suc = {$nat 1};
|
|
144
|
+
add = $pair <{.x.1 x, .y suc y} add, .y>;
|
|
145
|
+
|
|
146
|
+
### Basic extension codes
|
|
147
|
+
|
|
148
|
+
Since _basic extension_ introduces integers, booleans, and strings, there are three
|
|
149
|
+
predefined types: `int`, `bool`, and `string`. A vector product code can also be defined
|
|
150
|
+
by `[ codeExp ]`. All members of the vector are the same code. E.g.,
|
|
151
|
+
|
|
152
|
+
$intVector = [ int ];
|
|
153
|
+
$boolVector = [ bool ];
|
|
154
|
+
$tree = [ tree ];
|
|
155
|
+
|
|
156
|
+
emptyList? = $intVector $[ string ]; -- as only an empty vector can be a vector
|
|
157
|
+
-- of integers and a vector of strings
|
|
158
|
+
|
|
130
159
|
|
|
131
160
|
|
package/README.md
CHANGED
|
@@ -51,14 +51,14 @@ the field (or a vector with the index).
|
|
|
51
51
|
false
|
|
52
52
|
null
|
|
53
53
|
|
|
54
|
-
6.
|
|
55
|
-
`TIMES`, `
|
|
56
|
-
`SNOC`, `_log
|
|
54
|
+
6. The other "built-in" functions: `GT`, `EQ`, `PLUS`,
|
|
55
|
+
`TIMES`, `DIV`, `CONCAT`, `toJSON`, `fromJSON`, `CONS`,
|
|
56
|
+
`SNOC`, `toDateMsec`, `toDateStr`, and `_log!`. For example:
|
|
57
57
|
|
|
58
58
|
[1, 2, 3] PLUS --> integer constant function 6
|
|
59
59
|
[4, 4] TIMES toJSON --> string constant function "16"
|
|
60
60
|
[3, 2] GT --> vector constant function [3, 2]
|
|
61
|
-
[3, 4] GT
|
|
61
|
+
[3, 4] GT ... is not defined!
|
|
62
62
|
|
|
63
63
|
A more interesting example could be:
|
|
64
64
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fraczak/k",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "k-language for JSON-like data transformation",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"coffeescript": "^2.7.0",
|
|
24
|
-
"jiwson": "^0.
|
|
24
|
+
"jiwson": "^0.1.1"
|
|
25
25
|
}
|
|
26
26
|
}
|
package/parser.jison
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
var s = require("./symbol-table");
|
|
4
4
|
|
|
5
|
+
function fromEscString(escString) {
|
|
6
|
+
const isSingleQuoted = escString.startsWith("'");
|
|
7
|
+
let str = escString.substring(1, escString.length - 1);
|
|
8
|
+
if (isSingleQuoted) {
|
|
9
|
+
str = str.replace(/\\'/g, "'");
|
|
10
|
+
} else {
|
|
11
|
+
str = str.replace(/\\"/g, '"');
|
|
12
|
+
}
|
|
13
|
+
str = str.replace(/\\\\/g, '\\');
|
|
14
|
+
str = str.replace(/\\\//g, '/');
|
|
15
|
+
str = str.replace(/\\b/g, '\b');
|
|
16
|
+
str = str.replace(/\\f/g, '\f');
|
|
17
|
+
str = str.replace(/\\n/g, '\n');
|
|
18
|
+
str = str.replace(/\\r/g, '\r');
|
|
19
|
+
str = str.replace(/\\t/g, '\t');
|
|
20
|
+
str = str.replace(/\\u([\dA-F]{4})/gi, (match, p1) => String.fromCharCode(parseInt(p1, 16)));
|
|
21
|
+
|
|
22
|
+
return str;
|
|
23
|
+
}
|
|
24
|
+
|
|
5
25
|
%}
|
|
6
26
|
|
|
7
27
|
%lex
|
|
@@ -24,7 +44,7 @@ var s = require("./symbol-table");
|
|
|
24
44
|
";" return 'SC';
|
|
25
45
|
":" return 'COL';
|
|
26
46
|
"$" return 'DOLLAR';
|
|
27
|
-
\"[
|
|
47
|
+
\"([^"\\]|\\(.|\n))*\"|\'([^'\\]|\\(.|\n))*\' return 'STRING';
|
|
28
48
|
[a-zA-Z_][a-zA-Z0-9_?!]* return 'NAME';
|
|
29
49
|
0|[-]?[1-9][0-9]* return 'INT';
|
|
30
50
|
<<EOF>> return 'EOF';
|
|
@@ -40,11 +60,11 @@ var s = require("./symbol-table");
|
|
|
40
60
|
%%
|
|
41
61
|
|
|
42
62
|
name: NAME { $$ = String(yytext); };
|
|
43
|
-
str: STRING { $$ = String(yytext)
|
|
63
|
+
str: STRING { $$ = fromEscString(String(yytext)); };
|
|
44
64
|
int: INT { $$ = parseInt(String(yytext)); };
|
|
45
65
|
|
|
46
66
|
input_with_eof: defs comp EOF {
|
|
47
|
-
result = {defs: {rels: s.rels, codes: s.codes}, exp: $2};
|
|
67
|
+
const result = {defs: {rels: s.rels, codes: s.codes}, exp: $2};
|
|
48
68
|
// console.log(JSON.stringify(result, "", 2));
|
|
49
69
|
return result;
|
|
50
70
|
};
|
package/parser.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* parser generated by jison 0.
|
|
1
|
+
/* parser generated by jison 0.1.1 */
|
|
2
2
|
/*
|
|
3
3
|
Returns a Parser object of the following structure:
|
|
4
4
|
|
|
@@ -76,6 +76,26 @@
|
|
|
76
76
|
|
|
77
77
|
var s = require("./symbol-table");
|
|
78
78
|
|
|
79
|
+
function fromEscString(escString) {
|
|
80
|
+
const isSingleQuoted = escString.startsWith("'");
|
|
81
|
+
let str = escString.substring(1, escString.length - 1);
|
|
82
|
+
if (isSingleQuoted) {
|
|
83
|
+
str = str.replace(/\\'/g, "'");
|
|
84
|
+
} else {
|
|
85
|
+
str = str.replace(/\\"/g, '"');
|
|
86
|
+
}
|
|
87
|
+
str = str.replace(/\\\\/g, '\\');
|
|
88
|
+
str = str.replace(/\\\//g, '/');
|
|
89
|
+
str = str.replace(/\\b/g, '\b');
|
|
90
|
+
str = str.replace(/\\f/g, '\f');
|
|
91
|
+
str = str.replace(/\\n/g, '\n');
|
|
92
|
+
str = str.replace(/\\r/g, '\r');
|
|
93
|
+
str = str.replace(/\\t/g, '\t');
|
|
94
|
+
str = str.replace(/\\u([\dA-F]{4})/gi, (match, p1) => String.fromCharCode(parseInt(p1, 16)));
|
|
95
|
+
|
|
96
|
+
return str;
|
|
97
|
+
}
|
|
98
|
+
|
|
79
99
|
|
|
80
100
|
|
|
81
101
|
var parser = (function(){
|
|
@@ -94,14 +114,14 @@ case 1:
|
|
|
94
114
|
this.$ = String(yytext);
|
|
95
115
|
break;
|
|
96
116
|
case 2:
|
|
97
|
-
this.$ = String(yytext)
|
|
117
|
+
this.$ = fromEscString(String(yytext));
|
|
98
118
|
break;
|
|
99
119
|
case 3:
|
|
100
120
|
this.$ = parseInt(String(yytext));
|
|
101
121
|
break;
|
|
102
122
|
case 4:
|
|
103
123
|
|
|
104
|
-
result = {defs: {rels: s.rels, codes: s.codes}, exp: $$[$0-1]};
|
|
124
|
+
const result = {defs: {rels: s.rels, codes: s.codes}, exp: $$[$0-1]};
|
|
105
125
|
// console.log(JSON.stringify(result, "", 2));
|
|
106
126
|
return result;
|
|
107
127
|
|
|
@@ -713,7 +733,7 @@ case 15:return 28;
|
|
|
713
733
|
break;
|
|
714
734
|
case 16:return 15;
|
|
715
735
|
break;
|
|
716
|
-
case 17:return 6
|
|
736
|
+
case 17:return 6;
|
|
717
737
|
break;
|
|
718
738
|
case 18:return 4;
|
|
719
739
|
break;
|
|
@@ -723,7 +743,7 @@ case 20:return 12;
|
|
|
723
743
|
break;
|
|
724
744
|
}
|
|
725
745
|
},
|
|
726
|
-
rules: [/^(?:[/][*]([*][^/]|[^*])*[*][/])/,/^(?:(\/\/|#|%|--)[^\n]*)/,/^(?:\s+)/,/^(?:<)/,/^(?:\{)/,/^(?:\[)/,/^(?:\()/,/^(?:>)/,/^(?:\})/,/^(?:\])/,/^(?:\))/,/^(?:=)/,/^(?:\.)/,/^(?:,)/,/^(?:;)/,/^(?::)/,/^(?:\$)/,/^(?:"[
|
|
746
|
+
rules: [/^(?:[/][*]([*][^/]|[^*])*[*][/])/,/^(?:(\/\/|#|%|--)[^\n]*)/,/^(?:\s+)/,/^(?:<)/,/^(?:\{)/,/^(?:\[)/,/^(?:\()/,/^(?:>)/,/^(?:\})/,/^(?:\])/,/^(?:\))/,/^(?:=)/,/^(?:\.)/,/^(?:,)/,/^(?:;)/,/^(?::)/,/^(?:\$)/,/^(?:"([^"\\]|\\(.|\n))*"|'([^'\\]|\\(.|\n))*')/,/^(?:[a-zA-Z_][a-zA-Z0-9_?!]*)/,/^(?:0|[-]?[1-9][0-9]*)/,/^(?:$)/],
|
|
727
747
|
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],"inclusive":true}}
|
|
728
748
|
});
|
|
729
749
|
return lexer;
|
package/run.coffee
CHANGED
|
@@ -20,11 +20,6 @@ builtin =
|
|
|
20
20
|
return args if ok
|
|
21
21
|
"PLUS": (args) -> valid args.reduce ((res, x) -> res + x), 0
|
|
22
22
|
"TIMES": (args) -> valid args.reduce ((res, x) -> res * x), 1
|
|
23
|
-
"MINUS": (args) ->
|
|
24
|
-
return valid(- args) if 'number' is typeof args
|
|
25
|
-
do ([res,args...] = args) ->
|
|
26
|
-
return valid (- res) if args.length is 0
|
|
27
|
-
valid args.reduce ((res, x) -> res - x), res
|
|
28
23
|
"DIV": ([x,y]) ->
|
|
29
24
|
div = x // y
|
|
30
25
|
rem = x %% y
|
package/run.js
CHANGED
|
@@ -49,19 +49,6 @@
|
|
|
49
49
|
return res * x;
|
|
50
50
|
}), 1));
|
|
51
51
|
},
|
|
52
|
-
"MINUS": function(args) {
|
|
53
|
-
if ('number' === typeof args) {
|
|
54
|
-
return valid(-args);
|
|
55
|
-
}
|
|
56
|
-
return (function([res, ...args]) {
|
|
57
|
-
if (args.length === 0) {
|
|
58
|
-
return valid(-res);
|
|
59
|
-
}
|
|
60
|
-
return valid(args.reduce((function(res, x) {
|
|
61
|
-
return res - x;
|
|
62
|
-
}), res));
|
|
63
|
-
})(args);
|
|
64
|
-
},
|
|
65
52
|
"DIV": function([x, y]) {
|
|
66
53
|
var div, rem;
|
|
67
54
|
div = Math.floor(x / y);
|
package/symbol-table.coffee
CHANGED
|
@@ -7,21 +7,37 @@ identity = op: "identity"
|
|
|
7
7
|
is_identity_rel = (rel) ->
|
|
8
8
|
rel.op is "identity"
|
|
9
9
|
|
|
10
|
+
is_constant_rel = (rel) ->
|
|
11
|
+
switch rel?.op
|
|
12
|
+
when "int", "str"
|
|
13
|
+
true
|
|
14
|
+
when "vector"
|
|
15
|
+
Object.values(rel[rel.op]).every is_constant_rel
|
|
16
|
+
when "product"
|
|
17
|
+
Object.values(rel[rel.op]).every ({exp}) ->
|
|
18
|
+
is_constant_rel exp
|
|
19
|
+
else
|
|
20
|
+
false
|
|
21
|
+
|
|
10
22
|
is_empty_rel = (rel) ->
|
|
11
23
|
rel.op is "union" and rel.union.length is 0
|
|
12
24
|
|
|
13
25
|
is_full_rel = (rel) ->
|
|
26
|
+
return true if is_constant_rel rel
|
|
14
27
|
switch rel.op
|
|
15
28
|
when "int", "str", "identity"
|
|
16
29
|
true
|
|
17
30
|
when "comp"
|
|
18
31
|
rel.comp.every is_full_rel
|
|
19
|
-
when "
|
|
32
|
+
when "vector"
|
|
20
33
|
Object.values(rel[rel.op]).every is_full_rel
|
|
34
|
+
when "product"
|
|
35
|
+
Object.values(rel[rel.op]).every ({exp}) ->
|
|
36
|
+
is_full_rel exp
|
|
21
37
|
else
|
|
22
38
|
false
|
|
23
39
|
|
|
24
|
-
|
|
40
|
+
comp_first = (e1, e2) ->
|
|
25
41
|
return e2 if is_identity_rel e1
|
|
26
42
|
return e1 if is_identity_rel e2
|
|
27
43
|
return e1 if is_empty_rel e1
|
|
@@ -34,6 +50,16 @@ comp = (e1, e2) ->
|
|
|
34
50
|
return {op: "comp", comp: [].concat([e1],e2.comp)}
|
|
35
51
|
{op: "comp", comp: [e1,e2]}
|
|
36
52
|
|
|
53
|
+
comp = (e1, e2) ->
|
|
54
|
+
result = comp_first e1, e2
|
|
55
|
+
return result unless result.op is "comp"
|
|
56
|
+
result.comp = result.comp.reduceRight (c, e) ->
|
|
57
|
+
if is_constant_rel(c[0]) and is_full_rel e
|
|
58
|
+
return c
|
|
59
|
+
return [e, c...]
|
|
60
|
+
, []
|
|
61
|
+
result
|
|
62
|
+
|
|
37
63
|
union = (rels) ->
|
|
38
64
|
list = []
|
|
39
65
|
do ->
|
package/symbol-table.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
|
2
2
|
(function() {
|
|
3
|
-
var add_code, add_rel, as_ref, codes, comp, identity, is_empty_rel, is_full_rel, is_identity_rel, rels, union;
|
|
3
|
+
var add_code, add_rel, as_ref, codes, comp, comp_first, identity, is_constant_rel, is_empty_rel, is_full_rel, is_identity_rel, rels, union;
|
|
4
4
|
|
|
5
5
|
rels = Object.create(null);
|
|
6
6
|
|
|
@@ -19,11 +19,30 @@
|
|
|
19
19
|
return rel.op === "identity";
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
is_constant_rel = function(rel) {
|
|
23
|
+
switch (rel != null ? rel.op : void 0) {
|
|
24
|
+
case "int":
|
|
25
|
+
case "str":
|
|
26
|
+
return true;
|
|
27
|
+
case "vector":
|
|
28
|
+
return Object.values(rel[rel.op]).every(is_constant_rel);
|
|
29
|
+
case "product":
|
|
30
|
+
return Object.values(rel[rel.op]).every(function({exp}) {
|
|
31
|
+
return is_constant_rel(exp);
|
|
32
|
+
});
|
|
33
|
+
default:
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
22
38
|
is_empty_rel = function(rel) {
|
|
23
39
|
return rel.op === "union" && rel.union.length === 0;
|
|
24
40
|
};
|
|
25
41
|
|
|
26
42
|
is_full_rel = function(rel) {
|
|
43
|
+
if (is_constant_rel(rel)) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
27
46
|
switch (rel.op) {
|
|
28
47
|
case "int":
|
|
29
48
|
case "str":
|
|
@@ -31,15 +50,18 @@
|
|
|
31
50
|
return true;
|
|
32
51
|
case "comp":
|
|
33
52
|
return rel.comp.every(is_full_rel);
|
|
34
|
-
case "product":
|
|
35
53
|
case "vector":
|
|
36
54
|
return Object.values(rel[rel.op]).every(is_full_rel);
|
|
55
|
+
case "product":
|
|
56
|
+
return Object.values(rel[rel.op]).every(function({exp}) {
|
|
57
|
+
return is_full_rel(exp);
|
|
58
|
+
});
|
|
37
59
|
default:
|
|
38
60
|
return false;
|
|
39
61
|
}
|
|
40
62
|
};
|
|
41
63
|
|
|
42
|
-
|
|
64
|
+
comp_first = function(e1, e2) {
|
|
43
65
|
if (is_identity_rel(e1)) {
|
|
44
66
|
return e2;
|
|
45
67
|
}
|
|
@@ -76,6 +98,21 @@
|
|
|
76
98
|
};
|
|
77
99
|
};
|
|
78
100
|
|
|
101
|
+
comp = function(e1, e2) {
|
|
102
|
+
var result;
|
|
103
|
+
result = comp_first(e1, e2);
|
|
104
|
+
if (result.op !== "comp") {
|
|
105
|
+
return result;
|
|
106
|
+
}
|
|
107
|
+
result.comp = result.comp.reduceRight(function(c, e) {
|
|
108
|
+
if (is_constant_rel(c[0]) && is_full_rel(e)) {
|
|
109
|
+
return c;
|
|
110
|
+
}
|
|
111
|
+
return [e, ...c];
|
|
112
|
+
}, []);
|
|
113
|
+
return result;
|
|
114
|
+
};
|
|
115
|
+
|
|
79
116
|
union = function(rels) {
|
|
80
117
|
var list;
|
|
81
118
|
list = [];
|
package/index.cjs
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
(async function() {
|
|
3
|
-
var compile, finalize, parse, run, runScriptOnData, t;
|
|
4
|
-
|
|
5
|
-
({parse} = await import("./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);
|
package/symbol-table.cjs
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
(function() {
|
|
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
|
-
};
|
|
13
|
-
|
|
14
|
-
identity = {
|
|
15
|
-
op: "identity"
|
|
16
|
-
};
|
|
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
|
-
|
|
42
|
-
comp = function(e1, e2) {
|
|
43
|
-
if (is_identity_rel(e1)) {
|
|
44
|
-
return e2;
|
|
45
|
-
}
|
|
46
|
-
if (is_identity_rel(e2)) {
|
|
47
|
-
return e1;
|
|
48
|
-
}
|
|
49
|
-
if (is_empty_rel(e1)) {
|
|
50
|
-
return e1;
|
|
51
|
-
}
|
|
52
|
-
if (is_empty_rel(e2)) {
|
|
53
|
-
return e2;
|
|
54
|
-
}
|
|
55
|
-
if (e1.op === "comp" && e2.op === "comp") {
|
|
56
|
-
return {
|
|
57
|
-
op: "comp",
|
|
58
|
-
comp: [].concat(e1.comp, e2.comp)
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
if (e1.op === "comp") {
|
|
62
|
-
return {
|
|
63
|
-
op: "comp",
|
|
64
|
-
comp: [].concat(e1.comp, [e2])
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
if (e2.op === "comp") {
|
|
68
|
-
return {
|
|
69
|
-
op: "comp",
|
|
70
|
-
comp: [].concat([e1], e2.comp)
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
op: "comp",
|
|
75
|
-
comp: [e1, e2]
|
|
76
|
-
};
|
|
77
|
-
};
|
|
78
|
-
|
|
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};
|
|
127
|
-
|
|
128
|
-
}).call(this);
|
package/test.cjs
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
// Generated by CoffeeScript 2.7.0
|
|
2
|
-
(function() {
|
|
3
|
-
var k, k_expression, k_fn;
|
|
4
|
-
|
|
5
|
-
k = require("./index.cjs");
|
|
6
|
-
console.log(k);
|
|
7
|
-
|
|
8
|
-
console.log('var k = require("k");');
|
|
9
|
-
|
|
10
|
-
console.log("");
|
|
11
|
-
|
|
12
|
-
[
|
|
13
|
-
["ANYTHING...",
|
|
14
|
-
'()'],
|
|
15
|
-
["ANYTHING...",
|
|
16
|
-
'{"ala" name, 23 age}'],
|
|
17
|
-
[
|
|
18
|
-
{
|
|
19
|
-
year: 2002,
|
|
20
|
-
age: 19
|
|
21
|
-
},
|
|
22
|
-
'[.year, .age]'
|
|
23
|
-
],
|
|
24
|
-
["duplicate me",
|
|
25
|
-
'[(), ()]'],
|
|
26
|
-
["nesting",
|
|
27
|
-
'[[[()]]]'],
|
|
28
|
-
["nesting and accessing",
|
|
29
|
-
'[[()]] {() nested, .0.0 val}'],
|
|
30
|
-
[
|
|
31
|
-
{
|
|
32
|
-
test: "parse integer"
|
|
33
|
-
},
|
|
34
|
-
'0000'
|
|
35
|
-
],
|
|
36
|
-
[
|
|
37
|
-
{
|
|
38
|
-
x: 3,
|
|
39
|
-
y: 4
|
|
40
|
-
},
|
|
41
|
-
'[.y,.x] PLUS'
|
|
42
|
-
]
|
|
43
|
-
].map(function([data, script]) {
|
|
44
|
-
console.log(`k_expression = '${script}';`);
|
|
45
|
-
console.log(`k.run(k_expression,${JSON.stringify(data)});`);
|
|
46
|
-
console.log(`// RETURNS: ${JSON.stringify(k.run(script, data))}`);
|
|
47
|
-
return console.log("");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
k_expression = '{.name nom, <[.age, 18] GT .0, [.age, 12] GT "ado", "enfant"> age}';
|
|
51
|
-
|
|
52
|
-
k_fn = k.compile(k_expression);
|
|
53
|
-
|
|
54
|
-
console.log(`var k_fn = k.compile('${k_expression}');`);
|
|
55
|
-
|
|
56
|
-
console.log("");
|
|
57
|
-
|
|
58
|
-
[
|
|
59
|
-
{
|
|
60
|
-
age: 23,
|
|
61
|
-
name: "Emily"
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
age: 16,
|
|
65
|
-
name: "Katrina"
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
age: 2,
|
|
69
|
-
name: "Mark"
|
|
70
|
-
}
|
|
71
|
-
].map(function(data) {
|
|
72
|
-
console.log(`k_fn(${JSON.stringify(data)});`);
|
|
73
|
-
console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
|
|
74
|
-
return console.log("");
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
k_expression = "$t = < i: int, t: [ t ] > ; <$t, $int>";
|
|
78
|
-
|
|
79
|
-
k_fn = k.compile(k_expression);
|
|
80
|
-
|
|
81
|
-
console.log(`var k_fn = k.compile('${k_expression}');`);
|
|
82
|
-
|
|
83
|
-
console.log("");
|
|
84
|
-
|
|
85
|
-
[
|
|
86
|
-
1,
|
|
87
|
-
{
|
|
88
|
-
i: 1
|
|
89
|
-
},
|
|
90
|
-
[
|
|
91
|
-
{
|
|
92
|
-
i: 2
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
i: 3
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
t: []
|
|
99
|
-
}
|
|
100
|
-
],
|
|
101
|
-
{
|
|
102
|
-
"t": [
|
|
103
|
-
{
|
|
104
|
-
"i": 2
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
"i": 3
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
"t": []
|
|
111
|
-
}
|
|
112
|
-
]
|
|
113
|
-
}
|
|
114
|
-
].map(function(data) {
|
|
115
|
-
console.log(`k_fn(${JSON.stringify(data)});`);
|
|
116
|
-
console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
|
|
117
|
-
return console.log("");
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
k_expression = "$ < < [ int ] ints, [ bool ] bools > list, string None>";
|
|
121
|
-
|
|
122
|
-
k_fn = k.compile(k_expression);
|
|
123
|
-
|
|
124
|
-
console.log(`var k_fn = k.compile('${k_expression}');`);
|
|
125
|
-
|
|
126
|
-
console.log("");
|
|
127
|
-
|
|
128
|
-
[
|
|
129
|
-
{
|
|
130
|
-
None: "None"
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
list: {
|
|
134
|
-
ints: []
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
list: {
|
|
139
|
-
ints: [1,
|
|
140
|
-
2,
|
|
141
|
-
3]
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
{
|
|
145
|
-
list: {
|
|
146
|
-
bools: [true,
|
|
147
|
-
false]
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
list: {
|
|
152
|
-
bools: [true,
|
|
153
|
-
0]
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
].map(function(data) {
|
|
157
|
-
console.log(`k_fn(${JSON.stringify(data)});`);
|
|
158
|
-
console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
|
|
159
|
-
return console.log("");
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
}).call(this);
|