@mirascript/mirascript 0.1.22 → 0.1.24
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/bench/index.ts +45 -0
- package/dist/{chunk-PECLT2P6.js → chunk-AZICQWZD.js} +35 -9
- package/dist/chunk-AZICQWZD.js.map +6 -0
- package/dist/{chunk-4T5YE7LC.js → chunk-K7JDJG3G.js} +26 -31
- package/dist/chunk-K7JDJG3G.js.map +6 -0
- package/dist/{chunk-7HH5Y4QO.js → chunk-UCIDBTZL.js} +599 -535
- package/dist/chunk-UCIDBTZL.js.map +6 -0
- package/dist/chunk-X6LYEGOK.js +69 -0
- package/dist/chunk-X6LYEGOK.js.map +6 -0
- package/dist/cli/index.js +4 -4
- package/dist/compiler/compile-fast.d.ts.map +1 -1
- package/dist/compiler/create-script.d.ts +6 -2
- package/dist/compiler/create-script.d.ts.map +1 -1
- package/dist/compiler/emit/constants.d.ts +1 -1
- package/dist/compiler/emit/constants.d.ts.map +1 -1
- package/dist/compiler/emit/index.d.ts.map +1 -1
- package/dist/compiler/worker.js +1 -1
- package/dist/helpers/analyze.d.ts +8 -0
- package/dist/helpers/analyze.d.ts.map +1 -0
- package/dist/index.js +3 -3
- package/dist/subtle.d.ts +3 -2
- package/dist/subtle.d.ts.map +1 -1
- package/dist/subtle.js +12 -7
- package/dist/vm/operations/call.d.ts +3 -0
- package/dist/vm/operations/call.d.ts.map +1 -0
- package/dist/vm/operations/common.d.ts +3 -0
- package/dist/vm/operations/common.d.ts.map +1 -0
- package/dist/vm/operations/compound.d.ts +12 -0
- package/dist/vm/operations/compound.d.ts.map +1 -0
- package/dist/vm/operations/convert.d.ts +6 -0
- package/dist/vm/operations/convert.d.ts.map +1 -0
- package/dist/vm/operations/cp.d.ts +2 -0
- package/dist/vm/operations/cp.d.ts.map +1 -0
- package/dist/vm/operations/helpers.d.ts +19 -0
- package/dist/vm/operations/helpers.d.ts.map +1 -0
- package/dist/vm/operations/index.d.ts +10 -0
- package/dist/vm/operations/index.d.ts.map +1 -0
- package/dist/vm/operations/operator.d.ts +24 -0
- package/dist/vm/operations/operator.d.ts.map +1 -0
- package/dist/vm/operations/slice.d.ts +4 -0
- package/dist/vm/operations/slice.d.ts.map +1 -0
- package/dist/vm/operations/type-check.d.ts +9 -0
- package/dist/vm/operations/type-check.d.ts.map +1 -0
- package/dist/vm/operations/utils.d.ts +11 -0
- package/dist/vm/operations/utils.d.ts.map +1 -0
- package/dist/vm/types/boundary.d.ts +2 -3
- package/dist/vm/types/boundary.d.ts.map +1 -1
- package/dist/vm/types/context.d.ts +2 -4
- package/dist/vm/types/context.d.ts.map +1 -1
- package/dist/vm/types/extern.d.ts +3 -3
- package/dist/vm/types/extern.d.ts.map +1 -1
- package/dist/vm/types/index.d.ts +1 -1
- package/dist/vm/types/index.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/compiler/compile-fast.ts +32 -12
- package/src/compiler/create-script.ts +19 -5
- package/src/compiler/emit/constants.ts +1 -1
- package/src/compiler/emit/index.ts +18 -25
- package/src/compiler/emit/sourcemap.ts +8 -8
- package/src/helpers/analyze.ts +70 -0
- package/src/subtle.ts +3 -2
- package/src/vm/lib/global/debug.ts +1 -1
- package/src/vm/lib/global/sequence/all-any.ts +2 -2
- package/src/vm/lib/global/sequence/find.ts +2 -2
- package/src/vm/lib/global/sequence/map-filter.ts +1 -1
- package/src/vm/lib/global/sequence/sort.ts +1 -1
- package/src/vm/lib/global/sequence/with.ts +2 -2
- package/src/vm/lib/global/sequence/zip.ts +1 -1
- package/src/vm/lib/helpers.ts +1 -1
- package/src/vm/lib/mod/matrix.ts +2 -2
- package/src/vm/operations/call.ts +18 -0
- package/src/vm/operations/common.ts +6 -0
- package/src/vm/operations/compound.ts +148 -0
- package/src/vm/operations/convert.ts +24 -0
- package/src/vm/operations/cp.ts +1 -0
- package/src/vm/{helpers.ts → operations/helpers.ts} +17 -18
- package/src/vm/operations/index.ts +9 -0
- package/src/vm/operations/operator.ts +131 -0
- package/src/vm/operations/slice.ts +41 -0
- package/src/vm/operations/type-check.ts +38 -0
- package/src/vm/operations/utils.ts +66 -0
- package/src/vm/types/boundary.ts +18 -13
- package/src/vm/types/context.ts +72 -38
- package/src/vm/types/extern.ts +24 -9
- package/src/vm/types/index.ts +1 -1
- package/dist/chunk-4T5YE7LC.js.map +0 -6
- package/dist/chunk-7HH5Y4QO.js.map +0 -6
- package/dist/chunk-PECLT2P6.js.map +0 -6
- package/dist/chunk-RNLB52WP.js +0 -1
- package/dist/chunk-RNLB52WP.js.map +0 -6
- package/dist/vm/env.d.ts +0 -3
- package/dist/vm/env.d.ts.map +0 -1
- package/dist/vm/helpers.d.ts +0 -20
- package/dist/vm/helpers.d.ts.map +0 -1
- package/dist/vm/operations.d.ts +0 -49
- package/dist/vm/operations.d.ts.map +0 -1
- package/src/vm/env.ts +0 -16
- package/src/vm/operations.ts +0 -412
package/dist/vm/operations.d.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { TypeName, VmAny, VmRecord, VmValue, VmArray, VmConst } from './types/index.js';
|
|
2
|
-
export declare const $Add: (a: VmAny, b: VmAny) => number;
|
|
3
|
-
export declare const $Sub: (a: VmAny, b: VmAny) => number;
|
|
4
|
-
export declare const $Mul: (a: VmAny, b: VmAny) => number;
|
|
5
|
-
export declare const $Div: (a: VmAny, b: VmAny) => number;
|
|
6
|
-
export declare const $Mod: (a: VmAny, b: VmAny) => number;
|
|
7
|
-
export declare const $Pow: (a: VmAny, b: VmAny) => number;
|
|
8
|
-
export declare const $And: (a: VmAny, b: VmAny) => boolean;
|
|
9
|
-
export declare const $Or: (a: VmAny, b: VmAny) => boolean;
|
|
10
|
-
export declare const $Gt: (a: VmAny, b: VmAny) => boolean;
|
|
11
|
-
export declare const $Gte: (a: VmAny, b: VmAny) => boolean;
|
|
12
|
-
export declare const $Lt: (a: VmAny, b: VmAny) => boolean;
|
|
13
|
-
export declare const $Lte: (a: VmAny, b: VmAny) => boolean;
|
|
14
|
-
export declare const $Eq: (a: VmAny, b: VmAny) => boolean;
|
|
15
|
-
export declare const $Neq: (a: VmAny, b: VmAny) => boolean;
|
|
16
|
-
export declare const $Aeq: (a: VmAny, b: VmAny) => boolean;
|
|
17
|
-
export declare const $Naeq: (a: VmAny, b: VmAny) => boolean;
|
|
18
|
-
export declare const $Same: (a: VmAny, b: VmAny) => boolean;
|
|
19
|
-
export declare const $Nsame: (a: VmAny, b: VmAny) => boolean;
|
|
20
|
-
export declare const $In: (value: VmAny, iterable: VmAny) => boolean;
|
|
21
|
-
export declare const $Concat: (...args: readonly string[]) => string;
|
|
22
|
-
export declare const $Pos: (a: VmAny) => number;
|
|
23
|
-
export declare const $Neg: (a: VmAny) => number;
|
|
24
|
-
export declare const $Not: (a: VmAny) => boolean;
|
|
25
|
-
export declare const $Length: (value: VmAny) => number;
|
|
26
|
-
export declare const $Omit: (value: VmAny, omitted: ReadonlyArray<number | string>) => VmRecord;
|
|
27
|
-
export declare const $Pick: (value: VmAny, picked: ReadonlyArray<number | string>) => VmRecord;
|
|
28
|
-
export declare const $Slice: (value: VmAny, start: VmAny, end: VmAny) => VmArray;
|
|
29
|
-
export declare const $SliceExclusive: (value: VmAny, start: VmAny, end: VmAny) => VmArray;
|
|
30
|
-
export declare const $AssertInit: (value: VmAny) => asserts value is VmValue;
|
|
31
|
-
export declare const $Call: (func: VmValue, args: readonly VmAny[]) => VmValue;
|
|
32
|
-
export declare const $Type: (value: VmAny) => TypeName;
|
|
33
|
-
export declare const $ToBoolean: (value: VmAny) => boolean;
|
|
34
|
-
export declare const $ToString: (value: VmAny) => string;
|
|
35
|
-
export declare const $ToNumber: (value: VmAny) => number;
|
|
36
|
-
export declare const $IsBoolean: (value: VmAny) => value is boolean;
|
|
37
|
-
export declare const $IsNumber: (value: VmAny) => value is number;
|
|
38
|
-
export declare const $IsString: (value: VmAny) => value is string;
|
|
39
|
-
export declare const $IsRecord: (value: VmAny) => value is VmRecord;
|
|
40
|
-
export declare const $IsArray: (value: VmAny) => value is VmArray;
|
|
41
|
-
export declare const $AssertNonNil: (value: VmAny) => asserts value is NonNullable<VmValue>;
|
|
42
|
-
export declare const $Has: (obj: VmAny, key: VmAny) => boolean;
|
|
43
|
-
export declare const $Get: (obj: VmAny, key: VmAny) => VmValue;
|
|
44
|
-
export declare const $Set: (obj: VmAny, key: VmAny, value: VmAny) => void;
|
|
45
|
-
export declare const $Iterable: (value: VmAny) => Iterable<VmValue | undefined>;
|
|
46
|
-
export declare const $RecordSpread: (record: VmAny) => VmRecord | null;
|
|
47
|
-
export declare const $ArraySpread: (array: VmAny) => Iterable<VmConst | undefined>;
|
|
48
|
-
export declare const $Format: (value: VmAny, format: VmAny) => string;
|
|
49
|
-
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../src/vm/operations.ts"],"names":[],"mappings":"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"}
|
package/src/vm/env.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import * as operations from './operations.js';
|
|
2
|
-
import * as helpers from './helpers.js';
|
|
3
|
-
import { entries } from '../helpers/utils.js';
|
|
4
|
-
|
|
5
|
-
export const keys: string[] = [];
|
|
6
|
-
export const values: unknown[] = [];
|
|
7
|
-
|
|
8
|
-
for (const [key, value] of entries(operations)) {
|
|
9
|
-
keys.push(key);
|
|
10
|
-
values.push(value);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
for (const [key, value] of entries(helpers)) {
|
|
14
|
-
keys.push(key);
|
|
15
|
-
values.push(value);
|
|
16
|
-
}
|
package/src/vm/operations.ts
DELETED
|
@@ -1,412 +0,0 @@
|
|
|
1
|
-
import { VmError } from '../helpers/error.js';
|
|
2
|
-
import { hasOwnEnumerable, isNaN, isSafeInteger, keys, create } from '../helpers/utils.js';
|
|
3
|
-
import { toNumber, toString, toBoolean, toFormat } from '../helpers/convert/index.js';
|
|
4
|
-
import { display } from '../helpers/serialize.js';
|
|
5
|
-
import { isVmPrimitive, isVmArray, isVmRecord, isVmFunction, isVmExtern, isVmWrapper } from '../helpers/types.js';
|
|
6
|
-
import type { TypeName, VmAny, VmImmutable, VmRecord, VmValue, VmArray, VmConst } from './types/index.js';
|
|
7
|
-
|
|
8
|
-
const { abs, min, trunc, ceil } = Math;
|
|
9
|
-
const { slice, at } = Array.prototype;
|
|
10
|
-
|
|
11
|
-
const isSame = (a: VmValue, b: VmValue): boolean => {
|
|
12
|
-
// Check for NaN
|
|
13
|
-
if (typeof a == 'number' && typeof b == 'number') return a === b || (isNaN(a) && isNaN(b));
|
|
14
|
-
// Check all primitive types, and fast path for reference equality
|
|
15
|
-
if (a === b) return true;
|
|
16
|
-
// Any primitives and functions arrive here are not equal
|
|
17
|
-
if (a == null || typeof a != 'object' || b == null || typeof b != 'object') return false;
|
|
18
|
-
// Handle wrapper values
|
|
19
|
-
if (isVmWrapper(a)) return a.same(b);
|
|
20
|
-
if (isVmWrapper(b)) return b.same(a);
|
|
21
|
-
// Handle array values
|
|
22
|
-
if (isVmArray(a) && isVmArray(b)) {
|
|
23
|
-
const len = a.length;
|
|
24
|
-
if (len !== b.length) {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
// Compare array items
|
|
28
|
-
for (let i = 0; i < len; i++) {
|
|
29
|
-
if (!isSame(a[i] ?? null, b[i] ?? null)) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
// Handle record values
|
|
36
|
-
if (!isVmArray(a) && !isVmArray(b)) {
|
|
37
|
-
// Compare record fields
|
|
38
|
-
const aKeys = keys(a);
|
|
39
|
-
const bKeys = keys(b);
|
|
40
|
-
if (aKeys.length !== bKeys.length) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
for (const key of aKeys) {
|
|
44
|
-
if (!hasOwnEnumerable(b, key)) {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
/* c8 ignore next 2 */
|
|
48
|
-
const av = a[key] ?? null;
|
|
49
|
-
const bv = b[key] ?? null;
|
|
50
|
-
if (!isSame(av, bv)) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
return false;
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const overloadNumberString = (a: VmAny, b: VmAny): boolean => {
|
|
60
|
-
if (typeof a == 'number' || typeof b == 'number') return true;
|
|
61
|
-
if (typeof a == 'string' || typeof b == 'string') return false;
|
|
62
|
-
return true;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
// Math operations
|
|
66
|
-
export const $Add = (a: VmAny, b: VmAny): number => {
|
|
67
|
-
return $ToNumber(a) + $ToNumber(b);
|
|
68
|
-
};
|
|
69
|
-
export const $Sub = (a: VmAny, b: VmAny): number => {
|
|
70
|
-
return $ToNumber(a) - $ToNumber(b);
|
|
71
|
-
};
|
|
72
|
-
export const $Mul = (a: VmAny, b: VmAny): number => {
|
|
73
|
-
return $ToNumber(a) * $ToNumber(b);
|
|
74
|
-
};
|
|
75
|
-
export const $Div = (a: VmAny, b: VmAny): number => {
|
|
76
|
-
return $ToNumber(a) / $ToNumber(b);
|
|
77
|
-
};
|
|
78
|
-
export const $Mod = (a: VmAny, b: VmAny): number => {
|
|
79
|
-
return $ToNumber(a) % $ToNumber(b);
|
|
80
|
-
};
|
|
81
|
-
export const $Pow = (a: VmAny, b: VmAny): number => {
|
|
82
|
-
return $ToNumber(a) ** $ToNumber(b);
|
|
83
|
-
};
|
|
84
|
-
// Logical operations without short-circuiting
|
|
85
|
-
export const $And = (a: VmAny, b: VmAny): boolean => {
|
|
86
|
-
return $ToBoolean(a) && $ToBoolean(b);
|
|
87
|
-
};
|
|
88
|
-
export const $Or = (a: VmAny, b: VmAny): boolean => {
|
|
89
|
-
return $ToBoolean(a) || $ToBoolean(b);
|
|
90
|
-
};
|
|
91
|
-
// Comparison operations
|
|
92
|
-
export const $Gt = (a: VmAny, b: VmAny): boolean => {
|
|
93
|
-
if (overloadNumberString(a, b)) {
|
|
94
|
-
return $ToNumber(a) > $ToNumber(b);
|
|
95
|
-
} else {
|
|
96
|
-
return $ToString(a) > $ToString(b);
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
export const $Gte = (a: VmAny, b: VmAny): boolean => {
|
|
100
|
-
if (overloadNumberString(a, b)) {
|
|
101
|
-
return $ToNumber(a) >= $ToNumber(b);
|
|
102
|
-
} else {
|
|
103
|
-
return $ToString(a) >= $ToString(b);
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
export const $Lt = (a: VmAny, b: VmAny): boolean => {
|
|
107
|
-
if (overloadNumberString(a, b)) {
|
|
108
|
-
return $ToNumber(a) < $ToNumber(b);
|
|
109
|
-
} else {
|
|
110
|
-
return $ToString(a) < $ToString(b);
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
export const $Lte = (a: VmAny, b: VmAny): boolean => {
|
|
114
|
-
if (overloadNumberString(a, b)) {
|
|
115
|
-
return $ToNumber(a) <= $ToNumber(b);
|
|
116
|
-
} else {
|
|
117
|
-
return $ToString(a) <= $ToString(b);
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
export const $Eq = (a: VmAny, b: VmAny): boolean => {
|
|
121
|
-
$AssertInit(a);
|
|
122
|
-
$AssertInit(b);
|
|
123
|
-
// Number comparison is a special case to handle NaN correctly
|
|
124
|
-
if (typeof a == 'number' && typeof b == 'number') return a === b;
|
|
125
|
-
return isSame(a, b);
|
|
126
|
-
};
|
|
127
|
-
export const $Neq = (a: VmAny, b: VmAny): boolean => {
|
|
128
|
-
return !$Eq(a, b);
|
|
129
|
-
};
|
|
130
|
-
export const $Aeq = (a: VmAny, b: VmAny): boolean => {
|
|
131
|
-
if (overloadNumberString(a, b)) {
|
|
132
|
-
const an = $ToNumber(a);
|
|
133
|
-
const bn = $ToNumber(b);
|
|
134
|
-
const EPS = 1e-15;
|
|
135
|
-
if (isNaN(an) || isNaN(bn)) return false;
|
|
136
|
-
// Since Inf - Inf is NaN, we must check for equality first
|
|
137
|
-
if (an === bn) return true;
|
|
138
|
-
const absoluteDifference = abs(an - bn);
|
|
139
|
-
if (absoluteDifference < EPS) return true;
|
|
140
|
-
const base = min(abs(an), abs(bn));
|
|
141
|
-
return absoluteDifference < base * EPS;
|
|
142
|
-
} else {
|
|
143
|
-
// For strings, we use normalized case-insensitive comparison
|
|
144
|
-
const as = $ToString(a);
|
|
145
|
-
const bs = $ToString(b);
|
|
146
|
-
if (as === bs) return true;
|
|
147
|
-
const ai = as.toLowerCase();
|
|
148
|
-
const bi = bs.toLowerCase();
|
|
149
|
-
if (ai === bi) return true;
|
|
150
|
-
const an = ai.normalize('NFC');
|
|
151
|
-
const bn = bi.normalize('NFC');
|
|
152
|
-
return an === bn;
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
export const $Naeq = (a: VmAny, b: VmAny): boolean => {
|
|
156
|
-
return !$Aeq(a, b);
|
|
157
|
-
};
|
|
158
|
-
export const $Same = (a: VmAny, b: VmAny): boolean => {
|
|
159
|
-
$AssertInit(a);
|
|
160
|
-
$AssertInit(b);
|
|
161
|
-
return isSame(a, b);
|
|
162
|
-
};
|
|
163
|
-
export const $Nsame = (a: VmAny, b: VmAny): boolean => {
|
|
164
|
-
return !$Same(a, b);
|
|
165
|
-
};
|
|
166
|
-
export const $In = (value: VmAny, iterable: VmAny): boolean => {
|
|
167
|
-
$AssertInit(value);
|
|
168
|
-
$AssertInit(iterable);
|
|
169
|
-
if (iterable == null) return false;
|
|
170
|
-
if (typeof iterable != 'object') return false;
|
|
171
|
-
if (isVmArray(iterable)) {
|
|
172
|
-
if (value == null) {
|
|
173
|
-
// array may have empty slots
|
|
174
|
-
for (const item of iterable) if (item == null) return true;
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
// JS %SameValueZero is same with `isSame` in this context
|
|
178
|
-
if (isVmPrimitive(value)) return iterable.includes(value);
|
|
179
|
-
// value is not null here, so it's ok to skip empty slots, since `isSame(null, something)` is always false
|
|
180
|
-
return iterable.some((item = null) => isSame(item, value satisfies NonNullable<VmValue>));
|
|
181
|
-
}
|
|
182
|
-
// iterable is a record or an extern here, value should be a string
|
|
183
|
-
const key = toString(value, undefined);
|
|
184
|
-
if (isVmWrapper(iterable)) return iterable.has(key);
|
|
185
|
-
return hasOwnEnumerable(iterable satisfies VmRecord, key);
|
|
186
|
-
};
|
|
187
|
-
export const $Concat = (...args: readonly string[]): string => {
|
|
188
|
-
return args.map((a) => toFormat(a, null)).join('');
|
|
189
|
-
};
|
|
190
|
-
export const $Pos = (a: VmAny): number => {
|
|
191
|
-
return $ToNumber(a);
|
|
192
|
-
};
|
|
193
|
-
export const $Neg = (a: VmAny): number => {
|
|
194
|
-
return -$ToNumber(a);
|
|
195
|
-
};
|
|
196
|
-
export const $Not = (a: VmAny): boolean => {
|
|
197
|
-
return !$ToBoolean(a);
|
|
198
|
-
};
|
|
199
|
-
export const $Length = (value: VmAny): number => {
|
|
200
|
-
$AssertInit(value);
|
|
201
|
-
if (isVmArray(value)) return value.length;
|
|
202
|
-
if (isVmRecord(value)) return keys(value).length;
|
|
203
|
-
if (isVmWrapper(value)) return value.keys().length;
|
|
204
|
-
|
|
205
|
-
throw new VmError(`Value has no length: ${display(value)}`, 0);
|
|
206
|
-
};
|
|
207
|
-
export const $Omit = (value: VmAny, omitted: ReadonlyArray<number | string>): VmRecord => {
|
|
208
|
-
$AssertInit(value);
|
|
209
|
-
if (value == null || !isVmRecord(value)) return {};
|
|
210
|
-
const result: Record<string, VmConst> = {};
|
|
211
|
-
const valueKeys = keys(value);
|
|
212
|
-
const omittedSet = new Set(omitted.map($ToString));
|
|
213
|
-
for (const key of valueKeys) {
|
|
214
|
-
if (!omittedSet.has(key)) {
|
|
215
|
-
/* c8 ignore next */
|
|
216
|
-
result[key] = value[key] ?? null;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
return result;
|
|
220
|
-
};
|
|
221
|
-
export const $Pick = (value: VmAny, picked: ReadonlyArray<number | string>): VmRecord => {
|
|
222
|
-
$AssertInit(value);
|
|
223
|
-
if (value == null || !isVmRecord(value)) return {};
|
|
224
|
-
const result: Record<string, VmConst> = {};
|
|
225
|
-
for (const key of picked) {
|
|
226
|
-
const k = $ToString(key);
|
|
227
|
-
if (hasOwnEnumerable(value, k)) {
|
|
228
|
-
result[k] = value[k] ?? null;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return result;
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
const sliceCore = (value: VmArray, start: number, end: number, exclusive: boolean): VmArray => {
|
|
235
|
-
const { length } = value;
|
|
236
|
-
|
|
237
|
-
if (isNaN(start)) start = 0;
|
|
238
|
-
else if (start < 0) start = length + start;
|
|
239
|
-
if (isNaN(end)) end = exclusive ? length : length - 1;
|
|
240
|
-
else if (end < 0) end = length + end;
|
|
241
|
-
|
|
242
|
-
start = ceil(start);
|
|
243
|
-
if (exclusive || !isSafeInteger(end)) {
|
|
244
|
-
end = ceil(end);
|
|
245
|
-
} else {
|
|
246
|
-
end = end + 1;
|
|
247
|
-
}
|
|
248
|
-
return slice.call(value, start, end) as VmArray;
|
|
249
|
-
};
|
|
250
|
-
export const $Slice = (value: VmAny, start: VmAny, end: VmAny): VmArray => {
|
|
251
|
-
$AssertInit(value);
|
|
252
|
-
if (!isVmArray(value)) throw new VmError(`Expected array, got ${display(value)}`, []);
|
|
253
|
-
const s = start != null ? $ToNumber(start) : 0;
|
|
254
|
-
const e = end != null ? $ToNumber(end) : value.length - 1;
|
|
255
|
-
return sliceCore(value, s, e, false);
|
|
256
|
-
};
|
|
257
|
-
export const $SliceExclusive = (value: VmAny, start: VmAny, end: VmAny): VmArray => {
|
|
258
|
-
$AssertInit(value);
|
|
259
|
-
if (!isVmArray(value)) throw new VmError(`Expected array, got ${display(value)}`, []);
|
|
260
|
-
const s = start != null ? $ToNumber(start) : 0;
|
|
261
|
-
const e = end != null ? $ToNumber(end) : value.length;
|
|
262
|
-
return sliceCore(value, s, e, true);
|
|
263
|
-
};
|
|
264
|
-
export const $AssertInit: (value: VmAny) => asserts value is VmValue = (value) => {
|
|
265
|
-
if (value === undefined) throw new VmError(`Uninitialized value`, null);
|
|
266
|
-
};
|
|
267
|
-
export const $Call = (func: VmValue, args: readonly VmAny[]): VmValue => {
|
|
268
|
-
for (const a of args) {
|
|
269
|
-
$AssertInit(a);
|
|
270
|
-
}
|
|
271
|
-
if (isVmExtern(func)) {
|
|
272
|
-
return func.call(args as readonly VmValue[]) ?? null;
|
|
273
|
-
}
|
|
274
|
-
if (isVmFunction(func)) {
|
|
275
|
-
return func(...(args as readonly VmValue[])) ?? null;
|
|
276
|
-
}
|
|
277
|
-
throw new VmError(`Value is not callable: ${display(func)}`, null);
|
|
278
|
-
};
|
|
279
|
-
export const $Type = (value: VmAny): TypeName => {
|
|
280
|
-
// 允许未初始化值通过
|
|
281
|
-
if (value == null) return 'nil';
|
|
282
|
-
if (isVmWrapper(value)) return value.type;
|
|
283
|
-
if (isVmArray(value)) return 'array';
|
|
284
|
-
if (typeof value == 'object') return 'record';
|
|
285
|
-
return typeof value as TypeName;
|
|
286
|
-
};
|
|
287
|
-
export const $ToBoolean = (value: VmAny): boolean => {
|
|
288
|
-
if (typeof value == 'boolean') return value;
|
|
289
|
-
$AssertInit(value);
|
|
290
|
-
return toBoolean(value, undefined);
|
|
291
|
-
};
|
|
292
|
-
export const $ToString = (value: VmAny): string => {
|
|
293
|
-
if (typeof value == 'string') return value;
|
|
294
|
-
$AssertInit(value);
|
|
295
|
-
return toString(value, undefined);
|
|
296
|
-
};
|
|
297
|
-
export const $ToNumber = (value: VmAny): number => {
|
|
298
|
-
if (typeof value == 'number') return value;
|
|
299
|
-
$AssertInit(value);
|
|
300
|
-
return toNumber(value, undefined);
|
|
301
|
-
};
|
|
302
|
-
export const $IsBoolean = (value: VmAny): value is boolean => {
|
|
303
|
-
$AssertInit(value);
|
|
304
|
-
return typeof value == 'boolean';
|
|
305
|
-
};
|
|
306
|
-
export const $IsNumber = (value: VmAny): value is number => {
|
|
307
|
-
$AssertInit(value);
|
|
308
|
-
return typeof value == 'number';
|
|
309
|
-
};
|
|
310
|
-
export const $IsString = (value: VmAny): value is string => {
|
|
311
|
-
$AssertInit(value);
|
|
312
|
-
return typeof value == 'string';
|
|
313
|
-
};
|
|
314
|
-
export const $IsRecord = (value: VmAny): value is VmRecord => {
|
|
315
|
-
$AssertInit(value);
|
|
316
|
-
return isVmRecord(value);
|
|
317
|
-
};
|
|
318
|
-
export const $IsArray = (value: VmAny): value is VmArray => {
|
|
319
|
-
$AssertInit(value);
|
|
320
|
-
return isVmArray(value);
|
|
321
|
-
};
|
|
322
|
-
export const $AssertNonNil = (value: VmAny): asserts value is NonNullable<VmValue> => {
|
|
323
|
-
$AssertInit(value);
|
|
324
|
-
if (value !== null) return;
|
|
325
|
-
throw new VmError(`Expected non-nil value`, null);
|
|
326
|
-
};
|
|
327
|
-
export const $Has = (obj: VmAny, key: VmAny): boolean => {
|
|
328
|
-
$AssertInit(obj);
|
|
329
|
-
const pk = $ToString(key);
|
|
330
|
-
if (obj == null || typeof obj != 'object') return false;
|
|
331
|
-
if (isVmWrapper(obj)) return obj.has(pk);
|
|
332
|
-
return hasOwnEnumerable(obj, pk);
|
|
333
|
-
};
|
|
334
|
-
export const $Get = (obj: VmAny, key: VmAny): VmValue => {
|
|
335
|
-
$AssertInit(obj);
|
|
336
|
-
if (isVmArray(obj)) {
|
|
337
|
-
const index = $ToNumber(key);
|
|
338
|
-
if (isNaN(index)) return null;
|
|
339
|
-
return (at.call(obj, trunc(index)) as VmConst | undefined) ?? null;
|
|
340
|
-
}
|
|
341
|
-
const pk = $ToString(key);
|
|
342
|
-
if (obj == null || typeof obj != 'object') return null;
|
|
343
|
-
if (isVmWrapper(obj)) return obj.get(pk) ?? null;
|
|
344
|
-
if (!hasOwnEnumerable(obj, pk)) return null;
|
|
345
|
-
return (obj as Record<string, VmImmutable>)[pk] ?? null;
|
|
346
|
-
};
|
|
347
|
-
export const $Set = (obj: VmAny, key: VmAny, value: VmAny): void => {
|
|
348
|
-
$AssertInit(obj);
|
|
349
|
-
$AssertInit(value);
|
|
350
|
-
const pk = $ToString(key);
|
|
351
|
-
if (obj == null) return;
|
|
352
|
-
if (!isVmExtern(obj)) throw new VmError(`Expected extern, got ${display(obj)}`, undefined);
|
|
353
|
-
obj.set(pk, value);
|
|
354
|
-
};
|
|
355
|
-
export const $Iterable = (value: VmAny): Iterable<VmValue | undefined> => {
|
|
356
|
-
$AssertInit(value);
|
|
357
|
-
if (isVmWrapper(value)) return value.keys();
|
|
358
|
-
if (isVmArray(value)) return value;
|
|
359
|
-
if (value != null && typeof value == 'object') return keys(value);
|
|
360
|
-
throw new VmError(`Value is not iterable: ${display(value)}`, isVmFunction(value) ? [] : [value]);
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
export const $RecordSpread = (record: VmAny): VmRecord | null => {
|
|
364
|
-
$AssertInit(record);
|
|
365
|
-
if (record == null || isVmRecord(record)) return record;
|
|
366
|
-
if (isVmArray(record)) {
|
|
367
|
-
const result: Record<string, VmConst> = {};
|
|
368
|
-
const len = record.length;
|
|
369
|
-
for (let i = 0; i < len; i++) {
|
|
370
|
-
const item = record[i];
|
|
371
|
-
result[i] = item ?? null;
|
|
372
|
-
}
|
|
373
|
-
return result;
|
|
374
|
-
}
|
|
375
|
-
if (isVmExtern(record)) {
|
|
376
|
-
const result: Record<string, VmConst> = create(null);
|
|
377
|
-
for (const key of record.keys()) {
|
|
378
|
-
const value = record.get(key) ?? null;
|
|
379
|
-
// 当前只有 Primitive 不会进行二次包装
|
|
380
|
-
if (isVmPrimitive(value)) {
|
|
381
|
-
result[key] = value;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
return result;
|
|
385
|
-
}
|
|
386
|
-
throw new VmError(`Expected record, array, extern or nil, got ${display(record)}`, null);
|
|
387
|
-
};
|
|
388
|
-
|
|
389
|
-
export const $ArraySpread = (array: VmAny): Iterable<VmConst | undefined> => {
|
|
390
|
-
$AssertInit(array);
|
|
391
|
-
if (array == null) return [];
|
|
392
|
-
if (isVmArray(array)) return array;
|
|
393
|
-
if (isVmExtern(array) && typeof (array.value as Iterable<unknown>)[Symbol.iterator] == 'function') {
|
|
394
|
-
const result: VmConst[] = [];
|
|
395
|
-
for (const item of array.value as Iterable<unknown>) {
|
|
396
|
-
// 当前只有 Primitive 不会进行二次包装
|
|
397
|
-
if (isVmPrimitive(item)) {
|
|
398
|
-
result.push(item);
|
|
399
|
-
} else {
|
|
400
|
-
result.push(null);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
return result;
|
|
404
|
-
}
|
|
405
|
-
throw new VmError(`Expected array, iterable extern or nil, got ${display(array)}`, []);
|
|
406
|
-
};
|
|
407
|
-
|
|
408
|
-
export const $Format = (value: VmAny, format: VmAny): string => {
|
|
409
|
-
$AssertInit(value);
|
|
410
|
-
const f = format == null ? '' : $ToString(format);
|
|
411
|
-
return toFormat(value, f);
|
|
412
|
-
};
|