greybel-interpreter 3.0.4 → 3.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.
Files changed (83) hide show
  1. package/dist/context/types.d.ts +8 -0
  2. package/dist/context/types.js +2 -0
  3. package/dist/context.d.ts +17 -5
  4. package/dist/context.js +47 -28
  5. package/dist/cps.js +6 -5
  6. package/dist/handler/output.d.ts +2 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +3 -3
  9. package/dist/interpreter.d.ts +10 -3
  10. package/dist/interpreter.js +51 -46
  11. package/dist/operations/assign-globals.d.ts +11 -0
  12. package/dist/operations/assign-globals.js +31 -0
  13. package/dist/operations/assign-locals.d.ts +11 -0
  14. package/dist/operations/assign-locals.js +31 -0
  15. package/dist/operations/assign-outer.d.ts +11 -0
  16. package/dist/operations/assign-outer.js +31 -0
  17. package/dist/operations/assign-self.d.ts +11 -0
  18. package/dist/operations/assign-self.js +41 -0
  19. package/dist/operations/assign.js +16 -3
  20. package/dist/operations/block.js +3 -1
  21. package/dist/operations/call.js +16 -8
  22. package/dist/operations/chunk.js +0 -2
  23. package/dist/operations/evaluate.js +1 -1
  24. package/dist/operations/for.js +5 -1
  25. package/dist/operations/function-reference.js +6 -3
  26. package/dist/operations/function.d.ts +1 -1
  27. package/dist/operations/function.js +10 -6
  28. package/dist/operations/if-statement.js +5 -0
  29. package/dist/operations/import.js +1 -1
  30. package/dist/operations/reference-globals.d.ts +7 -0
  31. package/dist/operations/reference-globals.js +13 -0
  32. package/dist/operations/reference-locals.d.ts +7 -0
  33. package/dist/operations/reference-locals.js +13 -0
  34. package/dist/operations/reference-outer.d.ts +7 -0
  35. package/dist/operations/reference-outer.js +13 -0
  36. package/dist/operations/reference-self.d.ts +7 -0
  37. package/dist/operations/reference-self.js +13 -0
  38. package/dist/operations/resolve-globals.d.ts +5 -0
  39. package/dist/operations/resolve-globals.js +24 -0
  40. package/dist/operations/resolve-locals.d.ts +5 -0
  41. package/dist/operations/resolve-locals.js +24 -0
  42. package/dist/operations/resolve-outer.d.ts +5 -0
  43. package/dist/operations/resolve-outer.js +24 -0
  44. package/dist/operations/resolve-self.d.ts +5 -0
  45. package/dist/operations/resolve-self.js +24 -0
  46. package/dist/operations/resolve.d.ts +1 -1
  47. package/dist/operations/resolve.js +30 -18
  48. package/dist/operations/while.js +5 -1
  49. package/dist/types/base.d.ts +3 -1
  50. package/dist/types/function.d.ts +12 -6
  51. package/dist/types/function.js +47 -33
  52. package/dist/types/list.d.ts +6 -3
  53. package/dist/types/list.js +26 -7
  54. package/dist/types/map.d.ts +6 -3
  55. package/dist/types/map.js +64 -8
  56. package/dist/types/nil.d.ts +1 -0
  57. package/dist/types/nil.js +3 -0
  58. package/dist/types/number.d.ts +6 -3
  59. package/dist/types/number.js +20 -8
  60. package/dist/types/string.d.ts +6 -3
  61. package/dist/types/string.js +20 -9
  62. package/dist/types/with-intrinsics.d.ts +9 -1
  63. package/dist/types/with-intrinsics.js +6 -0
  64. package/dist/utils/create-assign.d.ts +3 -0
  65. package/dist/utils/create-assign.js +25 -0
  66. package/dist/utils/create-resolve.d.ts +5 -0
  67. package/dist/utils/create-resolve.js +51 -0
  68. package/dist/utils/deep-equal.js +9 -4
  69. package/dist/utils/error.d.ts +1 -1
  70. package/dist/utils/error.js +2 -2
  71. package/dist/utils/get-super.d.ts +3 -0
  72. package/dist/utils/get-super.js +12 -0
  73. package/dist/utils/hash.d.ts +3 -0
  74. package/dist/utils/hash.js +41 -0
  75. package/dist/utils/lookup-path.d.ts +3 -0
  76. package/dist/utils/lookup-path.js +16 -0
  77. package/dist/utils/next-tick.d.ts +1 -0
  78. package/dist/utils/next-tick.js +10 -0
  79. package/dist/utils/object-value.d.ts +11 -1
  80. package/dist/utils/object-value.js +54 -27
  81. package/dist/utils/uuid.d.ts +1 -0
  82. package/dist/utils/uuid.js +36 -0
  83. package/package.json +3 -2
