greybel-interpreter 2.5.2 → 2.6.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.
package/dist/index.d.ts CHANGED
@@ -40,7 +40,6 @@ export { CustomNil } from './types/nil';
40
40
  export { CustomNumber } from './types/number';
41
41
  export { CustomString, CustomStringIterator } from './types/string';
42
42
  export { CustomObject, CustomValueWithIntrinsics } from './types/with-intrinsics';
43
- export { deepEqual } from './utils/deep-equal';
44
43
  export { PrepareError, RuntimeError } from './utils/error';
45
44
  export { ObjectValue } from './utils/object-value';
46
45
  export { Path } from './utils/path';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Operation = exports.Not = exports.Noop = exports.NewInstance = exports.NegatedBinary = exports.MapOperation = exports.Literal = exports.List = exports.Include = exports.Import = exports.IfStatement = exports.Clause = exports.FunctionOperation = exports.For = exports.StringProcessorHandler = exports.NumberProcessorHandler = exports.MapProcessorHandler = exports.ListProcessorHandler = exports.handleString = exports.handleNumber = exports.handleMap = exports.handleList = exports.handle = exports.GenericProcessorHandler = exports.Evaluate = exports.DebuggerStatement = exports.Continue = exports.Chunk = exports.Call = exports.Break = exports.Block = exports.Assign = exports.Interpreter = exports.HandlerContainer = exports.ResourceHandler = exports.DefaultResourceHandler = exports.OutputHandler = exports.DefaultOutputHandler = exports.ErrorHandler = exports.DefaultErrorHandler = exports.CPSContext = exports.CPS = exports.Scope = exports.ProcessState = exports.OperationContext = exports.LoopState = exports.FunctionState = exports.Debugger = exports.ContextType = exports.ContextState = void 0;
4
- exports.Path = exports.ObjectValue = exports.RuntimeError = exports.PrepareError = exports.deepEqual = exports.CustomValueWithIntrinsics = exports.CustomObject = exports.CustomStringIterator = exports.CustomString = exports.CustomNumber = exports.CustomNil = exports.CustomMapIterator = exports.CustomMap = exports.CustomListIterator = exports.CustomList = exports.CustomFunction = exports.Argument = exports.DefaultType = exports.CustomBoolean = exports.CustomValue = exports.While = exports.Return = exports.ResolveResult = exports.Resolve = exports.OperationSegment = exports.IndexSegment = exports.IdentifierSegment = exports.Reference = void 0;
4
+ exports.Path = exports.ObjectValue = exports.RuntimeError = exports.PrepareError = exports.CustomValueWithIntrinsics = exports.CustomObject = exports.CustomStringIterator = exports.CustomString = exports.CustomNumber = exports.CustomNil = exports.CustomMapIterator = exports.CustomMap = exports.CustomListIterator = exports.CustomList = exports.CustomFunction = exports.Argument = exports.DefaultType = exports.CustomBoolean = exports.CustomValue = exports.While = exports.Return = exports.ResolveResult = exports.Resolve = exports.OperationSegment = exports.IndexSegment = exports.IdentifierSegment = exports.Reference = void 0;
5
5
  var context_1 = require("./context");
6
6
  Object.defineProperty(exports, "ContextState", { enumerable: true, get: function () { return context_1.ContextState; } });
7
7
  Object.defineProperty(exports, "ContextType", { enumerable: true, get: function () { return context_1.ContextType; } });
