@fraczak/k 2.1.6 → 3.0.2

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/chatGPT.md~ ADDED
@@ -0,0 +1,119 @@
1
+ Thank you for the clarification. Let's revise the explanation to correctly describe the projection from union types as a check.
2
+
3
+ ### Key Concepts and Constructs of Kernel/Core
4
+
5
+ 1. **Program Structure**:
6
+ - Consists of a possibly empty list of statements, each ending with a semicolon (`;`), followed by an expression.
7
+ - Statements can be:
8
+ - **Code Definitions**: Define data types and start with a dollar sign (`$`).
9
+ - **Relation Definitions**: Define partial functions for data transformations.
10
+
11
+ 2. **Code Definitions (Data Types)**:
12
+ - **Union Types**: Defined using angle brackets (`<...>`).
13
+ ```kernelcore
14
+ $ bool = <{} true, {} false>;
15
+ ```
16
+ - **Product Types**: Defined using curly braces (`{...}`).
17
+ ```kernelcore
18
+ $ pair_of_bools = {bool x, bool y};
19
+ ```
20
+
21
+ 3. **Relation Definitions (Partial Functions)**:
22
+ - **Projection (Field Extraction)**: Partial functions that extract fields from product types or check for specific variants in union types.
23
+ ```kernelcore
24
+ // Extract the `x` field from a pair_of_bools (product type)
25
+ extract_x = $pair_of_bools .x;
26
+
27
+ // Extract the `y` field from a pair_of_bools (product type)
28
+ extract_y = $pair_of_bools .y;
29
+
30
+ // Check if a bool is the `true` variant (union type)
31
+ check_true = $bool .true;
32
+
33
+ // Check if a bool is the `false` variant (union type)
34
+ check_false = $bool .false;
35
+ ```
36
+ - **Functional Composition**: Sequential application of partial functions.
37
+ ```kernelcore
38
+ is_x_true = $pair_of_bools .x .true;
39
+ ```
40
+ - **Parallel (Product) Composition**: Combine multiple partial functions to construct a new product type.
41
+ ```kernelcore
42
+ extract_both = $pair_of_bools {.x x_value, .y y_value};
43
+ ```
44
+ - **Concurrent (Union) Composition**: Try different functions in sequence, returning the first successful result.
45
+ ```kernelcore
46
+ is_any_true = $pair_of_bools <.x .true true_bool, .y .true true_bool, false_bool>;
47
+ ```
48
+
49
+ 4. **Constants**:
50
+ - Constants are partial functions that ignore their input.
51
+ ```kernelcore
52
+ true_bool = {{} true};
53
+ false_bool = {{} false};
54
+ ```
55
+
56
+ 5. **Names and Labels**:
57
+ - Names and labels are alphanumerical sequences of ASCII characters, following the convention `[a-zA-Z_][a-zA-Z0-9_]*`.
58
+
59
+ 6. **Final Expression**:
60
+ - A final expression evaluates usage examples and collects results in a single product.
61
+ ```kernelcore
62
+ {pair1 is_x_true result1,
63
+ pair2 is_x_true result2,
64
+ pair1 extract_both both_values,
65
+ pair1 is_any_true any_true1,
66
+ pair2 is_any_true any_true2,
67
+ pair3 is_any_true any_true3}
68
+ ```
69
+
70
+ ### Complete Example Program
71
+
72
+ ```kernelcore
73
+ // Define a boolean type as a union of true and false
74
+ $ bool = <{} true, {} false>;
75
+
76
+ // Define a pair of booleans as a product of two booleans
77
+ $ pair_of_bools = {bool x, bool y};
78
+
79
+ // Projection (Field Extraction)
80
+ // Extract the `x` field from a pair_of_bools (product type)
81
+ extract_x = $pair_of_bools .x;
82
+
83
+ // Extract the `y` field from a pair_of_bools (product type)
84
+ extract_y = $pair_of_bools .y;
85
+
86
+ // Check if a bool is the `true` variant (union type)
87
+ check_true = $bool .true;
88
+
89
+ // Check if a bool is the `false` variant (union type)
90
+ check_false = $bool .false;
91
+
92
+ // Check if the `x` field is `true`
93
+ is_x_true = $pair_of_bools .x .true;
94
+
95
+ // Extract both `x` and `y` fields into a new product
96
+ extract_both = $pair_of_bools {.x x_value, .y y_value};
97
+
98
+ // Check if either `x` or `y` is `true`
99
+ is_any_true = $pair_of_bools <.x .true true_bool, .y .true true_bool, false_bool>;
100
+
101
+ // Define constants
102
+ true_bool = {{} true};
103
+ false_bool = {{} false};
104
+
105
+ // Create instances of `pair_of_bools`
106
+ pair1 = {true_bool x, true_bool y};
107
+ pair2 = {true_bool x, false_bool y};
108
+ pair3 = {false_bool x, false_bool y};
109
+
110
+ // Final expression to evaluate usage examples
111
+ {pair1 is_x_true result1,
112
+ pair2 is_x_true result2,
113
+ pair1 extract_both both_values,
114
+ pair1 is_any_true any_true1,
115
+ pair2 is_any_true any_true2,
116
+ pair3 is_any_true any_true3}
117
+ ```
118
+
119
+ This updated introduction and complete example program now correctly describe the projection from union types as checks, providing a comprehensive overview of kernel/core. If there are any further questions or a
@@ -0,0 +1,121 @@
1
+ # Pattern and its graph representation
2
+
3
+ Intuitively, a _pattern_ is an adhock description of a set of codes
4
+ by providing some characteristics of the codes. Those characteristics are:
5
+
6
+ 1. Is this product vs union?
7
+ 2. The code has to have field (label) leading to a type or another parretn
8
+
9
+ Code patterns is a graph with:
10
+
11
+ 1. edges labeled by `fields`
12
+ 2. nodes labeled by one of the:
13
+
14
+ 1. `/*/` - open unkown
15
+ 2. `{*}` - open product
16
+ 3. `<*>` - open union
17
+ 4. `//` - close uknown
18
+ 5. `{}` - close product
19
+ 6. `<>` - close union
20
+
21
+ A graph without "open" and "unknown" nodes is "code".
22
+
23
+ Actually every node in such a graph corresponds to a code pattern.
24
+
25
+ ## Pattern Graph
26
+
27
+ Example:
28
+
29
+ $nat = < {} _, nat 0, nat 1>;
30
+ rlz = $nat <.0._ {{{} _} 0}, .0 rlz, ()>;
31
+
32
+ We get `codes`:
33
+
34
+ id | code
35
+ ------|----------------------
36
+ '{}' | {}
37
+ 'nat' | <nat 0, nat 1, {} _>
38
+
39
+ and the (singleton) forest of expressons:
40
+
41
+ id | ref-name | rel
42
+ ------|----------|--------------
43
+ 0 | 'rlz' | ($nat < (.0 ._ {{{} _} 0}), (.0 rlz), ()>)
44
+
45
+ ### Initialize pattern graph
46
+
47
+ 1. We annotate the expression forest by unique pattern ids, all initialized as `*`, e.g.:
48
+
49
+ id | name | rel*
50
+ ---|-------|-----------------
51
+ 0 | 'rlz' | ( $nat < ( .0 ._ { { {} _} 0} ) , ( .0 rlz ) , () > )
52
+ | | %0 ( %1 $nat %2 < %3 ( %4 .0 %5 ._ %6 { %7 { %8 {} %9 _} %10 0} %11 ) %12, %13 ( %14 .0 %15 rlz %16 ) %17 , %18 () %19 > %20 ) %21
53
+
54
+ 2. The pattern graph (with 22 nodes) has no edges.
55
+
56
+ ### Pattern graph folding
57
+
58
+ Given a pattern graph, `(V,E)`, and an expression forest, `F`, we calculate a `folding` of the pattern graph,
59
+ which consists of:
60
+
61
+ 1. equivalence classes `eq` over `V + C`
62
+ - `%x $t $y` implies `%x ~ %y ~ $t`
63
+ - `%x ( %y ...)` implies `%x ~ %y`
64
+ - `(... %x ) %y` implies `%x ~ %y`
65
+ - `%x () %y` implies `%x ~ %y`
66
+ - `%x { %y1 ..., %y2 ..., ..., %yn ...}` implies `%x ~ %y1 ~ %y2 ~ ... ~ %yn`
67
+ - `%x < %y1 ..., %y2 ..., ..., %yn ...>` implies `%x ~ %y1 ~ %y2 ~ ... ~ %yn`
68
+ - `<... %y1, ... %y2, ..., ... %yn > %x` implies `%x ~ %y1 ~ %y2 ~ ... ~ %yn`
69
+ - if `%x ~ $t` and `%x .field %y` implies `%y ~ $t.field`
70
+ 2. new edges, `E'`
71
+ - `%x .field %y` implies `%x -[field]-> %y`
72
+ - `{..., ... %x field, ...} %y` implies `%y -[field]-> %x`
73
+ 3. pattern refinements, `R`
74
+ - `{... field} %x` implies `%x: <*>`
75
+ - `{... field, ...} %y` implies `%y: {}`
76
+
77
+ In our example:
78
+
79
+ `eq: {0,1,nat,2,3,4,11,12,13,14,15,16,17,18,19,20,21}, {5}, {6,7,8}, {9}, {10}`
80
+
81
+ `E': (4 -[0]-> 5), (5 -[_]-> 6), (10 -[_]-> 9), (11 -[0]-> 10), (14 -[0]-> 15)`
82
+
83
+ `R: 9:{}, 10:<*>`
84
+
85
+ By folding the pattern graph with those information we get:
86
+
87
+ %n ( %n $nat %n < %n ( %n .0 %n ._ %{} { %{} { %{} {} %{} _} %n 0} %n ) %n, %n ( %n .0 %n rlz %n ) %n , %n () %n > %n ) %n
88
+
89
+ ### Another example
90
+
91
+ dec = [(),-1] PLUS;
92
+ zero? = [(),0] EQ 0;
93
+ factorial = < zero? 1, [dec factorial, ()] TIMES >;
94
+ { () x, factorial "x!" }
95
+
96
+ name | rel*
97
+ -------|-----------------
98
+ PLUS | %1 $[int] %2 PLUS %3 $int %4
99
+ -1 | %5 {} %6 -1 %7 $int %8
100
+ EQ | %9 $[int] %10
101
+ dec | %11 [ %12 () %13, %14 -1 %15 ] %16 PLUS %17
102
+ zero? | %18 [ %19 () %20, %21 0 %22 ] %23 EQ %24 .0 %25
103
+
104
+ ----
105
+ Other observations:
106
+
107
+ Product like {.x ..., .y ...} implies the input is a product (not really valid)
108
+ Pattern `p = <{ p x, ... }>` implies, it is a union!, i.e., `p = < p x, ... >`, e.g, in `< .x, () >`.
109
+
110
+ ## To do
111
+
112
+ 0. rewrite the algo to be layered:
113
+ 1. pure algebraic (no vectors)
114
+ 2. with support for homogenous vectors
115
+ 3. native support for bytes, integers (`int64` only), booleans, and strings (`UTF8` only)
116
+ 1. incremental pattern graph construction
117
+ 2. folding pattern graph nodes corresponding to a code (e.g., parts of
118
+ the pattern graph whose nodes are all closed), adding codes into code graph and,
119
+ finally, re-minimizing it.
120
+ 3. support for 'built-in' types via plugins.
121
+ 4. do not simplify merge for code derivation sake.
@@ -0,0 +1,51 @@
1
+ function resolveCode(rel, inCode, outCode) {
2
+ const annotatedRel = {inCode, outCode, rel};
3
+ return annotatedRel;
4
+ }
5
+
6
+ // pat: { kind: [null, 'product', 'union'],
7
+ // closed: [true, false],
8
+ // fields: [{f: string, pat: pat}, ...]}
9
+ const emptyPat = { kind: 'union', closed: true, fields: [] };
10
+ const starPat = { kind: null, closed: false, fields: [] };
11
+ function isEmptyPat(pat) {
12
+ const {kind, closed, fields} = pat;
13
+ return kind === 'union' && closed && fields.length === 0;
14
+ }
15
+
16
+ function cap(pat1, pat2) {
17
+ if (pat1 === pat2) return pat1;
18
+ const {kind:kind1, closed:closed1, fields:fields1} = pat1;
19
+ const {kind:kind2, closed:closed2, fields:fields2} = pat2;
20
+ let kind, fields;
21
+ if (kind1 === null) {
22
+ kind = kind2;
23
+ } else if (kind2 === null) {
24
+ kind = kind1;
25
+ } else if (kind1 === kind2) {
26
+ kind = kind1;
27
+ } else
28
+ return emptyPat;
29
+
30
+ const map1 = new Map(fields1.map(({f, pat}) => [f, pat]));
31
+ const map2 = new Map(fields2.map(({f, pat}) => [f, pat]));
32
+ const fieldNames = new Set([...map1.keys(), ...map2.keys()]);
33
+ fields = [...fieldNames].map(f => {
34
+ const pat1 = map1.get(f) || starPat;
35
+ const pat2 = map2.get(f) || starPat;
36
+ const pat = cap(pat1, pat2);
37
+ return {f, pat};
38
+ });
39
+ if (fields.some(({pat}) => isEmptyPat(pat))) {
40
+ return emptyPat;
41
+ }
42
+ if ((closed1 && fields1.length !== fields.length) || (closed2 && fields2.length !== fields.length)) {
43
+ return emptyPat;
44
+ }
45
+ return {kind, closed: closed1 || closed2, fields};
46
+ }
47
+
48
+
49
+ export default { cap, starPat, emptyPat, isEmptyPat, resolveCode };
50
+ export { cap, starPat, emptyPat, isEmptyPat, resolveCode };
51
+
package/codes.mjs CHANGED
@@ -1,3 +1,56 @@
1
+ function isBuiltIn(code) {
2
+ return code.match(/^(int|string|bool)$/);
3
+ }
4
+
5
+ function logCeiling(n, base = 2) {
6
+ return Math.ceil(Math.log(n) / Math.log(base));
7
+ }
8
+
9
+ function encodeCodeToString(code, codes) {
10
+ if (isBuiltIn(code)) return code;
11
+ var i = 0;
12
+ const Q = [[code,i]];
13
+ const D = {[code]: i++};
14
+ var result=[];
15
+ while (Q.length > 0) {
16
+ const [x,c] = Q.shift();
17
+ const c_code = codes[x];
18
+ if (c_code.code == "vector") {
19
+ const u_arg = c_code.vector;
20
+ if (isBuiltIn(u_arg)) {
21
+ result.push(`$C${result.length}=[${u_arg}];`);
22
+ continue;
23
+ }
24
+ if (D[u_arg] === undefined) {
25
+ Q.push([u_arg,i]);
26
+ D[u_arg] = i++;
27
+ }
28
+ result.push(`$C${result.length}=[C${D[u_arg]}];`);
29
+ continue;
30
+ }
31
+ const u_args = Object.keys(c_code[c_code.code]).sort().map((k) => {
32
+ const u_arg = c_code[c_code.code][k];
33
+ if (isBuiltIn(u_arg))
34
+ return `${u_arg}${JSON.stringify(k)}`;
35
+ if (D[u_arg] === undefined) {
36
+ Q.push([u_arg,i]);
37
+ D[u_arg] = i++;
38
+ }
39
+ return `C${D[u_arg]}${JSON.stringify(k)}`;
40
+ });
41
+ if (c_code.code == "union") {
42
+ //result += `$${c}=<${u_args.join(",")}>;`;
43
+ result.push(`$C${result.length}=<${u_args.join(",")}>;`);
44
+ } else if (c_code.code == "product") {
45
+ //result += `$${c}={${u_args.join(",")}};`;
46
+ result.push(`$C${result.length}={${u_args.join(",")}};`);
47
+ } else {
48
+ throw new Error(`Unexpected code ${c_code.code}`);
49
+ }
50
+ }
51
+ return result.join("");
52
+ };
53
+
1
54
  function are_different(classes, representatives, name1, name2, codes) {
2
55
  if (name1 === name2) return false;
3
56
  const code1 = codes[name1];
@@ -63,6 +116,7 @@ function minimize(codes) {
63
116
  }
64
117
  }
