@fraczak/k 1.0.1 → 1.1.1

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/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,20 +35,57 @@ 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
+ # console.log {code,value}
52
+ switch code.code
53
+ when "vector"
54
+ value.every (x) ->
55
+ verify code.vector, x
56
+ when "product"
57
+ do (fields = Object.keys(value)) ->
58
+ return false unless fields.length is Object.keys(code.product).length
59
+ fields.every (label) ->
60
+ verify code.product[label], value[label]
61
+ when "union"
62
+ do (fields = Object.keys(value)) ->
63
+ return false unless fields.length is 1
64
+ verify code.union[fields[0]], value[fields[0]]
65
+ else
66
+ do (c = run.defs.codes[run.defs.representatives[code]]) ->
67
+ return verify c, value if c?
68
+ codes[code] value
36
69
 
37
70
  run = (exp, value) ->
71
+ # console.log {exp,value}
38
72
  return undefined if value is undefined
39
73
  try
40
74
  switch exp.op
75
+ when "code"
76
+ return value if verify exp.code, value
41
77
  when "identity"
42
78
  return value
43
79
  when "str", "int"
44
80
  return exp[exp.op]
45
81
  when "ref"
46
- return do (value = builtin[exp.ref] value) ->
47
- throw new Error "Undefined" if value is undefined
48
- value
82
+ do (defn = run.defs.rels[exp.ref]?[0]) ->
83
+ if defn?
84
+ run defn, value
85
+ else
86
+ do ( value = builtin[exp.ref] value ) ->
87
+ throw new Error "Undefined" if value is undefined
88
+ value
49
89
  when "dot"
50
90
  return value[exp.dot]
51
91
  when "comp"
@@ -71,6 +111,8 @@ run = (exp, value) ->
71
111
  result[label] = value
72
112
  result
73
113
  , {}
114
+ else
115
+ console.log exp.op
74
116
 
75
117
 
76
118
  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,28 +87,93 @@
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
+ // console.log {code,value}
115
+ switch (code.code) {
116
+ case "vector":
117
+ return value.every(function(x) {
118
+ return verify(code.vector, x);
119
+ });
120
+ case "product":
121
+ return (function(fields) {
122
+ if (fields.length !== Object.keys(code.product).length) {
123
+ return false;
124
+ }
125
+ return fields.every(function(label) {
126
+ return verify(code.product[label], value[label]);
127
+ });
128
+ })(Object.keys(value));
129
+ case "union":
130
+ return (function(fields) {
131
+ if (fields.length !== 1) {
132
+ return false;
133
+ }
134
+ return verify(code.union[fields[0]], value[fields[0]]);
135
+ })(Object.keys(value));
136
+ default:
137
+ return (function(c) {
138
+ if (c != null) {
139
+ return verify(c, value);
140
+ }
141
+ return codes[code](value);
142
+ })(run.defs.codes[run.defs.representatives[code]]);
86
143
  }
87
144
  };
88
145
 
89
146
  run = function(exp, value) {
90
- var e, i, len, ref, result;
147
+ var e, i, len, ref, ref1, result;
91
148
  if (value === void 0) {
149
+ // console.log {exp,value}
92
150
  return void 0;
93
151
  }
94
152
  try {
95
153
  switch (exp.op) {
154
+ case "code":
155
+ if (verify(exp.code, value)) {
156
+ return value;
157
+ }
158
+ break;
96
159
  case "identity":
97
160
  return value;
98
161
  case "str":
99
162
  case "int":
100
163
  return exp[exp.op];
101
164
  case "ref":
102
- return (function(value) {
103
- if (value === void 0) {
104
- throw new Error("Undefined");
165
+ return (function(defn) {
166
+ if (defn != null) {
167
+ return run(defn, value);
168
+ } else {
169
+ return (function(value) {
170
+ if (value === void 0) {
171
+ throw new Error("Undefined");
172
+ }
173
+ return value;
174
+ })(builtin[exp.ref](value));
105
175
  }
106
- return value;
107
- })(builtin[exp.ref](value));
176
+ })((ref = run.defs.rels[exp.ref]) != null ? ref[0] : void 0);
108
177
  case "dot":
109
178
  return value[exp.dot];
110
179
  case "comp":
@@ -125,9 +194,9 @@
125
194
  return result;
126
195
  });
127
196
  case "union":
128
- ref = exp.union;
129
- for (i = 0, len = ref.length; i < len; i++) {
130
- e = ref[i];
197
+ ref1 = exp.union;
198
+ for (i = 0, len = ref1.length; i < len; i++) {
199
+ e = ref1[i];
131
200
  result = (function() {
132
201
  try {
133
202
  return run(e, value);
@@ -148,6 +217,8 @@
148
217
  return result;
149
218
  })(run(exp, value));
150
219
  }, {});
220
+ default:
221
+ return console.log(exp.op);
151
222
  }
152
223
  } catch (error) {}
153
224
  };