@@ -117,8 +117,6 @@ Object.defineProperty(exports, "CustomStringIterator", { enumerable: true, get:
117
117
  var with_intrinsics_1 = require("./types/with-intrinsics");
118
118
  Object.defineProperty(exports, "CustomObject", { enumerable: true, get: function () { return with_intrinsics_1.CustomObject; } });
119
119
  Object.defineProperty(exports, "CustomValueWithIntrinsics", { enumerable: true, get: function () { return with_intrinsics_1.CustomValueWithIntrinsics; } });
120
- var deep_equal_1 = require("./utils/deep-equal");
121
- Object.defineProperty(exports, "deepEqual", { enumerable: true, get: function () { return deep_equal_1.deepEqual; } });
122
120
  var error_2 = require("./utils/error");
123
121
  Object.defineProperty(exports, "PrepareError", { enumerable: true, get: function () { return error_2.PrepareError; } });
124
122
  Object.defineProperty(exports, "RuntimeError", { enumerable: true, get: function () { return error_2.RuntimeError; } });
@@ -18,6 +18,7 @@ export interface InterpreterOptions {
18
18
  environmentVariables?: Map<string, string>;
19
19
  }
20
20
  export declare class Interpreter extends EventEmitter {
21
+ static clearAllIntrinsics(): void;
21
22
  target: string;
22
23
  api: ObjectValue;
23
24
  params: Array<string>;
@@ -28,6 +28,13 @@ const boolean_1 = require("./types/boolean");
28
28
  exports.PARAMS_PROPERTY = new string_1.CustomString('params');
29
29
  exports.IS_GREYBEL_PROPERTY = new string_1.CustomString('IS_GREYBEL');
30
30
  class Interpreter extends events_1.EventEmitter {
31
+ static clearAllIntrinsics() {
32
+ number_1.CustomNumber.clearIntrinsics();
33
+ string_1.CustomString.clearIntrinsics();
34
+ function_1.CustomFunction.intrinsics.clear();
35
+ list_1.CustomList.clearIntrinsics();
36
+ map_1.CustomMap.clearIntrinsics();
37
+ }
31
38
  constructor(options) {
32
39
  var _a, _b, _c, _d, _e, _f;
33
40
  super();
@@ -19,7 +19,6 @@ const map_1 = require("../types/map");
19
19
  const nil_1 = require("../types/nil");
20
20
  const number_1 = require("../types/number");
21
21
  const string_1 = require("../types/string");
22
- const deep_equal_1 = require("../utils/deep-equal");
23
22
  const operation_1 = require("./operation");
24
23
  exports.GenericProcessorHandler = {
25
24
  [greyscript_core_1.Operator.And]: (a, b) => new boolean_1.CustomBoolean(a.toTruthy() && b.toTruthy()),
@@ -126,13 +125,13 @@ exports.ListProcessorHandler = {
126
125
  },
127
126
  [greyscript_core_1.Operator.Equal]: (left, right) => {
128
127
  if (right instanceof list_1.CustomList) {
129
- return new boolean_1.CustomBoolean((0, deep_equal_1.deepEqual)(left, right));
128
+ return new boolean_1.CustomBoolean(left.hash() === right.hash());
130
129
  }
131
130
  return default_1.DefaultType.Void;
132
131
  },
133
132
  [greyscript_core_1.Operator.NotEqual]: (left, right) => {
134
133
  if (right instanceof list_1.CustomList) {
135
- return new boolean_1.CustomBoolean(!(0, deep_equal_1.deepEqual)(left, right));
134
+ return new boolean_1.CustomBoolean(left.hash() !== right.hash());
136
135
  }
137
136
  return default_1.DefaultType.Void;
138
137
  },
@@ -158,13 +157,13 @@ exports.MapProcessorHandler = {
158
157
  },
159
158
  [greyscript_core_1.Operator.Equal]: (left, right) => {
160
159
  if (right instanceof map_1.CustomMap) {
161
- return new boolean_1.CustomBoolean((0, deep_equal_1.deepEqual)(left, right));
160
+ return new boolean_1.CustomBoolean(left.hash() === right.hash());
162
161
  }
163
162
  return default_1.DefaultType.Void;
164
163
  },
165
164
  [greyscript_core_1.Operator.NotEqual]: (left, right) => {
166
165
  if (right instanceof map_1.CustomMap) {
167
- return new boolean_1.CustomBoolean(!(0, deep_equal_1.deepEqual)(left, right));
166
+ return new boolean_1.CustomBoolean(left.hash() !== right.hash());
168
167
  }
169
168
  return default_1.DefaultType.Void;
170
169
  }
@@ -8,4 +8,5 @@ export declare abstract class CustomValue {
8
8
  abstract toTruthy(): boolean;
9
9
  abstract fork(): CustomValue;
10
10
  abstract instanceOf(value: CustomValue): boolean;
11
+ abstract hash(recursionDepth?: number): number;
11
12
  }
@@ -35,4 +35,5 @@ export declare class CustomFunction extends CustomValue {
35
35
  toTruthy(): boolean;
36
36
  instanceOf(v: CustomValue): boolean;
37
37
  run(self: CustomValue, args: Array<CustomValue>, callContext: OperationContext, next?: CustomMap): Promise<CustomValue>;
38
+ hash(): number;
38
39
  }
@@ -14,6 +14,7 @@ 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");
@@ -134,6 +135,9 @@ class CustomFunction extends base_1.CustomValue {
134
135
  return this.value(fnCtx !== null && fnCtx !== void 0 ? fnCtx : callContext, selfValue, argMap, isa);
135
136
  });
136
137
  }
138
+ hash() {
139
+ return (0, hash_1.getStringHashCode)(this.toString());
140
+ }
137
141
  }
138
142
  CustomFunction.intrinsics = new object_value_1.ObjectValue();
139
143
  exports.CustomFunction = CustomFunction;
@@ -28,4 +28,5 @@ export declare class CustomList extends CustomObject {
28
28
  has(path: Path<CustomValue> | CustomValue): boolean;
29
29
  set(path: Path<CustomValue> | CustomValue, newValue: CustomValue): void;
30
30
  get(path: Path<CustomValue> | CustomValue): CustomValue;
31
+ hash(recursionDepth?: number): number;
31
32
  }
@@ -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");
@@ -156,6 +157,15 @@ class CustomList extends with_intrinsics_1.CustomObject {
156
157
  }
157
158
  throw new Error(`Unknown path in list ${path.toString()}.`);
158
159
  }
160
+ hash(recursionDepth = 0) {
161
+ let result = (0, hash_1.getHashCode)(this.value.length);
162
+ if (recursionDepth > 16)
163
+ return result;
164
+ this.value.forEach((value) => {
165
+ result = (0, hash_1.rotateBits)(result) ^ value.hash(recursionDepth + 1);
166
+ });
167
+ return result;
168
+ }
159
169
  }
160
170
  CustomList.intrinsics = new object_value_1.ObjectValue();
161
171
  exports.CustomList = CustomList;
@@ -34,4 +34,5 @@ export declare class CustomMap extends CustomObject {
34
34
  get(path: Path<CustomValue> | CustomValue): CustomValue;
35
35
  createInstance(): CustomMap;
36
36
  getIsa(): CustomMap | null;
37
+ hash(recursionDepth?: number): number;
37
38
  }
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");
@@ -181,6 +182,16 @@ class CustomMap extends with_intrinsics_1.CustomObject {
181
182
  const isa = this.value.get(exports.ISA_PROPERTY);
182
183
  return isa instanceof CustomMap ? isa : null;
183
184
  }
185
+ hash(recursionDepth = 0) {
186
+ let result = (0, hash_1.getHashCode)(this.value.size);
187
+ if (recursionDepth > 16)
188
+ return result;
189
+ this.value.forEach((value, key) => {
190
+ result ^= key.hash(recursionDepth + 1);
191
+ result ^= value.hash(recursionDepth + 1);
192
+ });
193
+ return result;
194
+ }
184
195
  }
