@mirascript/mirascript 0.1.15 → 0.1.16
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/{chunk-NT235HY3.js → chunk-LU4ZKFF6.js} +1411 -608
- package/dist/chunk-LU4ZKFF6.js.map +6 -0
- package/dist/chunk-RIT53WVY.js +1 -0
- package/dist/chunk-RLWIIOH5.js +12 -0
- package/dist/chunk-RLWIIOH5.js.map +6 -0
- package/dist/{chunk-JVFUK7AN.js → chunk-YZGL3D7L.js} +739 -1366
- package/dist/chunk-YZGL3D7L.js.map +6 -0
- package/dist/cli/index.js +11 -67
- package/dist/cli/index.js.map +2 -2
- package/dist/compiler/compile-fast.d.ts +1 -1
- package/dist/compiler/compile-fast.d.ts.map +1 -1
- package/dist/compiler/create-script.d.ts +10 -1
- package/dist/compiler/create-script.d.ts.map +1 -1
- package/dist/compiler/diagnostic.d.ts +1 -1
- package/dist/compiler/diagnostic.d.ts.map +1 -1
- package/dist/compiler/emit/constants.d.ts +3 -0
- package/dist/compiler/emit/constants.d.ts.map +1 -0
- package/dist/compiler/emit/consts.d.ts +6 -0
- package/dist/compiler/emit/consts.d.ts.map +1 -0
- package/dist/compiler/emit/globals.d.ts +17 -0
- package/dist/compiler/emit/globals.d.ts.map +1 -0
- package/dist/compiler/emit/index.d.ts +58 -0
- package/dist/compiler/emit/index.d.ts.map +1 -0
- package/dist/compiler/emit/sourcemap.d.ts +6 -0
- package/dist/compiler/emit/sourcemap.d.ts.map +1 -0
- package/dist/compiler/index.d.ts +3 -2
- package/dist/compiler/index.d.ts.map +1 -1
- package/dist/compiler/worker.js +1 -1
- package/dist/helpers/constants.d.ts +10 -0
- package/dist/helpers/constants.d.ts.map +1 -1
- package/dist/helpers/convert.d.ts +12 -0
- package/dist/helpers/convert.d.ts.map +1 -0
- package/dist/{vm → helpers}/error.d.ts +1 -1
- package/dist/helpers/error.d.ts.map +1 -0
- package/dist/helpers/serialize.d.ts +13 -4
- package/dist/helpers/serialize.d.ts.map +1 -1
- package/dist/helpers/types.d.ts +54 -0
- package/dist/helpers/types.d.ts.map +1 -0
- package/dist/index.js +11 -17
- package/dist/subtle.d.ts +3 -2
- package/dist/subtle.d.ts.map +1 -1
- package/dist/subtle.js +21 -15
- package/dist/vm/checkpoint.d.ts +9 -0
- package/dist/vm/checkpoint.d.ts.map +1 -0
- package/dist/vm/helpers.d.ts +4 -10
- package/dist/vm/helpers.d.ts.map +1 -1
- package/dist/vm/index.d.ts +3 -3
- package/dist/vm/index.d.ts.map +1 -1
- package/dist/vm/lib/global/bit.d.ts +7 -7
- package/dist/vm/lib/global/bit.d.ts.map +1 -1
- package/dist/vm/lib/global/debug.d.ts +2 -2
- package/dist/vm/lib/global/debug.d.ts.map +1 -1
- package/dist/vm/lib/global/index.d.ts +0 -1
- package/dist/vm/lib/global/index.d.ts.map +1 -1
- package/dist/vm/lib/global/json.d.ts +2 -2
- package/dist/vm/lib/global/json.d.ts.map +1 -1
- package/dist/vm/lib/global/math-additional.d.ts +1 -1
- package/dist/vm/lib/global/math-additional.d.ts.map +1 -1
- package/dist/vm/lib/global/math-arr.d.ts +5 -5
- package/dist/vm/lib/global/math-arr.d.ts.map +1 -1
- package/dist/vm/lib/global/math-unary.d.ts +26 -26
- package/dist/vm/lib/global/math-unary.d.ts.map +1 -1
- package/dist/vm/lib/global/math.d.ts +3 -3
- package/dist/vm/lib/global/math.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/all-any.d.ts +2 -2
- package/dist/vm/lib/global/sequence/all-any.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/entries.d.ts +5 -5
- package/dist/vm/lib/global/sequence/entries.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/find.d.ts +3 -3
- package/dist/vm/lib/global/sequence/find.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/flatten.d.ts +1 -1
- package/dist/vm/lib/global/sequence/flatten.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/len.d.ts +1 -1
- package/dist/vm/lib/global/sequence/len.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/map-filter.d.ts +3 -3
- package/dist/vm/lib/global/sequence/map-filter.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/repeat.d.ts +1 -1
- package/dist/vm/lib/global/sequence/repeat.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/reverse.d.ts +1 -1
- package/dist/vm/lib/global/sequence/reverse.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/sort.d.ts +2 -2
- package/dist/vm/lib/global/sequence/sort.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/with.d.ts +2 -2
- package/dist/vm/lib/global/sequence/with.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/zip.d.ts +1 -1
- package/dist/vm/lib/global/sequence/zip.d.ts.map +1 -1
- package/dist/vm/lib/global/string.d.ts +10 -10
- package/dist/vm/lib/global/string.d.ts.map +1 -1
- package/dist/vm/lib/global/time.d.ts +3 -13
- package/dist/vm/lib/global/time.d.ts.map +1 -1
- package/dist/vm/lib/global/to-primitive.d.ts +4 -4
- package/dist/vm/lib/global/to-primitive.d.ts.map +1 -1
- package/dist/vm/lib/helpers.d.ts +53 -0
- package/dist/vm/lib/helpers.d.ts.map +1 -0
- package/dist/vm/lib/index.d.ts +4 -0
- package/dist/vm/lib/index.d.ts.map +1 -0
- package/dist/vm/lib/{_loader.d.ts → loader.d.ts} +5 -5
- package/dist/vm/lib/loader.d.ts.map +1 -0
- package/dist/vm/lib/mod/index.d.ts +2 -0
- package/dist/vm/lib/mod/index.d.ts.map +1 -0
- package/dist/vm/lib/mod/matrix.d.ts +15 -0
- package/dist/vm/lib/mod/matrix.d.ts.map +1 -0
- package/dist/vm/operations.d.ts +2 -4
- package/dist/vm/operations.d.ts.map +1 -1
- package/dist/vm/types/boundary.d.ts +1 -1
- package/dist/vm/types/boundary.d.ts.map +1 -1
- package/dist/vm/types/context.d.ts +10 -9
- package/dist/vm/types/context.d.ts.map +1 -1
- package/dist/vm/types/extern.d.ts +1 -3
- package/dist/vm/types/extern.d.ts.map +1 -1
- package/dist/vm/types/function.d.ts +1 -6
- package/dist/vm/types/function.d.ts.map +1 -1
- package/dist/vm/types/index.d.ts +31 -17
- package/dist/vm/types/index.d.ts.map +1 -1
- package/dist/vm/types/module.d.ts +2 -4
- package/dist/vm/types/module.d.ts.map +1 -1
- package/dist/vm/types/wrapper.d.ts +0 -2
- package/dist/vm/types/wrapper.d.ts.map +1 -1
- package/package.json +7 -3
- package/src/cli/index.ts +1 -1
- package/src/compiler/compile-fast.ts +1 -2
- package/src/compiler/create-script.ts +12 -2
- package/src/compiler/diagnostic.ts +17 -8
- package/src/compiler/emit/constants.ts +2 -0
- package/src/compiler/emit/consts.ts +47 -0
- package/src/compiler/emit/globals.ts +39 -0
- package/src/compiler/{emit.ts → emit/index.ts} +16 -200
- package/src/compiler/emit/sourcemap.ts +163 -0
- package/src/compiler/index.ts +9 -9
- package/src/compiler/worker.ts +1 -1
- package/src/helpers/constants.ts +12 -0
- package/src/helpers/convert.ts +128 -0
- package/src/{vm → helpers}/error.ts +1 -1
- package/src/helpers/serialize.ts +71 -24
- package/src/helpers/types.ts +267 -0
- package/src/subtle.ts +3 -1
- package/src/vm/checkpoint.ts +42 -0
- package/src/vm/helpers.ts +9 -53
- package/src/vm/index.ts +3 -3
- package/src/vm/lib/global/bit.ts +8 -9
- package/src/vm/lib/global/debug.ts +5 -4
- package/src/vm/lib/global/index.ts +0 -1
- package/src/vm/lib/global/json.ts +2 -2
- package/src/vm/lib/global/math-additional.ts +2 -4
- package/src/vm/lib/global/math-arr.ts +1 -1
- package/src/vm/lib/global/math-unary.ts +2 -4
- package/src/vm/lib/global/math.ts +3 -4
- package/src/vm/lib/global/sequence/all-any.ts +11 -6
- package/src/vm/lib/global/sequence/entries.ts +1 -1
- package/src/vm/lib/global/sequence/find.ts +4 -3
- package/src/vm/lib/global/sequence/flatten.ts +2 -3
- package/src/vm/lib/global/sequence/len.ts +1 -1
- package/src/vm/lib/global/sequence/map-filter.ts +4 -3
- package/src/vm/lib/global/sequence/repeat.ts +2 -4
- package/src/vm/lib/global/sequence/reverse.ts +1 -1
- package/src/vm/lib/global/sequence/sort.ts +6 -5
- package/src/vm/lib/global/sequence/with.ts +21 -20
- package/src/vm/lib/global/sequence/zip.ts +3 -3
- package/src/vm/lib/global/string.ts +16 -27
- package/src/vm/lib/global/time.ts +59 -30
- package/src/vm/lib/global/to-primitive.ts +27 -18
- package/src/vm/lib/{_helpers.ts → helpers.ts} +129 -41
- package/src/vm/lib/index.ts +16 -0
- package/src/vm/lib/{_loader.ts → loader.ts} +3 -11
- package/src/vm/lib/mod/index.ts +1 -0
- package/src/vm/lib/{global/mod → mod}/matrix.ts +9 -7
- package/src/vm/operations.ts +31 -126
- package/src/vm/types/boundary.ts +10 -13
- package/src/vm/types/context.ts +17 -24
- package/src/vm/types/extern.ts +8 -15
- package/src/vm/types/function.ts +4 -19
- package/src/vm/types/index.ts +47 -25
- package/src/vm/types/module.ts +3 -7
- package/src/vm/types/wrapper.ts +1 -5
- package/dist/chunk-35JGBXRE.js +0 -1
- package/dist/chunk-JVFUK7AN.js.map +0 -6
- package/dist/chunk-NT235HY3.js.map +0 -6
- package/dist/compiler/emit.d.ts +0 -5
- package/dist/compiler/emit.d.ts.map +0 -1
- package/dist/vm/error.d.ts.map +0 -1
- package/dist/vm/lib/_helpers.d.ts +0 -35
- package/dist/vm/lib/_helpers.d.ts.map +0 -1
- package/dist/vm/lib/_loader.d.ts.map +0 -1
- package/dist/vm/lib/global/mod/index.d.ts +0 -3
- package/dist/vm/lib/global/mod/index.d.ts.map +0 -1
- package/dist/vm/lib/global/mod/matrix.d.ts +0 -15
- package/dist/vm/lib/global/mod/matrix.d.ts.map +0 -1
- package/dist/vm/types/any.d.ts +0 -10
- package/dist/vm/types/any.d.ts.map +0 -1
- package/dist/vm/types/array.d.ts +0 -12
- package/dist/vm/types/array.d.ts.map +0 -1
- package/dist/vm/types/callable.d.ts +0 -5
- package/dist/vm/types/callable.d.ts.map +0 -1
- package/dist/vm/types/const.d.ts +0 -15
- package/dist/vm/types/const.d.ts.map +0 -1
- package/dist/vm/types/immutable.d.ts +0 -15
- package/dist/vm/types/immutable.d.ts.map +0 -1
- package/dist/vm/types/primitive.d.ts +0 -7
- package/dist/vm/types/primitive.d.ts.map +0 -1
- package/dist/vm/types/record.d.ts +0 -20
- package/dist/vm/types/record.d.ts.map +0 -1
- package/dist/vm/types/script.d.ts +0 -14
- package/dist/vm/types/script.d.ts.map +0 -1
- package/dist/vm/types/value.d.ts +0 -14
- package/dist/vm/types/value.d.ts.map +0 -1
- package/src/vm/lib/global/mod/index.ts +0 -4
- package/src/vm/types/any.ts +0 -33
- package/src/vm/types/array.ts +0 -19
- package/src/vm/types/callable.ts +0 -10
- package/src/vm/types/const.ts +0 -109
- package/src/vm/types/immutable.ts +0 -22
- package/src/vm/types/primitive.ts +0 -14
- package/src/vm/types/record.ts +0 -53
- package/src/vm/types/script.ts +0 -18
- package/src/vm/types/value.ts +0 -22
- /package/dist/{chunk-35JGBXRE.js.map → chunk-RIT53WVY.js.map} +0 -0
package/src/vm/operations.ts
CHANGED
|
@@ -1,28 +1,12 @@
|
|
|
1
|
-
import { VmError } from '
|
|
2
|
-
import {
|
|
3
|
-
isVmPrimitive,
|
|
4
|
-
isVmArray,
|
|
5
|
-
isVmRecord,
|
|
6
|
-
isVmFunction,
|
|
7
|
-
isVmExtern,
|
|
8
|
-
isVmModule,
|
|
9
|
-
isVmWrapper,
|
|
10
|
-
getVmFunctionInfo,
|
|
11
|
-
type TypeName,
|
|
12
|
-
type VmAny,
|
|
13
|
-
type VmImmutable,
|
|
14
|
-
type VmRecord,
|
|
15
|
-
type VmValue,
|
|
16
|
-
type VmArray,
|
|
17
|
-
type VmConst,
|
|
18
|
-
type VmPrimitive,
|
|
19
|
-
type VmFunction,
|
|
20
|
-
} from './types/index.js';
|
|
1
|
+
import { VmError } from '../helpers/error.js';
|
|
21
2
|
import { hasOwnEnumerable, isNaN, isSafeInteger, keys, create } from '../helpers/utils.js';
|
|
3
|
+
import { toNumber, toString, toBoolean, toFormat } from '../helpers/convert.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';
|
|
22
7
|
|
|
23
8
|
const { abs, min, trunc, ceil } = Math;
|
|
24
9
|
const { slice, at } = Array.prototype;
|
|
25
|
-
const { POSITIVE_INFINITY, NEGATIVE_INFINITY } = Number;
|
|
26
10
|
|
|
27
11
|
const isSame = (a: VmValue, b: VmValue): boolean => {
|
|
28
12
|
// Check for NaN
|
|
@@ -60,7 +44,10 @@ const isSame = (a: VmValue, b: VmValue): boolean => {
|
|
|
60
44
|
if (!hasOwnEnumerable(b, key)) {
|
|
61
45
|
return false;
|
|
62
46
|
}
|
|
63
|
-
|
|
47
|
+
/* c8 ignore next 2 */
|
|
48
|
+
const av = a[key] ?? null;
|
|
49
|
+
const bv = b[key] ?? null;
|
|
50
|
+
if (!isSame(av, bv)) {
|
|
64
51
|
return false;
|
|
65
52
|
}
|
|
66
53
|
}
|
|
@@ -180,28 +167,25 @@ export const $In = (value: VmAny, iterable: VmAny): boolean => {
|
|
|
180
167
|
$AssertInit(value);
|
|
181
168
|
$AssertInit(iterable);
|
|
182
169
|
if (iterable == null) return false;
|
|
170
|
+
if (typeof iterable != 'object') return false;
|
|
183
171
|
if (isVmArray(iterable)) {
|
|
184
172
|
if (value == null) {
|
|
185
173
|
// array may have empty slots
|
|
186
|
-
for (const item of iterable)
|
|
187
|
-
if (item == null) return true;
|
|
188
|
-
}
|
|
174
|
+
for (const item of iterable) if (item == null) return true;
|
|
189
175
|
return false;
|
|
190
176
|
}
|
|
191
177
|
// JS %SameValueZero is same with `isSame` in this context
|
|
192
178
|
if (isVmPrimitive(value)) return iterable.includes(value);
|
|
193
179
|
// value is not null here, so it's ok to skip empty slots, since `isSame(null, something)` is always false
|
|
194
|
-
value satisfies NonNullable<VmValue
|
|
195
|
-
return iterable.some((item = null) => isSame(item, value));
|
|
180
|
+
return iterable.some((item = null) => isSame(item, value satisfies NonNullable<VmValue>));
|
|
196
181
|
}
|
|
197
182
|
// iterable is a record or an extern here, value should be a string
|
|
198
|
-
|
|
199
|
-
if (
|
|
200
|
-
iterable satisfies
|
|
201
|
-
return false;
|
|
183
|
+
const key = toString(value, undefined);
|
|
184
|
+
if (isVmWrapper(iterable)) return iterable.has(key);
|
|
185
|
+
return hasOwnEnumerable(iterable satisfies VmRecord, key);
|
|
202
186
|
};
|
|
203
|
-
export const $Concat = (...args: string[]): string => {
|
|
204
|
-
return args.map(
|
|
187
|
+
export const $Concat = (...args: readonly string[]): string => {
|
|
188
|
+
return args.map((a) => toFormat(a, null)).join('');
|
|
205
189
|
};
|
|
206
190
|
export const $Pos = (a: VmAny): number => {
|
|
207
191
|
return $ToNumber(a);
|
|
@@ -229,6 +213,7 @@ export const $Omit = (value: VmAny, omitted: ReadonlyArray<number | string>): Vm
|
|
|
229
213
|
const omittedSet = new Set(omitted.map($ToString));
|
|
230
214
|
for (const key of valueKeys) {
|
|
231
215
|
if (!omittedSet.has(key)) {
|
|
216
|
+
/* c8 ignore next */
|
|
232
217
|
result[key] = value[key] ?? null;
|
|
233
218
|
}
|
|
234
219
|
}
|
|
@@ -290,82 +275,30 @@ export const $Call = (func: VmValue, args: readonly VmAny[]): VmValue => {
|
|
|
290
275
|
if (isVmFunction(func)) {
|
|
291
276
|
return func(...(args as readonly VmValue[])) ?? null;
|
|
292
277
|
}
|
|
293
|
-
throw new VmError(`
|
|
278
|
+
throw new VmError(`Value is not callable: ${display(func)}`, null);
|
|
294
279
|
};
|
|
295
280
|
export const $Type = (value: VmAny): TypeName => {
|
|
296
|
-
|
|
297
|
-
if (
|
|
298
|
-
if (
|
|
281
|
+
// 允许未初始化值通过
|
|
282
|
+
if (value == null) return 'nil';
|
|
283
|
+
if (isVmWrapper(value)) return value.type;
|
|
299
284
|
if (isVmArray(value)) return 'array';
|
|
300
285
|
if (typeof value == 'object') return 'record';
|
|
301
286
|
return typeof value as TypeName;
|
|
302
287
|
};
|
|
303
288
|
export const $ToBoolean = (value: VmAny): boolean => {
|
|
289
|
+
if (typeof value == 'boolean') return value;
|
|
304
290
|
$AssertInit(value);
|
|
305
|
-
return value
|
|
306
|
-
};
|
|
307
|
-
/** 将值转为字符串 */
|
|
308
|
-
function numberToString(value: number): string {
|
|
309
|
-
if (isNaN(value)) return 'nan';
|
|
310
|
-
if (value === Infinity) return 'inf';
|
|
311
|
-
if (value === -Infinity) return '-inf';
|
|
312
|
-
return String(value);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/** 将值转为字符串 */
|
|
316
|
-
export function $InnerToString(value: VmAny, useBraces: boolean): string {
|
|
317
|
-
if (value == null) return 'nil';
|
|
318
|
-
if (isVmWrapper(value)) return value.toString(useBraces);
|
|
319
|
-
if (typeof value == 'function') {
|
|
320
|
-
const name = getVmFunctionInfo(value)?.fullName;
|
|
321
|
-
return name ? `<function ${name}>` : `<function>`;
|
|
322
|
-
}
|
|
323
|
-
if (isVmArray(value)) {
|
|
324
|
-
const strings: string[] = [];
|
|
325
|
-
for (const item of value) {
|
|
326
|
-
strings.push($InnerToString(item, true));
|
|
327
|
-
}
|
|
328
|
-
// 在 join 过程中会自动把 null/undefined 和 empty slot 转为 ''
|
|
329
|
-
// 与 innerToString 行为不一致
|
|
330
|
-
const results = strings.join(', ');
|
|
331
|
-
if (!useBraces) return results;
|
|
332
|
-
return `[${results}]`;
|
|
333
|
-
}
|
|
334
|
-
if (typeof value == 'object') {
|
|
335
|
-
const entries = keys(value)
|
|
336
|
-
.map((key) => `${key}: ${$InnerToString(value[key], true)}`)
|
|
337
|
-
.join(', ');
|
|
338
|
-
if (!useBraces) return entries;
|
|
339
|
-
return `(${entries})`;
|
|
340
|
-
}
|
|
341
|
-
if (typeof value == 'number') {
|
|
342
|
-
return numberToString(value);
|
|
343
|
-
}
|
|
344
|
-
return String(value);
|
|
345
|
-
}
|
|
291
|
+
return toBoolean(value, undefined);
|
|
292
|
+
};
|
|
346
293
|
export const $ToString = (value: VmAny): string => {
|
|
347
|
-
$AssertInit(value);
|
|
348
294
|
if (typeof value == 'string') return value;
|
|
349
|
-
|
|
350
|
-
return
|
|
295
|
+
$AssertInit(value);
|
|
296
|
+
return toString(value, undefined);
|
|
351
297
|
};
|
|
352
298
|
export const $ToNumber = (value: VmAny): number => {
|
|
353
|
-
$AssertInit(value);
|
|
354
299
|
if (typeof value == 'number') return value;
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
value = value.trim();
|
|
358
|
-
if (value === '') return 0;
|
|
359
|
-
if (value === 'inf' || value === '+inf' || value === 'Infinity' || value === '+Infinity') {
|
|
360
|
-
return POSITIVE_INFINITY;
|
|
361
|
-
}
|
|
362
|
-
if (value === '-inf' || value === '-Infinity') {
|
|
363
|
-
return NEGATIVE_INFINITY;
|
|
364
|
-
}
|
|
365
|
-
return Number(value);
|
|
366
|
-
}
|
|
367
|
-
if (typeof value == 'boolean') return value ? 1 : 0;
|
|
368
|
-
return Number.NaN;
|
|
300
|
+
$AssertInit(value);
|
|
301
|
+
return toNumber(value, undefined);
|
|
369
302
|
};
|
|
370
303
|
export const $IsBoolean = (value: VmAny): value is boolean => {
|
|
371
304
|
$AssertInit(value);
|
|
@@ -473,36 +406,8 @@ export const $ArraySpread = (array: VmAny): Iterable<VmConst | undefined> => {
|
|
|
473
406
|
throw new VmError(`Expected array, iterable extern or nil, got ${$Type(array)}`, []);
|
|
474
407
|
};
|
|
475
408
|
|
|
476
|
-
/** 渲染数字 */
|
|
477
|
-
function formatNumber(value: number): string {
|
|
478
|
-
if (!Number.isFinite(value)) return numberToString(value);
|
|
479
|
-
if (value === 0) return '0';
|
|
480
|
-
const s = value.toString();
|
|
481
|
-
let ps;
|
|
482
|
-
const abs = Math.abs(value);
|
|
483
|
-
if (abs >= 1000 || abs < 0.001) {
|
|
484
|
-
const ps1 = value.toExponential();
|
|
485
|
-
const ps2 = value.toExponential(5);
|
|
486
|
-
ps = ps1.length < ps2.length ? ps1 : ps2;
|
|
487
|
-
} else {
|
|
488
|
-
ps = value.toPrecision(6);
|
|
489
|
-
}
|
|
490
|
-
return ps.length < s.length ? ps : s;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
409
|
export const $Format = (value: VmAny, format: VmAny): string => {
|
|
494
410
|
$AssertInit(value);
|
|
495
|
-
const f = format == null ? '' :
|
|
496
|
-
|
|
497
|
-
if (typeof value == 'number') {
|
|
498
|
-
if (/^\.\d+$/.test(f)) {
|
|
499
|
-
let digits = Math.trunc(Number(f.slice(1)));
|
|
500
|
-
if (!(digits <= 100)) digits = 100;
|
|
501
|
-
return value.toFixed(digits);
|
|
502
|
-
} else {
|
|
503
|
-
return formatNumber(value);
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
return $ToString(value);
|
|
411
|
+
const f = format == null ? '' : $ToString(format);
|
|
412
|
+
return toFormat(value, f);
|
|
508
413
|
};
|
package/src/vm/types/boundary.ts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isVmExtern,
|
|
3
|
-
import {
|
|
1
|
+
import { defineProperty, apply } from '../../helpers/utils.js';
|
|
2
|
+
import { isVmExtern, isVmFunction, isVmWrapper } from '../../helpers/types.js';
|
|
3
|
+
import { kVmFunctionProxy } from '../../helpers/constants.js';
|
|
4
|
+
import type { VmFunctionLike, VmFunction } from './function.js';
|
|
5
|
+
import { VmExtern } from './extern.js';
|
|
4
6
|
import type { VmAny, VmConst, VmModule, VmPrimitive, VmValue } from './index.js';
|
|
5
7
|
import { $Call } from '../operations.js';
|
|
6
|
-
import { defineProperty, apply } from '../../helpers/utils.js';
|
|
7
|
-
|
|
8
|
-
const kProxy = Symbol.for('mirascript.vm.function.proxy');
|
|
9
8
|
|
|
10
9
|
/** 创建 Mirascript 函数在宿主语言运行的代理 */
|
|
11
10
|
export function toVmFunctionProxy<T extends VmFunctionLike>(fn: VmFunction<T>): T {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const cached = (fn as unknown as { [kProxy]?: T })[kProxy];
|
|
11
|
+
const cached = (fn as unknown as { [kVmFunctionProxy]?: T })[kVmFunctionProxy];
|
|
15
12
|
if (cached != null) return cached;
|
|
16
13
|
|
|
17
14
|
const proxy = (...args: unknown[]) => {
|
|
@@ -22,8 +19,8 @@ export function toVmFunctionProxy<T extends VmFunctionLike>(fn: VmFunction<T>):
|
|
|
22
19
|
);
|
|
23
20
|
return unwrapFromVmValue(ret);
|
|
24
21
|
};
|
|
25
|
-
defineProperty(fn,
|
|
26
|
-
defineProperty(proxy,
|
|
22
|
+
defineProperty(fn, kVmFunctionProxy, { value: proxy });
|
|
23
|
+
defineProperty(proxy, kVmFunctionProxy, { value: fn });
|
|
27
24
|
defineProperty(proxy, 'name', {
|
|
28
25
|
value: fn.name,
|
|
29
26
|
configurable: true,
|
|
@@ -35,7 +32,7 @@ export function toVmFunctionProxy<T extends VmFunctionLike>(fn: VmFunction<T>):
|
|
|
35
32
|
export function fromVmFunctionProxy<T extends VmFunctionLike>(fn: T): VmFunction<T> | undefined {
|
|
36
33
|
if (isVmFunction(fn)) return fn;
|
|
37
34
|
|
|
38
|
-
const original = (fn as unknown as { [
|
|
35
|
+
const original = (fn as unknown as { [kVmFunctionProxy]?: VmFunction<T> })[kVmFunctionProxy];
|
|
39
36
|
if (original && isVmFunction(original)) return original;
|
|
40
37
|
|
|
41
38
|
return undefined;
|
|
@@ -76,7 +73,7 @@ export function wrapToVmValue(
|
|
|
76
73
|
|
|
77
74
|
/** 取消宿主语言的值的 Mirascript 包装 */
|
|
78
75
|
export function unwrapFromVmValue(value: VmAny): unknown {
|
|
79
|
-
if (
|
|
76
|
+
if (isVmFunction(value)) {
|
|
80
77
|
return toVmFunctionProxy(value);
|
|
81
78
|
}
|
|
82
79
|
if (value == null || typeof value != 'object') return value;
|
package/src/vm/types/context.ts
CHANGED
|
@@ -1,27 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
VmFunction,
|
|
3
|
-
type VmAny,
|
|
4
|
-
type VmImmutable,
|
|
5
|
-
type VmValue,
|
|
6
|
-
wrapToVmValue,
|
|
7
|
-
isVmAny,
|
|
8
|
-
type VmFunctionLike,
|
|
9
|
-
} from './index.js';
|
|
10
1
|
import { create, entries, keys } from '../../helpers/utils.js';
|
|
11
|
-
import
|
|
12
|
-
import { VmError } from '
|
|
2
|
+
import { isVmAny } from '../../helpers/types.js';
|
|
3
|
+
import { VmError } from '../../helpers/error.js';
|
|
4
|
+
import { kVmContext } from '../../helpers/constants.js';
|
|
5
|
+
import type { lib } from '../lib/index.js';
|
|
6
|
+
import type { VmAny, VmImmutable, VmValue, VmFunctionLike, VmModule } from './index.js';
|
|
7
|
+
import { wrapToVmValue } from './boundary.js';
|
|
8
|
+
import { VmFunction } from './function.js';
|
|
13
9
|
|
|
14
|
-
/** 全局导入的标准库 */
|
|
15
|
-
type GlobalKeys = keyof typeof global;
|
|
16
10
|
/** 全局导入的标准库值 */
|
|
17
|
-
type
|
|
18
|
-
? VmFunction<
|
|
19
|
-
:
|
|
11
|
+
type ToLibValue<V> = V extends VmFunctionLike
|
|
12
|
+
? VmFunction<V>
|
|
13
|
+
: V extends Record<string, VmImmutable | VmFunctionLike>
|
|
14
|
+
? ToLibModule<V>
|
|
15
|
+
: V;
|
|
16
|
+
/** 全局导入的标准库值 */
|
|
17
|
+
type ToLibModule<V extends Record<string, VmImmutable | VmFunctionLike>> = VmModule<{
|
|
18
|
+
[key in keyof V]: ToLibValue<V[key]>;
|
|
19
|
+
}>;
|
|
20
20
|
/** 全局导入的标准库 */
|
|
21
21
|
type VmContextBase = {
|
|
22
|
-
[key in
|
|
22
|
+
[key in keyof typeof lib]: ToLibValue<(typeof lib)[key]>;
|
|
23
23
|
};
|
|
24
|
-
const kVmContext = Symbol.for('mirascript.vm.context');
|
|
25
24
|
/** MiraScript 执行上下文的基础,仅包含标准库 */
|
|
26
25
|
export type VmSharedContext = VmContextBase & Record<string, VmImmutable>;
|
|
27
26
|
/** MiraScript 执行上下文 */
|
|
@@ -184,9 +183,3 @@ export function createVmContext(...args: CreateVmContextWithValues | CreateVmCon
|
|
|
184
183
|
}
|
|
185
184
|
return new ValueVmContext(env, describer ?? undefined);
|
|
186
185
|
}
|
|
187
|
-
|
|
188
|
-
/** 检查是否为执行上下文 */
|
|
189
|
-
export function isVmContext(context: unknown): context is VmContext {
|
|
190
|
-
if (context == null || typeof context != 'object') return false;
|
|
191
|
-
return (context as VmContext)[kVmContext] === true;
|
|
192
|
-
}
|
package/src/vm/types/extern.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { VmError } from '
|
|
2
|
-
import { VmWrapper } from './wrapper.js';
|
|
3
|
-
import type { TypeName, VmAny, VmConst, VmPrimitive, VmValue } from './index.js';
|
|
1
|
+
import { VmError } from '../../helpers/error.js';
|
|
4
2
|
import { getPrototypeOf, hasOwn, apply, isArray } from '../../helpers/utils.js';
|
|
3
|
+
import { innerToString } from '../../helpers/convert.js';
|
|
4
|
+
import { isVmExtern } from '../../helpers/types.js';
|
|
5
|
+
import { kVmExtern } from '../../helpers/constants.js';
|
|
6
|
+
import type { TypeName, VmAny, VmConst, VmPrimitive, VmValue } from './index.js';
|
|
7
|
+
import { VmWrapper } from './wrapper.js';
|
|
5
8
|
import { unwrapFromVmValue, wrapToVmValue } from './boundary.js';
|
|
6
|
-
import { $InnerToString } from '../operations.js';
|
|
7
9
|
|
|
8
10
|
const ObjectPrototype = Object.prototype;
|
|
9
11
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
@@ -100,17 +102,13 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
|
|
|
100
102
|
if (toString === ArrayToString && isArray(this.value)) {
|
|
101
103
|
const mapped = ArrayMap.call(this.value, (item: unknown) => {
|
|
102
104
|
if (item === undefined) return '';
|
|
103
|
-
return
|
|
105
|
+
return innerToString(wrapToVmValue(item ?? null, null), true);
|
|
104
106
|
});
|
|
105
107
|
const str = mapped.join(', ');
|
|
106
108
|
if (useBraces) return `[${str}]`;
|
|
107
109
|
return str;
|
|
108
110
|
}
|
|
109
|
-
|
|
110
|
-
return String(this.value);
|
|
111
|
-
} catch {
|
|
112
|
-
return super.toString(useBraces);
|
|
113
|
-
}
|
|
111
|
+
return String(this.value);
|
|
114
112
|
}
|
|
115
113
|
/** @inheritdoc */
|
|
116
114
|
override get type(): TypeName {
|
|
@@ -157,9 +155,4 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
|
|
|
157
155
|
}
|
|
158
156
|
}
|
|
159
157
|
|
|
160
|
-
const kVmExtern = Symbol.for('mirascript.vm.extern');
|
|
161
158
|
Object.defineProperty(VmExtern.prototype, kVmExtern, { value: true });
|
|
162
|
-
/** 检查值是否为 Mirascript 外部值 */
|
|
163
|
-
export function isVmExtern<T extends object>(value: unknown): value is VmExtern<T> {
|
|
164
|
-
return value != null && typeof value == 'object' && kVmExtern in value;
|
|
165
|
-
}
|
package/src/vm/types/function.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { Writable } from 'type-fest';
|
|
2
2
|
import { defineProperty } from '../../helpers/utils.js';
|
|
3
|
-
import {
|
|
3
|
+
import { kVmFunction, VM_FUNCTION_ANONYMOUS_NAME } from '../../helpers/constants.js';
|
|
4
4
|
import type { VmAny, VmValue } from './index.js';
|
|
5
5
|
import { fromVmFunctionProxy } from './boundary.js';
|
|
6
|
-
|
|
7
|
-
const kVmFunction = Symbol.for('mirascript.vm.function');
|
|
6
|
+
import { CpEnter, CpExit } from '../checkpoint.js';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Mirascript 函数签名
|
|
@@ -46,17 +45,6 @@ export type VmFunctionOption = Partial<
|
|
|
46
45
|
}
|
|
47
46
|
>;
|
|
48
47
|
|
|
49
|
-
/** 检查是否为 Mirascript 函数 */
|
|
50
|
-
export function isVmFunction<T extends VmFunctionLike>(value: unknown): value is VmFunction<T> {
|
|
51
|
-
return getVmFunctionInfo(value) != null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/** 检查是否为 Mirascript 函数,并获取其信息 */
|
|
55
|
-
export function getVmFunctionInfo(value: unknown): VmFunctionInfo | undefined {
|
|
56
|
-
if (typeof value != 'function') return undefined;
|
|
57
|
-
return (value as VmFunction)[kVmFunction];
|
|
58
|
-
}
|
|
59
|
-
|
|
60
48
|
/** 创建 Mirascript 函数 */
|
|
61
49
|
export function VmFunction<T extends VmFunctionLike>(fn: T, option: VmFunctionOption = {}): VmFunction<T> {
|
|
62
50
|
if (typeof fn != 'function') {
|
|
@@ -68,7 +56,7 @@ export function VmFunction<T extends VmFunctionLike>(fn: T, option: VmFunctionOp
|
|
|
68
56
|
if (exists) return exists;
|
|
69
57
|
|
|
70
58
|
const info: Writable<VmFunctionInfo> = {
|
|
71
|
-
fullName: option.fullName ?? fn.name,
|
|
59
|
+
fullName: option.fullName ?? (fn.name === VM_FUNCTION_ANONYMOUS_NAME ? '' : fn.name),
|
|
72
60
|
isLib: option.isLib ?? false,
|
|
73
61
|
summary: option.summary || undefined,
|
|
74
62
|
params: option.params,
|
|
@@ -89,10 +77,7 @@ export function VmFunction<T extends VmFunctionLike>(fn: T, option: VmFunctionOp
|
|
|
89
77
|
CpExit();
|
|
90
78
|
}
|
|
91
79
|
}) as typeof fn;
|
|
92
|
-
defineProperty(fn, 'name', {
|
|
93
|
-
value: original.name,
|
|
94
|
-
configurable: true,
|
|
95
|
-
});
|
|
80
|
+
defineProperty(fn, 'name', { value: original.name });
|
|
96
81
|
}
|
|
97
82
|
defineProperty(fn, kVmFunction, {
|
|
98
83
|
value: Object.freeze(info),
|
package/src/vm/types/index.ts
CHANGED
|
@@ -1,12 +1,36 @@
|
|
|
1
|
-
import type { VmArray } from './array.js';
|
|
2
1
|
import type { VmExtern } from './extern.js';
|
|
3
2
|
import type { VmFunction } from './function.js';
|
|
4
3
|
import type { VmModule } from './module.js';
|
|
5
|
-
import type { VmRecord } from './record.js';
|
|
6
4
|
|
|
7
5
|
/** 类型名称 */
|
|
8
6
|
export type TypeName = keyof VmValueMap;
|
|
9
7
|
|
|
8
|
+
/** Mirascript 虚拟机内的未初始化变量 */
|
|
9
|
+
export type VmUninitialized = undefined;
|
|
10
|
+
/** Mirascript 原始值 */
|
|
11
|
+
export type VmPrimitive = null | number | string | boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Mirascript 数组
|
|
14
|
+
* 数组中的 `undefined`、`null` 及 <empty slot> 均视作 `nil`
|
|
15
|
+
*/
|
|
16
|
+
export type VmArray = ReadonlyArray<VmConst | undefined>;
|
|
17
|
+
/**
|
|
18
|
+
* Mirascript 记录
|
|
19
|
+
* 仅拥有且可枚举的字符串键视作存在
|
|
20
|
+
* 字段值 `undefined` 和 `null` 均视作 `nil`
|
|
21
|
+
*/
|
|
22
|
+
export type VmRecord = {
|
|
23
|
+
readonly [key: string]: VmConst | undefined;
|
|
24
|
+
};
|
|
25
|
+
/** Mirascript 虚拟机内的值语义值 */
|
|
26
|
+
export type VmConst = VmPrimitive | VmRecord | VmArray;
|
|
27
|
+
/** Mirascript 虚拟机内的不可变值 */
|
|
28
|
+
export type VmImmutable = VmConst | VmFunction | VmModule;
|
|
29
|
+
/** Mirascript 虚拟机内的合法值 */
|
|
30
|
+
export type VmValue = VmImmutable | VmExtern;
|
|
31
|
+
/** Mirascript 虚拟机内的值(包括未初始化变量) */
|
|
32
|
+
export type VmAny = VmValue | VmUninitialized;
|
|
33
|
+
|
|
10
34
|
/** 类型名称映射 */
|
|
11
35
|
export interface VmValueMap {
|
|
12
36
|
/** 空值 */
|
|
@@ -29,32 +53,30 @@ export interface VmValueMap {
|
|
|
29
53
|
module: VmModule;
|
|
30
54
|
}
|
|
31
55
|
|
|
32
|
-
export { wrapToVmValue, unwrapFromVmValue, toVmFunctionProxy, fromVmFunctionProxy } from './boundary.js';
|
|
33
|
-
export { type VmContext, type VmSharedContext, isVmContext, defineVmContextValue, createVmContext } from './context.js';
|
|
34
|
-
export { type VmScript, isVmScript } from './script.js';
|
|
35
|
-
export { isVmCallable } from './callable.js';
|
|
36
|
-
|
|
37
|
-
export { type VmArray, VM_ARRAY_MAX_LENGTH, isVmArray } from './array.js';
|
|
38
56
|
export {
|
|
39
|
-
|
|
40
|
-
|
|
57
|
+
isVmAny,
|
|
58
|
+
isVmArray,
|
|
41
59
|
isVmArrayLikeRecord,
|
|
42
60
|
isVmArrayLikeRecordByEntires,
|
|
43
61
|
isVmArrayLikeRecordByKeys,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
export { VmExtern, isVmExtern } from './extern.js';
|
|
49
|
-
export {
|
|
50
|
-
VmFunction,
|
|
62
|
+
isVmCallable,
|
|
63
|
+
isVmConst,
|
|
64
|
+
isVmContext,
|
|
65
|
+
isVmExtern,
|
|
51
66
|
isVmFunction,
|
|
67
|
+
isVmImmutable,
|
|
68
|
+
isVmModule,
|
|
69
|
+
isVmPrimitive,
|
|
70
|
+
isVmRecord,
|
|
71
|
+
isVmScript,
|
|
72
|
+
isVmValue,
|
|
73
|
+
isVmWrapper,
|
|
52
74
|
getVmFunctionInfo,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
export {
|
|
58
|
-
export {
|
|
59
|
-
export { type
|
|
60
|
-
export {
|
|
75
|
+
} from '../../helpers/types.js';
|
|
76
|
+
|
|
77
|
+
export { wrapToVmValue, unwrapFromVmValue } from './boundary.js';
|
|
78
|
+
|
|
79
|
+
export { type VmContext, type VmSharedContext, defineVmContextValue, createVmContext } from './context.js';
|
|
80
|
+
export { VmExtern } from './extern.js';
|
|
81
|
+
export { VmFunction, type VmFunctionInfo, type VmFunctionLike, type VmFunctionOption } from './function.js';
|
|
82
|
+
export { VmModule } from './module.js';
|
package/src/vm/types/module.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { kVmModule } from '../../helpers/constants.js';
|
|
1
2
|
import { hasOwnEnumerable, keys } from '../../helpers/utils.js';
|
|
2
|
-
import type { TypeName, VmAny,
|
|
3
|
+
import type { TypeName, VmAny, VmImmutable } from './index.js';
|
|
3
4
|
import { VmWrapper } from './wrapper.js';
|
|
4
5
|
|
|
5
6
|
/** Mirascript 模块 */
|
|
6
|
-
export class VmModule<const T extends Record<string,
|
|
7
|
+
export class VmModule<const T extends Record<string, VmImmutable> = Record<string, VmImmutable>> extends VmWrapper<T> {
|
|
7
8
|
constructor(
|
|
8
9
|
/** 模块名称 */
|
|
9
10
|
readonly name: string,
|
|
@@ -39,9 +40,4 @@ export class VmModule<const T extends Record<string, VmValue> = Record<string, V
|
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
const kVmModule = Symbol.for('mirascript.vm.module');
|
|
43
43
|
Object.defineProperty(VmModule.prototype, kVmModule, { value: true });
|
|
44
|
-
/** 检查值是否为 Mirascript 模块 */
|
|
45
|
-
export function isVmModule<T extends Record<string, VmValue>>(value: unknown): value is VmModule<T> {
|
|
46
|
-
return value != null && typeof value == 'object' && kVmModule in value;
|
|
47
|
-
}
|
package/src/vm/types/wrapper.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { kVmWrapper } from '../../helpers/constants.js';
|
|
1
2
|
import type { TypeName, VmAny } from './index.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -29,9 +30,4 @@ export abstract class VmWrapper<T extends object> {
|
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
const kVmWrapper = Symbol.for('mirascript.vm.wrapper');
|
|
33
33
|
Object.defineProperty(VmWrapper.prototype, kVmWrapper, { value: true });
|
|
34
|
-
/** 检查值是否为 MiraScript 包装器 */
|
|
35
|
-
export function isVmWrapper<T extends object>(value: unknown): value is VmWrapper<T> {
|
|
36
|
-
return value != null && typeof value == 'object' && kVmWrapper in value;
|
|
37
|
-
}
|
package/dist/chunk-35JGBXRE.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=chunk-35JGBXRE.js.map
|