greybel-interpreter 2.5.3 → 2.6.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/dist/context.d.ts +3 -0
- package/dist/context.js +7 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +1 -3
- package/dist/operations/assign-self.js +8 -1
- package/dist/operations/assign.js +8 -1
- package/dist/operations/evaluate.js +4 -5
- package/dist/operations/function.d.ts +1 -1
- package/dist/operations/function.js +2 -2
- package/dist/types/base.d.ts +1 -0
- package/dist/types/function.d.ts +3 -1
- package/dist/types/function.js +8 -2
- package/dist/types/list.d.ts +1 -0
- package/dist/types/list.js +10 -0
- package/dist/types/map.d.ts +1 -0
- package/dist/types/map.js +11 -0
- package/dist/types/nil.d.ts +1 -0
- package/dist/types/nil.js +3 -0
- package/dist/types/number.d.ts +1 -0
- package/dist/types/number.js +4 -0
- package/dist/types/string.d.ts +1 -0
- package/dist/types/string.js +4 -0
- package/dist/utils/hash.d.ts +3 -0
- package/dist/utils/hash.js +41 -0
- package/dist/utils/object-value.d.ts +10 -1
- package/dist/utils/object-value.js +47 -27
- package/package.json +3 -2
- package/dist/utils/deep-equal.d.ts +0 -1
- package/dist/utils/deep-equal.js +0 -38
package/dist/context.d.ts
CHANGED
|
@@ -67,12 +67,14 @@ export interface ContextOptions {
|
|
|
67
67
|
cps?: CPS;
|
|
68
68
|
processState?: ProcessState;
|
|
69
69
|
environmentVariables?: Map<string, string>;
|
|
70
|
+
ignoreOuter?: boolean;
|
|
70
71
|
}
|
|
71
72
|
export interface ContextForkOptions {
|
|
72
73
|
type: ContextType;
|
|
73
74
|
state: ContextState;
|
|
74
75
|
target?: string;
|
|
75
76
|
injected?: boolean;
|
|
77
|
+
ignoreOuter?: boolean;
|
|
76
78
|
}
|
|
77
79
|
export declare class OperationContext {
|
|
78
80
|
target: string;
|
|
@@ -112,6 +114,7 @@ export declare class OperationContext {
|
|
|
112
114
|
lookupApi(): OperationContext;
|
|
113
115
|
lookupGlobals(): OperationContext;
|
|
114
116
|
lookupLocals(): OperationContext;
|
|
117
|
+
lookupOuter(): OperationContext;
|
|
115
118
|
extend(map: ObjectValue): OperationContext;
|
|
116
119
|
set(path: Path<CustomValue> | CustomValue, value: CustomValue): void;
|
|
117
120
|
get(path: Path<CustomValue> | CustomValue): CustomValue;
|
package/dist/context.js
CHANGED
|
@@ -149,7 +149,7 @@ class FunctionState {
|
|
|
149
149
|
exports.FunctionState = FunctionState;
|
|
150
150
|
class OperationContext {
|
|
151
151
|
constructor(options = {}) {
|
|
152
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o
|
|
152
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
153
153
|
this.target = (_a = options.target) !== null && _a !== void 0 ? _a : 'unknown';
|
|
154
154
|
this.stackTrace = (_b = options.stackTrace) !== null && _b !== void 0 ? _b : [];
|
|
155
155
|
this.previous = (_c = options.previous) !== null && _c !== void 0 ? _c : null;
|
|
@@ -168,7 +168,7 @@ class OperationContext {
|
|
|
168
168
|
this.api = this.lookupApi();
|
|
169
169
|
this.globals = this.lookupGlobals();
|
|
170
170
|
this.locals = (_o = this.lookupLocals()) !== null && _o !== void 0 ? _o : this;
|
|
171
|
-
this.outer =
|
|
171
|
+
this.outer = options.ignoreOuter ? null : this.lookupOuter();
|
|
172
172
|
}
|
|
173
173
|
isIgnoredInDebugging(op) {
|
|
174
174
|
return op instanceof operation_1.OperationBlock || op instanceof noop_1.Noop;
|
|
@@ -272,6 +272,10 @@ class OperationContext {
|
|
|
272
272
|
lookupLocals() {
|
|
273
273
|
return this.lookupType(OperationContext.lookupLocalsType);
|
|
274
274
|
}
|
|
275
|
+
lookupOuter() {
|
|
276
|
+
var _a, _b;
|
|
277
|
+
return (_b = (_a = this.locals.previous) === null || _a === void 0 ? void 0 : _a.lookupLocals()) !== null && _b !== void 0 ? _b : null;
|
|
278
|
+
}
|
|
275
279
|
extend(map) {
|
|
276
280
|
var _a;
|
|
277
281
|
if (this.state === ContextState.Temporary) {
|
|
@@ -316,6 +320,7 @@ class OperationContext {
|
|
|
316
320
|
previous: this,
|
|
317
321
|
type: options.type,
|
|
318
322
|
state: options.state,
|
|
323
|
+
ignoreOuter: options.ignoreOuter,
|
|
319
324
|
isProtected: false,
|
|
320
325
|
injected: this.injected,
|
|
321
326
|
debugger: this.debugger,
|
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.
|
|
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; } });
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.AssignSelf = void 0;
|
|
13
13
|
const default_1 = require("../types/default");
|
|
14
|
+
const function_1 = require("./function");
|
|
14
15
|
const operation_1 = require("./operation");
|
|
15
16
|
class AssignSelf extends operation_1.Operation {
|
|
16
17
|
constructor(item, target) {
|
|
@@ -25,7 +26,13 @@ class AssignSelf extends operation_1.Operation {
|
|
|
25
26
|
}
|
|
26
27
|
handle(ctx) {
|
|
27
28
|
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
-
|
|
29
|
+
let rightValue;
|
|
30
|
+
if (this.right instanceof function_1.FunctionOperation) {
|
|
31
|
+
rightValue = yield this.right.handle(ctx, true);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
rightValue = yield this.right.handle(ctx);
|
|
35
|
+
}
|
|
29
36
|
ctx.functionState.context = rightValue;
|
|
30
37
|
return default_1.DefaultType.Void;
|
|
31
38
|
});
|
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.Assign = void 0;
|
|
13
13
|
const default_1 = require("../types/default");
|
|
14
14
|
const create_resolve_1 = require("../utils/create-resolve");
|
|
15
|
+
const function_1 = require("./function");
|
|
15
16
|
const operation_1 = require("./operation");
|
|
16
17
|
const resolve_1 = require("./resolve");
|
|
17
18
|
class Assign extends operation_1.Operation {
|
|
@@ -33,10 +34,16 @@ class Assign extends operation_1.Operation {
|
|
|
33
34
|
if (ctx.isExit()) {
|
|
34
35
|
return default_1.DefaultType.Void;
|
|
35
36
|
}
|
|
36
|
-
const rightValue = yield this.right.handle(ctx);
|
|
37
37
|
if (resolveResult.path.count() === 0) {
|
|
38
38
|
throw new Error('Resolve path cannot be empty.');
|
|
39
39
|
}
|
|
40
|
+
let rightValue;
|
|
41
|
+
if (this.right instanceof function_1.FunctionOperation) {
|
|
42
|
+
rightValue = yield this.right.handle(ctx, true);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
rightValue = yield this.right.handle(ctx);
|
|
46
|
+
}
|
|
40
47
|
if (!(resolveResult.handle instanceof resolve_1.ResolveNil)) {
|
|
41
48
|
const resultValueCtx = resolveResult.handle;
|
|
42
49
|
resultValueCtx.set(resolveResult.path, rightValue);
|
|
@@ -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((
|
|
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(
|
|
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((
|
|
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(
|
|
166
|
+
return new boolean_1.CustomBoolean(left.hash() !== right.hash());
|
|
168
167
|
}
|
|
169
168
|
return default_1.DefaultType.Void;
|
|
170
169
|
}
|
|
@@ -15,5 +15,5 @@ export declare class FunctionOperation extends Operation {
|
|
|
15
15
|
args: FunctionOperationArgument[];
|
|
16
16
|
constructor(item: ASTFunctionStatement, target?: string);
|
|
17
17
|
build(visit: CPSVisit): Promise<Operation>;
|
|
18
|
-
handle(ctx: OperationContext): Promise<CustomValue>;
|
|
18
|
+
handle(ctx: OperationContext, assignOuter?: boolean): Promise<CustomValue>;
|
|
19
19
|
}
|
|
@@ -54,7 +54,7 @@ class FunctionOperation extends operation_1.Operation {
|
|
|
54
54
|
return this;
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
-
handle(ctx) {
|
|
57
|
+
handle(ctx, assignOuter = false) {
|
|
58
58
|
const func = new function_1.CustomFunction(ctx, 'anonymous', (fnCtx, self, args, next) => __awaiter(this, void 0, void 0, function* () {
|
|
59
59
|
const functionState = new context_1.FunctionState();
|
|
60
60
|
functionState.context = self;
|
|
@@ -73,7 +73,7 @@ class FunctionOperation extends operation_1.Operation {
|
|
|
73
73
|
fnCtx.functionState = functionState;
|
|
74
74
|
yield this.block.handle(fnCtx);
|
|
75
75
|
return functionState.value;
|
|
76
|
-
}));
|
|
76
|
+
}), assignOuter);
|
|
77
77
|
for (const item of this.args) {
|
|
78
78
|
func.addArgument(item.name, item.op);
|
|
79
79
|
}
|
package/dist/types/base.d.ts
CHANGED
package/dist/types/function.d.ts
CHANGED
|
@@ -21,10 +21,11 @@ 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;
|
|
24
25
|
static createExternalAnonymous(callback: Callback): CustomFunction;
|
|
25
26
|
static createExternal(name: string, callback: Callback): CustomFunction;
|
|
26
27
|
static createExternalWithSelf(name: string, callback: Callback): CustomFunction;
|
|
27
|
-
constructor(scope: OperationContext, name: string, callback: Callback);
|
|
28
|
+
constructor(scope: OperationContext, name: string, callback: Callback, assignOuter?: boolean);
|
|
28
29
|
addArgument(name: string, defaultValue?: Operation | CustomValue): CustomFunction;
|
|
29
30
|
fork(): CustomValue;
|
|
30
31
|
getCustomType(): string;
|
|
@@ -35,4 +36,5 @@ export declare class CustomFunction extends CustomValue {
|
|
|
35
36
|
toTruthy(): boolean;
|
|
36
37
|
instanceOf(v: CustomValue): boolean;
|
|
37
38
|
run(self: CustomValue, args: Array<CustomValue>, callContext: OperationContext, next?: CustomMap): Promise<CustomValue>;
|
|
39
|
+
hash(): number;
|
|
38
40
|
}
|
package/dist/types/function.js
CHANGED
|
@@ -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");
|
|
@@ -51,12 +52,13 @@ class CustomFunction extends base_1.CustomValue {
|
|
|
51
52
|
static createExternalWithSelf(name, callback) {
|
|
52
53
|
return new CustomFunction(null, name, callback).addArgument(exports.SELF_NAMESPACE);
|
|
53
54
|
}
|
|
54
|
-
constructor(scope, name, callback) {
|
|
55
|
+
constructor(scope, name, callback, assignOuter = false) {
|
|
55
56
|
super();
|
|
56
57
|
this.scope = scope;
|
|
57
58
|
this.name = name;
|
|
58
59
|
this.value = callback;
|
|
59
60
|
this.argumentDefs = [];
|
|
61
|
+
this.assignOuter = assignOuter;
|
|
60
62
|
}
|
|
61
63
|
addArgument(name, defaultValue = default_1.DefaultType.Void) {
|
|
62
64
|
this.argumentDefs.push(new Argument(name, defaultValue));
|
|
@@ -111,7 +113,8 @@ class CustomFunction extends base_1.CustomValue {
|
|
|
111
113
|
}
|
|
112
114
|
const fnCtx = (_a = this.scope) === null || _a === void 0 ? void 0 : _a.fork({
|
|
113
115
|
type: context_1.ContextType.Function,
|
|
114
|
-
state: context_1.ContextState.Default
|
|
116
|
+
state: context_1.ContextState.Default,
|
|
117
|
+
ignoreOuter: !this.assignOuter
|
|
115
118
|
});
|
|
116
119
|
const argMap = new Map();
|
|
117
120
|
const hasSelf = !(self instanceof nil_1.CustomNil);
|
|
@@ -134,6 +137,9 @@ class CustomFunction extends base_1.CustomValue {
|
|
|
134
137
|
return this.value(fnCtx !== null && fnCtx !== void 0 ? fnCtx : callContext, selfValue, argMap, isa);
|
|
135
138
|
});
|
|
136
139
|
}
|
|
140
|
+
hash() {
|
|
141
|
+
return (0, hash_1.getStringHashCode)(this.toString());
|
|
142
|
+
}
|
|
137
143
|
}
|
|
138
144
|
CustomFunction.intrinsics = new object_value_1.ObjectValue();
|
|
139
145
|
exports.CustomFunction = CustomFunction;
|
package/dist/types/list.d.ts
CHANGED
|
@@ -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
|
}
|
package/dist/types/list.js
CHANGED
|
@@ -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;
|
package/dist/types/map.d.ts
CHANGED
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;
|
package/dist/types/nil.d.ts
CHANGED
package/dist/types/nil.js
CHANGED
package/dist/types/number.d.ts
CHANGED
|
@@ -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;
|
package/dist/types/number.js
CHANGED
|
@@ -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;
|
package/dist/types/string.d.ts
CHANGED
|
@@ -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
|
}
|
package/dist/types/string.js
CHANGED
|
@@ -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,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
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17
|
-
|
|
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
|
-
|
|
25
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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.
|
|
3
|
+
"version": "2.6.1",
|
|
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;
|
package/dist/utils/deep-equal.js
DELETED
|
@@ -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;
|