@fraczak/k 1.0.0 → 1.1.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/README.md +46 -10
- package/bnat.k +121 -0
- package/code.k +18 -0
- package/factorial.k +11 -0
- package/fib.k +15 -0
- package/index.coffee +2 -1
- package/index.js +2 -1
- package/k.coffee +35 -21
- package/k.js +52 -31
- package/k.sh +52 -31
- package/package.json +3 -3
- package/parser.jison +53 -7
- package/parser.js +99 -46
- package/pow.k +7 -0
- package/run.coffee +50 -10
- package/run.js +80 -11
- package/test.coffee +16 -0
- package/test.js +43 -0
- package/{test.t → test.k} +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# k-language
|
|
2
2
|
|
|
3
|
-
Another JSON
|
|
3
|
+
Another JSON transformation notation. A `k`-expression
|
|
4
4
|
(script) defines a __partial function__, i.e., a function which, in
|
|
5
5
|
general, is not defined for every input. `k`-expressions can be
|
|
6
6
|
combined to build other `k`-expressions in three ways:
|
|
@@ -11,14 +11,15 @@ combined to build other `k`-expressions in three ways:
|
|
|
11
11
|
|
|
12
12
|
Apart from empty composition, `()`, which defines _identity_, the paranthesis can be omitted.
|
|
13
13
|
|
|
14
|
-
2. product, e.g., vector:
|
|
14
|
+
2. product, e.g., vector or structure:
|
|
15
15
|
|
|
16
16
|
[ E1, E2, E3, ... ]
|
|
17
|
-
|
|
18
|
-
or structure:
|
|
19
|
-
|
|
20
17
|
{ E1 "e1", E2 "e2", E3 "e3", ... }
|
|
21
18
|
|
|
19
|
+
Now, structure can also be written similarly to JSON, ie.,
|
|
20
|
+
|
|
21
|
+
{ e1: E1, e2: E2, e3: E3, ... }
|
|
22
|
+
|
|
22
23
|
3. union (merge), e.g.:
|
|
23
24
|
|
|
24
25
|
< E1, E2, E3, ... >
|
|
@@ -42,11 +43,10 @@ Elementary partial functions are:
|
|
|
42
43
|
'another "String"'
|
|
43
44
|
123
|
|
44
45
|
false
|
|
45
|
-
|
|
46
|
-
Those functions are always defined, i.e., they ignore their argument.
|
|
46
|
+
null
|
|
47
47
|
|
|
48
48
|
3. There is a number of built-in functions: `GT`, `EQ`, `PLUS`,
|
|
49
|
-
`TIMES`, `MINUS`, `DIV`, `CONCAT`, `toJSON`, `fromJSON`. For example
|
|
49
|
+
`TIMES`, `MINUS`, `DIV`, `CONCAT`, `toJSON`, `fromJSON`, `CONS`, `SNOC`. For example
|
|
50
50
|
|
|
51
51
|
[1, 2, 3] PLUS --> integer constant 6
|
|
52
52
|
[4, 4] TIMES toJSON --> string constant "16"
|
|
@@ -61,6 +61,43 @@ Elementary partial functions are:
|
|
|
61
61
|
|
|
62
62
|
[3,8] < [.0, .1] GT, [.1, .0] GT > .0 --> 8
|
|
63
63
|
|
|
64
|
+
## User defined functions
|
|
65
|
+
|
|
66
|
+
`k`-expression can be prefixed by function definitions. E.g.:
|
|
67
|
+
|
|
68
|
+
dec = [(),1] MINUS;
|
|
69
|
+
factorial = <
|
|
70
|
+
[1,()] GT 1,
|
|
71
|
+
[dec factorial, ()] TIMES
|
|
72
|
+
>;
|
|
73
|
+
{ x: (), "x!": factorial }
|
|
74
|
+
|
|
75
|
+
## Value encodings (also called _types_ or _codes_)
|
|
76
|
+
|
|
77
|
+
There are three predefined value encodings: `int`, `string`, and `bool`. The language
|
|
78
|
+
supports `code`-expressions:
|
|
79
|
+
|
|
80
|
+
* product, e.g., `{x: int, y: int, flag: bool}`
|
|
81
|
+
* disjoint union, e.g., `<x: string, y: bool>`
|
|
82
|
+
* vector, e.g., `[ int ]` (all elements of the vector use the same encoding)
|
|
83
|
+
|
|
84
|
+
One can define recursive codes. E.g.,
|
|
85
|
+
|
|
86
|
+
$ tree = <leaf: string, tree: {left: tree, right: tree}>;
|
|
87
|
+
|
|
88
|
+
Each _code_ definition starts with a `$`.
|
|
89
|
+
The above example defines new code called _tree_.
|
|
90
|
+
|
|
91
|
+
The code can be then used in a `k`-expression as a filter. A `code`-expression
|
|
92
|
+
within `k`-expression is again prefixed by `$`.
|
|
93
|
+
|
|
94
|
+
$tree = <leaf: string, tree: {left: tree, right: tree}>;
|
|
95
|
+
inc = [(),1] PLUS;
|
|
96
|
+
height = $ tree <
|
|
97
|
+
.leaf 0,
|
|
98
|
+
.tree [.left height, .right height] <GT .0, .1> inc
|
|
99
|
+
> $ int;
|
|
100
|
+
height
|
|
64
101
|
|
|
65
102
|
|
|
66
103
|
## Command line script
|
|
@@ -113,7 +150,7 @@ run the language from command line.
|
|
|
113
150
|
|
|
114
151
|
If we want to read `json` objects from a file, e.g., `my-objects.json`, we do
|
|
115
152
|
|
|
116
|
-
$ ./k.coffee -k test.k
|
|
153
|
+
$ ./k.coffee -k test.k my-objects.json
|
|
117
154
|
{"x&y":"x=432 & y=123"}
|
|
118
155
|
{"x&y":"onlyx=987"}
|
|
119
156
|
{"x&y":"no x nor y"}
|
|
@@ -178,4 +215,3 @@ run the language from command line.
|
|
|
178
215
|
|
|
179
216
|
k_fn({"age":2,"name":"Mark"})
|
|
180
217
|
// RETURNS: {"nom":"Mark","age":"enfant"}
|
|
181
|
-
|
package/bnat.k
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
-- Standard binary encoding of natural
|
|
2
|
+
-- numbers with addition (+).
|
|
3
|
+
|
|
4
|
+
_ = {{} _};
|
|
5
|
+
_1 = {() "1"};
|
|
6
|
+
_0 = {() "0"};
|
|
7
|
+
|
|
8
|
+
n0 = _ ;
|
|
9
|
+
n1 = _ _1;
|
|
10
|
+
|
|
11
|
+
from_digit = <
|
|
12
|
+
[0, ()] EQ _, -- {_: {}}
|
|
13
|
+
[1, ()] EQ n1, -- {"1": {_: {}}}
|
|
14
|
+
[2, ()] EQ _ _0 _1, -- {"1": {"0": {_: {}}}}
|
|
15
|
+
[3, ()] EQ _ _1 _1, -- {"1": {"1": {_: {}}}}
|
|
16
|
+
[4, ()] EQ _ _0 _0 _1, -- {"1": {"0": {"0": {_: {}}}}}
|
|
17
|
+
[5, ()] EQ _ _1 _0 _1,
|
|
18
|
+
[6, ()] EQ _ _0 _1 _1,
|
|
19
|
+
[7, ()] EQ _ _1 _1 _1,
|
|
20
|
+
[8, ()] EQ _ _0 _0 _0 _1,
|
|
21
|
+
[9, ()] EQ _ _1 _0 _0 _1,
|
|
22
|
+
[10, ()] EQ _ _0 _1 _0 _1
|
|
23
|
+
>;
|
|
24
|
+
|
|
25
|
+
to_digit = <
|
|
26
|
+
._ 0,
|
|
27
|
+
."1"._ 1,
|
|
28
|
+
."1"."0"._ 2,
|
|
29
|
+
."1"."1"._ 3,
|
|
30
|
+
."1"."0"."0"._ 4,
|
|
31
|
+
."1"."0"."1"._ 5,
|
|
32
|
+
."1"."1"."0"._ 6,
|
|
33
|
+
."1"."1"."1"._ 7,
|
|
34
|
+
."1"."0"."0"."0"._ 8,
|
|
35
|
+
."1"."0"."0"."1"._ 9,
|
|
36
|
+
."1"."0"."1"."0"._ 10,
|
|
37
|
+
."1"."0"."1"."1"._ 11,
|
|
38
|
+
."1"."1"."0"."0"._ 12,
|
|
39
|
+
."1"."1"."0"."1"._ 13,
|
|
40
|
+
."1"."1"."1"."0"._ 14,
|
|
41
|
+
."1"."1"."1"."1"._ 15
|
|
42
|
+
> ;
|
|
43
|
+
|
|
44
|
+
remove_leading_zeros =
|
|
45
|
+
< ."0" remove_leading_zeros, () >;
|
|
46
|
+
|
|
47
|
+
_append_zero =
|
|
48
|
+
< ._ _ _0, -- ( _ -> 0 _)
|
|
49
|
+
."1" _append_zero _1, -- ('1 ... -> '1 [$.1 | _append_zero]),
|
|
50
|
+
."0" _append_zero _0 -- ('0 ... -> '0 [$.0 | _append_zero]),
|
|
51
|
+
>
|
|
52
|
+
;
|
|
53
|
+
|
|
54
|
+
_append_one =
|
|
55
|
+
<
|
|
56
|
+
._ _ _1,
|
|
57
|
+
."1" _append_one _1,
|
|
58
|
+
."0" _append_one _0
|
|
59
|
+
>
|
|
60
|
+
;
|
|
61
|
+
|
|
62
|
+
reverse_bnat = {() x, _ y} _reverse_bnat;
|
|
63
|
+
|
|
64
|
+
_reverse_bnat =
|
|
65
|
+
<
|
|
66
|
+
{.x._ x, .y y} .y,
|
|
67
|
+
{.x."0" x, .y _0 y} _reverse_bnat,
|
|
68
|
+
{.x."1" x, .y _1 y} _reverse_bnat
|
|
69
|
+
>;
|
|
70
|
+
|
|
71
|
+
_add2wc =
|
|
72
|
+
-- least significant bit first addition with carry
|
|
73
|
+
--- :{ :bnat x, :bnat y, :[0,1] c}
|
|
74
|
+
-- _log_
|
|
75
|
+
<
|
|
76
|
+
{.x."0" x, .y."0" y, .c."0" c} {.x x, .y y, _ _0 c} _add2wc _0,
|
|
77
|
+
{.x."0" x, .y."0" y, .c."1" c} {.x x, .y y, _ _0 c} _add2wc _1,
|
|
78
|
+
|
|
79
|
+
{.x."0" x, .y."1" y, .c."0" c} {.x x, .y y, _ _0 c} _add2wc _1,
|
|
80
|
+
{.x."0" x, .y."1" y, .c."1" c} {.x x, .y y, _ _1 c} _add2wc _0,
|
|
81
|
+
|
|
82
|
+
{.x."1" x, .y."0" y, .c."0" c} {.x x, .y y, _ _0 c} _add2wc _1,
|
|
83
|
+
{.x."1" x, .y."0" y, .c."1" c} {.x x, .y y, _ _1 c} _add2wc _0,
|
|
84
|
+
|
|
85
|
+
{.x."1" x, .y."1" y, .c."0" c} {.x x, .y y, _ _1 c} _add2wc _0,
|
|
86
|
+
{.x."1" x, .y."1" y, .c."1" c} {.x x, .y y, _ _1 c} _add2wc _1,
|
|
87
|
+
{.x._ x, .c."0" c, .y y} .y,
|
|
88
|
+
{.y._ y, .c."0" c, .x x} .x,
|
|
89
|
+
{.x._ x, .c."1" c, .y._ y} n1,
|
|
90
|
+
{.x._ x, .y."0" y, .c."1" c} .y _1,
|
|
91
|
+
{.x."0" x, .y._ y, .c."1" c} .x _1,
|
|
92
|
+
{.x._ x, .y."1" y, .c."1" c} {_ x, .y y, {} _1 c} _add2wc _0,
|
|
93
|
+
{.x."1" x, .y._ y, .c."1" c} {.x x, _ y, {} _1 c} _add2wc _0
|
|
94
|
+
>;
|
|
95
|
+
|
|
96
|
+
plus = <
|
|
97
|
+
SNOC {
|
|
98
|
+
x: .0 from_digit remove_leading_zeros reverse_bnat,
|
|
99
|
+
y: .1 plus remove_leading_zeros reverse_bnat,
|
|
100
|
+
c: {} _0 } _add2wc reverse_bnat,
|
|
101
|
+
.0 from_digit
|
|
102
|
+
>;
|
|
103
|
+
|
|
104
|
+
to_string = <
|
|
105
|
+
._ "0",
|
|
106
|
+
toString
|
|
107
|
+
>;
|
|
108
|
+
|
|
109
|
+
toString = <
|
|
110
|
+
._ "",
|
|
111
|
+
["0", ."0" toString] CONCAT,
|
|
112
|
+
["1", ."1" toString] CONCAT
|
|
113
|
+
>;
|
|
114
|
+
|
|
115
|
+
[(), plus]
|
|
116
|
+
{
|
|
117
|
+
input: .0,
|
|
118
|
+
sum: {raw: .1, digits: .1 <to_digit,"...too big...">, binary: .1 to_string}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
-- example: > echo '[9,9,9,8]' | ./k.sh -k ./bnat.k
|
package/code.k
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
inc = [(),1] PLUS;
|
|
2
|
+
$tree = <leaf: string, tree: {left: tree, right: tree}>;
|
|
3
|
+
height = $tree <
|
|
4
|
+
.leaf 0,
|
|
5
|
+
.tree [.left height, .right height] <GT .0, .1> inc
|
|
6
|
+
> $int;
|
|
7
|
+
|
|
8
|
+
<$tree,
|
|
9
|
+
{tree:
|
|
10
|
+
{ left: { leaf: "a"},
|
|
11
|
+
right: { tree:
|
|
12
|
+
{ left: {leaf: "b"},
|
|
13
|
+
right: {leaf: "c"}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
> _log_ height
|
package/factorial.k
ADDED
package/fib.k
ADDED
package/index.coffee
CHANGED
package/index.js
CHANGED
package/k.coffee
CHANGED
|
@@ -4,7 +4,8 @@ k = require "./"
|
|
|
4
4
|
|
|
5
5
|
prog = process.argv[1]
|
|
6
6
|
|
|
7
|
-
{kScript,jsonStream} =
|
|
7
|
+
{kScript,jsonStream,oneJson} =
|
|
8
|
+
do (oneJson = false, args = process.argv.slice(2)) ->
|
|
8
9
|
try
|
|
9
10
|
kScript = do (arg = args.shift()) ->
|
|
10
11
|
throw new Error() unless arg?
|
|
@@ -16,30 +17,43 @@ prog = process.argv[1]
|
|
|
16
17
|
kScript = k.compile kScript
|
|
17
18
|
|
|
18
19
|
jsonStream = do (arg = args.shift()) ->
|
|
20
|
+
if arg is "-1"
|
|
21
|
+
oneJson = true
|
|
22
|
+
arg = args.shift()
|
|
19
23
|
return process.stdin unless arg?
|
|
20
|
-
fs.createReadStream
|
|
24
|
+
fs.createReadStream arg
|
|
21
25
|
|
|
22
|
-
{kScript, jsonStream}
|
|
26
|
+
{kScript, jsonStream, oneJson}
|
|
23
27
|
catch e
|
|
24
28
|
console.error e
|
|
25
|
-
console.error "Usage: #{prog} ( k-expr | -k k-file ) [ json-file ]"
|
|
29
|
+
console.error "Usage: #{prog} ( k-expr | -k k-file ) [ -1 ] [ json-file ]"
|
|
26
30
|
console.error " E.g., echo '{\"a\": 12}' | #{prog} '[(),()]'"
|
|
27
31
|
process.exit -1
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
33
|
+
if oneJson
|
|
34
|
+
do (buffer = []) ->
|
|
35
|
+
jsonStream.on 'data', (data) ->
|
|
36
|
+
buffer.push data
|
|
37
|
+
jsonStream.on 'end', ->
|
|
38
|
+
try
|
|
39
|
+
console.log JSON.stringify kScript JSON.parse buffer.join('')
|
|
40
|
+
catch e
|
|
41
|
+
console.error e
|
|
42
|
+
else
|
|
43
|
+
do (buffer = [], line = 0) ->
|
|
44
|
+
jsonStream.on 'data', (data) ->
|
|
45
|
+
[first, rest...] = data.toString("utf8").split "\n"
|
|
46
|
+
buffer.push first
|
|
47
|
+
if rest.length > 0
|
|
48
|
+
todo = buffer.join ""
|
|
49
|
+
[rest..., last] = rest
|
|
50
|
+
buffer = [last]
|
|
51
|
+
todo = [todo, rest...]
|
|
52
|
+
for json in todo
|
|
53
|
+
if not json.match /^[ \n\t]*(?:#.*)?$/
|
|
54
|
+
try
|
|
55
|
+
console.log JSON.stringify kScript JSON.parse json
|
|
56
|
+
catch e
|
|
57
|
+
console.error "Problem [line #{line}]: '#{json}'"
|
|
58
|
+
console.error e
|
|
59
|
+
line = line + 1
|
package/k.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Generated by CoffeeScript 2.7.0
|
|
2
2
|
(function() {
|
|
3
3
|
//!/usr/bin/env coffee
|
|
4
|
-
var fs, jsonStream, k, kScript, prog,
|
|
4
|
+
var fs, jsonStream, k, kScript, oneJson, prog,
|
|
5
5
|
splice = [].splice;
|
|
6
6
|
|
|
7
7
|
fs = require("fs");
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
prog = process.argv[1];
|
|
12
12
|
|
|
13
|
-
({kScript, jsonStream} = (function(args) {
|
|
13
|
+
({kScript, jsonStream, oneJson} = (function(oneJson, args) {
|
|
14
14
|
var e;
|
|
15
15
|
try {
|
|
16
16
|
kScript = (function(arg) {
|
|
@@ -25,48 +25,69 @@
|
|
|
25
25
|
})(args.shift());
|
|
26
26
|
kScript = k.compile(kScript);
|
|
27
27
|
jsonStream = (function(arg) {
|
|
28
|
+
if (arg === "-1") {
|
|
29
|
+
oneJson = true;
|
|
30
|
+
arg = args.shift();
|
|
31
|
+
}
|
|
28
32
|
if (arg == null) {
|
|
29
33
|
return process.stdin;
|
|
30
34
|
}
|
|
31
|
-
return fs.createReadStream(
|
|
35
|
+
return fs.createReadStream(arg);
|
|
32
36
|
})(args.shift());
|
|
33
|
-
return {kScript, jsonStream};
|
|
37
|
+
return {kScript, jsonStream, oneJson};
|
|
34
38
|
} catch (error) {
|
|
35
39
|
e = error;
|
|
36
40
|
console.error(e);
|
|
37
|
-
console.error(`Usage: ${prog} ( k-expr | -k k-file ) [ json-file ]`);
|
|
41
|
+
console.error(`Usage: ${prog} ( k-expr | -k k-file ) [ -1 ] [ json-file ]`);
|
|
38
42
|
console.error(` E.g., echo '{\"a\": 12}' | ${prog} '[(),()]'`);
|
|
39
43
|
return process.exit(-1);
|
|
40
44
|
}
|
|
41
|
-
})(process.argv.slice(2)));
|
|
45
|
+
})(false, process.argv.slice(2)));
|
|
42
46
|
|
|
43
|
-
(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
if (oneJson) {
|
|
48
|
+
(function(buffer) {
|
|
49
|
+
jsonStream.on('data', function(data) {
|
|
50
|
+
return buffer.push(data);
|
|
51
|
+
});
|
|
52
|
+
return jsonStream.on('end', function() {
|
|
53
|
+
var e;
|
|
54
|
+
try {
|
|
55
|
+
return console.log(JSON.stringify(kScript(JSON.parse(buffer.join('')))));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
e = error;
|
|
58
|
+
return console.error(e);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
})([]);
|
|
62
|
+
} else {
|
|
63
|
+
(function(buffer, line) {
|
|
64
|
+
return jsonStream.on('data', function(data) {
|
|
65
|
+
var e, first, i, json, last, len, ref, rest, results, todo;
|
|
66
|
+
[first, ...rest] = data.toString("utf8").split("\n");
|
|
67
|
+
buffer.push(first);
|
|
68
|
+
if (rest.length > 0) {
|
|
69
|
+
todo = buffer.join("");
|
|
70
|
+
ref = rest, [...rest] = ref, [last] = splice.call(rest, -1);
|
|
71
|
+
buffer = [last];
|
|
72
|
+
todo = [todo, ...rest];
|
|
73
|
+
results = [];
|
|
74
|
+
for (i = 0, len = todo.length; i < len; i++) {
|
|
75
|
+
json = todo[i];
|
|
76
|
+
if (!json.match(/^[ \n\t]*(?:#.*)?$/)) {
|
|
77
|
+
try {
|
|
78
|
+
console.log(JSON.stringify(kScript(JSON.parse(json))));
|
|
79
|
+
} catch (error) {
|
|
80
|
+
e = error;
|
|
81
|
+
console.error(`Problem [line ${line}]: '${json}'`);
|
|
82
|
+
console.error(e);
|
|
83
|
+
}
|
|
63
84
|
}
|
|
85
|
+
results.push(line = line + 1);
|
|
64
86
|
}
|
|
65
|
-
results
|
|
87
|
+
return results;
|
|
66
88
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
})([], 0);
|
|
89
|
+
});
|
|
90
|
+
})([], 0);
|
|
91
|
+
}
|
|
71
92
|
|
|
72
93
|
}).call(this);
|
package/k.sh
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Generated by CoffeeScript 2.7.0
|
|
3
3
|
(function() {
|
|
4
4
|
//!/usr/bin/env coffee
|
|
5
|
-
var fs, jsonStream, k, kScript, prog,
|
|
5
|
+
var fs, jsonStream, k, kScript, oneJson, prog,
|
|
6
6
|
splice = [].splice;
|
|
7
7
|
|
|
8
8
|
fs = require("fs");
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
prog = process.argv[1];
|
|
13
13
|
|
|
14
|
-
({kScript, jsonStream} = (function(args) {
|
|
14
|
+
({kScript, jsonStream, oneJson} = (function(oneJson, args) {
|
|
15
15
|
var e;
|
|
16
16
|
try {
|
|
17
17
|
kScript = (function(arg) {
|
|
@@ -26,48 +26,69 @@
|
|
|
26
26
|
})(args.shift());
|
|
27
27
|
kScript = k.compile(kScript);
|
|
28
28
|
jsonStream = (function(arg) {
|
|
29
|
+
if (arg === "-1") {
|
|
30
|
+
oneJson = true;
|
|
31
|
+
arg = args.shift();
|
|
32
|
+
}
|
|
29
33
|
if (arg == null) {
|
|
30
34
|
return process.stdin;
|
|
31
35
|
}
|
|
32
|
-
return fs.createReadStream(
|
|
36
|
+
return fs.createReadStream(arg);
|
|
33
37
|
})(args.shift());
|
|
34
|
-
return {kScript, jsonStream};
|
|
38
|
+
return {kScript, jsonStream, oneJson};
|
|
35
39
|
} catch (error) {
|
|
36
40
|
e = error;
|
|
37
41
|
console.error(e);
|
|
38
|
-
console.error(`Usage: ${prog} ( k-expr | -k k-file ) [ json-file ]`);
|
|
42
|
+
console.error(`Usage: ${prog} ( k-expr | -k k-file ) [ -1 ] [ json-file ]`);
|
|
39
43
|
console.error(` E.g., echo '{\"a\": 12}' | ${prog} '[(),()]'`);
|
|
40
44
|
return process.exit(-1);
|
|
41
45
|
}
|
|
42
|
-
})(process.argv.slice(2)));
|
|
46
|
+
})(false, process.argv.slice(2)));
|
|
43
47
|
|
|
44
|
-
(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
48
|
+
if (oneJson) {
|
|
49
|
+
(function(buffer) {
|
|
50
|
+
jsonStream.on('data', function(data) {
|
|
51
|
+
return buffer.push(data);
|
|
52
|
+
});
|
|
53
|
+
return jsonStream.on('end', function() {
|
|
54
|
+
var e;
|
|
55
|
+
try {
|
|
56
|
+
return console.log(JSON.stringify(kScript(JSON.parse(buffer.join('')))));
|
|
57
|
+
} catch (error) {
|
|
58
|
+
e = error;
|
|
59
|
+
return console.error(e);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
})([]);
|
|
63
|
+
} else {
|
|
64
|
+
(function(buffer, line) {
|
|
65
|
+
return jsonStream.on('data', function(data) {
|
|
66
|
+
var e, first, i, json, last, len, ref, rest, results, todo;
|
|
67
|
+
[first, ...rest] = data.toString("utf8").split("\n");
|
|
68
|
+
buffer.push(first);
|
|
69
|
+
if (rest.length > 0) {
|
|
70
|
+
todo = buffer.join("");
|
|
71
|
+
ref = rest, [...rest] = ref, [last] = splice.call(rest, -1);
|
|
72
|
+
buffer = [last];
|
|
73
|
+
todo = [todo, ...rest];
|
|
74
|
+
results = [];
|
|
75
|
+
for (i = 0, len = todo.length; i < len; i++) {
|
|
76
|
+
json = todo[i];
|
|
77
|
+
if (!json.match(/^[ \n\t]*(?:#.*)?$/)) {
|
|
78
|
+
try {
|
|
79
|
+
console.log(JSON.stringify(kScript(JSON.parse(json))));
|
|
80
|
+
} catch (error) {
|
|
81
|
+
e = error;
|
|
82
|
+
console.error(`Problem [line ${line}]: '${json}'`);
|
|
83
|
+
console.error(e);
|
|
84
|
+
}
|
|
64
85
|
}
|
|
86
|
+
results.push(line = line + 1);
|
|
65
87
|
}
|
|
66
|
-
results
|
|
88
|
+
return results;
|
|
67
89
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
})([], 0);
|
|
90
|
+
});
|
|
91
|
+
})([], 0);
|
|
92
|
+
}
|
|
72
93
|
|
|
73
94
|
}).call(this);
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fraczak/k",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "k-language for
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "k-language for JSON-like data transformation",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"prepare": "coffee -c symbol-table.coffee; jison parser.jison",
|
|
8
8
|
"prepublishOnly": "coffee -c *.coffee; echo '#!/usr/bin/env node' | cat - k.js > k.sh",
|
|
9
|
-
"test": "coffee -c symbol-table.coffee; jison parser.jison; coffee test.coffee
|
|
9
|
+
"test": "coffee -c symbol-table.coffee; jison parser.jison; coffee test.coffee"
|
|
10
10
|
},
|
|
11
11
|
"author": "Wojciech Fraczak",
|
|
12
12
|
"license": "ISC",
|
package/parser.jison
CHANGED
|
@@ -18,17 +18,21 @@ var s = require("./symbol-table");
|
|
|
18
18
|
"}" return 'RC';
|
|
19
19
|
"]" return 'RB';
|
|
20
20
|
")" return 'RP';
|
|
21
|
+
"=" return 'EQ';
|
|
21
22
|
"." return 'DOT';
|
|
22
23
|
"," return 'COMMA';
|
|
24
|
+
";" return 'SC';
|
|
25
|
+
":" return 'COL';
|
|
26
|
+
"$" return 'DOLLAR';
|
|
23
27
|
\"[^\"\n]*\"|\'[^\'\n]*\' return 'STRING'
|
|
24
|
-
[a-zA-Z_][a-zA-Z0-9_]*
|
|
28
|
+
[a-zA-Z_][a-zA-Z0-9_?!]* return 'NAME';
|
|
25
29
|
0|[-]?[1-9][0-9]* return 'INT';
|
|
26
30
|
<<EOF>> return 'EOF';
|
|
27
31
|
|
|
28
32
|
/lex
|
|
29
33
|
|
|
30
34
|
%token NAME STRING INT
|
|
31
|
-
%token LA LC LB LP RA RP RB RC COMMA
|
|
35
|
+
%token LA LC LB LP RA RP RB RC EQ DOT COMMA SC COL DOLLAR
|
|
32
36
|
%token EOF
|
|
33
37
|
|
|
34
38
|
%start input_with_eof
|
|
@@ -39,14 +43,53 @@ name: NAME { $$ = String(yytext); };
|
|
|
39
43
|
str: STRING { $$ = String(yytext).slice(1,-1); };
|
|
40
44
|
int: INT { $$ = parseInt(String(yytext)); };
|
|
41
45
|
|
|
42
|
-
input_with_eof: comp EOF {
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
input_with_eof: defs comp EOF {
|
|
47
|
+
result = {defs: $1, exp: $2};
|
|
48
|
+
// console.log(JSON.stringify(result, "", 2));
|
|
49
|
+
return result;
|
|
45
50
|
};
|
|
46
51
|
|
|
52
|
+
defs: { $$ = {codes: {}, rels: {}}; }
|
|
53
|
+
| defs name EQ comp SC { $1.rels[$2] = $4; $$ = $1; }
|
|
54
|
+
| defs DOLLAR name EQ code SC { $1.codes[$3] = $5; $$ = $1; }
|
|
55
|
+
;
|
|
56
|
+
|
|
57
|
+
code
|
|
58
|
+
: name { $$ = {code: "ref", ref: $1}; }
|
|
59
|
+
| LC labelled_codes RC { $$ = {code: "product",
|
|
60
|
+
product: $2.reduce((r, lc) => {
|
|
61
|
+
r[lc.label] = lc.code;
|
|
62
|
+
return r }
|
|
63
|
+
, {})}; }
|
|
64
|
+
| LB code RB { $$ = {code: "vector", vector: $2}; }
|
|
65
|
+
| LA labelled_codes RA { $$ = {code: "union",
|
|
66
|
+
union: $2.reduce((r, lc) => {
|
|
67
|
+
r[lc.label] = lc.code;
|
|
68
|
+
return r }
|
|
69
|
+
, {})}; }
|
|
70
|
+
;
|
|
71
|
+
|
|
72
|
+
labelled_codes
|
|
73
|
+
: { $$ = [] }
|
|
74
|
+
| non_empty_labelled_codes { $$ = $1; }
|
|
75
|
+
;
|
|
76
|
+
|
|
77
|
+
non_empty_labelled_codes
|
|
78
|
+
: code_label { $$ = [$1]; }
|
|
79
|
+
| non_empty_labelled_codes COMMA code_label
|
|
80
|
+
{ $$ = [].concat($1,$3); }
|
|
81
|
+
;
|
|
82
|
+
|
|
83
|
+
code_label
|
|
84
|
+
: code name { $$ = {label: $2, code: $1}; }
|
|
85
|
+
| code str { $$ = {label: $2, code: $1}; }
|
|
86
|
+
| name COL code { $$ = {label: $1, code: $3}; }
|
|
87
|
+
| str COL code { $$ = {label: $1, code: $3}; }
|
|
88
|
+
;
|
|
89
|
+
|
|
47
90
|
comp
|
|
48
|
-
: exp
|
|
49
|
-
| comp exp
|
|
91
|
+
: exp { $$ = $1; }
|
|
92
|
+
| comp exp { $$ = s.comp($1, $2); }
|
|
50
93
|
;
|
|
51
94
|
|
|
52
95
|
exp
|
|
@@ -61,6 +104,7 @@ exp
|
|
|
61
104
|
| DOT int { $$ = {op: "dot", dot: $2}; }
|
|
62
105
|
| DOT str { $$ = {op: "dot", dot: $2}; }
|
|
63
106
|
| DOT name { $$ = {op: "dot", dot: $2}; }
|
|
107
|
+
| DOLLAR code { $$ = {op: "code", code: $2}; }
|
|
64
108
|
;
|
|
65
109
|
|
|
66
110
|
labelled
|
|
@@ -78,6 +122,8 @@ non_empty_labelled
|
|
|
78
122
|
comp_label
|
|
79
123
|
: comp name { $$ = {label: $2, exp: $1}; }
|
|
80
124
|
| comp str { $$ = {label: $2, exp: $1}; }
|
|
125
|
+
| name COL comp { $$ = {label: $1, exp: $3}; }
|
|
126
|
+
| str COL comp { $$ = {label: $1, exp: $3}; }
|
|
81
127
|
;
|
|
82
128
|
|
|
83
129
|
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=[
|
|
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,17,20,22,31,33],$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,17,20,22,31,33],$Vb=[2,25],$Vc=[1,24],$Vd=[1,25],$Ve=[1,26],$Vf=[4,6,8,12,14,15,17,19,20,21,22,23,26,31,32,33],$Vg=[2,42],$Vh=[2,28],$Vi=[2,8],$Vj=[2,12],$Vk=[19,26],$Vl=[21,23,26],$Vm=[19,23,26],$Vn=[2,38],$Vo=[2,39];
|
|
76
76
|
var parser = {trace: function trace () { },
|
|
77
77
|
yy: {},
|
|
78
|
-
symbols_: {"error":2,"name":3,"NAME":4,"str":5,"STRING":6,"int":7,"INT":8,"input_with_eof":9,"
|
|
79
|
-
terminals_: {2:"error",4:"NAME",6:"STRING",8:"INT",
|
|
80
|
-
productions_: [0,[3,1],[5,1],[7,1],[9,
|
|
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,"code":16,"LC":17,"labelled_codes":18,"RC":19,"LB":20,"RB":21,"LA":22,"RA":23,"non_empty_labelled_codes":24,"code_label":25,"COMMA":26,"COL":27,"exp":28,"labelled":29,"list":30,"LP":31,"RP":32,"DOT":33,"non_empty_labelled":34,"comp_label":35,"non_empty_list":36,"$accept":0,"$end":1},
|
|
79
|
+
terminals_: {2:"error",4:"NAME",6:"STRING",8:"INT",12:"EOF",13:"EQ",14:"SC",15:"DOLLAR",17:"LC",19:"RC",20:"LB",21:"RB",22:"LA",23:"RA",26:"COMMA",27:"COL",31:"LP",32:"RP",33:"DOT"},
|
|
80
|
+
productions_: [0,[3,1],[5,1],[7,1],[9,3],[10,0],[10,5],[10,6],[16,1],[16,3],[16,3],[16,3],[18,0],[18,1],[24,1],[24,3],[25,2],[25,2],[25,3],[25,3],[11,1],[11,2],[28,3],[28,3],[28,3],[28,1],[28,2],[28,3],[28,1],[28,1],[28,2],[28,2],[28,2],[28,2],[29,0],[29,1],[34,1],[34,3],[35,2],[35,2],[35,3],[35,3],[30,0],[30,1],[36,1],[36,3]],
|
|
81
81
|
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
|
|
82
82
|
/* this == yyval */
|
|
83
83
|
|
|
@@ -94,68 +94,113 @@ case 3:
|
|
|
94
94
|
break;
|
|
95
95
|
case 4:
|
|
96
96
|
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
result = {defs: $$[$0-2], exp: $$[$0-1]};
|
|
98
|
+
// console.log(JSON.stringify(result, "", 2));
|
|
99
|
+
return result;
|
|
99
100
|
|
|
100
101
|
break;
|
|
101
|
-
case 5:
|
|
102
|
-
this.$ =
|
|
102
|
+
case 5:
|
|
103
|
+
this.$ = {codes: {}, rels: {}};
|
|
103
104
|
break;
|
|
104
105
|
case 6:
|
|
105
|
-
|
|
106
|
+
$$[$0-4].rels[$$[$0-3]] = $$[$0-1]; this.$ = $$[$0-4];
|
|
106
107
|
break;
|
|
107
108
|
case 7:
|
|
108
|
-
this.$ = $$[$0-
|
|
109
|
+
$$[$0-5].codes[$$[$0-3]] = $$[$0-1]; this.$ = $$[$0-5];
|
|
109
110
|
break;
|
|
110
111
|
case 8:
|
|
111
|
-
this.$ = {
|
|
112
|
+
this.$ = {code: "ref", ref: $$[$0]};
|
|
112
113
|
break;
|
|
113
114
|
case 9:
|
|
114
|
-
this.$ = {
|
|
115
|
+
this.$ = {code: "product",
|
|
116
|
+
product: $$[$0-1].reduce((r, lc) => {
|
|
117
|
+
r[lc.label] = lc.code;
|
|
118
|
+
return r }
|
|
119
|
+
, {})};
|
|
115
120
|
break;
|
|
116
121
|
case 10:
|
|
117
|
-
this.$ = {
|
|
122
|
+
this.$ = {code: "vector", vector: $$[$0-1]};
|
|
118
123
|
break;
|
|
119
124
|
case 11:
|
|
120
|
-
this.$ =
|
|
125
|
+
this.$ = {code: "union",
|
|
126
|
+
union: $$[$0-1].reduce((r, lc) => {
|
|
127
|
+
r[lc.label] = lc.code;
|
|
128
|
+
return r }
|
|
129
|
+
, {})};
|
|
121
130
|
break;
|
|
122
131
|
case 12:
|
|
132
|
+
this.$ = []
|
|
133
|
+
break;
|
|
134
|
+
case 13: case 20: case 35: case 43:
|
|
135
|
+
this.$ = $$[$0];
|
|
136
|
+
break;
|
|
137
|
+
case 14: case 44:
|
|
138
|
+
this.$ = [$$[$0]];
|
|
139
|
+
break;
|
|
140
|
+
case 15: case 45:
|
|
141
|
+
this.$ = [].concat($$[$0-2],$$[$0]);
|
|
142
|
+
break;
|
|
143
|
+
case 16: case 17:
|
|
144
|
+
this.$ = {label: $$[$0], code: $$[$0-1]};
|
|
145
|
+
break;
|
|
146
|
+
case 18: case 19:
|
|
147
|
+
this.$ = {label: $$[$0-2], code: $$[$0]};
|
|
148
|
+
break;
|
|
149
|
+
case 21:
|
|
150
|
+
this.$ = s.comp($$[$0-1], $$[$0]);
|
|
151
|
+
break;
|
|
152
|
+
case 22:
|
|
153
|
+
this.$ = $$[$0-1];
|
|
154
|
+
break;
|
|
155
|
+
case 23:
|
|
156
|
+
this.$ = {op: "vector", vector: $$[$0-1]};
|
|
157
|
+
break;
|
|
158
|
+
case 24:
|
|
159
|
+
this.$ = {op: "union", union: $$[$0-1]};
|
|
160
|
+
break;
|
|
161
|
+
case 25:
|
|
162
|
+
this.$ = {op: "ref", ref: $$[$0]};
|
|
163
|
+
break;
|
|
164
|
+
case 26:
|
|
165
|
+
this.$ = s.identity;
|
|
166
|
+
break;
|
|
167
|
+
case 27:
|
|
123
168
|
this.$ = $$[$0-1];
|
|
124
169
|
break;
|
|
125
|
-
case
|
|
170
|
+
case 28:
|
|
126
171
|
this.$ = {op: "str", str: $$[$0]};
|
|
127
172
|
break;
|
|
128
|
-
case
|
|
173
|
+
case 29:
|
|
129
174
|
this.$ = {op: "int", int: $$[$0]};
|
|
130
175
|
break;
|
|
131
|
-
case
|
|
176
|
+
case 30: case 31: case 32:
|
|
132
177
|
this.$ = {op: "dot", dot: $$[$0]};
|
|
133
178
|
break;
|
|
134
|
-
case
|
|
179
|
+
case 33:
|
|
180
|
+
this.$ = {op: "code", code: $$[$0]};
|
|
181
|
+
break;
|
|
182
|
+
case 34:
|
|
135
183
|
this.$ = {op: "product", product: []};
|
|
136
184
|
break;
|
|
137
|
-
case
|
|
185
|
+
case 36:
|
|
138
186
|
this.$ = {op: "product", product: [$$[$0]]};
|
|
139
187
|
break;
|
|
140
|
-
case
|
|
188
|
+
case 37:
|
|
141
189
|
$$[$0-2].product = [].concat($$[$0-2].product,$$[$0]); this.$ = $$[$0-2];
|
|
142
190
|
break;
|
|
143
|
-
case
|
|
191
|
+
case 38: case 39:
|
|
144
192
|
this.$ = {label: $$[$0], exp: $$[$0-1]};
|
|
145
193
|
break;
|
|
146
|
-
case
|
|
147
|
-
this.$ = [];
|
|
148
|
-
break;
|
|
149
|
-
case 26:
|
|
150
|
-
this.$ = [$$[$0]];
|
|
194
|
+
case 40: case 41:
|
|
195
|
+
this.$ = {label: $$[$0-2], exp: $$[$0]};
|
|
151
196
|
break;
|
|
152
|
-
case
|
|
153
|
-
this.$ = []
|
|
197
|
+
case 42:
|
|
198
|
+
this.$ = [];
|
|
154
199
|
break;
|
|
155
200
|
}
|
|
156
201
|
},
|
|
157
|
-
table: [{3:
|
|
158
|
-
defaultActions: {
|
|
202
|
+
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],17:$V4,20:$V5,22:$V6,28:6,31:$V7,33:$V8},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,12:[1,17],15:$V9,17:$V4,20:$V5,22:$V6,28:18,31:$V7,33:$V8},o($Va,$Vb,{13:[1,21]}),{3:22,4:$V1,16:23,17:$Vc,20:$Vd,22:$Ve},o($Vf,[2,20]),o([4,6,8,12,13,14,15,17,19,20,21,22,23,26,27,31,32,33],[2,1]),{3:31,4:$V1,5:32,6:$V2,7:13,8:$V3,11:30,15:$V9,17:$V4,19:[2,34],20:$V5,22:$V6,28:6,29:27,31:$V7,33:$V8,34:28,35:29},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:35,15:$V9,17:$V4,20:$V5,21:$Vg,22:$V6,28:6,30:33,31:$V7,33:$V8,36:34},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:35,15:$V9,17:$V4,20:$V5,22:$V6,23:$Vg,28:6,30:36,31:$V7,33:$V8,36:34},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:38,15:$V9,17:$V4,20:$V5,22:$V6,28:6,31:$V7,32:[1,37],33:$V8},o($Vf,$Vh),o($Vf,[2,29]),{3:41,4:$V1,5:40,6:$V2,7:39,8:$V3},o([4,6,8,12,14,15,17,19,20,21,22,23,26,27,31,32,33],[2,2]),o($Vf,[2,3]),{1:[2,4]},o($Vf,[2,21]),o($Vf,$Vb),{3:42,4:$V1,16:23,17:$Vc,20:$Vd,22:$Ve},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:43,15:$V9,17:$V4,20:$V5,22:$V6,28:6,31:$V7,33:$V8},o($Va,$Vi,{13:[1,44]}),o($Vf,[2,33]),{3:49,4:$V1,5:50,6:$V2,16:48,17:$Vc,18:45,19:$Vj,20:$Vd,22:$Ve,24:46,25:47},{3:42,4:$V1,16:51,17:$Vc,20:$Vd,22:$Ve},{3:49,4:$V1,5:50,6:$V2,16:48,17:$Vc,18:52,20:$Vd,22:$Ve,23:$Vj,24:46,25:47},{19:[1,53]},{19:[2,35],26:[1,54]},o($Vk,[2,36]),{3:55,4:$V1,5:56,6:$V2,7:13,8:$V3,15:$V9,17:$V4,20:$V5,22:$V6,28:18,31:$V7,33:$V8},o($V0,$Vb,{27:[1,57]}),o($V0,$Vh,{27:[1,58]}),{21:[1,59]},o([21,23],[2,43],{26:[1,60]}),o($Vl,[2,44],{5:12,7:13,28:18,3:19,4:$V1,6:$V2,8:$V3,15:$V9,17:$V4,20:$V5,22:$V6,31:$V7,33:$V8}),{23:[1,61]},o($Vf,[2,26]),{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,15:$V9,17:$V4,20:$V5,22:$V6,28:18,31:$V7,32:[1,62],33:$V8},o($Vf,[2,30]),o($Vf,[2,31]),o($Vf,[2,32]),o($Vf,$Vi),{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,14:[1,63],15:$V9,17:$V4,20:$V5,22:$V6,28:18,31:$V7,33:$V8},{3:42,4:$V1,16:64,17:$Vc,20:$Vd,22:$Ve},{19:[1,65]},o([19,23],[2,13],{26:[1,66]}),o($Vm,[2,14]),{3:67,4:$V1,5:68,6:$V2},o([4,6],$Vi,{27:[1,69]}),{27:[1,70]},{21:[1,71]},{23:[1,72]},o($Vf,[2,22]),{3:31,4:$V1,5:32,6:$V2,7:13,8:$V3,11:30,15:$V9,17:$V4,20:$V5,22:$V6,28:6,31:$V7,33:$V8,35:73},o($V0,$Vb,{19:$Vn,26:$Vn}),o($V0,$Vh,{19:$Vo,26:$Vo}),{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:74,15:$V9,17:$V4,20:$V5,22:$V6,28:6,31:$V7,33:$V8},{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:75,15:$V9,17:$V4,20:$V5,22:$V6,28:6,31:$V7,33:$V8},o($Vf,[2,23]),{3:19,4:$V1,5:12,6:$V2,7:13,8:$V3,11:76,15:$V9,17:$V4,20:$V5,22:$V6,28:6,31:$V7,33:$V8},o($Vf,[2,24]),o($Vf,[2,27]),o($V0,[2,6]),{14:[1,77]},o($Vf,[2,9]),{3:49,4:$V1,5:50,6:$V2,16:48,17:$Vc,20:$Vd,22:$Ve,25:78},o($Vm,[2,16]),o($Vm,[2,17]),{3:42,4:$V1,16:79,17:$Vc,20:$Vd,22:$Ve},{3:42,4:$V1,16:80,17:$Vc,20:$Vd,22:$Ve},o($Vf,[2,10]),o($Vf,[2,11]),o($Vk,[2,37]),o($Vk,[2,40],{5:12,7:13,28:18,3:19,4:$V1,6:$V2,8:$V3,15:$V9,17:$V4,20:$V5,22:$V6,31:$V7,33:$V8}),o($Vk,[2,41],{5:12,7:13,28:18,3:19,4:$V1,6:$V2,8:$V3,15:$V9,17:$V4,20:$V5,22:$V6,31:$V7,33:$V8}),o($Vl,[2,45],{5:12,7:13,28:18,3:19,4:$V1,6:$V2,8:$V3,15:$V9,17:$V4,20:$V5,22:$V6,31:$V7,33:$V8}),o($V0,[2,7]),o($Vm,[2,15]),o($Vm,[2,18]),o($Vm,[2,19])],
|
|
203
|
+
defaultActions: {17:[2,4]},
|
|
159
204
|
parseError: function parseError (str, hash) {
|
|
160
205
|
if (hash.recoverable) {
|
|
161
206
|
this.trace(str);
|
|
@@ -641,38 +686,46 @@ case 1:/* one line comment */
|
|
|
641
686
|
break;
|
|
642
687
|
case 2:/* blanks */
|
|
643
688
|
break;
|
|
644
|
-
case 3:return
|
|
689
|
+
case 3:return 22;
|
|
690
|
+
break;
|
|
691
|
+
case 4:return 17;
|
|
692
|
+
break;
|
|
693
|
+
case 5:return 20;
|
|
694
|
+
break;
|
|
695
|
+
case 6:return 31;
|
|
696
|
+
break;
|
|
697
|
+
case 7:return 23;
|
|
645
698
|
break;
|
|
646
|
-
case
|
|
699
|
+
case 8:return 19;
|
|
647
700
|
break;
|
|
648
|
-
case
|
|
701
|
+
case 9:return 21;
|
|
649
702
|
break;
|
|
650
|
-
case
|
|
703
|
+
case 10:return 32;
|
|
651
704
|
break;
|
|
652
|
-
case
|
|
705
|
+
case 11:return 13;
|
|
653
706
|
break;
|
|
654
|
-
case
|
|
707
|
+
case 12:return 33;
|
|
655
708
|
break;
|
|
656
|
-
case
|
|
709
|
+
case 13:return 26;
|
|
657
710
|
break;
|
|
658
|
-
case
|
|
711
|
+
case 14:return 14;
|
|
659
712
|
break;
|
|
660
|
-
case
|
|
713
|
+
case 15:return 27;
|
|
661
714
|
break;
|
|
662
|
-
case
|
|
715
|
+
case 16:return 15;
|
|
663
716
|
break;
|
|
664
|
-
case
|
|
717
|
+
case 17:return 6
|
|
665
718
|
break;
|
|
666
|
-
case
|
|
719
|
+
case 18:return 4;
|
|
667
720
|
break;
|
|
668
|
-
case
|
|
721
|
+
case 19:return 8;
|
|
669
722
|
break;
|
|
670
|
-
case
|
|
723
|
+
case 20:return 12;
|
|
671
724
|
break;
|
|
672
725
|
}
|
|
673
726
|
},
|
|
674
|
-
rules: [/^(?:[/][*]([*][^/]|[^*])*[*][/])/,/^(?:(\/\/|#|%|--)[^\n]*)/,/^(?:\s+)/,/^(?:<)/,/^(?:\{)/,/^(?:\[)/,/^(?:\()/,/^(?:>)/,/^(?:\})/,/^(?:\])/,/^(?:\))/,/^(?:\.)/,/^(?:,)/,/^(?:"[^\"\n]*"|'[^\'\n]*')/,/^(?:[a-zA-Z_][a-zA-Z0-9_]*)/,/^(?:0|[-]?[1-9][0-9]*)/,/^(?:$)/],
|
|
675
|
-
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16],"inclusive":true}}
|
|
727
|
+
rules: [/^(?:[/][*]([*][^/]|[^*])*[*][/])/,/^(?:(\/\/|#|%|--)[^\n]*)/,/^(?:\s+)/,/^(?:<)/,/^(?:\{)/,/^(?:\[)/,/^(?:\()/,/^(?:>)/,/^(?:\})/,/^(?:\])/,/^(?:\))/,/^(?:=)/,/^(?:\.)/,/^(?:,)/,/^(?:;)/,/^(?::)/,/^(?:\$)/,/^(?:"[^\"\n]*"|'[^\'\n]*')/,/^(?:[a-zA-Z_][a-zA-Z0-9_?!]*)/,/^(?:0|[-]?[1-9][0-9]*)/,/^(?:$)/],
|
|
728
|
+
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}}
|
|
676
729
|
});
|
|
677
730
|
return lexer;
|
|
678
731
|
})();
|
package/pow.k
ADDED
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,45 +35,82 @@ 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
|
+
switch code.code
|
|
52
|
+
when "ref"
|
|
53
|
+
do (c = run.defs.codes[code.ref]) ->
|
|
54
|
+
return verify c, value if c?
|
|
55
|
+
codes[code.ref] value
|
|
56
|
+
when "vector"
|
|
57
|
+
value.every (x) ->
|
|
58
|
+
verify code.vector, x
|
|
59
|
+
when "product"
|
|
60
|
+
do (fields = Object.keys(value)) ->
|
|
61
|
+
return false unless fields.length is Object.keys(code.product).length
|
|
62
|
+
fields.every (label) ->
|
|
63
|
+
verify code.product[label], value[label]
|
|
64
|
+
when "union"
|
|
65
|
+
do (fields = Object.keys(value)) ->
|
|
66
|
+
return false unless fields.length is 1
|
|
67
|
+
verify code.union[fields[0]], value[fields[0]]
|
|
36
68
|
|
|
37
69
|
run = (exp, value) ->
|
|
38
|
-
return undefined
|
|
70
|
+
return undefined if value is undefined
|
|
39
71
|
try
|
|
40
72
|
switch exp.op
|
|
73
|
+
when "code"
|
|
74
|
+
return value if verify exp.code, value
|
|
41
75
|
when "identity"
|
|
42
76
|
return value
|
|
43
77
|
when "str", "int"
|
|
44
78
|
return exp[exp.op]
|
|
45
79
|
when "ref"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
80
|
+
do (defn = run.defs.rels[exp.ref]) ->
|
|
81
|
+
if defn?
|
|
82
|
+
run defn, value
|
|
83
|
+
else
|
|
84
|
+
do ( value = builtin[exp.ref] value ) ->
|
|
85
|
+
throw new Error "Undefined" if value is undefined
|
|
86
|
+
value
|
|
49
87
|
when "dot"
|
|
50
88
|
return value[exp.dot]
|
|
51
89
|
when "comp"
|
|
52
90
|
return exp.comp.reduce (value, exp) ->
|
|
53
91
|
value = run exp, value
|
|
54
|
-
throw new Error "Undefined"
|
|
92
|
+
throw new Error "Undefined" if value is undefined
|
|
55
93
|
value
|
|
56
94
|
, value
|
|
57
95
|
when "vector"
|
|
58
96
|
return exp.vector.map (exp) ->
|
|
59
97
|
result = run exp, value
|
|
60
|
-
throw new Error "Undefined"
|
|
98
|
+
throw new Error "Undefined" if result is undefined
|
|
61
99
|
result
|
|
62
100
|
when "union"
|
|
63
101
|
for e in exp.union
|
|
64
102
|
result = try run e, value
|
|
65
|
-
return result
|
|
103
|
+
return result unless result is undefined
|
|
66
104
|
return undefined
|
|
67
105
|
when "product"
|
|
68
106
|
return exp.product.reduce (result, {label, exp}) ->
|
|
69
107
|
do (value = run exp, value) ->
|
|
70
|
-
throw new Error "Undefined"
|
|
108
|
+
throw new Error "Undefined" if value is undefined
|
|
71
109
|
result[label] = value
|
|
72
110
|
result
|
|
73
111
|
, {}
|
|
112
|
+
else
|
|
113
|
+
console.log exp.op
|
|
74
114
|
|
|
75
115
|
|
|
76
|
-
module.exports = run
|
|
116
|
+
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,34 +87,97 @@
|
|
|
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
|
+
switch (code.code) {
|
|
115
|
+
case "ref":
|
|
116
|
+
return (function(c) {
|
|
117
|
+
if (c != null) {
|
|
118
|
+
return verify(c, value);
|
|
119
|
+
}
|
|
120
|
+
return codes[code.ref](value);
|
|
121
|
+
})(run.defs.codes[code.ref]);
|
|
122
|
+
case "vector":
|
|
123
|
+
return value.every(function(x) {
|
|
124
|
+
return verify(code.vector, x);
|
|
125
|
+
});
|
|
126
|
+
case "product":
|
|
127
|
+
return (function(fields) {
|
|
128
|
+
if (fields.length !== Object.keys(code.product).length) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
return fields.every(function(label) {
|
|
132
|
+
return verify(code.product[label], value[label]);
|
|
133
|
+
});
|
|
134
|
+
})(Object.keys(value));
|
|
135
|
+
case "union":
|
|
136
|
+
return (function(fields) {
|
|
137
|
+
if (fields.length !== 1) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return verify(code.union[fields[0]], value[fields[0]]);
|
|
141
|
+
})(Object.keys(value));
|
|
86
142
|
}
|
|
87
143
|
};
|
|
88
144
|
|
|
89
145
|
run = function(exp, value) {
|
|
90
146
|
var e, i, len, ref, result;
|
|
91
|
-
if (value
|
|
147
|
+
if (value === void 0) {
|
|
92
148
|
return void 0;
|
|
93
149
|
}
|
|
94
150
|
try {
|
|
95
151
|
switch (exp.op) {
|
|
152
|
+
case "code":
|
|
153
|
+
if (verify(exp.code, value)) {
|
|
154
|
+
return value;
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
96
157
|
case "identity":
|
|
97
158
|
return value;
|
|
98
159
|
case "str":
|
|
99
160
|
case "int":
|
|
100
161
|
return exp[exp.op];
|
|
101
162
|
case "ref":
|
|
102
|
-
return (function(
|
|
103
|
-
if (
|
|
104
|
-
|
|
163
|
+
return (function(defn) {
|
|
164
|
+
if (defn != null) {
|
|
165
|
+
return run(defn, value);
|
|
166
|
+
} else {
|
|
167
|
+
return (function(value) {
|
|
168
|
+
if (value === void 0) {
|
|
169
|
+
throw new Error("Undefined");
|
|
170
|
+
}
|
|
171
|
+
return value;
|
|
172
|
+
})(builtin[exp.ref](value));
|
|
105
173
|
}
|
|
106
|
-
|
|
107
|
-
})(builtin[exp.ref](value));
|
|
174
|
+
})(run.defs.rels[exp.ref]);
|
|
108
175
|
case "dot":
|
|
109
176
|
return value[exp.dot];
|
|
110
177
|
case "comp":
|
|
111
178
|
return exp.comp.reduce(function(value, exp) {
|
|
112
179
|
value = run(exp, value);
|
|
113
|
-
if (value
|
|
180
|
+
if (value === void 0) {
|
|
114
181
|
throw new Error("Undefined");
|
|
115
182
|
}
|
|
116
183
|
return value;
|
|
@@ -119,7 +186,7 @@
|
|
|
119
186
|
return exp.vector.map(function(exp) {
|
|
120
187
|
var result;
|
|
121
188
|
result = run(exp, value);
|
|
122
|
-
if (result
|
|
189
|
+
if (result === void 0) {
|
|
123
190
|
throw new Error("Undefined");
|
|
124
191
|
}
|
|
125
192
|
return result;
|
|
@@ -133,7 +200,7 @@
|
|
|
133
200
|
return run(e, value);
|
|
134
201
|
} catch (error) {}
|
|
135
202
|
})();
|
|
136
|
-
if (result
|
|
203
|
+
if (result !== void 0) {
|
|
137
204
|
return result;
|
|
138
205
|
}
|
|
139
206
|
}
|
|
@@ -141,13 +208,15 @@
|
|
|
141
208
|
case "product":
|
|
142
209
|
return exp.product.reduce(function(result, {label, exp}) {
|
|
143
210
|
return (function(value) {
|
|
144
|
-
if (value
|
|
211
|
+
if (value === void 0) {
|
|
145
212
|
throw new Error("Undefined");
|
|
146
213
|
}
|
|
147
214
|
result[label] = value;
|
|
148
215
|
return result;
|
|
149
216
|
})(run(exp, value));
|
|
150
217
|
}, {});
|
|
218
|
+
default:
|
|
219
|
+
return console.log(exp.op);
|
|
151
220
|
}
|
|
152
221
|
} catch (error) {}
|
|
153
222
|
};
|
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
|
>
|