@fraczak/k 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # k-language
2
2
 
3
+ npm install @fraczak/k
4
+
3
5
  Another JSON transformation notation. A `k`-expression
4
6
  (script) defines a __partial function__, i.e., a function which, in
5
7
  general, is not defined for every input. `k`-expressions can be
@@ -55,11 +57,11 @@ Elementary partial functions are:
55
57
 
56
58
  A more interesting example could be:
57
59
 
58
- < [.0, .1] GT, [.1, .0] GT > .0
60
+ < GT .0, .1>
59
61
 
60
- which selects the bigger of two first integers of a vector argument, i.e.,
62
+ which selects the maximum element in two element vector, i.e.,
61
63
 
62
- [3,8] < [.0, .1] GT, [.1, .0] GT > .0 --> 8
64
+ [3,8] < GT .0, .1 > --> 8
63
65
 
64
66
  ## User defined functions
65
67
 
@@ -72,7 +74,18 @@ Elementary partial functions are:
72
74
  >;
73
75
  { () x, factorial "x!" }
74
76
 
75
- ## Value encodings (also called _types_ or _codes_)
77
+ Another example could be finding the biggest (max) value in a vector:
78
+
79
+ max = <
80
+ SNOC -- [x0, x1, x2, ...] -> [x0, [x1, x2, ...]]
81
+ [.0, .1 max] -- [x0, [x1, x2, ...]] -> [x0, max(x1,x2,...)], i.e., recursive call
82
+ <GT.0,.1>, -- if x0 > max(x1,x2,...) then x0 else max(x1,x2,...)
83
+ -- when SNOC is not defined, e.g. the argument is a singleton vector [x0]
84
+ .0 -- [x0] -> x0,
85
+ >;
86
+ max
87
+
88
+ ## Value encodings (also called _codes_)
76
89
 
77
90
  There are three predefined value encodings: `int`, `string`, and `bool`. The language
78
91
  supports `code`-expressions:
@@ -95,11 +108,12 @@ The above example defines new code called _tree_.
95
108
  The code can be then used in a `k`-expression as a filter. A `code`-expression
96
109
  within `k`-expression is again prefixed by `$`.
97
110
 
98
- $tree = <string leaf, {tree left, tree right} tree>;
111
+ $ tree = <string leaf, {tree left, tree right} tree>;
99
112
  inc = [(),1] PLUS;
113
+ max = <GT .0, .1>;
100
114
  height = $ tree <
101
115
  .leaf 0,
102
- .tree [.left height, .right height] <GT .0, .1> inc
116
+ .tree [.left height, .right height] max inc
103
117
  > $ int;
104
118
  height
105
119
 
@@ -124,7 +138,7 @@ run the language from command line.
124
138
  2. By providing only `k`-expression, the script will compile the
125
139
  `k`-expression and apply the generated function to the `stdin`, line by line:
126
140
 
127
- $ ./k.coffee '<["x=",.x," & y=",.y],["only x=",.x],["only y=",.y],["no x nor y"]>{CONCAT "x&y"}'
141
+ $ ./node_modules/.bin/k '<["x=",.x," & y=",.y],["only x=",.x],["only y=",.y],["no x nor y"]>{CONCAT "x&y"}'
128
142
 
129
143
  {"y": 123, "x": 432,"others": "..."} --> {"x&y":"x=432 & y=123"}
130
144
  {"x":987} --> {"x&y":"only x=987"}
@@ -150,11 +164,11 @@ run the language from command line.
150
164
 
151
165
  We can use it by:
152
166
 
153
- $ ./k.coffee -k test.k
167
+ $ ./node_modules/.bin/k -k test.k
154
168
 
155
169
  If we want to read `json` objects from a file, e.g., `my-objects.json`, we do
156
170
 
157
- $ ./k.coffee -k test.k my-objects.json
171
+ $ ./node_modules/.bin/k -k test.k my-objects.json
158
172
  {"x&y":"x=432 & y=123"}
159
173
  {"x&y":"onlyx=987"}
160
174
  {"x&y":"no x nor y"}
@@ -170,52 +184,62 @@ run the language from command line.
170
184
  ####################################################
171
185
 
172
186
  # Using from `javascript`
173
-
174
- var k = require("k");
187
+
188
+ var k = require("k");
189
+
190
+ k_expression = '()';
191
+ k.run(k_expression,"ANYTHING...");
192
+ // RETURNS: "ANYTHING..."
193
+
194
+ k_expression = '{"ala" name, 23 age}';
195
+ k.run(k_expression,"ANYTHING...");
196
+ // RETURNS: {"name":"ala","age":23}
197
+
198
+ k_expression = '[.year, .age]';
199
+ k.run(k_expression,{"year":2002,"age":19});
200
+ // RETURNS: [2002,19]
175
201
 
176
- var k_expression;
202
+ k_expression = '[(), ()]';
203
+ k.run(k_expression,"duplicate me");
204
+ // RETURNS: ["duplicate me","duplicate me"]
177
205
 