185
196
  CustomMap.intrinsics = new object_value_1.ObjectValue();
186
197
  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 0;
36
+ }
34
37
  }
35
38
  exports.CustomNil = CustomNil;
36
39
  exports.Void = new CustomNil();
@@ -22,6 +22,7 @@ export declare class CustomNumber extends CustomValueWithIntrinsics {
22
22
  has(_path: Path<CustomValue> | CustomValue): boolean;
23
23
  set(_path: Path<CustomValue> | CustomValue, _newValue: CustomValue): void;
24
24
  get(path: Path<CustomValue> | CustomValue): CustomValue;
25
+ hash(): number;
25
26
  }
26
27
  export declare const NegativeOne: CustomNumber;
27
28
  export declare const PositiveOne: CustomNumber;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Zero = exports.PositiveOne = exports.NegativeOne = exports.CustomNumber = exports.CustomNumberIterator = 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");
@@ -67,6 +68,9 @@ class CustomNumber extends with_intrinsics_1.CustomValueWithIntrinsics {
67
68
  }
68
69
  throw new Error(`Unknown path in number ${path.toString()}.`);
69
70
  }
71
+ hash() {
72
+ return (0, hash_1.getHashCode)(this.value);
73
+ }
70
74
  }
71
75
  CustomNumber.intrinsics = new object_value_1.ObjectValue();
72
76
  exports.CustomNumber = CustomNumber;