@@ -18,6 +18,7 @@ const map_1 = require("../types/map");
18
18
  const nil_1 = require("../types/nil");
19
19
  const string_1 = require("../types/string");
20
20
  const with_intrinsics_1 = require("../types/with-intrinsics");
21
+ const get_super_1 = require("../utils/get-super");
21
22
  const path_1 = require("../utils/path");
22
23
  const operation_1 = require("./operation");
23
24
  class SliceSegment {
@@ -107,20 +108,23 @@ class Resolve extends operation_1.Operation {
107
108
  switch (node.type) {
108
109
  case miniscript_core_1.ASTType.MemberExpression: {
109
110
  const memberExpr = node;
110
- yield this.buildProcessor(memberExpr.base, visit);
111
+ if (memberExpr.base != null)
112
+ yield this.buildProcessor(memberExpr.base, visit);
111
113
  yield this.buildProcessor(memberExpr.identifier, visit);
112
114
  break;
113
115
  }
114
116
  case miniscript_core_1.ASTType.IndexExpression: {
115
117
  const indexExpr = node;
116
- yield this.buildProcessor(indexExpr.base, visit);
118
+ if (indexExpr.base != null)
119
+ yield this.buildProcessor(indexExpr.base, visit);
117
120
  const indexSegment = new IndexSegment(yield visit(indexExpr.index));
118
121
  this.path.push(indexSegment);
119
122
  break;
120
123
  }
121
124
  case miniscript_core_1.ASTType.SliceExpression: {
122
125
  const sliceExpr = node;
123
- yield this.buildProcessor(sliceExpr.base, visit);
126
+ if (sliceExpr.base != null)
127
+ yield this.buildProcessor(sliceExpr.base, visit);
124
128
  const left = yield visit(sliceExpr.left);
125
129
  const right = yield visit(sliceExpr.right);
126
130
  const sliceSegment = new SliceSegment(left, right);
@@ -149,15 +153,17 @@ class Resolve extends operation_1.Operation {
149
153
  return this;
150
154
  });
151
155
  }
152
- getResult(ctx) {
156
+ getResult(ctx, handle = new ResolveNil()) {
153
157
  return __awaiter(this, void 0, void 0, function* () {
154
158
  let traversedPath = new path_1.Path();
155
- let handle = new ResolveNil();
159
+ let index = 0;
160
+ const exitObserver = ctx.processState.createExitObserver();
156
161
  const maxIndex = this.path.count();
157
162
  const lastIndex = maxIndex - 1;
158
- for (let index = 0; index < maxIndex; index++) {
159
- if (ctx.isExit()) {
160
- return new ResolveResult(null, default_1.DefaultType.Void);
163
+ for (; index < maxIndex; index++) {
164
+ if (exitObserver.occured()) {
165
+ exitObserver.close();
166
+ return new ResolveResult(null, new ResolveNil());
161
167
  }
162
168
  const current = this.path.at(index);
163
169
  if (current instanceof OperationSegment) {
@@ -173,7 +179,7 @@ class Resolve extends operation_1.Operation {
173
179
  if (!(handle instanceof ResolveNil)) {
174
180
  if (handle instanceof with_intrinsics_1.CustomValueWithIntrinsics) {
175
181
  const customValueCtx = handle;
176
- handle = customValueCtx.get(traversedPath);
182
+ handle = customValueCtx.get(traversedPath, ctx.contextTypeIntrinsics);
177
183
  }
178
184
  else {
179
185
  throw new Error(`Unknown path ${traversedPath.toString()}.`);
@@ -187,7 +193,8 @@ class Resolve extends operation_1.Operation {
187
193
  traversedPath.toString() === function_1.SUPER_NAMESPACE &&
188
194
  ctx.functionState.context &&
189
195
  previous instanceof map_1.CustomMap) {
190
- handle = yield handle.run(ctx.functionState.context, [], ctx, previous.getIsa());
196
+ handle.setNextContext(previous.getIsa());
197
+ handle = yield handle.run(ctx.functionState.context, [], ctx);
191
198
  }
192
199
  else {
193
200
  handle = yield handle.run(previous || default_1.DefaultType.Void, [], ctx);
@@ -207,15 +214,17 @@ class Resolve extends operation_1.Operation {
207
214
  }
208
215
  }
209
216
  }
217
+ exitObserver.close();
210
218
  return new ResolveResult(traversedPath, handle);
211
219
  });
212
220
  }
213
221
  handle(ctx, result = null, autoCall = true) {
214
- var _a;
215
222
  return __awaiter(this, void 0, void 0, function* () {
216
223
  if (result === null) {
224
+ const exitObserver = ctx.processState.createExitObserver();
217
225
  result = yield this.getResult(ctx);
218
- if (ctx.isExit()) {
226
+ exitObserver.close();
227
+ if (exitObserver.occured()) {
219
228
  return default_1.DefaultType.Void;
220
229
  }
221
230
  }
@@ -228,17 +237,20 @@ class Resolve extends operation_1.Operation {
228
237
  }
229
238
  if (result.handle instanceof with_intrinsics_1.CustomValueWithIntrinsics) {
230
239
  const customValueCtx = result.handle;
240
+ const { value: child, origin } = customValueCtx.getWithOrigin(result.path, ctx.contextTypeIntrinsics);
241
+ const next = (0, get_super_1.getSuper)(origin);
242
+ if (child instanceof function_1.CustomFunction) {
243
+ child.setNextContext(next);
244
+ }
231
245
  if (this.path.isSuper() && customValueCtx instanceof map_1.CustomMap) {
232
- const superChild = (_a = customValueCtx.getIsa()) === null || _a === void 0 ? void 0 : _a.get(result.path);
233
- if (autoCall && superChild instanceof function_1.CustomFunction) {
246
+ if (autoCall && child instanceof function_1.CustomFunction) {
234
247
  if (ctx.functionState.context) {
235
- return superChild.run(ctx.functionState.context, [], ctx, customValueCtx.getIsa());
248
+ return child.run(ctx.functionState.context, [], ctx);
236
249
  }
237
- return superChild.run(customValueCtx, [], ctx);
250
+ return child.run(customValueCtx, [], ctx);
238
251
  }
239
- return superChild;
252
+ return child;
240
253
  }
241
- const child = customValueCtx.get(result.path);
242
254
  if (autoCall && child instanceof function_1.CustomFunction) {
243
255
  return child.run(customValueCtx, [], ctx);
244
256
  }
@@ -35,12 +35,14 @@ class While extends operation_1.OperationBlock {
35
35
  state: context_1.ContextState.Temporary
36
36
  });
37
37
  const loopState = new context_1.LoopState();
38
+ const exitObserver = ctx.processState.createExitObserver();
38
39
  whileCtx.loopState = loopState;
39
40
  return new Promise((resolve, reject) => {
40
41
  const iteration = () => __awaiter(this, void 0, void 0, function* () {
41
42
  try {
42
43
  const conditionResult = yield whileCtx.step(this.condition);
43
44
  if (!conditionResult.toTruthy()) {
45
+ exitObserver.close();
44
46
  resolve(default_1.DefaultType.Void);
45
47
  return;
46
48
  }
@@ -48,13 +50,15 @@ class While extends operation_1.OperationBlock {
48
50
  yield this.block.handle(whileCtx);
49
51
  if (loopState.isBreak ||
50
52
  whileCtx.functionState.isReturn ||
51
- ctx.isExit()) {
53
+ exitObserver.occured()) {
54
+ exitObserver.close();
52
55
  resolve(default_1.DefaultType.Void);
53
56
  return;
54
57
  }
55
58
  (0, set_immediate_1.setImmediate)(iteration);
56
59
  }
57
60
  catch (err) {
61
+ exitObserver.close();
58
62
  reject(err);
59
63
  }
60
64
  });
@@ -1,3 +1,4 @@
1
+ import { ContextTypeIntrinsics } from '../context/types';
1
2
  export declare abstract class CustomValue {
2
3
  abstract value: any;
3
4
  abstract getCustomType(): string;
@@ -7,5 +8,6 @@ export declare abstract class CustomValue {
7
8
  abstract toString(): string;
8
9
  abstract toTruthy(): boolean;
9
10
  abstract fork(): CustomValue;
10
- abstract instanceOf(value: CustomValue): boolean;
11
+ abstract instanceOf(value: CustomValue, typeIntrinsics: ContextTypeIntrinsics): boolean;
12
+ abstract hash(recursionDepth?: number): number;
11
13
  }
@@ -1,10 +1,10 @@
1
1
  import { OperationContext } from '../context';
2
+ import { ContextTypeIntrinsics } from '../context/types';
2
3
  import { Operation } from '../operations/operation';
3
4
  import { ObjectValue } from '../utils/object-value';
4
5
  import { CustomValue } from './base';
5
- import { CustomMap } from './map';
6
6
  export interface Callback {
7
- (ctx: OperationContext, self: CustomValue, args: Map<string, CustomValue>, next?: CustomValue): Promise<NonNullable<CustomValue>>;
7
+ (ctx: OperationContext, self: CustomValue, args: Map<string, CustomValue>): Promise<NonNullable<CustomValue>>;
8
8
  }
9
9
  export declare const DEFAULT_FUNCTION_NAME = "anonymous";
10
10
  export declare const SELF_NAMESPACE = "self";
@@ -21,18 +21,24 @@ export declare class CustomFunction extends CustomValue {
21
21
  readonly name: string;
22
22
  readonly value: Callback;
23
23
  readonly argumentDefs: Array<Argument>;
24
+ readonly assignOuter: boolean;
25
+ private _nextContext;
24
26
  static createExternalAnonymous(callback: Callback): CustomFunction;
25
27
  static createExternal(name: string, callback: Callback): CustomFunction;
26
28
  static createExternalWithSelf(name: string, callback: Callback): CustomFunction;
27
- constructor(scope: OperationContext, name: string, callback: Callback);
29
+ constructor(scope: OperationContext, name: string, callback: Callback, argumentDefs?: Array<Argument>, assignOuter?: boolean);
28
30
  addArgument(name: string, defaultValue?: Operation | CustomValue): CustomFunction;
29
- fork(): CustomValue;
31
+ fork(): CustomFunction;
32
+ forkAs(name: string): CustomFunction;
30
33
  getCustomType(): string;
31
34
  toNumber(): number;
32
35
  toInt(): number;
33
36
  toJSON(): string;
34
37
  toString(): string;
35
38
  toTruthy(): boolean;
36
- instanceOf(v: CustomValue): boolean;
37
- run(self: CustomValue, args: Array<CustomValue>, callContext: OperationContext, next?: CustomMap): Promise<CustomValue>;
39
+ instanceOf(v: CustomValue, typeIntrinsics: ContextTypeIntrinsics): boolean;
40
+ setNextContext(value: CustomValue): this;
41
+ getNextContext(): CustomValue;
42
+ run(self: CustomValue, args: Array<CustomValue>, callContext: OperationContext): Promise<CustomValue>;
43
+ hash(): number;
38
44
  }
@@ -14,10 +14,10 @@ const context_1 = require("../context");
14
14
  const literal_1 = require("../operations/literal");
15
15
  const operation_1 = require("../operations/operation");
16
16
  const reference_1 = require("../operations/reference");
17
+ const hash_1 = require("../utils/hash");
17
18
  const object_value_1 = require("../utils/object-value");
18
19
  const base_1 = require("./base");
19
20
  const default_1 = require("./default");
20
- const map_1 = require("./map");
21
21
  const nil_1 = require("./nil");
22
22
  const string_1 = require("./string");
23
23
  exports.DEFAULT_FUNCTION_NAME = 'anonymous';
@@ -51,19 +51,24 @@ class CustomFunction extends base_1.CustomValue {
51
51
  static createExternalWithSelf(name, callback) {
52
52
  return new CustomFunction(null, name, callback).addArgument(exports.SELF_NAMESPACE);
53
53
  }
54
- constructor(scope, name, callback) {
54
+ constructor(scope, name, callback, argumentDefs = [], assignOuter = false) {
55
55
  super();
56
56
  this.scope = scope;
57
57
  this.name = name;
58
58
  this.value = callback;
59
- this.argumentDefs = [];
59
+ this.argumentDefs = argumentDefs;
60
+ this.assignOuter = assignOuter;
61
+ this._nextContext = null;
60
62
  }
61
63
  addArgument(name, defaultValue = default_1.DefaultType.Void) {
62
64
  this.argumentDefs.push(new Argument(name, defaultValue));
63
65
  return this;
64
66
  }
65
67
  fork() {
66
- return new CustomFunction(this.scope, this.name, this.value);
68
+ return new CustomFunction(this.scope, this.name, this.value, this.argumentDefs);
69
+ }
70
+ forkAs(name) {
71
+ return new CustomFunction(this.scope, name, this.value, this.argumentDefs);
67
72
  }
68
73
  getCustomType() {
69
74
  return 'function';
@@ -80,7 +85,8 @@ class CustomFunction extends base_1.CustomValue {
80
85
  toString() {
81
86
  let refs = 1;
82
87
  const args = this.argumentDefs.map((item) => {
83
- if (item.defaultValue instanceof literal_1.Literal) {
88
+ if (item.defaultValue instanceof literal_1.Literal ||
89
+ item.defaultValue instanceof reference_1.Reference) {
84
90
  const value = item.defaultValue.value;
85
91
  if (value instanceof nil_1.CustomNil) {
86
92
  return item.name;
@@ -100,46 +106,54 @@ class CustomFunction extends base_1.CustomValue {
100
106
  toTruthy() {
101
107
  return true;
102
108
  }
103
- instanceOf(v) {
104
- return v.value === CustomFunction.intrinsics;
109
+ instanceOf(v, typeIntrinsics) {
110
+ var _a;
111
+ return v.value === ((_a = typeIntrinsics.function) !== null && _a !== void 0 ? _a : CustomFunction.intrinsics);
112
+ }
113
+ setNextContext(value) {
114
+ this._nextContext = value;
115
+ return this;
105
116
  }
106
- run(self, args, callContext, next) {
107
- var _a, _b;
117
+ getNextContext() {
118
+ return this._nextContext;
119
+ }
120
+ run(self, args, callContext) {
121
+ var _a, _b, _c, _d;
108
122
  return __awaiter(this, void 0, void 0, function* () {
123
+ if (args.length > this.argumentDefs.length) {
124
+ throw new Error('Too many arguments.');
125
+ }
109
126
  const fnCtx = (_a = this.scope) === null || _a === void 0 ? void 0 : _a.fork({
110
127
  type: context_1.ContextType.Function,
111
- state: context_1.ContextState.Default
128
+ state: context_1.ContextState.Default,
129
+ ignoreOuter: !this.assignOuter,
130
+ processState: callContext.processState
112
131
  });
113
132
  const argMap = new Map();
114
- const isSelfNull = self instanceof nil_1.CustomNil;
115
- let index = 0;
116
- if (!isSelfNull) {
117
- for (; index < this.argumentDefs.length; index++) {
118
- const item = this.argumentDefs[index];
119
- if (item.name !== exports.SELF_NAMESPACE)
120
- break;
121
- }
122
- }
123
- let argIndex = 0;
124
- for (; index < this.argumentDefs.length; index++) {
125
- const item = this.argumentDefs[index];
126
- if (!isSelfNull && item.name === exports.SELF_NAMESPACE) {
127
- argIndex++;
133
+ const hasSelf = !(self instanceof nil_1.CustomNil);
134
+ let selfWithinArgs = default_1.DefaultType.Void;
135
+ let argIndex = this.argumentDefs.length - 1;
136
+ const selfParam = hasSelf && ((_b = this.argumentDefs[0]) === null || _b === void 0 ? void 0 : _b.name) === exports.SELF_NAMESPACE ? 1 : 0;
137
+ for (; argIndex >= selfParam; argIndex--) {
138
+ const item = this.argumentDefs[argIndex];
139
+ if (item.name === exports.SELF_NAMESPACE) {
140
+ selfWithinArgs = (_c = args[argIndex - selfParam]) !== null && _c !== void 0 ? _c : default_1.DefaultType.Void;
128
141
  continue;
129
142
  }
130
- if (argMap.has(item.name)) {
131
- argIndex++;
132
- continue;
133
- }
134
- argMap.set(item.name, (_b = args[argIndex++]) !== null && _b !== void 0 ? _b : (yield item.defaultValue.handle(fnCtx)));
143
+ argMap.set(item.name, (_d = args[argIndex - selfParam]) !== null && _d !== void 0 ? _d : (yield item.defaultValue.handle(fnCtx)));
135
144
  }
136
- if (!isSelfNull) {
137
- argMap.set(exports.SELF_NAMESPACE, self);
145
+ const selfValue = hasSelf ? self : selfWithinArgs;
146
+ if (selfValue) {
147
+ argMap.set(exports.SELF_NAMESPACE, selfValue);
138
148
  }
139
- const isa = next !== null && next !== void 0 ? next : (self instanceof map_1.CustomMap ? self.getIsa() : null);
140
- return this.value(fnCtx !== null && fnCtx !== void 0 ? fnCtx : callContext, self, argMap, isa);
149
+ const result = yield this.value(fnCtx !== null && fnCtx !== void 0 ? fnCtx : callContext, selfValue, argMap);
150
+ this._nextContext = null;
151
+ return result;
141
152
  });
142
153
  }
154
+ hash() {
155
+ return (0, hash_1.getStringHashCode)(this.toString());
156
+ }
143
157
  }
144
158
  CustomFunction.intrinsics = new object_value_1.ObjectValue();
145
159
  exports.CustomFunction = CustomFunction;
@@ -1,7 +1,8 @@
1
+ import { ContextTypeIntrinsics } from '../context/types';
1
2
  import { ObjectValue } from '../utils/object-value';
2
3
  import { Path } from '../utils/path';
3
4
  import { CustomValue } from './base';
4
- import { CustomObject } from './with-intrinsics';
5
+ import { CustomObject, CustomValueWithIntrinsicsResult } from './with-intrinsics';
5
6
  export declare class CustomListIterator implements Iterator<CustomValue> {
6
7
  value: Array<CustomValue>;
7
8
  index: number;
@@ -20,12 +21,14 @@ export declare class CustomList extends CustomObject {
20
21
  toNumber(): number;
21
22
  toInt(): number;
22
23
  toTruthy(): boolean;
23
- instanceOf(v: CustomValue): boolean;
24
+ instanceOf(v: CustomValue, typeIntrinsics: ContextTypeIntrinsics): boolean;
24
25
  slice(a: CustomValue, b: CustomValue): CustomList;
25
26
  extend(list: CustomList | Array<CustomValue>): CustomList;
26
27
  [Symbol.iterator](): CustomListIterator;
27
28
  getItemIndex(index: number): number;
28
29
  has(path: Path<CustomValue> | CustomValue): boolean;
29
30
  set(path: Path<CustomValue> | CustomValue, newValue: CustomValue): void;
30
- get(path: Path<CustomValue> | CustomValue): CustomValue;
31
+ get(path: Path<CustomValue> | CustomValue, typeIntrinsics: ContextTypeIntrinsics): CustomValue;
32
+ getWithOrigin(path: Path<CustomValue> | CustomValue, typeIntrinsics: ContextTypeIntrinsics): CustomValueWithIntrinsicsResult;
33
+ hash(recursionDepth?: number): number;
31
34
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CustomList = exports.CustomListIterator = void 0;
4
+ const hash_1 = require("../utils/hash");
4
5
  const object_value_1 = require("../utils/object-value");
5
6
  const path_1 = require("../utils/path");
6
7
  const base_1 = require("./base");
@@ -61,8 +62,9 @@ class CustomList extends with_intrinsics_1.CustomObject {
61
62
  toTruthy() {
62
63
  return this.value.length > 0;
63
64
  }
64
- instanceOf(v) {
65
- return v.value === CustomList.intrinsics;
65
+ instanceOf(v, typeIntrinsics) {
66
+ var _a;
67
+ return v.value === ((_a = typeIntrinsics.list) !== null && _a !== void 0 ? _a : CustomList.intrinsics);
66
68
  }
67
69
  slice(a, b) {
68
70
  return new CustomList(this.value.slice(a.toNumber(), b.toNumber()));
@@ -130,9 +132,10 @@ class CustomList extends with_intrinsics_1.CustomObject {
130
132
  }
131
133
  throw new Error(`Index is not a number.`);
132
134
  }
133
- get(path) {
135
+ get(path, typeIntrinsics) {
136
+ var _a;
134
137
  if (path instanceof base_1.CustomValue) {
135
- return this.get(new path_1.Path([path]));
138
+ return this.get(new path_1.Path([path]), typeIntrinsics);
136
139
  }
137
140
  const traversalPath = path.clone();
138
141
  const current = traversalPath.next();
@@ -142,7 +145,7 @@ class CustomList extends with_intrinsics_1.CustomObject {
142
145
  const sub = this.value[currentIndex];
143
146
  if (traversalPath.count() > 0) {
144
147
  if (sub instanceof with_intrinsics_1.CustomValueWithIntrinsics) {
145
- return sub.get(traversalPath);
148
+ return sub.get(traversalPath, typeIntrinsics);
146
149
  }
147
150
  }
148
151
  else if (traversalPath.count() === 0) {
@@ -151,11 +154,27 @@ class CustomList extends with_intrinsics_1.CustomObject {
151
154
  }
152
155
  throw new Error(`Index error (list index ${currentIndex} out of range).`);
153
156
  }
154
- else if (path.count() === 1 && CustomList.getIntrinsics().has(current)) {
155
- return CustomList.getIntrinsics().get(current);
157
+ const intrinsics = (_a = typeIntrinsics.list) !== null && _a !== void 0 ? _a : CustomList.getIntrinsics();
158
+ if (path.count() === 1 && intrinsics.has(current)) {
159
+ return intrinsics.get(current);
156
160
  }
157
161
  throw new Error(`Unknown path in list ${path.toString()}.`);
158
162
  }
163
+ getWithOrigin(path, typeIntrinsics) {
164
+ return {
165
+ value: this.get(path, typeIntrinsics),
166
+ origin: null
167
+ };
168
+ }
169
+ hash(recursionDepth = 0) {
170
+ let result = (0, hash_1.getHashCode)(this.value.length);
171
+ if (recursionDepth > 16)
172
+ return result;
173
+ this.value.forEach((value) => {
174
+ result = (0, hash_1.rotateBits)(result) ^ value.hash(recursionDepth + 1);
175
+ });
176
+ return result;
177
+ }
159
178
  }
160
179
  CustomList.intrinsics = new object_value_1.ObjectValue();
161
180
  exports.CustomList = CustomList;
@@ -1,8 +1,9 @@
1
+ import { ContextTypeIntrinsics } from '../context/types';
1
2
  import { ObjectValue } from '../utils/object-value';
2
3
  import { Path } from '../utils/path';
3
4
  import { CustomValue } from './base';
4
5
  import { CustomString } from './string';
5
- import { CustomObject } from './with-intrinsics';
6
+ import { CustomObject, CustomValueWithIntrinsicsResult } from './with-intrinsics';
6
7
  export declare const CLASS_ID_PROPERTY: CustomString;
7
8
  export declare const ISA_PROPERTY: CustomString;
8
9
  export declare const CUSTOM_MAP_MAX_DEPTH = 2;
@@ -26,12 +27,14 @@ export declare class CustomMap extends CustomObject {
26
27
  toNumber(): number;
27
28
  toInt(): number;
28
29
  toTruthy(): boolean;
29
- instanceOf(v: CustomValue): boolean;
30
+ instanceOf(v: CustomValue, typeIntrinsics: ContextTypeIntrinsics): boolean;
30
31
  [Symbol.iterator](): CustomMapIterator;
31
32
  extend(map: CustomMap | ObjectValue): CustomMap;
32
33
  has(path: Path<CustomValue> | CustomValue): boolean;
33
34
  set(path: Path<CustomValue> | CustomValue, newValue: CustomValue): void;
34
- get(path: Path<CustomValue> | CustomValue): CustomValue;
35
+ get(path: Path<CustomValue> | CustomValue, typeIntrinsics: ContextTypeIntrinsics): CustomValue;
36
+ getWithOrigin(path: Path<CustomValue> | CustomValue, typeIntrinsics: ContextTypeIntrinsics): CustomValueWithIntrinsicsResult;
35
37
  createInstance(): CustomMap;
36
38
  getIsa(): CustomMap | null;
39
+ hash(recursionDepth?: number): number;
37
40
  }
package/dist/types/map.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CustomMap = exports.CustomMapIterator = exports.CUSTOM_MAP_MAX_DEPTH_VALUE = exports.CUSTOM_MAP_MAX_DEPTH = exports.ISA_PROPERTY = exports.CLASS_ID_PROPERTY = void 0;
4
+ const hash_1 = require("../utils/hash");
4
5
  const object_value_1 = require("../utils/object-value");
5
6
  const path_1 = require("../utils/path");
6
7
  const base_1 = require("./base");
@@ -81,7 +82,8 @@ class CustomMap extends with_intrinsics_1.CustomObject {
81
82
  toTruthy() {
82
83
  return this.value.size > 0;
83
84
  }
84
- instanceOf(v) {
85
+ instanceOf(v, typeIntrinsics) {
86
+ var _a;
85
87
  if (v instanceof CustomMap) {
86
88
  let current = this;
87
89
  while ((current = current.getIsa())) {
@@ -89,7 +91,7 @@ class CustomMap extends with_intrinsics_1.CustomObject {
89
91
  return true;
90
92
  }
91
93
  }
92
- return v.value === CustomMap.intrinsics;
94
+ return v.value === ((_a = typeIntrinsics.map) !== null && _a !== void 0 ? _a : CustomMap.getIntrinsics());
93
95
  }
94
96
  return false;
95
97
  }
@@ -142,9 +144,10 @@ class CustomMap extends with_intrinsics_1.CustomObject {
142
144
  }
143
145
  this.value.set(last, newValue);
144
146
  }
145
- get(path) {
147
+ get(path, typeIntrinsics) {
148
+ var _a;
146
149
  if (path instanceof base_1.CustomValue) {
147
- return this.get(new path_1.Path([path]));
150
+ return this.get(new path_1.Path([path]), typeIntrinsics);
148
151
  }
149
152
  const traversalPath = path.clone();
150
153
  const current = traversalPath.next();
@@ -154,7 +157,7 @@ class CustomMap extends with_intrinsics_1.CustomObject {
154
157
  const sub = this.value.get(current);
155
158
  if (traversalPath.count() > 0) {
156
159
  if (sub instanceof with_intrinsics_1.CustomValueWithIntrinsics) {
157
- return sub.get(traversalPath);
160
+ return sub.get(traversalPath, typeIntrinsics);
158
161
  }
159
162
  }
160
163
  else if (traversalPath.count() === 0) {
@@ -162,10 +165,53 @@ class CustomMap extends with_intrinsics_1.CustomObject {
162
165
  }
163
166
  }
164
167
  else if (isa === null || isa === void 0 ? void 0 : isa.has(current)) {
165
- return isa.get(current);
168
+ return isa.get(current, typeIntrinsics);
166
169
  }
167
- else if (path.count() === 1 && CustomMap.getIntrinsics().has(current)) {
168
- return CustomMap.getIntrinsics().get(current);
170
+ const intrinsics = (_a = typeIntrinsics.map) !== null && _a !== void 0 ? _a : CustomMap.getIntrinsics();
171
+ if (traversalPath.count() === 0 && intrinsics.has(current)) {
172
+ return intrinsics.get(current);
173
+ }
174
+ }
175
+ throw new Error(`Unknown path in map ${path.toString()}.`);
176
+ }
177
+ getWithOrigin(path, typeIntrinsics) {
178
+ var _a;
179
+ if (path instanceof base_1.CustomValue) {
180
+ return this.getWithOrigin(new path_1.Path([path]), typeIntrinsics);
181
+ }
182
+ const traversalPath = path.clone();
183
+ const current = traversalPath.next();
184
+ const isa = this.getIsa();
185
+ if (current !== null) {
186
+ if (this.value.has(current)) {
187
+ const sub = this.value.get(current);
188
+ if (traversalPath.count() > 0) {
189
+ if (sub instanceof CustomMap) {
190
+ return sub.getWithOrigin(traversalPath, typeIntrinsics);
191
+ }
192
+ if (sub instanceof with_intrinsics_1.CustomValueWithIntrinsics) {
193
+ return {
194
+ value: sub.get(traversalPath, typeIntrinsics),
195
+ origin: this
196
+ };
197
+ }
198
+ }
199
+ else if (traversalPath.count() === 0) {
200
+ return {
201
+ value: sub,
202
+ origin: this
203
+ };
204
+ }
205
+ }
206
+ else if (isa === null || isa === void 0 ? void 0 : isa.has(current)) {
207
+ return isa.getWithOrigin(current, typeIntrinsics);
208
+ }
209
+ const intrinsics = (_a = typeIntrinsics.map) !== null && _a !== void 0 ? _a : CustomMap.getIntrinsics();
210
+ if (traversalPath.count() === 0 && intrinsics.has(current)) {
211
+ return {
212
+ value: intrinsics.get(current),
213
+ origin: null
214
+ };
169
215
  }
170
216
  }
171
217
  throw new Error(`Unknown path in map ${path.toString()}.`);
@@ -180,6 +226,16 @@ class CustomMap extends with_intrinsics_1.CustomObject {
180
226
  const isa = this.value.get(exports.ISA_PROPERTY);
181
227
  return isa instanceof CustomMap ? isa : null;
182
228
  }
229
+ hash(recursionDepth = 0) {
230
+ let result = (0, hash_1.getHashCode)(this.value.size);
231
+ if (recursionDepth > 16)
232
+ return result;
233
+ this.value.forEach((value, key) => {
234
+ result ^= key.hash(recursionDepth + 1);
235
+ result ^= value.hash(recursionDepth + 1);
236
+ });
237
+ return result;
238
+ }
183
239
  }
184
240
  CustomMap.intrinsics = new object_value_1.ObjectValue();
185
241
  exports.CustomMap = CustomMap;
@@ -9,5 +9,6 @@ export declare class CustomNil extends CustomValue {
9
9
  toInt(): number;
10
10
  toTruthy(): boolean;
11
11
  instanceOf(v: CustomValue): boolean;
12
+ hash(): number;
12
13
  }
13
14
  export declare const Void: CustomNil;
package/dist/types/nil.js CHANGED
@@ -31,6 +31,9 @@ class CustomNil extends base_1.CustomValue {
31
31
  instanceOf(v) {
32
32
  return v instanceof CustomNil;
33
33
  }
34
+ hash() {
35
+ return -1;
36
+ }
34
37
  }
35
38
  exports.CustomNil = CustomNil;
36
39
  exports.Void = new CustomNil();
@@ -1,7 +1,8 @@
1
+ import { ContextTypeIntrinsics } from '../context/types';
1
2
  import { ObjectValue } from '../utils/object-value';
2
3
  import { Path } from '../utils/path';
3
4
  import { CustomValue } from './base';
4
- import { CustomValueWithIntrinsics } from './with-intrinsics';
5
+ import { CustomValueWithIntrinsics, CustomValueWithIntrinsicsResult } from './with-intrinsics';
5
6
  export declare class CustomNumberIterator implements Iterator<CustomValue> {
6
7
  index: number;
7
8
  next(): IteratorResult<CustomValue>;
@@ -17,11 +18,13 @@ export declare class CustomNumber extends CustomValueWithIntrinsics {
17
18
  toInt(): number;
18
19
  toNumber(): number;
19
20
  toTruthy(): boolean;
20
- instanceOf(v: CustomValue): boolean;
21
+ instanceOf(v: CustomValue, typeIntrinsics: ContextTypeIntrinsics): boolean;
21
22
  [Symbol.iterator](): CustomNumberIterator;
22
23
  has(_path: Path<CustomValue> | CustomValue): boolean;
23
24
  set(_path: Path<CustomValue> | CustomValue, _newValue: CustomValue): void;
24
- get(path: Path<CustomValue> | CustomValue): CustomValue;
25
+ get(path: Path<CustomValue> | CustomValue, typeIntrinsics: ContextTypeIntrinsics): CustomValue;
26
+ getWithOrigin(path: Path<CustomValue> | CustomValue, typeIntrinsics: ContextTypeIntrinsics): CustomValueWithIntrinsicsResult;
27
+ hash(): number;
25
28
  }
26
29
  export declare const NegativeOne: CustomNumber;
27
30
  export declare const PositiveOne: CustomNumber;