178
- k_expression = '()';
179
- k.run(t_expression,"ANYTHING...");
180
- // RETURNS: "ANYTHING..."
206
+ k_expression = '[[[()]]]';
207
+ k.run(k_expression,"nesting");
208
+ // RETURNS: [[["nesting"]]]
181
209
 
182
- k_expression = '{"ala" name, 23 age}';
183
- k.run(k_expression,"ANYTHING...");
184
- // RETURNS: {"name":"ala","age":23}
210
+ k_expression = '[[()]] {() nested, .0.0 val}';
211
+ k.run(k_expression,"nesting and accessing");
212
+ // RETURNS: {"nested":[["nesting and accessing"]],"val":"nesting and accessing"}
185
213
 
186
- k_expression = '[.year, .age]';
187
- k.run(k_expression,{"year":2002,"age":19});
188
- // RETURNS: [2002,19]
214
+ k_expression = '0000';
215
+ k.run(k_expression,{"test":"parse integer"});
216
+ // RETURNS: 0
189
217
 
190
- k_expression = '[(), ()]';
191
- k.run(k_expression,"duplicate me");
192
- // RETURNS: ["duplicate me","duplicate me"]
218
+ k_expression = '[.y,.x] PLUS';
219
+ k.run(k_expression,{"x":3,"y":4});
220
+ // RETURNS: 7
193
221
 
194
- k_expression = '[[[()]]]';
195
- k.run(k_expression,"nesting");
196
- // RETURNS: [[["nesting"]]]
222
+ var k_fn = k.compile('{.name nom, <[.age, 18] GT .0, [.age, 12] GT "ado", "enfant"> age}');
197
223
 
198
- k_expression = '[[()]] {() nested, .0.0 val}';
199
- k.run(k_expression,"nesting and accessing")
200
- // RETURNS: {"nested":[["nesting and accessing"]],"val":"nesting and accessing"}
224
+ k_fn({"age":23,"name":"Emily"});
225
+ // RETURNS: {"nom":"Emily","age":23}
201
226
 
202
- k_expression = '0000';
203
- k.run(k_expression,{"test":"parse integer"});
204
- // RETURNS: 0
227
+ k_fn({"age":16,"name":"Katrina"});
228
+ // RETURNS: {"nom":"Katrina","age":"ado"}
205
229
 
206
- k_expression = '[.y,.x] PLUS';
207
- k.run(k_expression,{"x":3,"y":4});
208
- // RETURNS: 7
230
+ k_fn({"age":2,"name":"Mark"});
231
+ // RETURNS: {"nom":"Mark","age":"enfant"}
209
232
 
210
- k_expression = '{.name nom, <[.age, 18] GT .0, [.age, 12] GT "ado", "enfant"> age}';
233
+ var k_fn = k.compile('$t = < i: int, t: [ t ] > ; <$t, $int>');
211
234
 
212
- var k_fn = k.compile(k_expression);
235
+ k_fn(1);
236
+ // RETURNS: 1
213
237
 
214
- k_fn({"age":23,"name":"Emily"});
215
- // RETURNS: {"nom":"Emily","age":23}
238
+ k_fn({"i":1});
239
+ // RETURNS: {"i":1}
216
240
 
217
- k_fn({"age":16,"name":"Katrina"});
218
- // RETURNS: {"nom":"Katrina","age":"ado"}
241
+ k_fn([{"i":2},{"i":3},{"t":[]}]);
242
+ // RETURNS: undefined
219
243
 
220
- k_fn({"age":2,"name":"Mark"})
221
- // RETURNS: {"nom":"Mark","age":"enfant"}
244
+ k_fn({"t":[{"i":2},{"i":3},{"t":[]}]});
245
+ // RETURNS: {"t":[{"i":2},{"i":3},{"t":[]}]}
package/code.k CHANGED
@@ -1,8 +1,9 @@
1
1
  inc = [(),1] PLUS;
2
+ max = <GT .0, .1>; -- max = < SNOC [.0, .1 max] <GT .0, .1>, .0 >;
2
3
  $tree = < string leaf, {tree left, tree right} tree>;
3
4
  height = $tree <
4
- .leaf 0,
5
- .tree [.left height, .right height] <GT .0, .1> inc
5
+ .leaf 0,
6
+ .tree [.left height, .right height] max inc
6
7
  > $int;
7
8
 
8
9
  <$tree,
package/codes.coffee CHANGED
@@ -1,5 +1,6 @@
1
1
 
2
2
  are_different = (classes, representatives, name1, name2, codes) ->
3
+ # console.log {classes, representatives, name1, name2, codes}
3
4
  return false if name1 is name2
4
5
  code1 = codes[name1]
5
6
  code2 = codes[name2]
@@ -8,15 +9,19 @@ are_different = (classes, representatives, name1, name2, codes) ->
8
9
  switch code1.code
9
10
  when "union", "product"
10
11
  [fields1,fields2] = [code1, code2]. map (code) ->