65
118
  }
119
+
66
120
  return { classes, representatives };
67
121
  }
68
122
 
@@ -81,7 +135,7 @@ function normalizeAll(codes, representatives) {
81
135
  switch (code.code) {
82
136
  case "union":
83
137
  case "product":
84
- normalized[name] = { code: code.code };
138
+ normalized[name] = { ...code };
85
139
  normalized[name][code.code] = normalize(
86
140
  code[code.code],
87
141
  representatives
@@ -89,7 +143,7 @@ function normalizeAll(codes, representatives) {
89
143
  break;
90
144
  case "vector":
91
145
  normalized[name] = {
92
- code: "vector",
146
+ ...code,
93
147
  vector: representatives[code.vector] || code.vector,
94
148
  };
95
149
  }
@@ -99,5 +153,6 @@ function normalizeAll(codes, representatives) {
99
153
  }, {});
100
154
  }
101
155
 
102
- export default { minimize, normalize, normalizeAll };
103
- export { minimize, normalize, normalizeAll };
156
+
157
+ export default { minimize, normalize, normalizeAll, encodeCodeToString };
158
+ export { minimize, normalize, normalizeAll, encodeCodeToString };
package/filters.mjs ADDED
@@ -0,0 +1,59 @@
1
+ // filter is of type: [name|code|null|union|product|vector],
2
+ // null|union|product have fields, and can be open
3
+
4
+ function unify_with_code(codes, code, filter, context){
5
+ // console.log({code, filter, context});
6
+ if (context == undefined) return undefined;
7
+ if (code == undefined) return undefined;
8
+ switch (filter.type) {
9
+ case "code": {
10
+ if (filter.code == code)
11
+ return context;
12
+ return undefined;
13
+ }
14
+ case "name": {
15
+ const code_filter = {type: 'code', code: code};
16
+ if (filter.name in context) {
17
+ const new_filter = context[filter.name];
18
+ const new_context = {... context, [filter.name]: code_filter};
19
+ return unify_with_code(codes, code, new_filter, new_context);
20
+ }
21
+ return {...context, [filter.name]: {type: 'code', code: code}}
22
+ }
23
+ case "product":
24
+ case "union":
25
+ case null: {
26
+ const ctype = codes[code]?.code;
27
+ if (ctype != 'product' && ctype != 'union') return undefined;
28
+ const code_fields = codes[code][ctype];
29
+ const new_context = Object.keys(filter.fields).reduce((new_context, field) =>
30
+ unify_with_code(codes, code_fields[field], filter.fields[field], new_context)
31
+ , {...context});
32
+ if (filter.open !== true && Object.keys(code_fields).length != Object.keys(filter.fields).length)
33
+ return undefined;
34
+ return new_context;
35
+ }
36
+ case "vector": {
37
+ const ctype = codes[code]?.code;
38
+ if (ctype != 'vector') return undefined;
39
+ const code_vector = codes[code].vector;
40
+ return unify_with_code(codes, code_vector, filter.vector, context);
41
+ }
42
+ }
43
+ }
44
+
45
+ // we assume the names occurring in both filters are disjoint
46
+ function unify(codes, filter1, filter2, context ) {
47
+ if (context == undefined) return undefined;
48
+ if (filter1 == undefined || filter2 == undefined) return undefined;
49
+
50
+ switch (filter1.type) {
51
+ case "code":
52
+ return unify_with_code(codes, filter1.code, filter2, context);
53
+ }
54
+ }
55
+
56
+ export default { unify_with_code };
57
+ export { unify_with_code };
58
+
59
+
package/hash.mjs ADDED
@@ -0,0 +1,39 @@
1
+ const baseToShifted = {
2
+ '0': 'A', '1': 'B', '2': 'C', '3': 'D',
3
+ '4': 'E', '5': 'F', '6': 'G', '7': 'H',
4
+ '8': 'I', '9': 'J', 'a': 'K', 'b': 'L',
5
+ 'c': 'M', 'd': 'N', 'e': 'O', 'f': 'P',
6
+ 'g': 'Q', 'h': 'R', 'i': 'S', 'j': 'T',
7
+ 'k': 'U', 'l': 'V', 'm': 'W', 'n': 'X',
8
+ 'o': 'Y', 'p': 'Z', 'q': 'q', 'r': 'r',
9
+ 's': 's', 't': 't', 'u': 'u', 'v': 'v',
10
+ 'w': 'w', 'x': 'x', 'y': 'y', 'z': 'z'
11
+ };
12
+
13
+ const base = Object.keys(baseToShifted).length;
14
+
15
+ function shifString(baseString) {
16
+ let shiftedString = '';
17
+ for (let i = 0; i < baseString.length; i++) {
18
+ shiftedString += baseToShifted[baseString[i]];
19
+ }
20
+ return shiftedString;
21
+ }
22
+
23
+ function hash(inputString) {
24
+ if (inputString.match(/^\$C0=.*;$/))
25
+ inputString = inputString.slice(4,-1);
26
+ let hashValue = 0;
27
+ const prime = 31;
28
+ const mod = 1000000000039;
29
+
30
+ for (let i = 0; i < inputString.length; i++) {
31
+ let charCode = inputString.charCodeAt(i);
32
+ hashValue = (hashValue * prime + charCode) % mod;
33
+ }
34
+
35
+ return shifString(hashValue.toString(base));
36
+ }
37
+
38
+ export default hash;
39
+ export { hash };
package/index.mjs CHANGED
@@ -1,24 +1,54 @@
1
1
  import { parse } from "./parser.mjs";
2
+ import { patterns } from "./patterns.mjs";
2
3
  import run from "./run.mjs";
3
4
  import t from "./codes.mjs";
5
+ import hash from "./hash.mjs";
4
6
 
5
7
  function finalize(codes) {
6
8
  const representatives = t.minimize(codes).representatives;
9
+ const normalizedCodes = t.normalizeAll(codes, representatives);
10
+ const globalNames = Object.keys(normalizedCodes).reduce((globalNames, name) => {
11
+ const globalDef = t.encodeCodeToString(name, normalizedCodes);
12
+ normalizedCodes[name].def = globalDef;
13
+ globalNames[name] = hash(globalDef);
14
+ return globalNames;
15
+ }, {});
16
+ const globalCodes = Object.keys(normalizedCodes).reduce((globalCodes, name) => {
17
+ globalCodes[globalNames[name]] = normalizedCodes[name];
18
+ return globalCodes;
19
+ },{});
20
+ // console.log("globalCodes",globalCodes);
21
+
22
+ const extendedRepresentatives = Object.keys(representatives).reduce((result, name) => {
23
+ result[name] = globalNames[representatives[name]] || name;
24
+ return result;
25
+ }, Object.values(globalNames).reduce((result, name) => ({[name]: name, ...result}),{}));
26
+ // console.log("extendedRepresentatives",extendedRepresentatives);
27
+
28
+ const normalizedGlobalCodes = t.normalizeAll(globalCodes, extendedRepresentatives);
29
+ // console.log("normalizedGlobalCodes",normalizedGlobalCodes);
30
+
31
+
7
32
  return {
8
- codes: t.normalizeAll(codes, representatives),
9
- representatives,
33
+ codes: normalizedGlobalCodes,
34
+ representatives: extendedRepresentatives
10
35
  };
11
36
  }
12
37
 
13
38
  function compile(script) {
14
- const { defs, exp } = parse(script);
15
- const { codes, representatives } = finalize(defs.codes);
16
- run.defs = {
17
- codes,
18
- representatives,
19
- rels: defs.rels,
20
- };
21
- return run.bind(null, exp);
39
+ try {
40
+ run.defs = annotate(script);
41
+ } catch (e) {
42
+ console.error(e);
43
+ const { defs, exp } = parse(script);
44
+ const { codes, representatives } = finalize(defs.codes);
45
+ run.defs = {
46
+ rels: {...defs.rels, "__main__": [exp]},
47
+ codes, representatives
48
+ };
49
+ console.error("WARN: Recompiled without type reconciliation due to the type error above.");
50
+ }
51
+ return run.bind(null, run.defs.rels.__main__[0]);
22
52
  }
23
53
 
24
54
  compile.doc = "Transforms k-script (string) into a function";
@@ -28,5 +58,18 @@ function runScriptOnData(script, data) {
28
58
  }
29
59
  runScriptOnData.doc = "Run 'script' (string) on 'data': (script,data) -> data";
30
60
 
31
- export default { compile, run: runScriptOnData, parse };
32
- export { compile, runScriptOnData as run, parse };
61
+
62
+ function annotate(script) {
63
+ const { defs, exp } = parse(script);
64
+ const { codes, representatives } = finalize(defs.codes);
65
+
66
+ const rels = {...defs.rels, "__main__": [exp]};
67
+
68
+ const pats = patterns(codes, representatives, rels);
69
+
70
+ return {rels,codes,representatives, ...pats}
71
+ }
72
+ annotate.doc = "Annotate all the script expressions with patterns";
73
+
74
+ export default { compile, run: runScriptOnData, parse, annotate };
75
+ export { compile, runScriptOnData as run, parse, annotate };
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@fraczak/k",
3
- "version": "2.1.6",
3
+ "version": "3.0.2",
4
4
  "description": "k-language for JSON-like data transformation",
5
5
  "main": "index.mjs",
6
6
  "scripts": {
7
7
  "prepare": "jiwson -m es6 parser.jison -o parser.mjs",
8
- "test": "node test.mjs"
8
+ "test": "node test.mjs; for f in Code-derivation-tests/*.mjs; do echo $f; node $f; done; node test-fingerprint.mjs"
9
9
  },
10
10
  "repository": {
11
11
  "type": "git",