@@ -1,8 +1,31 @@
1
+ rels = Object.create null
2
+ codes = Object.create null
3
+ codes["{}"] = {code: "product", product: {}}
4
+
1
5
  identity = op: "identity"
2
6
 
7
+ is_identity_rel = (rel) ->
8
+ rel.op is "identity"
9
+
10
+ is_empty_rel = (rel) ->
11
+ rel.op is "union" and rel.union.length is 0
12
+
13
+ is_full_rel = (rel) ->
14
+ switch rel.op
15
+ when "int", "str", "identity"
16
+ true
17
+ when "comp"
18
+ rel.comp.every is_full_rel
19
+ when "product", "vector"
20
+ Object.values(rel[rel.op]).every is_full_rel
21
+ else
22
+ false
23
+
3
24
  comp = (e1, e2) ->
4
- return e2 if e1.op is "identity"
5
- return e1 if e2.op is "identity"
25
+ return e2 if is_identity_rel e1
26
+ return e1 if is_identity_rel e2
27
+ return e1 if is_empty_rel e1
28
+ return e2 if is_empty_rel e2
6
29
  if e1.op is "comp" and e2.op is "comp"
7
30
  return {op: "comp", comp: [].concat(e1.comp,e2.comp)}
8
31
  if e1.op is "comp"
@@ -11,4 +34,31 @@ comp = (e1, e2) ->
11
34
  return {op: "comp", comp: [].concat([e1],e2.comp)}
12
35
  {op: "comp", comp: [e1,e2]}
13
36
 
14
- module.exports = {identity, comp};
37
+ union = (rels) ->
38
+ list = []
39
+ do ->
40
+ for rel in rels
41
+ new_rels = if rel.op is "union"
42
+ rel.union
43
+ else
44
+ [rel]
45
+ for rel in new_rels
46
+ list.push rel
47
+ return if is_full_rel rel
48
+ return list[0] if list.length is 1
49
+ {op: "union", union: list}
50
+
51
+ as_ref = (codeExp) ->
52
+ return codeExp.ref if codeExp.code is "ref"
53
+ newName = ":#{Object.keys(codes).length}"
54
+ codes[newName] = codeExp
55
+ return newName
56
+
57
+ add_rel = (name, rel) ->
58
+ rels[name] ?= []
59
+ rels[name].push rel
60
+
61
+ add_code = (name, code) ->
62
+ codes[name] = code
63
+
64
+ module.exports = {identity, comp, union, rels, codes, add_rel, add_code, as_ref};
package/symbol-table.js CHANGED
@@ -1,18 +1,57 @@
1
1
  // Generated by CoffeeScript 2.7.0
2
2
  (function() {
3
- var comp, identity;
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
+ };
4
13
 
5
14
  identity = {
6
15
  op: "identity"
7
16
  };
8
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
+
9
42
  comp = function(e1, e2) {
10
- if (e1.op === "identity") {
43
+ if (is_identity_rel(e1)) {
11
44
  return e2;
12
45
  }
13
- if (e2.op === "identity") {
46
+ if (is_identity_rel(e2)) {
14
47
  return e1;
15
48
  }
49
+ if (is_empty_rel(e1)) {
50
+ return e1;
51
+ }
52
+ if (is_empty_rel(e2)) {
53
+ return e2;
54
+ }
16
55
  if (e1.op === "comp" && e2.op === "comp") {
17
56
  return {
18
57
  op: "comp",
@@ -37,6 +76,53 @@
37
76
  };
38
77
  };
39
78
 
40
- module.exports = {identity, comp};
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};
41
127
 
42
128
  }).call(this);
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);
@@ -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
- -- it is defined only if field 'x' is present
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
  >