@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/helpers.ts
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
|
+
import { defineProperty, isFinite } from '../helpers/utils.js';
|
|
2
|
+
import { VM_ARRAY_MAX_LENGTH, VM_FUNCTION_ANONYMOUS_NAME } from '../helpers/constants.js';
|
|
3
|
+
import { isVmConst } from '../helpers/types.js';
|
|
1
4
|
import { $AssertInit, $ToNumber } from './operations.js';
|
|
2
5
|
import type { VmFunctionLike } from './types/function.js';
|
|
3
6
|
import { DefaultVmContext, type VmContext } from './types/context.js';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
type VmAny,
|
|
9
|
-
type VmArray,
|
|
10
|
-
type VmValue,
|
|
11
|
-
VM_ARRAY_MAX_LENGTH,
|
|
12
|
-
} from './types/index.js';
|
|
13
|
-
import { isFinite } from '../helpers/utils.js';
|
|
7
|
+
import type { VmConst, VmAny, VmArray, VmValue } from './types/index.js';
|
|
8
|
+
import { VmFunction } from './types/function.js';
|
|
9
|
+
|
|
10
|
+
export { Cp, CpEnter, CpExit } from './checkpoint.js';
|
|
14
11
|
|
|
15
12
|
export const Vargs = (varags: VmAny[]): VmArray => {
|
|
16
13
|
for (let i = 0, l = varags.length; i < l; i++) {
|
|
@@ -33,7 +30,8 @@ export const ElementOpt = (key: string, value: VmAny): VmConst => {
|
|
|
33
30
|
return { [key]: value };
|
|
34
31
|
};
|
|
35
32
|
|
|
36
|
-
export const Function = (fn: VmFunctionLike): VmFunction => {
|
|
33
|
+
export const Function = (fn: VmFunctionLike, name = VM_FUNCTION_ANONYMOUS_NAME): VmFunction => {
|
|
34
|
+
defineProperty(fn, 'name', { value: name });
|
|
37
35
|
return VmFunction(fn, { isLib: false, injectCp: false });
|
|
38
36
|
};
|
|
39
37
|
|
|
@@ -73,48 +71,6 @@ export const ArrayRangeExclusive = (start: VmAny, end: VmAny): VmArray => {
|
|
|
73
71
|
return arr;
|
|
74
72
|
};
|
|
75
73
|
|
|
76
|
-
const MAX_DEPTH = 128;
|
|
77
|
-
|
|
78
|
-
let cpDepth = 0;
|
|
79
|
-
let cp = Number.NaN;
|
|
80
|
-
let cpTimeout = 100; // Default timeout in milliseconds
|
|
81
|
-
/** 检查点 */
|
|
82
|
-
export function Cp(): void {
|
|
83
|
-
if (!cp) {
|
|
84
|
-
cp = Date.now();
|
|
85
|
-
} else if (Date.now() - cp > cpTimeout) {
|
|
86
|
-
throw new RangeError('Execution timeout');
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/** 检查点 */
|
|
90
|
-
export function CpEnter(): void {
|
|
91
|
-
cpDepth++;
|
|
92
|
-
if (cpDepth <= 1) {
|
|
93
|
-
cp = Date.now();
|
|
94
|
-
cpDepth = 1;
|
|
95
|
-
} else if (cpDepth > MAX_DEPTH) {
|
|
96
|
-
throw new RangeError('Maximum call depth exceeded');
|
|
97
|
-
} else {
|
|
98
|
-
Cp();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
/** 检查点 */
|
|
102
|
-
export function CpExit(): void {
|
|
103
|
-
cpDepth--;
|
|
104
|
-
if (cpDepth < 1) {
|
|
105
|
-
cp = Number.NaN;
|
|
106
|
-
cpDepth = 0;
|
|
107
|
-
} else {
|
|
108
|
-
Cp();
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
/** 设置检查点超时时间 */
|
|
112
|
-
export function configCheckpoint(timeout = 100): void {
|
|
113
|
-
if (typeof timeout !== 'number' || timeout <= 0 || Number.isNaN(timeout)) {
|
|
114
|
-
throw new RangeError('Invalid timeout value');
|
|
115
|
-
}
|
|
116
|
-
cpTimeout = timeout;
|
|
117
|
-
}
|
|
118
74
|
/** 默认执行上下文 */
|
|
119
75
|
export function GlobalFallback(): VmContext {
|
|
120
76
|
return DefaultVmContext;
|
package/src/vm/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import './lib/
|
|
1
|
+
import './lib/index.js';
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export { VmError } from '../helpers/error.js';
|
|
4
4
|
export * from './types/index.js';
|
|
5
|
-
export { configCheckpoint } from './
|
|
5
|
+
export { configCheckpoint } from './checkpoint.js';
|
package/src/vm/lib/global/bit.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { VmLib } from '../_helpers.js';
|
|
1
|
+
import { VmLib, expectNumber } from '../helpers.js';
|
|
3
2
|
|
|
4
3
|
export const b_and = VmLib(
|
|
5
4
|
(x, y) => {
|
|
6
|
-
return
|
|
5
|
+
return expectNumber(0, x) & expectNumber(1, y);
|
|
7
6
|
},
|
|
8
7
|
{
|
|
9
8
|
summary: '返回两个数的按位与',
|
|
@@ -16,7 +15,7 @@ export const b_and = VmLib(
|
|
|
16
15
|
|
|
17
16
|
export const b_or = VmLib(
|
|
18
17
|
(x, y) => {
|
|
19
|
-
return
|
|
18
|
+
return expectNumber(0, x) | expectNumber(1, y);
|
|
20
19
|
},
|
|
21
20
|
{
|
|
22
21
|
summary: '返回两个数的按位或',
|
|
@@ -29,7 +28,7 @@ export const b_or = VmLib(
|
|
|
29
28
|
|
|
30
29
|
export const b_not = VmLib(
|
|
31
30
|
(x) => {
|
|
32
|
-
return
|
|
31
|
+
return ~expectNumber('x', x);
|
|
33
32
|
},
|
|
34
33
|
{
|
|
35
34
|
summary: '返回一个数的按位取反',
|
|
@@ -42,7 +41,7 @@ export const b_not = VmLib(
|
|
|
42
41
|
|
|
43
42
|
export const b_xor = VmLib(
|
|
44
43
|
(x, y) => {
|
|
45
|
-
return
|
|
44
|
+
return expectNumber(0, x) ^ expectNumber(1, y);
|
|
46
45
|
},
|
|
47
46
|
{
|
|
48
47
|
summary: '返回两个数的按位异或',
|
|
@@ -55,7 +54,7 @@ export const b_xor = VmLib(
|
|
|
55
54
|
|
|
56
55
|
export const shl = VmLib(
|
|
57
56
|
(x, y) => {
|
|
58
|
-
return
|
|
57
|
+
return expectNumber(0, x) << expectNumber(1, y);
|
|
59
58
|
},
|
|
60
59
|
{
|
|
61
60
|
summary: '返回第一个操作数左移指定的位数',
|
|
@@ -68,7 +67,7 @@ export const shl = VmLib(
|
|
|
68
67
|
|
|
69
68
|
export const sar = VmLib(
|
|
70
69
|
(x, y) => {
|
|
71
|
-
return
|
|
70
|
+
return expectNumber(0, x) >> expectNumber(1, y);
|
|
72
71
|
},
|
|
73
72
|
{
|
|
74
73
|
summary: '返回第一个操作数右移指定的位数',
|
|
@@ -81,7 +80,7 @@ export const sar = VmLib(
|
|
|
81
80
|
|
|
82
81
|
export const shr = VmLib(
|
|
83
82
|
(x, y) => {
|
|
84
|
-
return
|
|
83
|
+
return expectNumber(0, x) >>> expectNumber(1, y);
|
|
85
84
|
},
|
|
86
85
|
{
|
|
87
86
|
summary: '返回第一个操作数无符号右移指定的位数',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import supportsColor from 'supports-color';
|
|
2
|
-
import { VmError } from '
|
|
3
|
-
import {
|
|
2
|
+
import { VmError } from '../../../helpers/error.js';
|
|
3
|
+
import { toString } from '../../../helpers/convert.js';
|
|
4
4
|
import type { VmAny } from '../../types/index.js';
|
|
5
|
-
import { VmLib } from '../
|
|
5
|
+
import { VmLib } from '../helpers.js';
|
|
6
6
|
|
|
7
7
|
export const debug_print = VmLib(
|
|
8
8
|
(...args) => {
|
|
@@ -27,7 +27,8 @@ export const panic = VmLib(
|
|
|
27
27
|
if (message === undefined) console.error(...panic.prefix);
|
|
28
28
|
// eslint-disable-next-line no-console
|
|
29
29
|
else console.error(...panic.prefix, message);
|
|
30
|
-
const
|
|
30
|
+
const mgsStr = toString(message, null);
|
|
31
|
+
const error = !mgsStr ? 'panic' : 'panic: ' + mgsStr;
|
|
31
32
|
throw new VmError(error, undefined);
|
|
32
33
|
},
|
|
33
34
|
{
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isVmExtern, isVmModule } from '../../types/index.js';
|
|
2
|
-
import { required, rethrowError, VmLib } from '../
|
|
2
|
+
import { required, rethrowError, VmLib } from '../helpers.js';
|
|
3
3
|
const { parse, stringify } = JSON;
|
|
4
4
|
|
|
5
5
|
export const to_json = VmLib(
|
|
@@ -31,7 +31,7 @@ export const from_json = VmLib(
|
|
|
31
31
|
try {
|
|
32
32
|
return parse(json);
|
|
33
33
|
} catch (ex) {
|
|
34
|
-
if (fallback
|
|
34
|
+
if (fallback !== undefined) return fallback;
|
|
35
35
|
rethrowError('Invalid JSON', ex, null);
|
|
36
36
|
}
|
|
37
37
|
},
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-loss-of-precision */
|
|
2
2
|
import { isInteger, isNaN } from '../../../helpers/utils.js';
|
|
3
|
-
import {
|
|
4
|
-
import { required, VmLib } from '../_helpers.js';
|
|
3
|
+
import { expectNumber, VmLib } from '../helpers.js';
|
|
5
4
|
const { sqrt, pow, exp } = Math;
|
|
6
5
|
|
|
7
6
|
const GAMMA_G = 4.742_187_5;
|
|
@@ -18,8 +17,7 @@ const SQRT_2_PI = sqrt(2 * Math.PI);
|
|
|
18
17
|
|
|
19
18
|
export const factorial = VmLib(
|
|
20
19
|
(x): number => {
|
|
21
|
-
|
|
22
|
-
let n = $ToNumber(x);
|
|
20
|
+
let n = expectNumber('x', x);
|
|
23
21
|
if (isNaN(n) || n < 0) return Number.NaN;
|
|
24
22
|
if (n >= 171) return Number.POSITIVE_INFINITY; // will overflow
|
|
25
23
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { VmAny } from '../../types/index.js';
|
|
2
|
-
import { getNumbers, VmLib } from '../
|
|
2
|
+
import { getNumbers, VmLib } from '../helpers.js';
|
|
3
3
|
|
|
4
4
|
/** 生成函数 */
|
|
5
5
|
function build(f: (...values: readonly number[]) => number): (...values: readonly VmAny[]) => number {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import type { VmAny } from '../../index.js';
|
|
2
|
-
import {
|
|
3
|
-
import { required, VmLib } from '../_helpers.js';
|
|
2
|
+
import { expectNumber, VmLib } from '../helpers.js';
|
|
4
3
|
|
|
5
4
|
/** 生成函数 */
|
|
6
5
|
function build(f: (x: number) => number): (x: VmAny) => number {
|
|
7
6
|
return (x) => {
|
|
8
|
-
|
|
9
|
-
return f($ToNumber(x));
|
|
7
|
+
return f(expectNumber('x', x));
|
|
10
8
|
};
|
|
11
9
|
}
|
|
12
10
|
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { VmLib } from '../_helpers.js';
|
|
1
|
+
import { expectNumber, VmLib } from '../helpers.js';
|
|
3
2
|
const { atan2: _atan2, pow: _pow } = Math;
|
|
4
3
|
|
|
5
|
-
export const atan2 = VmLib((x, y) => _atan2(
|
|
4
|
+
export const atan2 = VmLib((x, y) => _atan2(expectNumber(0, x), expectNumber(1, y)), {
|
|
6
5
|
summary: '返回从原点到点 (x, y) 的角度(弧度)',
|
|
7
6
|
params: { x: 'x 坐标', y: 'y 坐标' },
|
|
8
7
|
paramsType: { x: 'number', y: 'number' },
|
|
9
8
|
returnsType: 'number',
|
|
10
9
|
});
|
|
11
|
-
export const pow = VmLib((x, y) => _pow(
|
|
10
|
+
export const pow = VmLib((x, y) => _pow(expectNumber(0, x), expectNumber(1, y)), {
|
|
12
11
|
summary: '返回 x 的 y 次幂',
|
|
13
12
|
params: { x: '底数', y: '指数' },
|
|
14
13
|
paramsType: { x: 'number', y: 'number' },
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { toBoolean } from '../../../../helpers/convert.js';
|
|
1
2
|
import { entries } from '../../../../helpers/utils.js';
|
|
2
3
|
import { Cp } from '../../../helpers.js';
|
|
3
|
-
import { $Call
|
|
4
|
+
import { $Call } from '../../../operations.js';
|
|
4
5
|
import { isVmArray } from '../../../types/index.js';
|
|
5
|
-
import { expectArrayOrRecord, expectCallable, VmLib } from '../../
|
|
6
|
+
import { expectArrayOrRecord, expectCallable, VmLib } from '../../helpers.js';
|
|
6
7
|
|
|
7
8
|
export const all = VmLib(
|
|
8
9
|
(data, predicate) => {
|
|
@@ -11,17 +12,19 @@ export const all = VmLib(
|
|
|
11
12
|
if (isVmArray(data)) {
|
|
12
13
|
for (let i = 0; i < data.length; i++) {
|
|
13
14
|
Cp();
|
|
15
|
+
/* c8 ignore next */
|
|
14
16
|
const value = data[i] ?? null;
|
|
15
17
|
const ret = $Call(predicate, [value, i, data]);
|
|
16
|
-
if (
|
|
18
|
+
if (!toBoolean(ret, undefined)) return false;
|
|
17
19
|
}
|
|
18
20
|
return true;
|
|
19
21
|
} else {
|
|
20
22
|
for (const [key, v] of entries(data)) {
|
|
21
23
|
Cp();
|
|
24
|
+
/* c8 ignore next */
|
|
22
25
|
const value = v ?? null;
|
|
23
26
|
const ret = $Call(predicate, [value, key, data]);
|
|
24
|
-
if (
|
|
27
|
+
if (!toBoolean(ret, undefined)) return false;
|
|
25
28
|
}
|
|
26
29
|
return true;
|
|
27
30
|
}
|
|
@@ -45,17 +48,19 @@ export const any = VmLib(
|
|
|
45
48
|
if (isVmArray(data)) {
|
|
46
49
|
for (let i = 0; i < data.length; i++) {
|
|
47
50
|
Cp();
|
|
51
|
+
/* c8 ignore next */
|
|
48
52
|
const value = data[i] ?? null;
|
|
49
53
|
const ret = $Call(predicate, [value, i, data]);
|
|
50
|
-
if (
|
|
54
|
+
if (toBoolean(ret, undefined)) return true;
|
|
51
55
|
}
|
|
52
56
|
return false;
|
|
53
57
|
} else {
|
|
54
58
|
for (const [key, v] of entries(data)) {
|
|
55
59
|
Cp();
|
|
60
|
+
/* c8 ignore next */
|
|
56
61
|
const value = v ?? null;
|
|
57
62
|
const ret = $Call(predicate, [value, key, data]);
|
|
58
|
-
if (
|
|
63
|
+
if (toBoolean(ret, undefined)) return true;
|
|
59
64
|
}
|
|
60
65
|
return false;
|
|
61
66
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isVmArray, isVmRecord, type VmConst } from '../../../types/index.js';
|
|
2
|
-
import { VmLib, expectArrayOrRecord, expectCompound } from '../../
|
|
2
|
+
import { VmLib, expectArrayOrRecord, expectCompound } from '../../helpers.js';
|
|
3
3
|
import { keys as _keys, values as _values, entries as _entries } from '../../../../helpers/utils.js';
|
|
4
4
|
|
|
5
5
|
export const keys = VmLib(
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { toBoolean } from '../../../../helpers/convert.js';
|
|
1
2
|
import { entries } from '../../../../helpers/utils.js';
|
|
2
3
|
import { Cp } from '../../../helpers.js';
|
|
3
|
-
import { $Call, $Same
|
|
4
|
+
import { $Call, $Same } from '../../../operations.js';
|
|
4
5
|
import { type VmValue, isVmArray, isVmCallable } from '../../../types/index.js';
|
|
5
|
-
import { VmLib, expectArrayOrRecord, required } from '../../
|
|
6
|
+
import { VmLib, expectArrayOrRecord, required } from '../../helpers.js';
|
|
6
7
|
|
|
7
8
|
export const find = VmLib(
|
|
8
9
|
(data, predicate) => {
|
|
@@ -11,7 +12,7 @@ export const find = VmLib(
|
|
|
11
12
|
const p = isVmCallable(predicate)
|
|
12
13
|
? (value: VmValue, key: number | string, data: VmValue) => {
|
|
13
14
|
const ret = $Call(predicate, [value, key, data]);
|
|
14
|
-
return
|
|
15
|
+
return toBoolean(ret, undefined);
|
|
15
16
|
}
|
|
16
17
|
: (value: VmValue) => $Same(predicate, value);
|
|
17
18
|
if (isVmArray(data)) {
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { VmLib, expectArray } from '../../_helpers.js';
|
|
1
|
+
import { VmLib, expectArray, expectNumber } from '../../helpers.js';
|
|
3
2
|
|
|
4
3
|
export const flatten = VmLib(
|
|
5
4
|
(data, depth = 1) => {
|
|
6
5
|
expectArray('data', data, data);
|
|
7
|
-
return data.flat(
|
|
6
|
+
return data.flat(expectNumber('depth', depth) as 1);
|
|
8
7
|
},
|
|
9
8
|
{
|
|
10
9
|
summary: '将数组扁平化',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toBoolean } from '../../../../helpers/convert.js';
|
|
2
|
+
import { $Call } from '../../../operations.js';
|
|
2
3
|
import { isVmConst, type VmAny, type VmValue } from '../../../types/index.js';
|
|
3
|
-
import { VmLib, expectCallable, expectConst, map as mapImpl } from '../../
|
|
4
|
+
import { VmLib, expectCallable, expectConst, map as mapImpl } from '../../helpers.js';
|
|
4
5
|
|
|
5
6
|
export * from './with.js';
|
|
6
7
|
export * from './entries.js';
|
|
@@ -43,7 +44,7 @@ export const filter = VmLib(
|
|
|
43
44
|
(data, predicate) =>
|
|
44
45
|
mapImplWrapped(data, 'predicate', predicate, (fn, value, key, data) => {
|
|
45
46
|
const ret = $Call(fn, [value, key, data]);
|
|
46
|
-
return
|
|
47
|
+
return toBoolean(ret, undefined) ? value : undefined;
|
|
47
48
|
}),
|
|
48
49
|
{
|
|
49
50
|
summary: '过滤数组或记录中的元素,返回满足条件的元素',
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { $ToNumber } from '../../../operations.js';
|
|
2
1
|
import type { VmConst } from '../../../types/index.js';
|
|
3
|
-
import { arrayLen, expectConst,
|
|
2
|
+
import { arrayLen, expectConst, expectNumber, VmLib } from '../../helpers.js';
|
|
4
3
|
|
|
5
4
|
export const repeat = VmLib(
|
|
6
5
|
(data, times) => {
|
|
7
6
|
expectConst('data', data, []);
|
|
8
|
-
|
|
9
|
-
const n = arrayLen($ToNumber(times));
|
|
7
|
+
const n = arrayLen(expectNumber('times', times));
|
|
10
8
|
const result: VmConst[] = [];
|
|
11
9
|
result.length = n;
|
|
12
10
|
result.fill(data);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toNumber } from '../../../../helpers/convert.js';
|
|
2
|
+
import { $Call } from '../../../operations.js';
|
|
2
3
|
import type { VmAny, VmConst, VmValue } from '../../../types/index.js';
|
|
3
|
-
import { VmLib, expectArray, expectCallable } from '../../
|
|
4
|
+
import { VmLib, expectArray, expectCallable } from '../../helpers.js';
|
|
4
5
|
|
|
5
6
|
/** 默认比较 */
|
|
6
7
|
function defaultCompare(a: VmValue = null, b: VmValue = null): number {
|
|
@@ -13,8 +14,8 @@ function defaultCompare(a: VmValue = null, b: VmValue = null): number {
|
|
|
13
14
|
return 0;
|
|
14
15
|
}
|
|
15
16
|
// nan is treated as 0
|
|
16
|
-
const an =
|
|
17
|
-
const bn =
|
|
17
|
+
const an = toNumber(a, 0) || 0;
|
|
18
|
+
const bn = toNumber(b, 0) || 0;
|
|
18
19
|
if (an < bn) return -1;
|
|
19
20
|
if (an > bn) return 1;
|
|
20
21
|
return 0;
|
|
@@ -26,7 +27,7 @@ function cmp(comparator: VmAny, recovered: VmValue): typeof defaultCompare {
|
|
|
26
27
|
expectCallable('comparator', comparator, recovered);
|
|
27
28
|
return (a: VmValue = null, b: VmValue = null) => {
|
|
28
29
|
const ret = $Call(comparator, [a, b]);
|
|
29
|
-
return
|
|
30
|
+
return toNumber(ret, 0);
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -1,24 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { VM_ARRAY_MAX_LENGTH } from '../../../../helpers/constants.js';
|
|
2
|
+
import { toNumber, toString } from '../../../../helpers/convert.js';
|
|
3
|
+
import { isVmArray, isVmRecord } from '../../../../helpers/types.js';
|
|
4
|
+
import { isArray, isInteger, isNaN } from '../../../../helpers/utils.js';
|
|
2
5
|
import { Element } from '../../../helpers.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
isVmArray,
|
|
6
|
-
isVmRecord,
|
|
7
|
-
VM_ARRAY_MAX_LENGTH,
|
|
8
|
-
type VmArray,
|
|
9
|
-
type VmConst,
|
|
10
|
-
type VmValue,
|
|
11
|
-
} from '../../../types/index.js';
|
|
12
|
-
import { VmLib, expectArrayOrRecord, expectConst, throwError } from '../../_helpers.js';
|
|
6
|
+
import type { VmArray, VmConst, VmValue } from '../../../types/index.js';
|
|
7
|
+
import { VmLib, expectArrayOrRecord, expectConst, throwError } from '../../helpers.js';
|
|
13
8
|
|
|
14
9
|
const arrIndex = (index: NonNullable<VmConst>): number => {
|
|
15
|
-
const idx = Math.trunc(
|
|
16
|
-
if (
|
|
17
|
-
|
|
10
|
+
const idx = Math.trunc(toNumber(index, Number.NaN));
|
|
11
|
+
if (isNaN(idx) || idx < 0) {
|
|
12
|
+
throwError('Array index must be a non-negative integer', index);
|
|
13
|
+
}
|
|
14
|
+
if (idx >= VM_ARRAY_MAX_LENGTH) {
|
|
15
|
+
throwError(`Array index exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`, index);
|
|
18
16
|
}
|
|
19
17
|
return idx;
|
|
20
18
|
};
|
|
21
19
|
|
|
20
|
+
const isArrIndex = (key: NonNullable<VmConst>): key is number => {
|
|
21
|
+
if (typeof key != 'number') return false;
|
|
22
|
+
return isInteger(key) && key >= 0 && key < VM_ARRAY_MAX_LENGTH;
|
|
23
|
+
};
|
|
24
|
+
|
|
22
25
|
const withInner = (obj: VmConst | undefined, key: VmArray, keyIndex: number, value: VmConst): VmConst => {
|
|
23
26
|
if (keyIndex >= key.length) {
|
|
24
27
|
return value;
|
|
@@ -29,7 +32,7 @@ const withInner = (obj: VmConst | undefined, key: VmArray, keyIndex: number, val
|
|
|
29
32
|
result = [...obj];
|
|
30
33
|
} else if (isVmRecord(obj)) {
|
|
31
34
|
result = { ...obj };
|
|
32
|
-
} else if (
|
|
35
|
+
} else if (isArrIndex(k)) {
|
|
33
36
|
result = [];
|
|
34
37
|
} else {
|
|
35
38
|
result = {};
|
|
@@ -41,7 +44,7 @@ const withInner = (obj: VmConst | undefined, key: VmArray, keyIndex: number, val
|
|
|
41
44
|
}
|
|
42
45
|
result[index] = withInner(result[index], key, keyIndex + 1, value);
|
|
43
46
|
} else {
|
|
44
|
-
const prop =
|
|
47
|
+
const prop = toString(k, undefined);
|
|
45
48
|
result[prop] = withInner(result[prop], key, keyIndex + 1, value);
|
|
46
49
|
}
|
|
47
50
|
return result;
|
|
@@ -86,11 +89,9 @@ const _with = VmLib(
|
|
|
86
89
|
let val: VmConst;
|
|
87
90
|
if (isVmArray(key)) {
|
|
88
91
|
index = arrIndex(key[0]!);
|
|
89
|
-
if (index < 0) continue;
|
|
90
92
|
val = withInner(result[index], key, 1, value);
|
|
91
93
|
} else {
|
|
92
94
|
index = arrIndex(key);
|
|
93
|
-
if (index < 0) continue;
|
|
94
95
|
val = value;
|
|
95
96
|
}
|
|
96
97
|
while (index > result.length) {
|
|
@@ -106,10 +107,10 @@ const _with = VmLib(
|
|
|
106
107
|
let val: VmConst;
|
|
107
108
|
if (isVmArray(key)) {
|
|
108
109
|
const firstKey = key[0]!;
|
|
109
|
-
prop =
|
|
110
|
+
prop = toString(firstKey, undefined);
|
|
110
111
|
val = withInner(result[prop], key, 1, value);
|
|
111
112
|
} else {
|
|
112
|
-
prop =
|
|
113
|
+
prop = toString(key, undefined);
|
|
113
114
|
val = value;
|
|
114
115
|
}
|
|
115
116
|
result[prop] = val;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { display } from '../../../../helpers/serialize.js';
|
|
2
2
|
import { Cp } from '../../../helpers.js';
|
|
3
3
|
import { isVmArray, type VmConst, type VmArray } from '../../../types/index.js';
|
|
4
|
-
import { VmLib, throwError } from '../../
|
|
4
|
+
import { VmLib, throwError } from '../../helpers.js';
|
|
5
5
|
import { entries } from './entries.js';
|
|
6
6
|
|
|
7
7
|
export const zip = VmLib(
|
|
@@ -10,7 +10,7 @@ export const zip = VmLib(
|
|
|
10
10
|
let len = 0;
|
|
11
11
|
for (const { 0: key, 1: arr } of ets) {
|
|
12
12
|
if (!isVmArray(arr)) {
|
|
13
|
-
throwError(`data[${
|
|
13
|
+
throwError(`data[${display(key)}] is not an array: ${display(arr)}`, null);
|
|
14
14
|
}
|
|
15
15
|
len = Math.max(len, arr.length);
|
|
16
16
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { expectArray, required, VmLib } from '../_helpers.js';
|
|
1
|
+
import { expectArray, expectString, VmLib } from '../helpers.js';
|
|
3
2
|
|
|
4
3
|
export const chars = VmLib(
|
|
5
4
|
(str) => {
|
|
6
|
-
|
|
7
|
-
return [...$ToString(str)];
|
|
5
|
+
return [...expectString('str', str)];
|
|
8
6
|
},
|
|
9
7
|
{
|
|
10
8
|
summary: '将字符串转换为字符数组',
|
|
@@ -17,9 +15,7 @@ export const chars = VmLib(
|
|
|
17
15
|
|
|
18
16
|
export const starts_with = VmLib(
|
|
19
17
|
(str, search) => {
|
|
20
|
-
|
|
21
|
-
required('search', search, null);
|
|
22
|
-
return $ToString(str).startsWith($ToString(search));
|
|
18
|
+
return expectString('str', str).startsWith(expectString('search', search));
|
|
23
19
|
},
|
|
24
20
|
{
|
|
25
21
|
summary: '检查字符串是否以指定子串开头',
|
|
@@ -31,9 +27,7 @@ export const starts_with = VmLib(
|
|
|
31
27
|
);
|
|
32
28
|
export const ends_with = VmLib(
|
|
33
29
|
(str, search) => {
|
|
34
|
-
|
|
35
|
-
required('search', search, null);
|
|
36
|
-
return $ToString(str).endsWith($ToString(search));
|
|
30
|
+
return expectString('str', str).endsWith(expectString('search', search));
|
|
37
31
|
},
|
|
38
32
|
{
|
|
39
33
|
summary: '检查字符串是否以指定子串结尾',
|
|
@@ -46,9 +40,7 @@ export const ends_with = VmLib(
|
|
|
46
40
|
|
|
47
41
|
export const contains = VmLib(
|
|
48
42
|
(str, search) => {
|
|
49
|
-
|
|
50
|
-
required('search', search, null);
|
|
51
|
-
return $ToString(str).includes($ToString(search));
|
|
43
|
+
return expectString('str', str).includes(expectString('search', search));
|
|
52
44
|
},
|
|
53
45
|
{
|
|
54
46
|
summary: '检查字符串是否包含指定子串',
|
|
@@ -61,8 +53,7 @@ export const contains = VmLib(
|
|
|
61
53
|
|
|
62
54
|
export const trim_start = VmLib(
|
|
63
55
|
(str) => {
|
|
64
|
-
|
|
65
|
-
return $ToString(str).trimStart();
|
|
56
|
+
return expectString('str', str).trimStart();
|
|
66
57
|
},
|
|
67
58
|
{
|
|
68
59
|
summary: '去除字符串开头的空白字符',
|
|
@@ -75,8 +66,7 @@ export const trim_start = VmLib(
|
|
|
75
66
|
|
|
76
67
|
export const trim_end = VmLib(
|
|
77
68
|
(str) => {
|
|
78
|
-
|
|
79
|
-
return $ToString(str).trimEnd();
|
|
69
|
+
return expectString('str', str).trimEnd();
|
|
80
70
|
},
|
|
81
71
|
{
|
|
82
72
|
summary: '去除字符串结尾的空白字符',
|
|
@@ -89,8 +79,7 @@ export const trim_end = VmLib(
|
|
|
89
79
|
|
|
90
80
|
export const trim = VmLib(
|
|
91
81
|
(str) => {
|
|
92
|
-
|
|
93
|
-
return $ToString(str).trim();
|
|
82
|
+
return expectString('str', str).trim();
|
|
94
83
|
},
|
|
95
84
|
{
|
|
96
85
|
summary: '去除字符串两端的空白字符',
|
|
@@ -103,9 +92,10 @@ export const trim = VmLib(
|
|
|
103
92
|
|
|
104
93
|
export const replace = VmLib(
|
|
105
94
|
(str, search, replacement = '') => {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
95
|
+
return expectString('str', str).replaceAll(
|
|
96
|
+
expectString('search', search),
|
|
97
|
+
expectString('replacement', replacement),
|
|
98
|
+
);
|
|
109
99
|
},
|
|
110
100
|
{
|
|
111
101
|
summary: '替换字符串中的指定子串',
|
|
@@ -118,9 +108,8 @@ export const replace = VmLib(
|
|
|
118
108
|
|
|
119
109
|
export const split = VmLib(
|
|
120
110
|
(str, separator = '') => {
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
const p = $ToString(separator);
|
|
111
|
+
const s = expectString('str', str);
|
|
112
|
+
const p = expectString('separator', separator);
|
|
124
113
|
if (!p) return [...s];
|
|
125
114
|
return s.split(p);
|
|
126
115
|
},
|
|
@@ -136,8 +125,8 @@ export const split = VmLib(
|
|
|
136
125
|
export const join = VmLib(
|
|
137
126
|
(arr, separator = '') => {
|
|
138
127
|
expectArray('arr', arr, null);
|
|
139
|
-
const s =
|
|
140
|
-
return arr.map((v) =>
|
|
128
|
+
const s = expectString('separator', separator);
|
|
129
|
+
return arr.map((v) => expectString(null, v)).join(s);
|
|
141
130
|
},
|
|
142
131
|
{
|
|
143
132
|
summary: '将字符串数组连接为单个字符串',
|