@calcit/procs 0.11.0-a8 → 0.11.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.
@@ -1,13 +1,12 @@
1
1
  import { CalcitRecord } from "./js-record.mjs";
2
+ import { CalcitImpl } from "./js-impl.mjs";
2
3
 
3
4
  export class CalcitEnum {
4
5
  prototype: CalcitRecord;
5
- impls: CalcitRecord[];
6
6
  cachedHash: number;
7
7
 
8
- constructor(prototype: CalcitRecord, impls: CalcitRecord[] = []) {
8
+ constructor(prototype: CalcitRecord) {
9
9
  this.prototype = prototype;
10
- this.impls = impls;
11
10
  this.cachedHash = null;
12
11
  }
13
12
 
@@ -15,13 +14,20 @@ export class CalcitEnum {
15
14
  return this.prototype.name.value;
16
15
  }
17
16
 
18
- withImpls(impls: CalcitRecord | CalcitRecord[]): CalcitEnum {
19
- if (impls instanceof CalcitRecord) {
20
- return new CalcitEnum(this.prototype, [impls]);
17
+ get impls(): CalcitImpl[] {
18
+ return this.prototype.structRef.impls;
19
+ }
20
+
21
+ withImpls(impls: CalcitImpl | CalcitImpl[]): CalcitEnum {
22
+ let nextImpls: CalcitImpl[];
23
+ if (impls instanceof CalcitImpl) {
24
+ nextImpls = [impls];
21
25
  } else if (Array.isArray(impls)) {
22
- return new CalcitEnum(this.prototype, impls);
26
+ nextImpls = impls;
27
+ } else {
28
+ throw new Error("Expected an impl as implementation");
23
29
  }
24
- throw new Error("Expected a record as implementation");
30
+ return new CalcitEnum(this.prototype.withImpls(nextImpls));
25
31
  }
26
32
 
27
33
  toString(): string {
@@ -0,0 +1,47 @@
1
+ import { Hash } from "@calcit/ternary-tree";
2
+ import { CalcitValue } from "./js-primes.mjs";
3
+ import { CalcitTag, castTag, findInFields, toString } from "./calcit-data.mjs";
4
+ import type { CalcitTrait } from "./js-trait.mjs";
5
+
6
+ export class CalcitImpl {
7
+ name: CalcitTag;
8
+ origin: CalcitTrait | null;
9
+ fields: Array<CalcitTag>;
10
+ values: Array<CalcitValue>;
11
+ cachedHash: Hash;
12
+
13
+ constructor(name: CalcitTag, fields: Array<CalcitTag>, values: Array<CalcitValue>, origin: CalcitTrait | null = null) {
14
+ this.name = name;
15
+ this.origin = origin;
16
+ this.fields = fields;
17
+ this.values = values;
18
+ this.cachedHash = null;
19
+ }
20
+
21
+ get(k: CalcitValue) {
22
+ let field = castTag(k);
23
+ let idx = findInFields(this.fields, field);
24
+ if (idx >= 0) {
25
+ return this.values[idx];
26
+ }
27
+ throw new Error(`Cannot find :${field} among (${this.fields.join(",")})`);
28
+ }
29
+
30
+ getOrNil(k: CalcitValue) {
31
+ let field = castTag(k);
32
+ let idx = findInFields(this.fields, field);
33
+ if (idx >= 0) {
34
+ return this.values[idx];
35
+ }
36
+ return undefined;
37
+ }
38
+
39
+ toString(disableJsDataWarning: boolean = false): string {
40
+ const parts = ["(%impl ", this.name.toString()];
41
+ for (let idx = 0; idx < this.fields.length; idx++) {
42
+ parts.push(" (", this.fields[idx].toString(), " ", toString(this.values[idx], true, disableJsDataWarning), ")");
43
+ }
44
+ parts.push(")");
45
+ return parts.join("");
46
+ }
47
+ }
@@ -2,12 +2,14 @@ import { CalcitTag, CalcitSymbol, CalcitFn, CalcitRecur } from "./calcit-data.mj
2
2
  import { CalcitRef } from "./js-ref.mjs";
3
3
  import { CalcitList, CalcitSliceList } from "./js-list.mjs";
4
4
  import { CalcitRecord } from "./js-record.mjs";
5
+ import { CalcitImpl } from "./js-impl.mjs";
5
6
  import { CalcitStruct } from "./js-struct.mjs";
6
7
  import { CalcitEnum } from "./js-enum.mjs";
7
8
  import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
8
9
  import { CalcitSet as CalcitSet } from "./js-set.mjs";
9
10
  import { CalcitTuple } from "./js-tuple.mjs";
10
11
  import { CalcitCirruQuote, cirru_deep_equal } from "./js-cirru.mjs";
12
+ import { CalcitTrait } from "./js-trait.mjs";
11
13
 
12
14
  export type CalcitValue =
13
15
  | string
@@ -25,6 +27,8 @@ export type CalcitValue =
25
27
  | CalcitFn
26
28
  | CalcitRecur // should not be exposed to function
27
29
  | CalcitRecord
30
+ | CalcitImpl
31
+ | CalcitTrait
28
32
  | CalcitStruct
29
33
  | CalcitEnum
30
34
  | CalcitCirruQuote
@@ -54,6 +58,7 @@ enum PseudoTypeIndex {
54
58
  set,
55
59
  map,
56
60
  record,
61
+ impl,
57
62
  struct,
58
63
  enum_type,
59
64
  fn,
@@ -76,6 +81,7 @@ let typeAsInt = (x: CalcitValue): number => {
76
81
  if (x instanceof CalcitSet) return PseudoTypeIndex.set;
77
82
  if (x instanceof CalcitMap || x instanceof CalcitSliceMap) return PseudoTypeIndex.map;
78
83
  if (x instanceof CalcitRecord) return PseudoTypeIndex.record;
84
+ if (x instanceof CalcitImpl) return PseudoTypeIndex.impl;
79
85
  if (x instanceof CalcitStruct) return PseudoTypeIndex.struct;
80
86
  if (x instanceof CalcitEnum) return PseudoTypeIndex.enum_type;
81
87
  if (x instanceof CalcitCirruQuote) return PseudoTypeIndex.cirru_quote;
@@ -1,16 +1,19 @@
1
1
  import { initTernaryTreeMap, Hash, insert } from "@calcit/ternary-tree";
2
2
  import { CalcitValue } from "./js-primes.mjs";
3
+ import { CalcitImpl } from "./js-impl.mjs";
3
4
  import { newTag, castTag, toString, CalcitTag, getStringName, findInFields } from "./calcit-data.mjs";
4
5
 
5
6
  import { CalcitMap, CalcitSliceMap } from "./js-map.mjs";
6
7
 
8
+ import { CalcitStruct } from "./js-struct.mjs";
9
+
7
10
  export class CalcitRecord {
8
11
  name: CalcitTag;
9
12
  fields: Array<CalcitTag>;
10
13
  values: Array<CalcitValue>;
11
- impls: Array<CalcitRecord>;
14
+ structRef: CalcitStruct;
12
15
  cachedHash: Hash;
13
- constructor(name: CalcitTag, fields: Array<CalcitTag>, values?: Array<CalcitValue>, impls?: Array<CalcitRecord>) {
16
+ constructor(name: CalcitTag, fields: Array<CalcitTag>, values?: Array<CalcitValue>, structRef?: CalcitStruct) {
14
17
  this.name = name;
15
18
  let fieldNames = fields.map(castTag);
16
19
  this.fields = fields;
@@ -23,7 +26,7 @@ export class CalcitRecord {
23
26
  this.values = new Array(fieldNames.length);
24
27
  }
25
28
  this.cachedHash = null;
26
- this.impls = impls || [];
29
+ this.structRef = structRef || new CalcitStruct(name, fields, new Array(fields.length).fill(null));
27
30
  }
28
31
  get(k: CalcitValue) {
29
32
  let field = castTag(k);
@@ -53,7 +56,7 @@ export class CalcitRecord {
53
56
  values[idx] = this.values[idx];
54
57
  }
55
58
  }
56
- return new CalcitRecord(this.name, this.fields, values, this.impls);
59
+ return new CalcitRecord(this.name, this.fields, values, this.structRef);
57
60
  }
58
61
  /** return -1 for missing */
59
62
  findIndex(k: CalcitValue) {
@@ -74,12 +77,17 @@ export class CalcitRecord {
74
77
  parts.push(")");
75
78
  return parts.join("");
76
79
  }
77
- withImpls(impl: CalcitValue): CalcitRecord {
78
- if (impl instanceof CalcitRecord) {
79
- return new CalcitRecord(this.name, this.fields, this.values, [impl]);
80
+ withImpls(impl: CalcitValue | CalcitImpl[]): CalcitRecord {
81
+ let nextImpls: CalcitImpl[];
82
+ if (impl instanceof CalcitImpl) {
83
+ nextImpls = [impl];
84
+ } else if (Array.isArray(impl)) {
85
+ nextImpls = impl;
80
86
  } else {
81
- throw new Error("Expected a record");
87
+ throw new Error("Expected an impl or array of impls");
82
88
  }
89
+ let nextStruct = new CalcitStruct(this.name, this.fields, this.structRef.fieldTypes, this.structRef.impls.concat(nextImpls));
90
+ return new CalcitRecord(this.name, this.fields, this.values, nextStruct);
83
91
  }
84
92
  }
85
93
 
@@ -96,7 +104,7 @@ export let new_record = (name: CalcitValue, ...fields: Array<CalcitValue>): Calc
96
104
  return new CalcitRecord(castTag(name), fieldNames);
97
105
  };
98
106
 
99
- export let new_impl_record = (impl: CalcitRecord, name: CalcitValue, ...fields: Array<CalcitValue>): CalcitValue => {
107
+ export let new_impl_record = (impl: CalcitImpl, name: CalcitValue, ...fields: Array<CalcitValue>): CalcitValue => {
100
108
  let fieldNames = fields.map(castTag).sort((x, y) => {
101
109
  if (x.idx < y.idx) {
102
110
  return -1;
@@ -106,7 +114,9 @@ export let new_impl_record = (impl: CalcitRecord, name: CalcitValue, ...fields:
106
114
  throw new Error(`Unexpected duplication in record fields: ${x.toString()}`);
107
115
  }
108
116
  });
109
- return new CalcitRecord(castTag(name), fieldNames, undefined, [impl]);
117
+ let nameTag = castTag(name);
118
+ let structRef = new CalcitStruct(nameTag, fieldNames, new Array(fieldNames.length).fill(null), [impl]);
119
+ return new CalcitRecord(nameTag, fieldNames, undefined, structRef);
110
120
  };
111
121
 
112
122
  export let fieldsEqual = (xs: Array<CalcitTag>, ys: Array<CalcitTag>): boolean => {
@@ -154,7 +164,7 @@ export let _$n__PCT__$M_ = (proto: CalcitValue, ...xs: Array<CalcitValue>): Calc
154
164
  values[i] = xs[idx * 2 + 1];
155
165
  }
156
166
 
157
- return new CalcitRecord(proto.name, proto.fields, values, proto.impls);
167
+ return new CalcitRecord(proto.name, proto.fields, values, proto.structRef);
158
168
  } else {
159
169
  throw new Error("Expected prototype to be a record");
160
170
  }
@@ -176,7 +186,7 @@ export let _$n_record_$o_with = (proto: CalcitValue, ...xs: Array<CalcitValue>):
176
186
  }
177
187
  values[idx] = v;
178
188
  }
179
- return new CalcitRecord(proto.name, proto.fields, values, proto.impls);
189
+ return new CalcitRecord(proto.name, proto.fields, values, proto.structRef);
180
190
  } else {
181
191
  throw new Error("Expected prototype to be a record");
182
192
  }
@@ -1,15 +1,15 @@
1
1
  import { CalcitTag, toString } from "./calcit-data.mjs";
2
2
  import { CalcitValue } from "./js-primes.mjs";
3
- import { CalcitRecord } from "./js-record.mjs";
3
+ import { CalcitImpl } from "./js-impl.mjs";
4
4
 
5
5
  export class CalcitStruct {
6
6
  name: CalcitTag;
7
7
  fields: CalcitTag[];
8
8
  fieldTypes: CalcitValue[];
9
- impls: CalcitRecord[];
9
+ impls: CalcitImpl[];
10
10
  cachedHash: number;
11
11
 
12
- constructor(name: CalcitTag, fields: CalcitTag[], fieldTypes: CalcitValue[], impls: CalcitRecord[] = []) {
12
+ constructor(name: CalcitTag, fields: CalcitTag[], fieldTypes: CalcitValue[], impls: CalcitImpl[] = []) {
13
13
  if (fields.length !== fieldTypes.length) {
14
14
  throw new Error("CalcitStruct: fields and fieldTypes length mismatch");
15
15
  }
@@ -20,13 +20,13 @@ export class CalcitStruct {
20
20
  this.cachedHash = null;
21
21
  }
22
22
 
23
- withImpls(impls: CalcitRecord | CalcitRecord[]): CalcitStruct {
24
- if (impls instanceof CalcitRecord) {
23
+ withImpls(impls: CalcitImpl | CalcitImpl[]): CalcitStruct {
24
+ if (impls instanceof CalcitImpl) {
25
25
  return new CalcitStruct(this.name, this.fields, this.fieldTypes, [impls]);
26
26
  } else if (Array.isArray(impls)) {
27
27
  return new CalcitStruct(this.name, this.fields, this.fieldTypes, impls);
28
28
  }
29
- throw new Error("Expected a record as implementation");
29
+ throw new Error("Expected an impl as implementation");
30
30
  }
31
31
 
32
32
  toString(disableJsDataWarning: boolean = false): string {
@@ -2,22 +2,32 @@ import { Hash } from "@calcit/ternary-tree";
2
2
 
3
3
  import { CalcitValue } from "./js-primes.mjs";
4
4
  import { _$n__$e_, newTag, toString } from "./calcit-data.mjs";
5
+ import { CalcitImpl } from "./js-impl.mjs";
5
6
  import { CalcitRecord } from "./js-record.mjs";
6
7
  import { CalcitEnum } from "./js-enum.mjs";
7
8
 
8
9
  export class CalcitTuple {
9
10
  tag: CalcitValue;
10
11
  extra: CalcitValue[];
11
- impls: CalcitRecord[];
12
12
  enumPrototype: CalcitRecord | CalcitEnum;
13
13
  cachedHash: Hash;
14
- constructor(tagName: CalcitValue, extra: CalcitValue[], impls: CalcitRecord[] = [], enumPrototype: CalcitRecord | CalcitEnum = null) {
14
+ constructor(tagName: CalcitValue, extra: CalcitValue[], enumPrototype: CalcitRecord | CalcitEnum = null) {
15
15
  this.tag = tagName;
16
16
  this.extra = extra;
17
- this.impls = impls;
18
17
  this.enumPrototype = enumPrototype;
19
18
  this.cachedHash = null;
20
19
  }
20
+
21
+ get impls(): CalcitImpl[] {
22
+ if (this.enumPrototype == null) {
23
+ return [];
24
+ }
25
+ if (this.enumPrototype instanceof CalcitEnum) {
26
+ return this.enumPrototype.impls;
27
+ }
28
+ return this.enumPrototype.structRef.impls;
29
+ }
30
+
21
31
  get(n: number) {
22
32
  if (n === 0) {
23
33
  return this.tag;
@@ -29,11 +39,11 @@ export class CalcitTuple {
29
39
  }
30
40
  assoc(n: number, v: CalcitValue) {
31
41
  if (n === 0) {
32
- return new CalcitTuple(v, this.extra, this.impls, this.enumPrototype);
42
+ return new CalcitTuple(v, this.extra, this.enumPrototype);
33
43
  } else if (n - 1 < this.extra.length) {
34
44
  let next_extra = this.extra.slice();
35
45
  next_extra[n - 1] = v;
36
- return new CalcitTuple(this.tag, next_extra, this.impls, this.enumPrototype);
46
+ return new CalcitTuple(this.tag, next_extra, this.enumPrototype);
37
47
  } else {
38
48
  throw new Error(`Tuple only have ${this.extra.length} elements`);
39
49
  }
@@ -67,15 +77,9 @@ export class CalcitTuple {
67
77
  const hasEnum = this.enumPrototype != null;
68
78
  const enumName = hasEnum ? (this.enumPrototype instanceof CalcitEnum ? this.enumPrototype.prototype.name.value : this.enumPrototype.name.value) : null;
69
79
 
70
- if (this.impls.length > 0 && hasEnum) {
71
- return `(%:: ${content} (:impls ${this.impls[0].name.value}) (:enum ${enumName}))`;
72
- }
73
80
  if (hasEnum) {
74
81
  return `(%:: ${content} (:enum ${enumName}))`;
75
82
  }
76
- if (this.impls.length > 0) {
77
- return `(:: ${content} (:impls ${this.impls[0].name.value}))`;
78
- }
79
83
  return `(:: ${content})`;
80
84
  }
81
85
  }