11
- Object.keys(code[code.code]).reduce (fields, label) ->
12
- fields[label] = representatives[code[code.code][label]]
13
- , {}
12
+ do (arg = code[code.code]) ->
13
+ Object.keys(arg).reduce (fields, label) ->
14
+ fields[label] = representatives[arg[label]] ? arg[label]
15
+ fields
16
+ , {}
14
17
  return true unless Object.keys(fields1).length is Object.keys(fields2).length
15
18
  for field,rep of fields1
19
+ # console.log {field,rep1:rep,rep2:fields2[field]}
16
20
  return true unless fields2[field] is rep
17
- return false
18
21
  when "vector"
19
- return representatives[code1.vector] isnt representatives[code2.vector]
22
+ [arg1,arg2] = [code1, code2]. map ({vector}) ->
23
+ representatives[vector] ? vector
24
+ return true unless arg1 is arg2
20
25
  false
21
26
 
22
27
  minimize = (codes) ->
package/codes.js CHANGED
@@ -3,8 +3,9 @@
3
3
  var are_different, compareAs, minimize, normalize, normalizeAll, pretty, pretty_labels;
4
4
 
5
5
  are_different = function(classes, representatives, name1, name2, codes) {
6
- var code1, code2, field, fields1, fields2, rep;
6
+ var arg1, arg2, code1, code2, field, fields1, fields2, rep;
7
7
  if (name1 === name2) {
8
+ // console.log {classes, representatives, name1, name2, codes}
8
9
  return false;
9
10
  }
10
11
  code1 = codes[name1];
@@ -17,9 +18,13 @@
17
18
  case "union":
18
19
  case "product":
19
20
  [fields1, fields2] = [code1, code2].map(function(code) {
20
- return Object.keys(code[code.code]).reduce(function(fields, label) {
21
- return fields[label] = representatives[code[code.code][label]];
22
- }, {});
21
+ return (function(arg) {
22
+ return Object.keys(arg).reduce(function(fields, label) {
23
+ var ref;
24
+ fields[label] = (ref = representatives[arg[label]]) != null ? ref : arg[label];
25
+ return fields;
26
+ }, {});
27
+ })(code[code.code]);
23
28
  });
24
29
  if (Object.keys(fields1).length !== Object.keys(fields2).length) {
25
30
  return true;
@@ -27,12 +32,20 @@
27
32
  for (field in fields1) {
28
33
  rep = fields1[field];
29
34
  if (fields2[field] !== rep) {
35
+
36
+ // console.log {field,rep1:rep,rep2:fields2[field]}
30
37
  return true;
31
38
  }
32
39
  }
33
- return false;
40
+ break;
34
41
  case "vector":
35
- return representatives[code1.vector] !== representatives[code2.vector];
42
+ [arg1, arg2] = [code1, code2].map(function({vector}) {
43
+ var ref;
44
+ return (ref = representatives[vector]) != null ? ref : vector;
45
+ });
46
+ if (arg1 !== arg2) {
47
+ return true;
48
+ }
36
49
  }
37
50
  return false;
38
51
  };
package/error.k ADDED
@@ -0,0 +1,8 @@
1
+
2
+ $ var = < int int, bool bool >;
3
+
4
+ <
5
+ $var "VAR",
6
+ _log!
7
+ $ < int i, bool j> " < int i, bool j>"
8
+ >
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fraczak/k",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "k-language for JSON-like data transformation",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/run.coffee CHANGED
@@ -48,7 +48,8 @@ codes =
48
48
  x is true or x is false
49
49
 
50
50
  verify = (code, value) ->
51
- # console.log {code,value}
51
+ # representatives = run.defs.representatives
52
+ # console.log {code,value,representatives}
52
53
  switch code.code
53
54
  when "vector"
54
55
  value.every (x) ->
package/run.js CHANGED
@@ -111,7 +111,8 @@
111
111
  };
112
112
 
113
113
  verify = function(code, value) {
114
- // console.log {code,value}
114
+ // representatives = run.defs.representatives
115
+ // console.log {code,value,representatives}
115
116
  switch (code.code) {
116
117
  case "vector":
117
118
  return value.every(function(x) {
package/typed-fib.k ADDED
@@ -0,0 +1,19 @@
1
+ inc = [(),1] PLUS;
2
+ fib2 =
3
+ $ { int target, int x, int "fib(x)", int "fib(x-1)" }
4
+ _log!
5
+ <
6
+ {[.target,.x]GT.0 target ,
7
+ .x inc x ,
8
+ [."fib(x)",."fib(x-1)"]PLUS "fib(x)" ,
9
+ ."fib(x)" "fib(x-1)" }
10
+ fib2,
11
+
12
+ {[.target,.x] EQ, ."fib(x)" result}
13
+ .result
14
+ >
15
+ $ int;
16
+
17
+ {() target, 0 x, 1 "fib(x)", 0 "fib(x-1)"} fib2
18
+
19
+