@@ -30,4 +30,5 @@ export declare class CustomString extends CustomValueWithIntrinsics {
30
30
  has(path: Path<CustomValue> | CustomValue): boolean;
31
31
  set(_path: Path<CustomValue> | CustomValue, _newValue: CustomValue): void;
32
32
  get(path: Path<CustomValue> | CustomValue): CustomValue;
33
+ hash(): number;
33
34
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CustomString = exports.CustomStringIterator = 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");
@@ -118,6 +119,9 @@ class CustomString extends with_intrinsics_1.CustomValueWithIntrinsics {
118
119
  }
119
120
  throw new Error(`Unknown path in string ${path.toString()}.`);
120
121
  }
122
+ hash() {
123
+ return (0, hash_1.getStringHashCode)(this.value);
124
+ }
121
125
  }
122
126
  CustomString.intrinsics = new object_value_1.ObjectValue();
123
127
  exports.CustomString = CustomString;
@@ -0,0 +1,3 @@
1
+ export declare function rotateBits(n: number): number;
2
+ export declare function getHashCode(value: number, offset?: number): number;
3
+ export declare const getStringHashCode: (value: string) => number;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getStringHashCode = exports.getHashCode = exports.rotateBits = void 0;
4
+ const lru_cache_1 = require("lru-cache");
5
+ function rotateBits(n) {
6
+ return (n >> 1) | (n << 31);
7
+ }
8
+ exports.rotateBits = rotateBits;
9
+ function getHashCode(value, offset = 0) {
10
+ let unsigned = value >>> 0;
11
+ unsigned = ((unsigned >> 16) ^ unsigned) * 0x45d9f3b;
12
+ unsigned = ((unsigned >> 16) ^ unsigned) * 0x45d9f3b;
13
+ unsigned = (unsigned >> 16) ^ unsigned;
14
+ return ((offset << 5) - offset + unsigned) | 0;
15
+ }
16
+ exports.getHashCode = getHashCode;
17
+ exports.getStringHashCode = (function () {
18
+ const cache = new lru_cache_1.LRUCache({
19
+ ttl: 1000 * 60 * 5,
20
+ max: 500
21
+ });
22
+ const generateHash = (value) => {
23
+ let hash = 0;
24
+ for (let i = 0; i < value.length; i++) {
25
+ const chr = value.charCodeAt(i);
26
+ hash = getHashCode(chr, hash);
27
+ }
28
+ return hash;
29
+ };
30
+ return (value) => {
31
+ if (value.length === 0) {
32
+ return 0;
33
+ }
34
+ if (cache.has(value)) {
35
+ return cache.get(value);
36
+ }
37
+ const hash = generateHash(value);
38
+ cache.set(value, hash);
39
+ return hash;
40
+ };
41
+ })();
@@ -1,8 +1,17 @@
1
1
  import { CustomValue } from '../types/base';
