@fraczak/k 1.3.4 → 2.0.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.
@@ -0,0 +1,133 @@
1
+ const rels = {};
2
+ const codes = {
3
+ "{}": {
4
+ code: "product",
5
+ product: {},
6
+ },
7
+ };
8
+
9
+ const identity = {
10
+ op: "identity",
11
+ };
12
+
13
+ function is_identity_rel(rel) {
14
+ return rel.op === "identity";
15
+ }
16
+
17
+ function is_constant_rel(rel) {
18
+ switch (rel.op) {
19
+ case "int":
20
+ case "str":
21
+ return true;
22
+ case "vector":
23
+ return Object.values(rel[rel.op]).every(is_constant_rel);
24
+ case "product":
25
+ return Object.values(rel[rel.op]).every(({ exp }) =>
26
+ is_constant_rel(exp)
27
+ );
28
+ default:
29
+ return false;
30
+ }
31
+ }
32
+
33
+ function is_empty_rel(rel) {
34
+ return rel.op === "union" && rel.union.length === 0;
35
+ }
36
+
37
+ function is_full_rel(rel) {
38
+ if (is_constant_rel(rel)) return true;
39
+ switch (rel.op) {
40
+ case "int":
41
+ case "str":
42
+ case "identity":
43
+ return true;
44
+ case "comp":
45
+ return rel.comp.every(is_full_rel);
46
+ case "vector":
47
+ return Object.values(rel[rel.op]).every(is_full_rel);
48
+ case "product":
49
+ return Object.values(rel[rel.op]).every(({ exp }) => is_full_rel(exp));
50
+ default:
51
+ return false;
52
+ }
53
+ }
54
+
55
+ function comp_first(e1, e2) {
56
+ if (is_identity_rel(e1)) return e2;
57
+ if (is_identity_rel(e2)) return e1;
58
+ if (is_empty_rel(e1)) return e1;
59
+ if (is_empty_rel(e2)) return e2;
60
+ if (e1.op === "comp" && e2.op === "comp")
61
+ return {
62
+ op: "comp",
63
+ comp: [].concat(e1.comp, e2.comp),
64
+ };
65
+ if (e1.op === "comp")
66
+ return {
67
+ op: "comp",
68
+ comp: [].concat(e1.comp, [e2]),
69
+ };
70
+ if (e2.op === "comp")
71
+ return {
72
+ op: "comp",
73
+ comp: [].concat([e1], e2.comp),
74
+ };
75
+ return {
76
+ op: "comp",
77
+ comp: [e1, e2],
78
+ };
79
+ }
80
+
81
+ function comp (e1, e2) {
82
+ const result = comp_first(e1, e2);
83
+ if (result.op !== "comp") return result;
84
+ result.comp = result.comp.reduceRight(
85
+ (c, e) => (c[0] && is_constant_rel(c[0]) && is_full_rel(e) ? c : [e, ...c]),
86
+ []
87
+ );
88
+ return result;
89
+ }
90
+
91
+ function union (rels) {
92
+ const list = [];
93
+ label: for (const rel of rels) {
94
+ const new_rels = rel.op === "union" ? rel.union : [rel];
95
+ for (const new_rel of new_rels) {
96
+ list.push(new_rel);
97
+ if (is_full_rel(new_rel)) break label;
98
+ }
99
+ }
100
+ if (list.length === 1) return list[0];
101
+ return {
102
+ op: "union",
103
+ union: list,
104
+ };
105
+ };
106
+
107
+ function as_ref (codeExp) {
108
+ if (codeExp.code === "ref") return codeExp.ref;
109
+ const newName = `:${Object.keys(codes).length}`;
110
+ codes[newName] = codeExp;
111
+ return newName;
112
+ };
113
+
114
+ function add_rel (name, rel) {
115
+ if (rels[name] == null) rels[name] = [];
116
+ rels[name].push(rel);
117
+ };
118
+
119
+ function add_code (name, code) {
120
+ codes[name] = code;
121
+ }
122
+
123
+ export default {
124
+ identity,
125
+ comp,
126
+ union,
127
+ rels,
128
+ codes,
129
+ add_rel,
130
+ add_code,
131
+ as_ref,
132
+ };
133
+ export { identity, comp, union, rels, codes, add_rel, add_code, as_ref };
package/test.mjs ADDED
@@ -0,0 +1,143 @@
1
+ import k from "./index.mjs";
2
+
3
+ [
4
+ ["ANYTHING...", "()"],
5
+ ["ANYTHING...", '{"ala" name, 23 age}'],
6
+ [
7
+ {
8
+ year: 2002,
9
+ age: 19,
10
+ },
11
+ "[.year, .age]",
12
+ ],
13
+ ["duplicate me", "[(), ()]"],
14
+ ["nesting", "[[[()]]]"],
15
+ ["nesting and accessing", "[[()]] {() nested, .0.0 val}"],
16
+ [
17
+ {
18
+ test: "parse integer",
19
+ },
20
+ "0000",
21
+ ],
22
+ [
23
+ {
24
+ x: 3,
25
+ y: 4,
26
+ },
27
+ "[.y,.x] PLUS",
28
+ ],
29
+ ].map(function ([data, script]) {
30
+ console.log(`k_expression = '${script}';`);
31
+ console.log(`k.run(k_expression,${JSON.stringify(data)});`);
32
+ console.log(`// RETURNS: ${JSON.stringify(k.run(script, data))}`);
33
+ return console.log("");
34
+ });
35
+
36
+ let k_expression =
37
+ '{.name nom, <[.age, 18] GT .0, [.age, 12] GT "ado", "enfant"> age}';
38
+
39
+ let k_fn = k.compile(k_expression);
40
+
41
+ console.log(`var k_fn = k.compile('${k_expression}');`);
42
+
43
+ console.log("");
44
+
45
+ [
46
+ {
47
+ age: 23,
48
+ name: "Emily",
49
+ },
50
+ {
51
+ age: 16,
52
+ name: "Katrina",
53
+ },
54
+ {
55
+ age: 2,
56
+ name: "Mark",
57
+ },
58
+ ].map(function (data) {
59
+ console.log(`k_fn(${JSON.stringify(data)});`);
60
+ console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
61
+ return console.log("");
62
+ });
63
+
64
+ k_expression = "$t = < i: int, t: [ t ] > ; <$t, $int>";
65
+
66
+ k_fn = k.compile(k_expression);
67
+
68
+ console.log(`var k_fn = k.compile('${k_expression}');`);
69
+
70
+ console.log("");
71
+
72
+ [
73
+ 1,
74
+ {
75
+ i: 1,
76
+ },
77
+ [
78
+ {
79
+ i: 2,
80
+ },
81
+ {
82
+ i: 3,
83
+ },
84
+ {
85
+ t: [],
86
+ },
87
+ ],
88
+ {
89
+ t: [
90
+ {
91
+ i: 2,
92
+ },
93
+ {
94
+ i: 3,
95
+ },
96
+ {
97
+ t: [],
98
+ },
99
+ ],
100
+ },
101
+ ].map(function (data) {
102
+ console.log(`k_fn(${JSON.stringify(data)});`);
103
+ console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
104
+ return console.log("");
105
+ });
106
+
107
+ k_expression = "$ < < [ int ] ints, [ bool ] bools > list, string None>";
108
+
109
+ k_fn = k.compile(k_expression);
110
+
111
+ console.log(`var k_fn = k.compile('${k_expression}');`);
112
+
113
+ console.log("");
114
+
115
+ [
116
+ {
117
+ None: "None",
118
+ },
119
+ {
120
+ list: {
121
+ ints: [],
122
+ },
123
+ },
124
+ {
125
+ list: {
126
+ ints: [1, 2, 3],
127
+ },
128
+ },
129
+ {
130
+ list: {
131
+ bools: [true, false],
132
+ },
133
+ },
134
+ {
135
+ list: {
136
+ bools: [true, 0],
137
+ },
138
+ },
139
+ ].map(function (data) {
140
+ console.log(`k_fn(${JSON.stringify(data)});`);
141
+ console.log(`// RETURNS: ${JSON.stringify(k_fn(data))}`);
142
+ return console.log("");
143
+ });
package/codes.coffee DELETED
@@ -1,81 +0,0 @@
1
-
2
- are_different = (classes, representatives, name1, name2, codes) ->
3
- # console.log {classes, representatives, name1, name2, codes}
4
- return false if name1 is name2
5
- code1 = codes[name1]
6
- code2 = codes[name2]
7
- # console.log {name1, code1, name2, code2}
8
- return true unless code1.code is code2.code
9
- switch code1.code
10
- when "union", "product"
11
- [fields1,fields2] = [code1, code2]. map (code) ->
12
- do (arg = code[code.code]) ->
13
- Object.keys(arg).reduce (fields, label) ->
14
- fields[label] = representatives[arg[label]] ? arg[label]
15
- fields
16
- , {}
17
- return true unless Object.keys(fields1).length is Object.keys(fields2).length
18
- for field,rep of fields1
19
- # console.log {field,rep1:rep,rep2:fields2[field]}
20
- return true unless fields2[field] is rep
21
- when "vector"
22
- [arg1,arg2] = [code1, code2]. map ({vector}) ->
23
- representatives[vector] ? vector
24
- return true unless arg1 is arg2
25
- false
26
-
27
- minimize = (codes) ->
28
- names = Object.keys codes
29
- classes = {}
30
- classes["{}"] = names
31
- representatives = names.reduce (representatives, name) ->
32
- representatives[name] = "{}"
33
- representatives
34
- , {}
35
- changed = true
36
- while changed
37
- changed = false
38
- for name1, eq_names of classes
39
- code = codes[name1]
40
- [eq_names, dif_names] = eq_names.reduce ([eq_names, dif_names], name2) ->
41
- if are_different(classes, representatives, name1, name2, codes)
42
- dif_names.push name2
43
- else
44
- eq_names.push name2
45
- [eq_names,dif_names]
46
- , [[],[]]
47
- classes[name1] = eq_names
48
- do (new_rep = dif_names[0]) ->
49
- if new_rep?
50
- changed = true
51
- classes[new_rep] = dif_names
52
- for x in dif_names
53
- representatives[x] = new_rep
54
- {classes,representatives}
55
-
56
- normalize = (label_ref_map, representatives) ->
57
- # console.log {label_ref_map, representatives}
58
- Object.keys(label_ref_map).reduce (result, label) ->
59
- result[label] = do (name = label_ref_map[label]) ->
60
- representatives[name] ? name
61
- result
62
- , {}
63
-
64
- normalizeAll = (codes,representatives) ->
65
- names = Object.keys codes
66
- normalized = names.reduce (normalized, name) ->
67
- if name is representatives[name]
68
- do (code = codes[name]) ->
69
- switch code.code
70
- when "union", "product"
71
- normalized[name] = { code: code.code }
72
- normalized[name][code.code] = normalize code[code.code], representatives
73
- when "vector"
74
- normalized[name] = {code:"vector", vector: representatives[code.vector] ? code.vector}
75
-
76
- normalized
77
- , {}
78
-
79
- module.exports = {minimize,normalize,normalizeAll}
80
-
81
-
package/codes.js DELETED
@@ -1,134 +0,0 @@
1
- // Generated by CoffeeScript 2.7.0
2
- (function() {
3
- var are_different, minimize, normalize, normalizeAll;
4
-
5
- are_different = function(classes, representatives, name1, name2, codes) {
6
- var arg1, arg2, code1, code2, field, fields1, fields2, rep;
7
- if (name1 === name2) {
8
- // console.log {classes, representatives, name1, name2, codes}
9
- return false;
10
- }
11
- code1 = codes[name1];
12
- code2 = codes[name2];
13
- if (code1.code !== code2.code) {
14
- // console.log {name1, code1, name2, code2}
15
- return true;
16
- }
17
- switch (code1.code) {
18
- case "union":
19
- case "product":
20
- [fields1, fields2] = [code1, code2].map(function(code) {
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]);
28
- });
29
- if (Object.keys(fields1).length !== Object.keys(fields2).length) {
30
- return true;
31
- }
32
- for (field in fields1) {
33
- rep = fields1[field];
34
- if (fields2[field] !== rep) {
35
-
36
- // console.log {field,rep1:rep,rep2:fields2[field]}
37
- return true;
38
- }
39
- }
40
- break;
41
- case "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
- }
49
- }
50
- return false;
51
- };
52
-
53
- minimize = function(codes) {
54
- var changed, classes, code, dif_names, eq_names, name1, names, representatives;
55
- names = Object.keys(codes);
56
- classes = {};
57
- classes["{}"] = names;
58
- representatives = names.reduce(function(representatives, name) {
59
- representatives[name] = "{}";
60
- return representatives;
61
- }, {});
62
- changed = true;
63
- while (changed) {
64
- changed = false;
65
- for (name1 in classes) {
66
- eq_names = classes[name1];
67
- code = codes[name1];
68
- [eq_names, dif_names] = eq_names.reduce(function([eq_names, dif_names], name2) {
69
- if (are_different(classes, representatives, name1, name2, codes)) {
70
- dif_names.push(name2);
71
- } else {
72
- eq_names.push(name2);
73
- }
74
- return [eq_names, dif_names];
75
- }, [[], []]);
76
- classes[name1] = eq_names;
77
- (function(new_rep) {
78
- var i, len, results, x;
79
- if (new_rep != null) {
80
- changed = true;
81
- classes[new_rep] = dif_names;
82
- results = [];
83
- for (i = 0, len = dif_names.length; i < len; i++) {
84
- x = dif_names[i];
85
- results.push(representatives[x] = new_rep);
86
- }
87
- return results;
88
- }
89
- })(dif_names[0]);
90
- }
91
- }
92
- return {classes, representatives};
93
- };
94
-
95
- normalize = function(label_ref_map, representatives) {
96
- // console.log {label_ref_map, representatives}
97
- return Object.keys(label_ref_map).reduce(function(result, label) {
98
- result[label] = (function(name) {
99
- var ref;
100
- return (ref = representatives[name]) != null ? ref : name;
101
- })(label_ref_map[label]);
102
- return result;
103
- }, {});
104
- };
105
-
106
- normalizeAll = function(codes, representatives) {
107
- var names, normalized;
108
- names = Object.keys(codes);
109
- return normalized = names.reduce(function(normalized, name) {
110
- if (name === representatives[name]) {
111
- (function(code) {
112
- var ref;
113
- switch (code.code) {
114
- case "union":
115
- case "product":
116
- normalized[name] = {
117
- code: code.code
118
- };
119
- return normalized[name][code.code] = normalize(code[code.code], representatives);
120
- case "vector":
121
- return normalized[name] = {
122
- code: "vector",
123
- vector: (ref = representatives[code.vector]) != null ? ref : code.vector
124
- };
125
- }
126
- })(codes[name]);
127
- }
128
- return normalized;
129
- }, {});
130
- };
131
-
132
- module.exports = {minimize, normalize, normalizeAll};
133
-
134
- }).call(this);
package/index.coffee DELETED
@@ -1,28 +0,0 @@
1
- {parse} = require "./parser.js"
2
- run = require "./run"
3
- t = require "./codes"
4
-
5
-
6
- finalize = (codes) ->
7
- representatives = t.minimize(codes).representatives
8
- codes = t.normalizeAll codes, representatives
9
-
10
- {codes, representatives}
11
-
12
-
13
- compile = (script) ->
14
- do ({defs,exp} = parse script) ->
15
- # console.log defs
16
- {codes, representatives} = finalize defs.codes
17
- # console.log {codes, representatives}
18
- run.defs = {codes, representatives, rels: defs.rels}
19
-
20
- (data) -> run exp, data
21
-
22
- compile.doc = "Transforms k-script (string) into a function"
23
-
24
- runScriptOnData = (script, data) ->
25
- compile(script) data
26
- runScriptOnData.doc = "Run 'script' (string) on 'data': (script,data) -> data"
27
-
28
- module.exports = {compile, run: runScriptOnData, parse}
package/index.js DELETED
@@ -1,49 +0,0 @@
1
- // Generated by CoffeeScript 2.7.0
2
- (function() {
3
- var compile, finalize, parse, run, runScriptOnData, t;
4
-
5
- ({parse} = require("./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/k.coffee DELETED
@@ -1,59 +0,0 @@
1
- #!/usr/bin/env coffee
2
- fs = require "fs"
3
- k = require "./"
4
-
5
- prog = process.argv[1]
6
-
7
- {kScript,jsonStream,oneJson} =
8
- do (oneJson = false, args = process.argv.slice(2)) ->
9
- try
10
- kScript = do (arg = args.shift()) ->
11
- throw new Error() unless arg?
12
- if arg is "-k"
13
- fs.readFileSync(args.shift()).toString "utf8"
14
- else
15
- arg
16
-
17
- kScript = k.compile kScript
18
-
19
- jsonStream = do (arg = args.shift()) ->
20
- if arg is "-1"
21
- oneJson = true
22
- arg = args.shift()
23
- return process.stdin unless arg?
24
- fs.createReadStream arg
25
-
26
- {kScript, jsonStream, oneJson}
27
- catch e
28
- console.error e
29
- console.error "Usage: #{prog} ( k-expr | -k k-file ) [ -1 ] [ json-file ]"
30
- console.error " E.g., echo '{\"a\": 12}' | #{prog} '[(),()]'"
31
- process.exit -1
32
-
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