2
- export declare class ObjectValue extends Map<CustomValue, CustomValue> {
2
+ export type ObjectValueKeyPair = [CustomValue, CustomValue];
3
+ export declare class ObjectValue {
4
+ private data;
5
+ constructor(entries?: ObjectValue | ObjectValueKeyPair[] | null);
3
6
  get(mapKey: CustomValue): CustomValue;
4
7
  has(mapKey: CustomValue): boolean;
5
8
  set(mapKey: CustomValue, mapValue: CustomValue): this;
6
9
  delete(mapKey: CustomValue): boolean;
10
+ values(): CustomValue[];
11
+ keys(): CustomValue[];
12
+ entries(): ObjectValueKeyPair[];
13
+ get size(): number;
14
+ forEach(callback: (value: CustomValue, key: CustomValue, map: ObjectValue) => any): void;
7
15
  extend(objVal: ObjectValue): this;
16
+ clear(): void;
8
17
  }
@@ -2,48 +2,68 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ObjectValue = void 0;
4
4
  const nil_1 = require("../types/nil");
5
- const deep_equal_1 = require("./deep-equal");
6
- class ObjectValue extends Map {
7
- get(mapKey) {
8
- for (const [key, value] of this.entries()) {
9
- if ((0, deep_equal_1.deepEqual)(key, mapKey)) {
10
- return value;
5
+ class ObjectValue {
6
+ constructor(entries) {
7
+ if (entries == null) {
8
+ this.data = new Map();
9
+ }
10
+ else if (entries instanceof ObjectValue) {
11
+ this.data = new Map(entries.data);
12
+ }
13
+ else if (Array.isArray(entries)) {
14
+ this.data = new Map();
15
+ for (const [key, value] of entries) {
16
+ this.set(key, value);
11
17
  }
12
18
  }
13
- return nil_1.Void;
19
+ if (this.data == null) {
20
+ throw new Error('Unknown entries type.');
21
+ }
22
+ }
23
+ get(mapKey) {
24
+ const hash = mapKey.hash();
25
+ if (!this.data.has(hash))
26
+ return nil_1.Void;
27
+ return this.data.get(hash)[1];
14
28
  }
15
29
  has(mapKey) {
16
- for (const key of this.keys()) {
17
- if ((0, deep_equal_1.deepEqual)(key, mapKey)) {
18
- return true;
19
- }
20
- }
21
- return false;
30
+ const hash = mapKey.hash();
31
+ return this.data.has(hash);
22
32
  }
23
33
  set(mapKey, mapValue) {
24
- for (const key of this.keys()) {
25
- if ((0, deep_equal_1.deepEqual)(key, mapKey)) {
26
- super.set(key, mapValue);
27
- return;
28
- }
29
- }
30
- super.set(mapKey, mapValue);
34
+ const hash = mapKey.hash();
35
+ this.data.set(hash, [mapKey, mapValue]);
31
36
  return this;
32
37
  }
33
38
  delete(mapKey) {
34
- for (const key of this.keys()) {
35
- if ((0, deep_equal_1.deepEqual)(key, mapKey)) {
36
- super.delete(key);
37
- return true;
38
- }
39
+ const hash = mapKey.hash();
40
+ return this.data.delete(hash);
41
+ }
42
+ values() {
43
+ return [...this.data.values()].map(([_, v]) => v);
44
+ }
45
+ keys() {
46
+ return [...this.data.values()].map(([k]) => k);
47
+ }
48
+ entries() {
49
+ return [...this.data.values()];
50
+ }
51
+ get size() {
52
+ return this.data.size;
53
+ }
54
+ forEach(callback) {
55
+ for (const [key, value] of this.data.values()) {
56
+ callback(value, key, this);
39
57
  }
40
- return false;
41
58
  }
42
59
  extend(objVal) {
43
- for (const [key, value] of objVal) {
60
+ for (const [key, value] of objVal.entries()) {
44
61
  this.set(key, value);
45
62
  }
46
63
  return this;
47
64
  }
65
+ clear() {
66
+ this.data.clear();
67
+ }
48
68
  }
49
69
  exports.ObjectValue = ObjectValue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "greybel-interpreter",
3
- "version": "2.5.2",
3
+ "version": "2.6.0",
4
4
  "description": "Interpreter",
5
5
  "main": "dist/index",
6
6
  "typings": "dist/index",
@@ -49,7 +49,8 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "greybel-core": "^0.9.13",
52
- "greyscript-core": "^0.9.14"
52
+ "greyscript-core": "^0.9.14",
53
+ "lru-cache": "^10.0.1"
53
54
  },
54
55
  "keywords": [
55
56
  "greyscript",
@@ -1 +0,0 @@
1
- export declare function deepEqual(a: any, b: any, maxDepth?: number): boolean;
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deepEqual = void 0;
4
- const with_intrinsics_1 = require("../types/with-intrinsics");
5
- function equalInner(a, b, maxDepth, depth = 0) {
6
- if (maxDepth <= depth)
7
- return a === b;
8
- if (a.value === b.value)
9
- return true;
10
- if (a && b && a instanceof with_intrinsics_1.CustomObject && b instanceof with_intrinsics_1.CustomObject) {
11
- if (a.constructor !== b.constructor)
12
- return false;
13
- if (Array.isArray(a.value)) {
14
- const length = a.value.length;
15
- if (length !== b.value.length)
16
- return false;
17
- for (let i = length; i-- !== 0;)
18
- if (!equalInner(a.value[i], b.value[i], maxDepth, depth + 1))
19
- return false;
20
- return true;
21
- }
22
- if (a.value instanceof Map) {
23
- if (a.value.size !== b.value.size)
24
- return false;
25
- for (const i of a.value.keys())
26
- if (!b.has(i) || !equalInner(a.get(i), b.get(i), maxDepth, depth + 1))
27
- return false;
28
- return true;
29
- }
30
- return false;
31
- }
32
- // true if both NaN, false otherwise
33
- return Number.isNaN(a.value) && Number.isNaN(b.value);
34
- }
35
- function deepEqual(a, b, maxDepth = 10) {
36
- return equalInner(a, b, maxDepth);
37
- }
38
- exports.deepEqual = deepEqual;