@mirascript/mirascript 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-5FQWUJIY.js +766 -0
- package/dist/chunk-5FQWUJIY.js.map +6 -0
- package/dist/chunk-BTDGMWFK.js +202 -0
- package/dist/chunk-BTDGMWFK.js.map +6 -0
- package/dist/chunk-DCXIWIW5.js +3419 -0
- package/dist/chunk-DCXIWIW5.js.map +6 -0
- package/dist/chunk-RAPJ3XLV.js +10 -0
- package/dist/chunk-RAPJ3XLV.js.map +6 -0
- package/dist/cli/execute.d.ts +4 -0
- package/dist/cli/execute.d.ts.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +191 -0
- package/dist/cli/index.js.map +6 -0
- package/dist/cli/print.d.ts +4 -0
- package/dist/cli/print.d.ts.map +1 -0
- package/dist/compiler/compile-bytecode.d.ts +12 -0
- package/dist/compiler/compile-bytecode.d.ts.map +1 -0
- package/dist/compiler/compile-fast.d.ts +7 -0
- package/dist/compiler/compile-fast.d.ts.map +1 -0
- package/dist/compiler/create-script.d.ts +7 -0
- package/dist/compiler/create-script.d.ts.map +1 -0
- package/dist/compiler/diagnostic.d.ts +56 -0
- package/dist/compiler/diagnostic.d.ts.map +1 -0
- package/dist/compiler/emit.d.ts +4 -0
- package/dist/compiler/emit.d.ts.map +1 -0
- package/dist/compiler/index.d.ts +13 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/types.d.ts +16 -0
- package/dist/compiler/types.d.ts.map +1 -0
- package/dist/compiler/worker-manager.d.ts +6 -0
- package/dist/compiler/worker-manager.d.ts.map +1 -0
- package/dist/compiler/worker.d.ts +6 -0
- package/dist/compiler/worker.d.ts.map +1 -0
- package/dist/compiler/worker.js +34 -0
- package/dist/compiler/worker.js.map +6 -0
- package/dist/helpers/constants.d.ts +3 -0
- package/dist/helpers/constants.d.ts.map +1 -0
- package/dist/helpers/serialize.d.ts +45 -0
- package/dist/helpers/serialize.d.ts.map +1 -0
- package/dist/helpers/utils.d.ts +36 -0
- package/dist/helpers/utils.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +6 -0
- package/dist/subtle.d.ts +7 -0
- package/dist/subtle.d.ts.map +1 -0
- package/dist/subtle.js +30 -0
- package/dist/subtle.js.map +6 -0
- package/dist/vm/env.d.ts +3 -0
- package/dist/vm/env.d.ts.map +1 -0
- package/dist/vm/error.d.ts +11 -0
- package/dist/vm/error.d.ts.map +1 -0
- package/dist/vm/helpers.d.ts +21 -0
- package/dist/vm/helpers.d.ts.map +1 -0
- package/dist/vm/index.d.ts +5 -0
- package/dist/vm/index.d.ts.map +1 -0
- package/dist/vm/lib/_helpers.d.ts +35 -0
- package/dist/vm/lib/_helpers.d.ts.map +1 -0
- package/dist/vm/lib/_loader.d.ts +16 -0
- package/dist/vm/lib/_loader.d.ts.map +1 -0
- package/dist/vm/lib/global/bit.d.ts +9 -0
- package/dist/vm/lib/global/bit.d.ts.map +1 -0
- package/dist/vm/lib/global/debug.d.ts +5 -0
- package/dist/vm/lib/global/debug.d.ts.map +1 -0
- package/dist/vm/lib/global/index.d.ts +10 -0
- package/dist/vm/lib/global/index.d.ts.map +1 -0
- package/dist/vm/lib/global/json.d.ts +4 -0
- package/dist/vm/lib/global/json.d.ts.map +1 -0
- package/dist/vm/lib/global/math-additional.d.ts +3 -0
- package/dist/vm/lib/global/math-additional.d.ts.map +1 -0
- package/dist/vm/lib/global/math-arr.d.ts +8 -0
- package/dist/vm/lib/global/math-arr.d.ts.map +1 -0
- package/dist/vm/lib/global/math-const.d.ts +3 -0
- package/dist/vm/lib/global/math-const.d.ts.map +1 -0
- package/dist/vm/lib/global/math-unary.d.ts +29 -0
- package/dist/vm/lib/global/math-unary.d.ts.map +1 -0
- package/dist/vm/lib/global/math.d.ts +9 -0
- package/dist/vm/lib/global/math.d.ts.map +1 -0
- package/dist/vm/lib/global/mod/index.d.ts +3 -0
- package/dist/vm/lib/global/mod/index.d.ts.map +1 -0
- package/dist/vm/lib/global/mod/matrix.d.ts +16 -0
- package/dist/vm/lib/global/mod/matrix.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/all-any.d.ts +4 -0
- package/dist/vm/lib/global/sequence/all-any.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/entries.d.ts +12 -0
- package/dist/vm/lib/global/sequence/entries.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/find.d.ts +10 -0
- package/dist/vm/lib/global/sequence/find.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/flatten.d.ts +3 -0
- package/dist/vm/lib/global/sequence/flatten.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/index.d.ts +12 -0
- package/dist/vm/lib/global/sequence/index.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/len.d.ts +3 -0
- package/dist/vm/lib/global/sequence/len.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/map-filter.d.ts +9 -0
- package/dist/vm/lib/global/sequence/map-filter.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/repeat.d.ts +4 -0
- package/dist/vm/lib/global/sequence/repeat.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/reverse.d.ts +3 -0
- package/dist/vm/lib/global/sequence/reverse.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/sort.d.ts +5 -0
- package/dist/vm/lib/global/sequence/sort.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/with.d.ts +5 -0
- package/dist/vm/lib/global/sequence/with.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/zip.d.ts +4 -0
- package/dist/vm/lib/global/sequence/zip.d.ts.map +1 -0
- package/dist/vm/lib/global/string.d.ts +12 -0
- package/dist/vm/lib/global/string.d.ts.map +1 -0
- package/dist/vm/lib/global/time.d.ts +15 -0
- package/dist/vm/lib/global/time.d.ts.map +1 -0
- package/dist/vm/lib/global/to-primitive.d.ts +6 -0
- package/dist/vm/lib/global/to-primitive.d.ts.map +1 -0
- package/dist/vm/operations.d.ts +49 -0
- package/dist/vm/operations.d.ts.map +1 -0
- package/dist/vm/types/checker.d.ts +30 -0
- package/dist/vm/types/checker.d.ts.map +1 -0
- package/dist/vm/types/context.d.ts +43 -0
- package/dist/vm/types/context.d.ts.map +1 -0
- package/dist/vm/types/extern.d.ts +32 -0
- package/dist/vm/types/extern.d.ts.map +1 -0
- package/dist/vm/types/function.d.ts +49 -0
- package/dist/vm/types/function.d.ts.map +1 -0
- package/dist/vm/types/index.d.ts +75 -0
- package/dist/vm/types/index.d.ts.map +1 -0
- package/dist/vm/types/module.d.ts +25 -0
- package/dist/vm/types/module.d.ts.map +1 -0
- package/dist/vm/types/script.d.ts +14 -0
- package/dist/vm/types/script.d.ts.map +1 -0
- package/dist/vm/types/wrapper.d.ts +25 -0
- package/dist/vm/types/wrapper.d.ts.map +1 -0
- package/package.json +55 -0
- package/src/cli/execute.ts +32 -0
- package/src/cli/index.ts +73 -0
- package/src/cli/print.ts +41 -0
- package/src/compiler/compile-bytecode.ts +65 -0
- package/src/compiler/compile-fast.ts +81 -0
- package/src/compiler/create-script.ts +34 -0
- package/src/compiler/diagnostic.ts +175 -0
- package/src/compiler/emit.ts +764 -0
- package/src/compiler/index.ts +67 -0
- package/src/compiler/types.ts +16 -0
- package/src/compiler/worker-manager.ts +60 -0
- package/src/compiler/worker.ts +37 -0
- package/src/helpers/constants.ts +3 -0
- package/src/helpers/serialize.ts +280 -0
- package/src/helpers/utils.ts +16 -0
- package/src/index.ts +3 -0
- package/src/subtle.ts +6 -0
- package/src/vm/env.ts +16 -0
- package/src/vm/error.ts +22 -0
- package/src/vm/helpers.ts +121 -0
- package/src/vm/index.ts +5 -0
- package/src/vm/lib/_helpers.ts +215 -0
- package/src/vm/lib/_loader.ts +51 -0
- package/src/vm/lib/global/bit.ts +93 -0
- package/src/vm/lib/global/debug.ts +36 -0
- package/src/vm/lib/global/index.ts +9 -0
- package/src/vm/lib/global/json.ts +45 -0
- package/src/vm/lib/global/math-additional.ts +71 -0
- package/src/vm/lib/global/math-arr.ts +62 -0
- package/src/vm/lib/global/math-const.ts +2 -0
- package/src/vm/lib/global/math-unary.ts +171 -0
- package/src/vm/lib/global/math.ts +27 -0
- package/src/vm/lib/global/mod/index.ts +4 -0
- package/src/vm/lib/global/mod/matrix.ts +579 -0
- package/src/vm/lib/global/sequence/all-any.ts +73 -0
- package/src/vm/lib/global/sequence/entries.ts +67 -0
- package/src/vm/lib/global/sequence/find.ts +49 -0
- package/src/vm/lib/global/sequence/flatten.ts +16 -0
- package/src/vm/lib/global/sequence/index.ts +11 -0
- package/src/vm/lib/global/sequence/len.ts +15 -0
- package/src/vm/lib/global/sequence/map-filter.ts +82 -0
- package/src/vm/lib/global/sequence/repeat.ts +28 -0
- package/src/vm/lib/global/sequence/reverse.ts +17 -0
- package/src/vm/lib/global/sequence/sort.ts +88 -0
- package/src/vm/lib/global/sequence/with.ts +43 -0
- package/src/vm/lib/global/sequence/zip.ts +40 -0
- package/src/vm/lib/global/string.ts +149 -0
- package/src/vm/lib/global/time.ts +73 -0
- package/src/vm/lib/global/to-primitive.ts +58 -0
- package/src/vm/operations.ts +497 -0
- package/src/vm/types/checker.ts +164 -0
- package/src/vm/types/context.ts +161 -0
- package/src/vm/types/extern.ts +166 -0
- package/src/vm/types/function.ts +136 -0
- package/src/vm/types/index.ts +124 -0
- package/src/vm/types/module.ts +40 -0
- package/src/vm/types/script.ts +18 -0
- package/src/vm/types/wrapper.ts +28 -0
|
@@ -0,0 +1,3419 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export
|
|
3
|
+
} from "./chunk-RAPJ3XLV.js";
|
|
4
|
+
|
|
5
|
+
// src/helpers/constants.ts
|
|
6
|
+
var constants_exports = {};
|
|
7
|
+
__export(constants_exports, {
|
|
8
|
+
REG_IDENTIFIER: () => REG_IDENTIFIER,
|
|
9
|
+
REG_ORDINAL: () => REG_ORDINAL
|
|
10
|
+
});
|
|
11
|
+
var REG_IDENTIFIER = /(?:_+|@+|\$+|\p{XID_Start})\p{XID_Continue}*/u;
|
|
12
|
+
var REG_ORDINAL = /(?:0|[1-9]\d{0,8}|1\d{9}|20\d{8}|21[0-3]\d{7}|214[0-6]\d{6}|2147[0-3]\d{5}|21474[0-7]\d{4}|214748[0-2]\d{3}|2147483[0-5]\d{2}|21474836[0-3]\d|214748364[0-7])/;
|
|
13
|
+
|
|
14
|
+
// src/helpers/utils.ts
|
|
15
|
+
var { isArray } = Array;
|
|
16
|
+
var { isFinite, isNaN, isInteger, isSafeInteger } = Number;
|
|
17
|
+
var { hasOwn, keys, values, entries, create, getPrototypeOf, fromEntries, defineProperty } = Object;
|
|
18
|
+
var hasOwnEnumerable = Function.call.bind(
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
20
|
+
Object.prototype.propertyIsEnumerable
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// src/vm/error.ts
|
|
24
|
+
var VmError = class _VmError extends Error {
|
|
25
|
+
constructor(message, recovered) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.recovered = recovered;
|
|
28
|
+
this.name = "VmError";
|
|
29
|
+
}
|
|
30
|
+
/** 从其他错误构造 */
|
|
31
|
+
static from(prefix, error, recovered) {
|
|
32
|
+
if (prefix && !prefix.endsWith(": ")) prefix += ": ";
|
|
33
|
+
const vmError = new _VmError(`${prefix}${error instanceof Error ? error.message : String(error)}`, recovered);
|
|
34
|
+
vmError.stack = error instanceof Error ? error.stack : void 0;
|
|
35
|
+
return vmError;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/vm/helpers.ts
|
|
40
|
+
var helpers_exports = {};
|
|
41
|
+
__export(helpers_exports, {
|
|
42
|
+
ArrayRange: () => ArrayRange,
|
|
43
|
+
ArrayRangeExclusive: () => ArrayRangeExclusive,
|
|
44
|
+
Cp: () => Cp,
|
|
45
|
+
CpEnter: () => CpEnter,
|
|
46
|
+
CpExit: () => CpExit,
|
|
47
|
+
Element: () => Element,
|
|
48
|
+
ElementOpt: () => ElementOpt,
|
|
49
|
+
Function: () => Function2,
|
|
50
|
+
GlobalFallback: () => GlobalFallback,
|
|
51
|
+
Upvalue: () => Upvalue,
|
|
52
|
+
Vargs: () => Vargs,
|
|
53
|
+
configCheckpoint: () => configCheckpoint
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// src/vm/operations.ts
|
|
57
|
+
var operations_exports = {};
|
|
58
|
+
__export(operations_exports, {
|
|
59
|
+
$Add: () => $Add,
|
|
60
|
+
$Aeq: () => $Aeq,
|
|
61
|
+
$And: () => $And,
|
|
62
|
+
$ArraySpread: () => $ArraySpread,
|
|
63
|
+
$AssertInit: () => $AssertInit,
|
|
64
|
+
$AssertNonNil: () => $AssertNonNil,
|
|
65
|
+
$Call: () => $Call,
|
|
66
|
+
$Concat: () => $Concat,
|
|
67
|
+
$Div: () => $Div,
|
|
68
|
+
$Eq: () => $Eq,
|
|
69
|
+
$Format: () => $Format,
|
|
70
|
+
$Get: () => $Get,
|
|
71
|
+
$Gt: () => $Gt,
|
|
72
|
+
$Gte: () => $Gte,
|
|
73
|
+
$Has: () => $Has,
|
|
74
|
+
$In: () => $In,
|
|
75
|
+
$IsArray: () => $IsArray,
|
|
76
|
+
$IsBoolean: () => $IsBoolean,
|
|
77
|
+
$IsNumber: () => $IsNumber,
|
|
78
|
+
$IsRecord: () => $IsRecord,
|
|
79
|
+
$IsString: () => $IsString,
|
|
80
|
+
$Iterable: () => $Iterable,
|
|
81
|
+
$Length: () => $Length,
|
|
82
|
+
$Lt: () => $Lt,
|
|
83
|
+
$Lte: () => $Lte,
|
|
84
|
+
$Mod: () => $Mod,
|
|
85
|
+
$Mul: () => $Mul,
|
|
86
|
+
$Naeq: () => $Naeq,
|
|
87
|
+
$Neg: () => $Neg,
|
|
88
|
+
$Neq: () => $Neq,
|
|
89
|
+
$Not: () => $Not,
|
|
90
|
+
$Nsame: () => $Nsame,
|
|
91
|
+
$Omit: () => $Omit,
|
|
92
|
+
$Or: () => $Or,
|
|
93
|
+
$Pick: () => $Pick,
|
|
94
|
+
$Pos: () => $Pos,
|
|
95
|
+
$Pow: () => $Pow,
|
|
96
|
+
$RecordSpread: () => $RecordSpread,
|
|
97
|
+
$Same: () => $Same,
|
|
98
|
+
$Set: () => $Set,
|
|
99
|
+
$Slice: () => $Slice,
|
|
100
|
+
$SliceExclusive: () => $SliceExclusive,
|
|
101
|
+
$Sub: () => $Sub,
|
|
102
|
+
$ToBoolean: () => $ToBoolean,
|
|
103
|
+
$ToNumber: () => $ToNumber,
|
|
104
|
+
$ToString: () => $ToString,
|
|
105
|
+
$Type: () => $Type
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// src/vm/types/wrapper.ts
|
|
109
|
+
var VmWrapper = class {
|
|
110
|
+
constructor(value) {
|
|
111
|
+
this.value = value;
|
|
112
|
+
}
|
|
113
|
+
/** Convert the object to JSON */
|
|
114
|
+
toJSON() {
|
|
115
|
+
return void 0;
|
|
116
|
+
}
|
|
117
|
+
/** 转为字符串 */
|
|
118
|
+
toString() {
|
|
119
|
+
return `<${this.type} ${this.describe}>`;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// src/vm/operations.ts
|
|
124
|
+
var { abs, min, trunc, ceil } = Math;
|
|
125
|
+
var { slice, at } = Array.prototype;
|
|
126
|
+
var { POSITIVE_INFINITY, NEGATIVE_INFINITY } = Number;
|
|
127
|
+
var isSame = (a, b) => {
|
|
128
|
+
if (typeof a == "number" && typeof b == "number") return a === b || isNaN(a) && isNaN(b);
|
|
129
|
+
if (a === b) return true;
|
|
130
|
+
if (a == null || typeof a != "object" || b == null || typeof b != "object") return false;
|
|
131
|
+
if (a instanceof VmWrapper) return a.same(b);
|
|
132
|
+
if (b instanceof VmWrapper) return b.same(a);
|
|
133
|
+
if (isVmArray(a) && isVmArray(b)) {
|
|
134
|
+
if (a.length !== b.length) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
const len2 = a.length;
|
|
138
|
+
for (let i = 0; i < len2; i++) {
|
|
139
|
+
if (!isSame(a[i] ?? null, b[i] ?? null)) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
if (!isVmArray(a) && !isVmArray(b)) {
|
|
146
|
+
const aKeys = keys(a);
|
|
147
|
+
const bKeys = keys(b);
|
|
148
|
+
if (aKeys.length !== bKeys.length) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
for (const key of aKeys) {
|
|
152
|
+
if (!hasOwnEnumerable(b, key)) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
if (!isSame(a[key] ?? null, b[key] ?? null)) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
};
|
|
163
|
+
var overloadNumberString = (a, b) => {
|
|
164
|
+
if (typeof a == "number" || typeof b == "number") return true;
|
|
165
|
+
if (typeof a == "string" || typeof b == "string") return false;
|
|
166
|
+
return true;
|
|
167
|
+
};
|
|
168
|
+
var $Add = (a, b) => {
|
|
169
|
+
return $ToNumber(a) + $ToNumber(b);
|
|
170
|
+
};
|
|
171
|
+
var $Sub = (a, b) => {
|
|
172
|
+
return $ToNumber(a) - $ToNumber(b);
|
|
173
|
+
};
|
|
174
|
+
var $Mul = (a, b) => {
|
|
175
|
+
return $ToNumber(a) * $ToNumber(b);
|
|
176
|
+
};
|
|
177
|
+
var $Div = (a, b) => {
|
|
178
|
+
return $ToNumber(a) / $ToNumber(b);
|
|
179
|
+
};
|
|
180
|
+
var $Mod = (a, b) => {
|
|
181
|
+
return $ToNumber(a) % $ToNumber(b);
|
|
182
|
+
};
|
|
183
|
+
var $Pow = (a, b) => {
|
|
184
|
+
return $ToNumber(a) ** $ToNumber(b);
|
|
185
|
+
};
|
|
186
|
+
var $And = (a, b) => {
|
|
187
|
+
return $ToBoolean(a) && $ToBoolean(b);
|
|
188
|
+
};
|
|
189
|
+
var $Or = (a, b) => {
|
|
190
|
+
return $ToBoolean(a) || $ToBoolean(b);
|
|
191
|
+
};
|
|
192
|
+
var $Gt = (a, b) => {
|
|
193
|
+
if (overloadNumberString(a, b)) {
|
|
194
|
+
return $ToNumber(a) > $ToNumber(b);
|
|
195
|
+
} else {
|
|
196
|
+
return $ToString(a) > $ToString(b);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
var $Gte = (a, b) => {
|
|
200
|
+
if (overloadNumberString(a, b)) {
|
|
201
|
+
return $ToNumber(a) >= $ToNumber(b);
|
|
202
|
+
} else {
|
|
203
|
+
return $ToString(a) >= $ToString(b);
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
var $Lt = (a, b) => {
|
|
207
|
+
if (overloadNumberString(a, b)) {
|
|
208
|
+
return $ToNumber(a) < $ToNumber(b);
|
|
209
|
+
} else {
|
|
210
|
+
return $ToString(a) < $ToString(b);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
var $Lte = (a, b) => {
|
|
214
|
+
if (overloadNumberString(a, b)) {
|
|
215
|
+
return $ToNumber(a) <= $ToNumber(b);
|
|
216
|
+
} else {
|
|
217
|
+
return $ToString(a) <= $ToString(b);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
var $Eq = (a, b) => {
|
|
221
|
+
$AssertInit(a);
|
|
222
|
+
$AssertInit(b);
|
|
223
|
+
if (typeof a == "number" && typeof b == "number") return a === b;
|
|
224
|
+
return isSame(a, b);
|
|
225
|
+
};
|
|
226
|
+
var $Neq = (a, b) => !$Eq(a, b);
|
|
227
|
+
var stringComparer = new Intl.Collator("en", {
|
|
228
|
+
usage: "sort",
|
|
229
|
+
numeric: false,
|
|
230
|
+
sensitivity: "base"
|
|
231
|
+
});
|
|
232
|
+
var $Aeq = (a, b) => {
|
|
233
|
+
if (overloadNumberString(a, b)) {
|
|
234
|
+
const an = $ToNumber(a);
|
|
235
|
+
const bn = $ToNumber(b);
|
|
236
|
+
const EPS = 1e-15;
|
|
237
|
+
if (isNaN(an) || isNaN(bn)) return false;
|
|
238
|
+
if (an === bn) return true;
|
|
239
|
+
const absoluteDifference = abs(an - bn);
|
|
240
|
+
if (absoluteDifference < EPS) return true;
|
|
241
|
+
const base = min(abs(an), abs(bn));
|
|
242
|
+
return absoluteDifference < base * EPS;
|
|
243
|
+
} else {
|
|
244
|
+
const as = $ToString(a);
|
|
245
|
+
const bs = $ToString(b);
|
|
246
|
+
if (as === bs) return true;
|
|
247
|
+
return stringComparer.compare(as, bs) === 0;
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
var $Naeq = (a, b) => !$Aeq(a, b);
|
|
251
|
+
var $Same = (a, b) => {
|
|
252
|
+
$AssertInit(a);
|
|
253
|
+
$AssertInit(b);
|
|
254
|
+
return isSame(a, b);
|
|
255
|
+
};
|
|
256
|
+
var $Nsame = (a, b) => !$Same(a, b);
|
|
257
|
+
var $In = (value, iterable) => {
|
|
258
|
+
$AssertInit(value);
|
|
259
|
+
$AssertInit(iterable);
|
|
260
|
+
if (iterable == null) return false;
|
|
261
|
+
if (isVmArray(iterable)) {
|
|
262
|
+
if (value == null) {
|
|
263
|
+
for (const item of iterable) {
|
|
264
|
+
if (item == null) return true;
|
|
265
|
+
}
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
if (isVmPrimitive(value)) return iterable.includes(value);
|
|
269
|
+
value;
|
|
270
|
+
return iterable.some((item = null) => isSame(item, value));
|
|
271
|
+
}
|
|
272
|
+
if (iterable instanceof VmWrapper) return iterable.has($ToString(value));
|
|
273
|
+
if (typeof iterable == "object") return hasOwnEnumerable(iterable, $ToString(value));
|
|
274
|
+
iterable;
|
|
275
|
+
return false;
|
|
276
|
+
};
|
|
277
|
+
var $Concat = (...args) => {
|
|
278
|
+
return args.map($Format).join("");
|
|
279
|
+
};
|
|
280
|
+
var $Pos = (a) => $ToNumber(a);
|
|
281
|
+
var $Neg = (a) => -$ToNumber(a);
|
|
282
|
+
var $Not = (a) => !$ToBoolean(a);
|
|
283
|
+
var $Length = (value) => {
|
|
284
|
+
$AssertInit(value);
|
|
285
|
+
if (isVmArray(value)) return value.length;
|
|
286
|
+
if (isVmRecord(value)) return keys(value).length;
|
|
287
|
+
if (value instanceof VmWrapper) {
|
|
288
|
+
return value.keys().length;
|
|
289
|
+
}
|
|
290
|
+
return Number.NaN;
|
|
291
|
+
};
|
|
292
|
+
var $Omit = (value, omitted) => {
|
|
293
|
+
$AssertInit(value);
|
|
294
|
+
if (value == null || !isVmRecord(value)) return {};
|
|
295
|
+
const result = {};
|
|
296
|
+
const valueKeys = keys(value);
|
|
297
|
+
const omittedSet = new Set(omitted.map($ToString));
|
|
298
|
+
for (const key of valueKeys) {
|
|
299
|
+
if (!omittedSet.has(key)) {
|
|
300
|
+
result[key] = value[key] ?? null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return result;
|
|
304
|
+
};
|
|
305
|
+
var $Pick = (value, picked) => {
|
|
306
|
+
$AssertInit(value);
|
|
307
|
+
if (value == null || !isVmRecord(value)) return {};
|
|
308
|
+
const result = {};
|
|
309
|
+
for (const key of picked) {
|
|
310
|
+
const k = $ToString(key);
|
|
311
|
+
if (hasOwnEnumerable(value, k)) {
|
|
312
|
+
result[k] = value[k] ?? null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return result;
|
|
316
|
+
};
|
|
317
|
+
var sliceCore = (value, start, end, exclusive) => {
|
|
318
|
+
const { length } = value;
|
|
319
|
+
if (isNaN(start)) start = 0;
|
|
320
|
+
else if (start < 0) start = length + start;
|
|
321
|
+
if (isNaN(end)) end = exclusive ? length : length - 1;
|
|
322
|
+
else if (end < 0) end = length + end;
|
|
323
|
+
start = ceil(start);
|
|
324
|
+
if (exclusive || !isSafeInteger(end)) {
|
|
325
|
+
end = ceil(end);
|
|
326
|
+
} else {
|
|
327
|
+
end = end + 1;
|
|
328
|
+
}
|
|
329
|
+
return slice.call(value, start, end);
|
|
330
|
+
};
|
|
331
|
+
var $Slice = (value, start, end) => {
|
|
332
|
+
$AssertInit(value);
|
|
333
|
+
if (!isVmArray(value)) throw new VmError(`Expected array, got ${$Type(value)}`, []);
|
|
334
|
+
const s = start != null ? $ToNumber(start) : 0;
|
|
335
|
+
const e = end != null ? $ToNumber(end) : value.length - 1;
|
|
336
|
+
return sliceCore(value, s, e, false);
|
|
337
|
+
};
|
|
338
|
+
var $SliceExclusive = (value, start, end) => {
|
|
339
|
+
$AssertInit(value);
|
|
340
|
+
if (!isVmArray(value)) throw new VmError(`Expected array, got ${$Type(value)}`, []);
|
|
341
|
+
const s = start != null ? $ToNumber(start) : 0;
|
|
342
|
+
const e = end != null ? $ToNumber(end) : value.length;
|
|
343
|
+
return sliceCore(value, s, e, true);
|
|
344
|
+
};
|
|
345
|
+
var $AssertInit = (value) => {
|
|
346
|
+
if (value === void 0) throw new VmError(`Uninitialized value`, null);
|
|
347
|
+
};
|
|
348
|
+
var $Call = (func, args) => {
|
|
349
|
+
for (const a of args) {
|
|
350
|
+
$AssertInit(a);
|
|
351
|
+
}
|
|
352
|
+
if (func instanceof VmExtern) {
|
|
353
|
+
return func.call(args) ?? null;
|
|
354
|
+
}
|
|
355
|
+
if (isVmFunction(func)) {
|
|
356
|
+
return func(...args) ?? null;
|
|
357
|
+
}
|
|
358
|
+
throw new VmError(`Expected callable, got ${$Type(func)}`, null);
|
|
359
|
+
};
|
|
360
|
+
var $Type = (value) => {
|
|
361
|
+
if (value === void 0 || value === null) return "nil";
|
|
362
|
+
if (value instanceof VmExtern) return "extern";
|
|
363
|
+
if (value instanceof VmModule) return "module";
|
|
364
|
+
if (isVmArray(value)) return "array";
|
|
365
|
+
if (typeof value == "object") return "record";
|
|
366
|
+
return typeof value;
|
|
367
|
+
};
|
|
368
|
+
var $ToBoolean = (value) => {
|
|
369
|
+
$AssertInit(value);
|
|
370
|
+
return value != null && value !== false;
|
|
371
|
+
};
|
|
372
|
+
function numberToString(value) {
|
|
373
|
+
if (isNaN(value)) return "nan";
|
|
374
|
+
if (value === Infinity) return "inf";
|
|
375
|
+
if (value === -Infinity) return "-inf";
|
|
376
|
+
return String(value);
|
|
377
|
+
}
|
|
378
|
+
function innerToString(value, useBraces) {
|
|
379
|
+
if (value == null) return "nil";
|
|
380
|
+
if (value instanceof VmWrapper) return value.toString();
|
|
381
|
+
if (typeof value == "function") {
|
|
382
|
+
const name = getVmFunctionInfo(value)?.fullName;
|
|
383
|
+
return name ? `<function ${name}>` : `<function>`;
|
|
384
|
+
}
|
|
385
|
+
if (isVmArray(value)) {
|
|
386
|
+
const strings = [];
|
|
387
|
+
for (const item of value) {
|
|
388
|
+
strings.push(innerToString(item, true));
|
|
389
|
+
}
|
|
390
|
+
const results = strings.join(", ");
|
|
391
|
+
if (!useBraces) return results;
|
|
392
|
+
return `[${results}]`;
|
|
393
|
+
}
|
|
394
|
+
if (typeof value == "object") {
|
|
395
|
+
const entries3 = keys(value).map((key) => `${key}: ${innerToString(value[key], true)}`).join(", ");
|
|
396
|
+
if (!useBraces) return entries3;
|
|
397
|
+
return `(${entries3})`;
|
|
398
|
+
}
|
|
399
|
+
if (typeof value == "number") {
|
|
400
|
+
return numberToString(value);
|
|
401
|
+
}
|
|
402
|
+
return String(value);
|
|
403
|
+
}
|
|
404
|
+
var $ToString = (value) => {
|
|
405
|
+
$AssertInit(value);
|
|
406
|
+
if (typeof value == "string") return value;
|
|
407
|
+
if (value === null) return "";
|
|
408
|
+
return innerToString(value, false);
|
|
409
|
+
};
|
|
410
|
+
var $ToNumber = (value) => {
|
|
411
|
+
$AssertInit(value);
|
|
412
|
+
if (typeof value == "number") return value;
|
|
413
|
+
if (value == null) return 0;
|
|
414
|
+
if (typeof value == "string") {
|
|
415
|
+
value = value.trim();
|
|
416
|
+
if (value === "") return 0;
|
|
417
|
+
if (value === "inf" || value === "+inf" || value === "Infinity" || value === "+Infinity") {
|
|
418
|
+
return POSITIVE_INFINITY;
|
|
419
|
+
}
|
|
420
|
+
if (value === "-inf" || value === "-Infinity") {
|
|
421
|
+
return NEGATIVE_INFINITY;
|
|
422
|
+
}
|
|
423
|
+
return Number(value);
|
|
424
|
+
}
|
|
425
|
+
if (typeof value == "boolean") return value ? 1 : 0;
|
|
426
|
+
return Number.NaN;
|
|
427
|
+
};
|
|
428
|
+
var $IsBoolean = (value) => {
|
|
429
|
+
$AssertInit(value);
|
|
430
|
+
return typeof value == "boolean";
|
|
431
|
+
};
|
|
432
|
+
var $IsNumber = (value) => {
|
|
433
|
+
$AssertInit(value);
|
|
434
|
+
return typeof value == "number";
|
|
435
|
+
};
|
|
436
|
+
var $IsString = (value) => {
|
|
437
|
+
$AssertInit(value);
|
|
438
|
+
return typeof value == "string";
|
|
439
|
+
};
|
|
440
|
+
var $IsRecord = (value) => {
|
|
441
|
+
$AssertInit(value);
|
|
442
|
+
return isVmRecord(value);
|
|
443
|
+
};
|
|
444
|
+
var $IsArray = (value) => {
|
|
445
|
+
$AssertInit(value);
|
|
446
|
+
return isVmArray(value);
|
|
447
|
+
};
|
|
448
|
+
var $AssertNonNil = (value) => {
|
|
449
|
+
$AssertInit(value);
|
|
450
|
+
if (value !== null) return;
|
|
451
|
+
throw new VmError("Expected non-nil value", null);
|
|
452
|
+
};
|
|
453
|
+
var $Has = (obj, key) => {
|
|
454
|
+
$AssertInit(obj);
|
|
455
|
+
const pk = $ToString(key);
|
|
456
|
+
if (obj == null || typeof obj != "object") return false;
|
|
457
|
+
if (obj instanceof VmWrapper) return obj.has(pk);
|
|
458
|
+
return hasOwnEnumerable(obj, pk);
|
|
459
|
+
};
|
|
460
|
+
var $Get = (obj, key) => {
|
|
461
|
+
$AssertInit(obj);
|
|
462
|
+
if (isVmArray(obj)) {
|
|
463
|
+
const index = $ToNumber(key);
|
|
464
|
+
if (isNaN(index)) return null;
|
|
465
|
+
return at.call(obj, trunc(index)) ?? null;
|
|
466
|
+
}
|
|
467
|
+
const pk = $ToString(key);
|
|
468
|
+
if (obj == null || typeof obj != "object") return null;
|
|
469
|
+
if (obj instanceof VmWrapper) return obj.get(pk) ?? null;
|
|
470
|
+
if (!hasOwnEnumerable(obj, pk)) return null;
|
|
471
|
+
return obj[pk] ?? null;
|
|
472
|
+
};
|
|
473
|
+
var $Set = (obj, key, value) => {
|
|
474
|
+
$AssertInit(obj);
|
|
475
|
+
$AssertInit(value);
|
|
476
|
+
const pk = $ToString(key);
|
|
477
|
+
if (obj == null) return;
|
|
478
|
+
if (!isVmExtern(obj)) throw new VmError(`Expected extern, got ${$Type(obj)}`, void 0);
|
|
479
|
+
obj.set(pk, value);
|
|
480
|
+
};
|
|
481
|
+
var $Iterable = (value) => {
|
|
482
|
+
$AssertInit(value);
|
|
483
|
+
if (value instanceof VmWrapper) return value.keys();
|
|
484
|
+
if (isVmArray(value)) return value;
|
|
485
|
+
if (value != null && typeof value == "object") return keys(value);
|
|
486
|
+
throw new VmError(`Value is not iterable`, isVmFunction(value) ? [] : [value]);
|
|
487
|
+
};
|
|
488
|
+
var $RecordSpread = (record) => {
|
|
489
|
+
$AssertInit(record);
|
|
490
|
+
if (record == null || isVmRecord(record)) return record;
|
|
491
|
+
if (isVmArray(record)) {
|
|
492
|
+
const result = {};
|
|
493
|
+
const len2 = record.length;
|
|
494
|
+
for (let i = 0; i < len2; i++) {
|
|
495
|
+
const item = record[i];
|
|
496
|
+
result[i] = item ?? null;
|
|
497
|
+
}
|
|
498
|
+
return result;
|
|
499
|
+
}
|
|
500
|
+
if (isVmExtern(record)) {
|
|
501
|
+
const result = create(null);
|
|
502
|
+
for (const key of record.keys()) {
|
|
503
|
+
const value = record.get(key) ?? null;
|
|
504
|
+
if (isVmPrimitive(value)) {
|
|
505
|
+
result[key] = value;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return result;
|
|
509
|
+
}
|
|
510
|
+
throw new VmError(`Expected record, array, extern or nil, got ${$Type(record)}`, null);
|
|
511
|
+
};
|
|
512
|
+
var $ArraySpread = (array) => {
|
|
513
|
+
$AssertInit(array);
|
|
514
|
+
if (array == null) return [];
|
|
515
|
+
if (isVmArray(array)) return array;
|
|
516
|
+
if (isVmExtern(array) && typeof array.value[Symbol.iterator] == "function") {
|
|
517
|
+
const result = [];
|
|
518
|
+
for (const item of array.value) {
|
|
519
|
+
if (isVmPrimitive(item)) {
|
|
520
|
+
result.push(item);
|
|
521
|
+
} else {
|
|
522
|
+
result.push(null);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return result;
|
|
526
|
+
}
|
|
527
|
+
throw new VmError(`Expected array, iterable extern or nil, got ${$Type(array)}`, []);
|
|
528
|
+
};
|
|
529
|
+
function formatNumber(value) {
|
|
530
|
+
if (!Number.isFinite(value)) return numberToString(value);
|
|
531
|
+
if (value === 0) return "0";
|
|
532
|
+
const s = value.toString();
|
|
533
|
+
let ps;
|
|
534
|
+
const abs3 = Math.abs(value);
|
|
535
|
+
if (abs3 >= 1e3 || abs3 < 1e-3) {
|
|
536
|
+
const ps1 = value.toExponential();
|
|
537
|
+
const ps2 = value.toExponential(5);
|
|
538
|
+
ps = ps1.length < ps2.length ? ps1 : ps2;
|
|
539
|
+
} else {
|
|
540
|
+
ps = value.toPrecision(6);
|
|
541
|
+
}
|
|
542
|
+
return ps.length < s.length ? ps : s;
|
|
543
|
+
}
|
|
544
|
+
var $Format = (value, format2) => {
|
|
545
|
+
$AssertInit(value);
|
|
546
|
+
const f = format2 == null ? "" : typeof format2 == "string" ? format2.trim() : $ToString(format2);
|
|
547
|
+
if (typeof value == "number") {
|
|
548
|
+
if (/^\.\d+$/.test(f)) {
|
|
549
|
+
let digits = Math.trunc(Number(f.slice(1)));
|
|
550
|
+
if (!(digits <= 100)) digits = 100;
|
|
551
|
+
return value.toFixed(digits);
|
|
552
|
+
} else {
|
|
553
|
+
return formatNumber(value);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return $ToString(value);
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
// src/vm/helpers.ts
|
|
560
|
+
var Vargs = (varags) => {
|
|
561
|
+
for (let i = 0, l = varags.length; i < l; i++) {
|
|
562
|
+
const el = varags[i];
|
|
563
|
+
if (!isVmConst(el)) {
|
|
564
|
+
varags[i] = null;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return varags;
|
|
568
|
+
};
|
|
569
|
+
var Element = (value) => {
|
|
570
|
+
$AssertInit(value);
|
|
571
|
+
if (!isVmConst(value)) return null;
|
|
572
|
+
return value;
|
|
573
|
+
};
|
|
574
|
+
var ElementOpt = (key, value) => {
|
|
575
|
+
$AssertInit(value);
|
|
576
|
+
if (value == null || !isVmConst(value)) return {};
|
|
577
|
+
return { [key]: value };
|
|
578
|
+
};
|
|
579
|
+
var Function2 = (fn) => {
|
|
580
|
+
return VmFunction(fn, { isLib: false, injectCp: false });
|
|
581
|
+
};
|
|
582
|
+
var Upvalue = (value) => {
|
|
583
|
+
$AssertInit(value);
|
|
584
|
+
return value;
|
|
585
|
+
};
|
|
586
|
+
var assertArrayLength = (start, end) => {
|
|
587
|
+
if (end - start > VM_ARRAY_MAX_LENGTH) {
|
|
588
|
+
throw new RangeError(`Array length exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`);
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
var isEmptyRange = (start, end) => {
|
|
592
|
+
return !isFinite(start) || !isFinite(end) || start > end;
|
|
593
|
+
};
|
|
594
|
+
var ArrayRange = (start, end) => {
|
|
595
|
+
const s = $ToNumber(start);
|
|
596
|
+
const e = $ToNumber(end);
|
|
597
|
+
if (isEmptyRange(s, e)) return [];
|
|
598
|
+
assertArrayLength(s, e);
|
|
599
|
+
const arr = [];
|
|
600
|
+
for (let i = s; i <= e; i++) {
|
|
601
|
+
arr.push(i);
|
|
602
|
+
}
|
|
603
|
+
return arr;
|
|
604
|
+
};
|
|
605
|
+
var ArrayRangeExclusive = (start, end) => {
|
|
606
|
+
const s = $ToNumber(start);
|
|
607
|
+
const e = $ToNumber(end);
|
|
608
|
+
if (isEmptyRange(s, e)) return [];
|
|
609
|
+
assertArrayLength(s, e);
|
|
610
|
+
const arr = [];
|
|
611
|
+
for (let i = s; i < e; i++) {
|
|
612
|
+
arr.push(i);
|
|
613
|
+
}
|
|
614
|
+
return arr;
|
|
615
|
+
};
|
|
616
|
+
var MAX_DEPTH = 128;
|
|
617
|
+
var cpDepth = 0;
|
|
618
|
+
var cp = Number.NaN;
|
|
619
|
+
var cpTimeout = 100;
|
|
620
|
+
function Cp() {
|
|
621
|
+
if (!cp) {
|
|
622
|
+
cp = Date.now();
|
|
623
|
+
} else if (Date.now() - cp > cpTimeout) {
|
|
624
|
+
throw new RangeError("Execution timeout");
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
function CpEnter() {
|
|
628
|
+
cpDepth++;
|
|
629
|
+
if (cpDepth <= 1) {
|
|
630
|
+
cp = Date.now();
|
|
631
|
+
cpDepth = 1;
|
|
632
|
+
} else if (cpDepth > MAX_DEPTH) {
|
|
633
|
+
throw new RangeError("Maximum call depth exceeded");
|
|
634
|
+
} else {
|
|
635
|
+
Cp();
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
function CpExit() {
|
|
639
|
+
cpDepth--;
|
|
640
|
+
if (cpDepth < 1) {
|
|
641
|
+
cp = Number.NaN;
|
|
642
|
+
cpDepth = 0;
|
|
643
|
+
} else {
|
|
644
|
+
Cp();
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
function configCheckpoint(timeout = 100) {
|
|
648
|
+
if (typeof timeout !== "number" || timeout <= 0 || Number.isNaN(timeout)) {
|
|
649
|
+
throw new RangeError("Invalid timeout value");
|
|
650
|
+
}
|
|
651
|
+
cpTimeout = timeout;
|
|
652
|
+
}
|
|
653
|
+
function GlobalFallback() {
|
|
654
|
+
return DefaultVmContext;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// src/vm/types/function.ts
|
|
658
|
+
var kVmFunction = Symbol.for("mirascript.vm.function");
|
|
659
|
+
var kProxy = Symbol.for("mirascript.vm.function.proxy");
|
|
660
|
+
function isVmFunction(value) {
|
|
661
|
+
return getVmFunctionInfo(value) != null;
|
|
662
|
+
}
|
|
663
|
+
function getVmFunctionInfo(value) {
|
|
664
|
+
if (typeof value != "function") return void 0;
|
|
665
|
+
return value[kVmFunction];
|
|
666
|
+
}
|
|
667
|
+
function VmFunction(fn, option = {}) {
|
|
668
|
+
if (typeof fn != "function") {
|
|
669
|
+
throw new TypeError("Invalid function");
|
|
670
|
+
}
|
|
671
|
+
const exists = fromVmFunctionProxy(fn);
|
|
672
|
+
if (exists) return exists;
|
|
673
|
+
const info = {
|
|
674
|
+
fullName: option.fullName ?? fn.name,
|
|
675
|
+
isLib: option.isLib ?? false,
|
|
676
|
+
summary: option.summary || void 0,
|
|
677
|
+
params: option.params,
|
|
678
|
+
paramsType: option.paramsType,
|
|
679
|
+
returns: option.returns || void 0,
|
|
680
|
+
returnsType: option.returnsType || void 0,
|
|
681
|
+
examples: option.examples?.length ? option.examples : void 0
|
|
682
|
+
};
|
|
683
|
+
if (option.injectCp) {
|
|
684
|
+
const original = fn;
|
|
685
|
+
info.original = original;
|
|
686
|
+
fn = ((...args) => {
|
|
687
|
+
try {
|
|
688
|
+
CpEnter();
|
|
689
|
+
const ret = original(...args);
|
|
690
|
+
return ret;
|
|
691
|
+
} finally {
|
|
692
|
+
CpExit();
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
defineProperty(fn, "name", {
|
|
696
|
+
value: original.name,
|
|
697
|
+
configurable: true
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
defineProperty(fn, kVmFunction, {
|
|
701
|
+
value: Object.freeze(info)
|
|
702
|
+
});
|
|
703
|
+
return fn;
|
|
704
|
+
}
|
|
705
|
+
function toVmFunctionProxy(fn) {
|
|
706
|
+
if (!isVmFunction(fn)) return fn;
|
|
707
|
+
const cached = fn[kProxy];
|
|
708
|
+
if (cached) return cached;
|
|
709
|
+
const proxy = (...args) => {
|
|
710
|
+
const ret = $Call(
|
|
711
|
+
fn,
|
|
712
|
+
// 作为函数参数传入的值一定丢失了它的 this
|
|
713
|
+
args.map((v) => wrapToVmValue(v, null))
|
|
714
|
+
);
|
|
715
|
+
return unwrapFromVmValue(ret);
|
|
716
|
+
};
|
|
717
|
+
defineProperty(fn, kProxy, { value: proxy });
|
|
718
|
+
defineProperty(proxy, kProxy, { value: fn });
|
|
719
|
+
defineProperty(proxy, "name", {
|
|
720
|
+
value: fn.name,
|
|
721
|
+
configurable: true
|
|
722
|
+
});
|
|
723
|
+
return proxy;
|
|
724
|
+
}
|
|
725
|
+
function fromVmFunctionProxy(fn) {
|
|
726
|
+
if (isVmFunction(fn)) return fn;
|
|
727
|
+
const original = fn[kProxy];
|
|
728
|
+
if (original && isVmFunction(original)) return original;
|
|
729
|
+
return void 0;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// src/vm/types/extern.ts
|
|
733
|
+
var { apply } = Reflect;
|
|
734
|
+
function wrapToVmValue(value, caller) {
|
|
735
|
+
if (value == null) return null;
|
|
736
|
+
switch (typeof value) {
|
|
737
|
+
case "function": {
|
|
738
|
+
const unwrapped = fromVmFunctionProxy(value);
|
|
739
|
+
if (unwrapped) return unwrapped;
|
|
740
|
+
return new VmExtern(value, caller);
|
|
741
|
+
}
|
|
742
|
+
case "object":
|
|
743
|
+
if (value instanceof VmWrapper) return value;
|
|
744
|
+
return new VmExtern(value, null);
|
|
745
|
+
case "string":
|
|
746
|
+
case "number":
|
|
747
|
+
case "boolean":
|
|
748
|
+
return value;
|
|
749
|
+
case "bigint":
|
|
750
|
+
return Number(value);
|
|
751
|
+
case "symbol":
|
|
752
|
+
case "undefined":
|
|
753
|
+
default:
|
|
754
|
+
return null;
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
function unwrapFromVmValue(value) {
|
|
758
|
+
if (typeof value == "function") {
|
|
759
|
+
return toVmFunctionProxy(value);
|
|
760
|
+
}
|
|
761
|
+
if (value == null || typeof value != "object") return value;
|
|
762
|
+
if (!(value instanceof VmExtern)) return value;
|
|
763
|
+
if (value.caller == null || typeof value.value != "function") {
|
|
764
|
+
return value.value;
|
|
765
|
+
}
|
|
766
|
+
const caller = value.caller.value;
|
|
767
|
+
const func = value.value;
|
|
768
|
+
return new Proxy(func, {
|
|
769
|
+
apply(target, thisArg, args) {
|
|
770
|
+
return apply(target, caller, args);
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
var ObjectPrototype = Object.prototype;
|
|
775
|
+
var ObjectToString = ObjectPrototype.toString;
|
|
776
|
+
var VmExtern = class _VmExtern extends VmWrapper {
|
|
777
|
+
constructor(value, caller = null) {
|
|
778
|
+
super(value);
|
|
779
|
+
this.caller = caller;
|
|
780
|
+
}
|
|
781
|
+
/** Check if the object has a property */
|
|
782
|
+
access(key, read) {
|
|
783
|
+
if (key.startsWith("_")) return false;
|
|
784
|
+
if (typeof this.value == "function" && (key === "prototype" || key === "arguments" || key === "caller"))
|
|
785
|
+
return false;
|
|
786
|
+
if (hasOwn(this.value, key)) return true;
|
|
787
|
+
if (!read) return true;
|
|
788
|
+
if (!(key in this.value)) return false;
|
|
789
|
+
if (key === "constructor") return false;
|
|
790
|
+
const prop = this.value[key];
|
|
791
|
+
if (key in Function.prototype && prop === Function.prototype[key]) return false;
|
|
792
|
+
if (key in Array.prototype && prop === Array.prototype[key]) return false;
|
|
793
|
+
if (key in Object.prototype && prop === Object.prototype[key]) return false;
|
|
794
|
+
return true;
|
|
795
|
+
}
|
|
796
|
+
/** @inheritdoc */
|
|
797
|
+
has(key) {
|
|
798
|
+
return this.access(key, true);
|
|
799
|
+
}
|
|
800
|
+
/** @inheritdoc */
|
|
801
|
+
get(key) {
|
|
802
|
+
if (!this.has(key)) return void 0;
|
|
803
|
+
const prop = this.value[key];
|
|
804
|
+
return wrapToVmValue(prop, this);
|
|
805
|
+
}
|
|
806
|
+
/** Set a property on the object */
|
|
807
|
+
set(key, value) {
|
|
808
|
+
if (!this.access(key, false)) return false;
|
|
809
|
+
const prop = unwrapFromVmValue(value);
|
|
810
|
+
this.value[key] = prop;
|
|
811
|
+
return true;
|
|
812
|
+
}
|
|
813
|
+
/** Call extern value */
|
|
814
|
+
call(args) {
|
|
815
|
+
const { value } = this;
|
|
816
|
+
const caller = this.caller?.value ?? null;
|
|
817
|
+
const unwrappedArgs = args.map(unwrapFromVmValue);
|
|
818
|
+
try {
|
|
819
|
+
const ret = apply(value, caller, unwrappedArgs);
|
|
820
|
+
return wrapToVmValue(ret, null);
|
|
821
|
+
} catch (ex) {
|
|
822
|
+
throw VmError.from(`Not a callable extern`, ex, null);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
/** @inheritdoc */
|
|
826
|
+
keys() {
|
|
827
|
+
const keys3 = [];
|
|
828
|
+
for (const key in this.value) {
|
|
829
|
+
if (this.has(key)) keys3.push(key);
|
|
830
|
+
}
|
|
831
|
+
return keys3;
|
|
832
|
+
}
|
|
833
|
+
/** @inheritdoc */
|
|
834
|
+
same(other) {
|
|
835
|
+
if (!(other instanceof _VmExtern)) return false;
|
|
836
|
+
return this.value === other.value && this.caller === other.caller;
|
|
837
|
+
}
|
|
838
|
+
/** @inheritdoc */
|
|
839
|
+
toString() {
|
|
840
|
+
const { toString } = this.value;
|
|
841
|
+
if (typeof toString != "function" || toString === ObjectToString) {
|
|
842
|
+
return super.toString();
|
|
843
|
+
}
|
|
844
|
+
try {
|
|
845
|
+
return String(this.value);
|
|
846
|
+
} catch {
|
|
847
|
+
return super.toString();
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
/** @inheritdoc */
|
|
851
|
+
get type() {
|
|
852
|
+
return "extern";
|
|
853
|
+
}
|
|
854
|
+
/** @inheritdoc */
|
|
855
|
+
get describe() {
|
|
856
|
+
const tag = ObjectToString.call(this.value).slice(8, -1);
|
|
857
|
+
if (tag === "Object") {
|
|
858
|
+
const proto = getPrototypeOf(this.value);
|
|
859
|
+
if (proto === ObjectPrototype) {
|
|
860
|
+
return "Object";
|
|
861
|
+
}
|
|
862
|
+
if (proto == null) {
|
|
863
|
+
return "Object: null prototype";
|
|
864
|
+
}
|
|
865
|
+
if (typeof proto.constructor === "function" && proto.constructor.name) {
|
|
866
|
+
return proto.constructor.name;
|
|
867
|
+
}
|
|
868
|
+
} else if (tag === "Function" && "prototype" in this.value && typeof this.value.prototype == "object") {
|
|
869
|
+
const { name } = this.value;
|
|
870
|
+
if (name) {
|
|
871
|
+
return `Class ${name}`;
|
|
872
|
+
} else {
|
|
873
|
+
return "Class";
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
return tag;
|
|
877
|
+
}
|
|
878
|
+
};
|
|
879
|
+
|
|
880
|
+
// src/vm/types/module.ts
|
|
881
|
+
var VmModule = class extends VmWrapper {
|
|
882
|
+
constructor(name, value) {
|
|
883
|
+
super(value);
|
|
884
|
+
this.name = name;
|
|
885
|
+
}
|
|
886
|
+
/** @inheritdoc */
|
|
887
|
+
has(key) {
|
|
888
|
+
return hasOwnEnumerable(this.value, key);
|
|
889
|
+
}
|
|
890
|
+
/** @inheritdoc */
|
|
891
|
+
get(key) {
|
|
892
|
+
if (!this.has(key)) return void 0;
|
|
893
|
+
return this.value[key] ?? null;
|
|
894
|
+
}
|
|
895
|
+
/** @inheritdoc */
|
|
896
|
+
keys() {
|
|
897
|
+
return keys(this.value);
|
|
898
|
+
}
|
|
899
|
+
/** @inheritdoc */
|
|
900
|
+
same(other) {
|
|
901
|
+
return this === other;
|
|
902
|
+
}
|
|
903
|
+
/** @inheritdoc */
|
|
904
|
+
get type() {
|
|
905
|
+
return "module";
|
|
906
|
+
}
|
|
907
|
+
/** @inheritdoc */
|
|
908
|
+
get describe() {
|
|
909
|
+
return this.name;
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
|
|
913
|
+
// src/vm/types/script.ts
|
|
914
|
+
var kVmScript = Symbol.for("mirascript.vm.script");
|
|
915
|
+
function isVmScript(value) {
|
|
916
|
+
return typeof value === "function" && value[kVmScript] === true;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// src/vm/types/checker.ts
|
|
920
|
+
var MAX_DEPTH2 = 32;
|
|
921
|
+
function isVmArrayDeep(value, depth) {
|
|
922
|
+
const proto1 = getPrototypeOf(value);
|
|
923
|
+
if (!isArray(proto1)) return false;
|
|
924
|
+
if (!depth) return true;
|
|
925
|
+
return value.every((item) => isVmConstInner(item, depth));
|
|
926
|
+
}
|
|
927
|
+
function isVmRecordDeep(value, depth) {
|
|
928
|
+
let isRecord;
|
|
929
|
+
const proto1 = getPrototypeOf(value);
|
|
930
|
+
if (proto1 == null) {
|
|
931
|
+
isRecord = true;
|
|
932
|
+
} else {
|
|
933
|
+
const proto2 = getPrototypeOf(proto1);
|
|
934
|
+
if (proto2 != null) {
|
|
935
|
+
isRecord = false;
|
|
936
|
+
} else {
|
|
937
|
+
isRecord = "hasOwnProperty" in value;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
if (!isRecord) return false;
|
|
941
|
+
if (!depth) return true;
|
|
942
|
+
return values(value).every((value2) => isVmConstInner(value2, depth));
|
|
943
|
+
}
|
|
944
|
+
function isVmConstInner(value, depth) {
|
|
945
|
+
if (depth++ >= MAX_DEPTH2) return false;
|
|
946
|
+
switch (typeof value) {
|
|
947
|
+
case "string":
|
|
948
|
+
case "number":
|
|
949
|
+
case "boolean":
|
|
950
|
+
case "undefined":
|
|
951
|
+
return true;
|
|
952
|
+
case "object":
|
|
953
|
+
if (value == null) return true;
|
|
954
|
+
if (value instanceof VmWrapper) return false;
|
|
955
|
+
if (isArray(value)) {
|
|
956
|
+
return isVmArrayDeep(value, depth);
|
|
957
|
+
} else {
|
|
958
|
+
return isVmRecordDeep(value, depth);
|
|
959
|
+
}
|
|
960
|
+
case "function":
|
|
961
|
+
case "bigint":
|
|
962
|
+
case "symbol":
|
|
963
|
+
default:
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
function isVmConst(value, checkDeep = false) {
|
|
968
|
+
switch (typeof value) {
|
|
969
|
+
case "string":
|
|
970
|
+
case "number":
|
|
971
|
+
case "boolean":
|
|
972
|
+
return true;
|
|
973
|
+
case "object":
|
|
974
|
+
if (value == null) return true;
|
|
975
|
+
if (value instanceof VmWrapper) return false;
|
|
976
|
+
if (!checkDeep) {
|
|
977
|
+
if (isArray(value)) {
|
|
978
|
+
return isVmArrayDeep(value, 0);
|
|
979
|
+
} else {
|
|
980
|
+
return isVmRecordDeep(value, 0);
|
|
981
|
+
}
|
|
982
|
+
} else {
|
|
983
|
+
return isVmConstInner(value, 1);
|
|
984
|
+
}
|
|
985
|
+
case "undefined":
|
|
986
|
+
case "function":
|
|
987
|
+
case "bigint":
|
|
988
|
+
case "symbol":
|
|
989
|
+
default:
|
|
990
|
+
return false;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
function isVmImmutable(value, checkDeep = false) {
|
|
994
|
+
return value instanceof VmModule || isVmFunction(value) || isVmConst(value, checkDeep);
|
|
995
|
+
}
|
|
996
|
+
function isVmValue(value, checkDeep = false) {
|
|
997
|
+
if (value === void 0) return false;
|
|
998
|
+
return isVmAny(value, checkDeep);
|
|
999
|
+
}
|
|
1000
|
+
function isVmAny(value, checkDeep) {
|
|
1001
|
+
switch (typeof value) {
|
|
1002
|
+
case "string":
|
|
1003
|
+
case "number":
|
|
1004
|
+
case "boolean":
|
|
1005
|
+
case "undefined":
|
|
1006
|
+
return true;
|
|
1007
|
+
case "object":
|
|
1008
|
+
if (value == null) return true;
|
|
1009
|
+
if (value instanceof VmWrapper) return true;
|
|
1010
|
+
return isVmConst(value, checkDeep);
|
|
1011
|
+
case "function":
|
|
1012
|
+
return isVmFunction(value);
|
|
1013
|
+
case "bigint":
|
|
1014
|
+
case "symbol":
|
|
1015
|
+
default:
|
|
1016
|
+
return false;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
// src/vm/types/index.ts
|
|
1021
|
+
function isVmArray(value) {
|
|
1022
|
+
if (!isArray(value)) return false;
|
|
1023
|
+
value;
|
|
1024
|
+
return true;
|
|
1025
|
+
}
|
|
1026
|
+
function isVmRecord(value) {
|
|
1027
|
+
if (value == null || typeof value !== "object") return false;
|
|
1028
|
+
if (value instanceof VmWrapper) return false;
|
|
1029
|
+
if (isVmArray(value)) return false;
|
|
1030
|
+
value;
|
|
1031
|
+
return true;
|
|
1032
|
+
}
|
|
1033
|
+
function isVmPrimitive(value) {
|
|
1034
|
+
if (value === null || typeof value == "number" || typeof value == "string" || typeof value == "boolean") {
|
|
1035
|
+
value;
|
|
1036
|
+
value;
|
|
1037
|
+
return true;
|
|
1038
|
+
}
|
|
1039
|
+
return false;
|
|
1040
|
+
}
|
|
1041
|
+
function isVmExtern(value) {
|
|
1042
|
+
return value instanceof VmExtern;
|
|
1043
|
+
}
|
|
1044
|
+
function isVmModule(value) {
|
|
1045
|
+
return value instanceof VmModule;
|
|
1046
|
+
}
|
|
1047
|
+
var VM_ARRAY_MAX_LENGTH = 2 ** 31 - 1;
|
|
1048
|
+
|
|
1049
|
+
// src/vm/types/context.ts
|
|
1050
|
+
var kVmContext = Symbol.for("mira:vm-context");
|
|
1051
|
+
var VmSharedContext = { __proto__: null };
|
|
1052
|
+
function defineVmContextValue(name, value, override = false) {
|
|
1053
|
+
if (!override && name in VmSharedContext) throw new Error(`Global variable '${name}' is already defined.`);
|
|
1054
|
+
let v;
|
|
1055
|
+
if (typeof value == "function") {
|
|
1056
|
+
v = VmFunction(value, {
|
|
1057
|
+
isLib: true,
|
|
1058
|
+
fullName: `global.${name}`
|
|
1059
|
+
});
|
|
1060
|
+
} else {
|
|
1061
|
+
v = value;
|
|
1062
|
+
}
|
|
1063
|
+
VmSharedContext[name] = v ?? null;
|
|
1064
|
+
}
|
|
1065
|
+
var DefaultVmContext = Object.freeze({
|
|
1066
|
+
[kVmContext]: true,
|
|
1067
|
+
/** @inheritdoc */
|
|
1068
|
+
keys() {
|
|
1069
|
+
return keys(VmSharedContext);
|
|
1070
|
+
},
|
|
1071
|
+
/** @inheritdoc */
|
|
1072
|
+
get(key) {
|
|
1073
|
+
return VmSharedContext[key] ?? null;
|
|
1074
|
+
},
|
|
1075
|
+
/** @inheritdoc */
|
|
1076
|
+
has(key) {
|
|
1077
|
+
return key in VmSharedContext;
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
1080
|
+
var _a;
|
|
1081
|
+
_a = kVmContext;
|
|
1082
|
+
var ValueVmContext = class {
|
|
1083
|
+
constructor(env) {
|
|
1084
|
+
this.env = env;
|
|
1085
|
+
this[_a] = true;
|
|
1086
|
+
this.cachedKeys = null;
|
|
1087
|
+
}
|
|
1088
|
+
/** @inheritdoc */
|
|
1089
|
+
keys() {
|
|
1090
|
+
this.cachedKeys ??= keys(this.env);
|
|
1091
|
+
return [...this.cachedKeys, ...DefaultVmContext.keys()];
|
|
1092
|
+
}
|
|
1093
|
+
/** @inheritdoc */
|
|
1094
|
+
get(key) {
|
|
1095
|
+
return this.env[key] ?? null;
|
|
1096
|
+
}
|
|
1097
|
+
/** @inheritdoc */
|
|
1098
|
+
has(key) {
|
|
1099
|
+
return key in this.env;
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
var _a2;
|
|
1103
|
+
_a2 = kVmContext;
|
|
1104
|
+
var FactoryVmContext = class {
|
|
1105
|
+
constructor(getter, enumerator) {
|
|
1106
|
+
this.getter = getter;
|
|
1107
|
+
this.enumerator = enumerator;
|
|
1108
|
+
this[_a2] = true;
|
|
1109
|
+
}
|
|
1110
|
+
/** @inheritdoc */
|
|
1111
|
+
keys() {
|
|
1112
|
+
if (!this.enumerator) return DefaultVmContext.keys();
|
|
1113
|
+
return [...this.enumerator(), ...DefaultVmContext.keys()];
|
|
1114
|
+
}
|
|
1115
|
+
/** @inheritdoc */
|
|
1116
|
+
get(key) {
|
|
1117
|
+
const value = this.getter(key);
|
|
1118
|
+
if (value !== void 0) return value;
|
|
1119
|
+
return DefaultVmContext.get(key);
|
|
1120
|
+
}
|
|
1121
|
+
/** @inheritdoc */
|
|
1122
|
+
has(key) {
|
|
1123
|
+
return this.getter(key) !== void 0 || DefaultVmContext.has(key);
|
|
1124
|
+
}
|
|
1125
|
+
};
|
|
1126
|
+
function createVmContext(...args) {
|
|
1127
|
+
if (args[0] == null && args[1] == null) {
|
|
1128
|
+
return { ...DefaultVmContext };
|
|
1129
|
+
}
|
|
1130
|
+
if (typeof args[0] == "function") {
|
|
1131
|
+
return new FactoryVmContext(args[0], args[1]);
|
|
1132
|
+
}
|
|
1133
|
+
const [vmValues, externValues] = args;
|
|
1134
|
+
const env = { __proto__: VmSharedContext };
|
|
1135
|
+
if (vmValues) {
|
|
1136
|
+
for (const [key, value] of entries(vmValues)) {
|
|
1137
|
+
if (!isVmAny(value, false)) continue;
|
|
1138
|
+
env[key] = value ?? null;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
if (externValues) {
|
|
1142
|
+
for (const [key, value] of entries(externValues)) {
|
|
1143
|
+
env[key] = value == null ? null : wrapToVmValue(value, null);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
return new ValueVmContext(env);
|
|
1147
|
+
}
|
|
1148
|
+
function isVmContext(context) {
|
|
1149
|
+
if (context == null || typeof context != "object") return false;
|
|
1150
|
+
return context[kVmContext] === true;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
// src/vm/lib/global/index.ts
|
|
1154
|
+
var global_exports = {};
|
|
1155
|
+
__export(global_exports, {
|
|
1156
|
+
"@e": () => E,
|
|
1157
|
+
"@pi": () => PI,
|
|
1158
|
+
abs: () => abs2,
|
|
1159
|
+
acos: () => acos,
|
|
1160
|
+
acosh: () => acosh,
|
|
1161
|
+
all: () => all,
|
|
1162
|
+
any: () => any,
|
|
1163
|
+
asin: () => asin,
|
|
1164
|
+
asinh: () => asinh,
|
|
1165
|
+
atan: () => atan,
|
|
1166
|
+
atan2: () => atan2,
|
|
1167
|
+
atanh: () => atanh,
|
|
1168
|
+
b_and: () => b_and,
|
|
1169
|
+
b_not: () => b_not,
|
|
1170
|
+
b_or: () => b_or,
|
|
1171
|
+
b_xor: () => b_xor,
|
|
1172
|
+
cbrt: () => cbrt,
|
|
1173
|
+
ceil: () => ceil2,
|
|
1174
|
+
chars: () => chars,
|
|
1175
|
+
contains: () => contains,
|
|
1176
|
+
cos: () => cos,
|
|
1177
|
+
cosh: () => cosh,
|
|
1178
|
+
debug_print: () => debug_print,
|
|
1179
|
+
ends_with: () => ends_with,
|
|
1180
|
+
entries: () => entries2,
|
|
1181
|
+
exp: () => exp,
|
|
1182
|
+
expm1: () => expm1,
|
|
1183
|
+
factorial: () => factorial,
|
|
1184
|
+
filter: () => filter,
|
|
1185
|
+
filter_map: () => filter_map,
|
|
1186
|
+
find: () => find,
|
|
1187
|
+
flatten: () => flatten,
|
|
1188
|
+
floor: () => floor,
|
|
1189
|
+
format: () => format,
|
|
1190
|
+
from_json: () => from_json,
|
|
1191
|
+
hypot: () => hypot,
|
|
1192
|
+
join: () => join,
|
|
1193
|
+
keys: () => keys2,
|
|
1194
|
+
len: () => len,
|
|
1195
|
+
log: () => log,
|
|
1196
|
+
log10: () => log10,
|
|
1197
|
+
log1p: () => log1p,
|
|
1198
|
+
log2: () => log2,
|
|
1199
|
+
map: () => map2,
|
|
1200
|
+
matrix: () => matrix,
|
|
1201
|
+
max: () => max,
|
|
1202
|
+
min: () => min2,
|
|
1203
|
+
panic: () => panic,
|
|
1204
|
+
pow: () => pow2,
|
|
1205
|
+
product: () => product,
|
|
1206
|
+
random: () => random,
|
|
1207
|
+
repeat: () => repeat,
|
|
1208
|
+
replace: () => replace,
|
|
1209
|
+
reverse: () => reverse,
|
|
1210
|
+
round: () => round,
|
|
1211
|
+
sar: () => sar,
|
|
1212
|
+
shl: () => shl,
|
|
1213
|
+
shr: () => shr,
|
|
1214
|
+
sign: () => sign,
|
|
1215
|
+
sin: () => sin,
|
|
1216
|
+
sinh: () => sinh,
|
|
1217
|
+
sort: () => sort,
|
|
1218
|
+
sort_by: () => sort_by,
|
|
1219
|
+
split: () => split,
|
|
1220
|
+
sqrt: () => sqrt,
|
|
1221
|
+
starts_with: () => starts_with,
|
|
1222
|
+
sum: () => sum,
|
|
1223
|
+
tan: () => tan,
|
|
1224
|
+
tanh: () => tanh,
|
|
1225
|
+
to_boolean: () => to_boolean,
|
|
1226
|
+
to_datetime: () => to_datetime,
|
|
1227
|
+
to_iso8601: () => to_iso8601,
|
|
1228
|
+
to_json: () => to_json,
|
|
1229
|
+
to_number: () => to_number,
|
|
1230
|
+
to_string: () => to_string,
|
|
1231
|
+
to_timestamp: () => to_timestamp,
|
|
1232
|
+
trim: () => trim,
|
|
1233
|
+
trim_end: () => trim_end,
|
|
1234
|
+
trim_start: () => trim_start,
|
|
1235
|
+
trunc: () => trunc2,
|
|
1236
|
+
values: () => values2,
|
|
1237
|
+
with: () => _with,
|
|
1238
|
+
zip: () => zip
|
|
1239
|
+
});
|
|
1240
|
+
|
|
1241
|
+
// src/vm/lib/_helpers.ts
|
|
1242
|
+
function throwError(message, recovered) {
|
|
1243
|
+
const recoveredValue = typeof recovered === "function" && !isVmFunction(recovered) ? recovered() : recovered;
|
|
1244
|
+
throw new VmError(message, recoveredValue);
|
|
1245
|
+
}
|
|
1246
|
+
function throwUnexpectedTypeError(name, expected, value, recovered) {
|
|
1247
|
+
const actual = $Type(value);
|
|
1248
|
+
if (typeof name == "string") throwError(`Expected ${expected} for parameter '${name}', got ${actual}`, recovered);
|
|
1249
|
+
const pos = name <= 0 ? "first" : name <= 1 ? "second" : name + 1 + "th";
|
|
1250
|
+
throwError(`Expected ${expected} at the ${pos} position, got ${actual}`, recovered);
|
|
1251
|
+
}
|
|
1252
|
+
function rethrowError(prefix, error, recovered) {
|
|
1253
|
+
const recoveredValue = typeof recovered === "function" && !isVmFunction(recovered) ? recovered() : recovered;
|
|
1254
|
+
throw VmError.from(prefix, error, recoveredValue);
|
|
1255
|
+
}
|
|
1256
|
+
function required(name, value, recovered) {
|
|
1257
|
+
if (value === void 0) {
|
|
1258
|
+
if (typeof name == "string") throwError(`Missing required parameter '${name}'`, recovered);
|
|
1259
|
+
const pos = name <= 0 ? "first" : name <= 1 ? "second" : name + 1 + "th";
|
|
1260
|
+
throwError(`Missing required parameter at the ${pos} position`, recovered);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
function expectArray(name, value, recovered) {
|
|
1264
|
+
required(name, value, recovered);
|
|
1265
|
+
if (!isVmArray(value)) {
|
|
1266
|
+
throwUnexpectedTypeError(name, "array", value, recovered);
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
function expectArrayOrRecord(name, value, recovered) {
|
|
1270
|
+
required(name, value, recovered);
|
|
1271
|
+
if (!isVmArray(value) && !isVmRecord(value)) {
|
|
1272
|
+
throwUnexpectedTypeError(name, "array | record", value, recovered);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
function expectCompound(name, value, recovered) {
|
|
1276
|
+
required(name, value, recovered);
|
|
1277
|
+
if (isVmPrimitive(value) || isVmFunction(value)) {
|
|
1278
|
+
throwUnexpectedTypeError(name, "array | record | module | extern", value, recovered);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
function expectConst(name, value, recovered) {
|
|
1282
|
+
required(name, value, recovered);
|
|
1283
|
+
if (!isVmConst(value)) {
|
|
1284
|
+
throwUnexpectedTypeError(name, "nil | number | boolean | string | array | record", value, recovered);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
function expectCallable(name, value, recovered) {
|
|
1288
|
+
required(name, value, recovered);
|
|
1289
|
+
const callable = isVmFunction(value) || isVmExtern(value);
|
|
1290
|
+
if (!callable) {
|
|
1291
|
+
throwUnexpectedTypeError(name, "callable", value, recovered);
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
function getNumbers(args) {
|
|
1295
|
+
if (args.length === 0) return [];
|
|
1296
|
+
if (args.length === 1 && isVmArray(args[0])) args = args[0];
|
|
1297
|
+
const numbers = [];
|
|
1298
|
+
for (const arg of args) {
|
|
1299
|
+
if (arg == null) continue;
|
|
1300
|
+
numbers.push($ToNumber(arg));
|
|
1301
|
+
}
|
|
1302
|
+
return numbers;
|
|
1303
|
+
}
|
|
1304
|
+
function arrayLen(len2) {
|
|
1305
|
+
if (len2 == null || isNaN(len2) || len2 <= 0) return 0;
|
|
1306
|
+
len2 = Math.trunc(len2);
|
|
1307
|
+
if (len2 > VM_ARRAY_MAX_LENGTH) throwError(`Array length exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`, null);
|
|
1308
|
+
return len2;
|
|
1309
|
+
}
|
|
1310
|
+
function map(data, mapper) {
|
|
1311
|
+
if (isVmPrimitive(data)) {
|
|
1312
|
+
return mapper(data, null, data) ?? null;
|
|
1313
|
+
}
|
|
1314
|
+
if (isVmArray(data)) {
|
|
1315
|
+
const result = [];
|
|
1316
|
+
const { length } = data;
|
|
1317
|
+
for (let i = 0; i < length; i++) {
|
|
1318
|
+
Cp();
|
|
1319
|
+
const ret = mapper(data[i] ?? null, i, data);
|
|
1320
|
+
if (ret === void 0) continue;
|
|
1321
|
+
if (isVmConst(ret)) {
|
|
1322
|
+
result.push(ret);
|
|
1323
|
+
} else {
|
|
1324
|
+
result.push(null);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
return result;
|
|
1328
|
+
} else {
|
|
1329
|
+
const e = [];
|
|
1330
|
+
for (const [key, value] of entries(data)) {
|
|
1331
|
+
Cp();
|
|
1332
|
+
const ret = mapper(value ?? null, key, data);
|
|
1333
|
+
if (ret === void 0) continue;
|
|
1334
|
+
if (isVmConst(ret)) {
|
|
1335
|
+
e.push([key, ret]);
|
|
1336
|
+
} else {
|
|
1337
|
+
e.push([key, null]);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
return fromEntries(e);
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
function VmLib(fn, option) {
|
|
1344
|
+
if (typeof fn != "function") throw new TypeError("Invalid function");
|
|
1345
|
+
if (isVmFunction(fn)) throw new TypeError("Cannot create VmLib from a VmFunction");
|
|
1346
|
+
const ret = fn;
|
|
1347
|
+
ret.params = option.params;
|
|
1348
|
+
ret.paramsType = option.paramsType;
|
|
1349
|
+
ret.returns = option.returns;
|
|
1350
|
+
ret.returnsType = option.returnsType;
|
|
1351
|
+
ret.summary = option.summary;
|
|
1352
|
+
ret.examples = option.examples;
|
|
1353
|
+
return ret;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
// src/vm/lib/global/math-arr.ts
|
|
1357
|
+
function build(f) {
|
|
1358
|
+
return (...values3) => {
|
|
1359
|
+
const numbers = getNumbers(values3);
|
|
1360
|
+
return f(...numbers);
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
var max = VmLib(build(Math.max), {
|
|
1364
|
+
summary: "返回一组数中的最大值",
|
|
1365
|
+
params: { "..values": "要比较的数值" },
|
|
1366
|
+
paramsType: { "..values": "number[]" },
|
|
1367
|
+
returnsType: "number",
|
|
1368
|
+
examples: ["max(3, 7, 2) // 7"]
|
|
1369
|
+
});
|
|
1370
|
+
var min2 = VmLib(build(Math.min), {
|
|
1371
|
+
summary: "返回一组数中的最小值",
|
|
1372
|
+
params: { "..values": "要比较的数值" },
|
|
1373
|
+
paramsType: { "..values": "number[]" },
|
|
1374
|
+
returnsType: "number",
|
|
1375
|
+
examples: ["min(3, 7, 2) // 2"]
|
|
1376
|
+
});
|
|
1377
|
+
var hypot = VmLib(build(Math.hypot), {
|
|
1378
|
+
summary: "返回所有参数平方和的平方根",
|
|
1379
|
+
params: { "..values": "要计算的数值" },
|
|
1380
|
+
paramsType: { "..values": "number[]" },
|
|
1381
|
+
returnsType: "number",
|
|
1382
|
+
examples: ["hypot(3, 4) // 5"]
|
|
1383
|
+
});
|
|
1384
|
+
var sum = VmLib(
|
|
1385
|
+
(...values3) => {
|
|
1386
|
+
const numbers = getNumbers(values3);
|
|
1387
|
+
return numbers.reduce((a, b) => a + b, 0);
|
|
1388
|
+
},
|
|
1389
|
+
{
|
|
1390
|
+
summary: "返回一组数的总和",
|
|
1391
|
+
params: { "..values": "要计算的数值" },
|
|
1392
|
+
paramsType: { "..values": "number[]" },
|
|
1393
|
+
returnsType: "number",
|
|
1394
|
+
examples: ["sum(1, 2, 3, 4) // 10"]
|
|
1395
|
+
}
|
|
1396
|
+
);
|
|
1397
|
+
var product = VmLib(
|
|
1398
|
+
(...values3) => {
|
|
1399
|
+
const numbers = getNumbers(values3);
|
|
1400
|
+
return numbers.reduce((a, b) => a * b, 1);
|
|
1401
|
+
},
|
|
1402
|
+
{
|
|
1403
|
+
summary: "返回一组数的乘积",
|
|
1404
|
+
params: { "..values": "要计算的数值" },
|
|
1405
|
+
paramsType: { "..values": "number[]" },
|
|
1406
|
+
returnsType: "number",
|
|
1407
|
+
examples: ["product(2, 3, 4) // 24"]
|
|
1408
|
+
}
|
|
1409
|
+
);
|
|
1410
|
+
|
|
1411
|
+
// src/vm/lib/global/math-const.ts
|
|
1412
|
+
var { PI, E } = Math;
|
|
1413
|
+
|
|
1414
|
+
// src/vm/lib/global/math-unary.ts
|
|
1415
|
+
function build2(f) {
|
|
1416
|
+
return (x) => {
|
|
1417
|
+
required("x", x, Number.NaN);
|
|
1418
|
+
return f($ToNumber(x));
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
var trunc2 = VmLib(build2(Math.trunc), {
|
|
1422
|
+
summary: "返回数值的整数部分(去除小数)",
|
|
1423
|
+
params: { x: "要取整数部分的数" },
|
|
1424
|
+
paramsType: { x: "number" },
|
|
1425
|
+
returnsType: "number"
|
|
1426
|
+
});
|
|
1427
|
+
var floor = VmLib(build2(Math.floor), {
|
|
1428
|
+
summary: "返回小于等于给定数的最大整数",
|
|
1429
|
+
params: { x: "要向下取整的数" },
|
|
1430
|
+
paramsType: { x: "number" },
|
|
1431
|
+
returnsType: "number"
|
|
1432
|
+
});
|
|
1433
|
+
var ceil2 = VmLib(build2(Math.ceil), {
|
|
1434
|
+
summary: "返回大于等于给定数的最小整数",
|
|
1435
|
+
params: { x: "要向上取整的数" },
|
|
1436
|
+
paramsType: { x: "number" },
|
|
1437
|
+
returnsType: "number"
|
|
1438
|
+
});
|
|
1439
|
+
var round = VmLib(build2(Math.round), {
|
|
1440
|
+
summary: "返回四舍五入后的整数",
|
|
1441
|
+
params: { x: "要四舍五入的数" },
|
|
1442
|
+
paramsType: { x: "number" },
|
|
1443
|
+
returnsType: "number"
|
|
1444
|
+
});
|
|
1445
|
+
var sign = VmLib(build2(Math.sign), {
|
|
1446
|
+
summary: "返回数值的符号(正数为 1,负数为 -1,零为 0)",
|
|
1447
|
+
params: { x: "要判断符号的数" },
|
|
1448
|
+
paramsType: { x: "number" },
|
|
1449
|
+
returnsType: "number"
|
|
1450
|
+
});
|
|
1451
|
+
var abs2 = VmLib(build2(Math.abs), {
|
|
1452
|
+
summary: "返回数值的绝对值",
|
|
1453
|
+
params: { x: "要取绝对值的数" },
|
|
1454
|
+
paramsType: { x: "number" },
|
|
1455
|
+
returnsType: "number"
|
|
1456
|
+
});
|
|
1457
|
+
var acos = VmLib(build2(Math.acos), {
|
|
1458
|
+
summary: "返回数值的反余弦值(弧度)",
|
|
1459
|
+
params: { x: "要计算反余弦的数" },
|
|
1460
|
+
paramsType: { x: "number" },
|
|
1461
|
+
returnsType: "number"
|
|
1462
|
+
});
|
|
1463
|
+
var acosh = VmLib(build2(Math.acosh), {
|
|
1464
|
+
summary: "返回数值的反双曲余弦值",
|
|
1465
|
+
params: { x: "要计算反双曲余弦的数" },
|
|
1466
|
+
paramsType: { x: "number" },
|
|
1467
|
+
returnsType: "number"
|
|
1468
|
+
});
|
|
1469
|
+
var asin = VmLib(build2(Math.asin), {
|
|
1470
|
+
summary: "返回数值的反正弦值(弧度)",
|
|
1471
|
+
params: { x: "要计算反正弦的数" },
|
|
1472
|
+
paramsType: { x: "number" },
|
|
1473
|
+
returnsType: "number"
|
|
1474
|
+
});
|
|
1475
|
+
var asinh = VmLib(build2(Math.asinh), {
|
|
1476
|
+
summary: "返回数值的反双曲正弦值",
|
|
1477
|
+
params: { x: "要计算反双曲正弦的数" },
|
|
1478
|
+
paramsType: { x: "number" },
|
|
1479
|
+
returnsType: "number"
|
|
1480
|
+
});
|
|
1481
|
+
var atan = VmLib(build2(Math.atan), {
|
|
1482
|
+
summary: "返回数值的反正切值(弧度)",
|
|
1483
|
+
params: { x: "要计算反正切的数" },
|
|
1484
|
+
paramsType: { x: "number" },
|
|
1485
|
+
returnsType: "number"
|
|
1486
|
+
});
|
|
1487
|
+
var atanh = VmLib(build2(Math.atanh), {
|
|
1488
|
+
summary: "返回数值的反双曲正切值",
|
|
1489
|
+
params: { x: "要计算反双曲正切的数" },
|
|
1490
|
+
paramsType: { x: "number" },
|
|
1491
|
+
returnsType: "number"
|
|
1492
|
+
});
|
|
1493
|
+
var cos = VmLib(build2(Math.cos), {
|
|
1494
|
+
summary: "返回数值的余弦值",
|
|
1495
|
+
params: { x: "要计算余弦的数(弧度)" },
|
|
1496
|
+
paramsType: { x: "number" },
|
|
1497
|
+
returnsType: "number"
|
|
1498
|
+
});
|
|
1499
|
+
var cosh = VmLib(build2(Math.cosh), {
|
|
1500
|
+
summary: "返回数值的双曲余弦值",
|
|
1501
|
+
params: { x: "要计算双曲余弦的数" },
|
|
1502
|
+
paramsType: { x: "number" },
|
|
1503
|
+
returnsType: "number"
|
|
1504
|
+
});
|
|
1505
|
+
var sin = VmLib(build2(Math.sin), {
|
|
1506
|
+
summary: "返回数值的正弦值",
|
|
1507
|
+
params: { x: "要计算正弦的数(弧度)" },
|
|
1508
|
+
paramsType: { x: "number" },
|
|
1509
|
+
returnsType: "number"
|
|
1510
|
+
});
|
|
1511
|
+
var sinh = VmLib(build2(Math.sinh), {
|
|
1512
|
+
summary: "返回数值的双曲正弦值",
|
|
1513
|
+
params: { x: "要计算双曲正弦的数" },
|
|
1514
|
+
paramsType: { x: "number" },
|
|
1515
|
+
returnsType: "number"
|
|
1516
|
+
});
|
|
1517
|
+
var tan = VmLib(build2(Math.tan), {
|
|
1518
|
+
summary: "返回数值的正切值",
|
|
1519
|
+
params: { x: "要计算正切的数(弧度)" },
|
|
1520
|
+
paramsType: { x: "number" },
|
|
1521
|
+
returnsType: "number"
|
|
1522
|
+
});
|
|
1523
|
+
var tanh = VmLib(build2(Math.tanh), {
|
|
1524
|
+
summary: "返回数值的双曲正切值",
|
|
1525
|
+
params: { x: "要计算双曲正切的数" },
|
|
1526
|
+
paramsType: { x: "number" },
|
|
1527
|
+
returnsType: "number"
|
|
1528
|
+
});
|
|
1529
|
+
var exp = VmLib(build2(Math.exp), {
|
|
1530
|
+
summary: "返回 e 的指定次幂",
|
|
1531
|
+
params: { x: "指数" },
|
|
1532
|
+
paramsType: { x: "number" },
|
|
1533
|
+
returnsType: "number"
|
|
1534
|
+
});
|
|
1535
|
+
var expm1 = VmLib(build2(Math.expm1), {
|
|
1536
|
+
summary: "返回 e 的 x 次幂减 1",
|
|
1537
|
+
params: { x: "指数" },
|
|
1538
|
+
paramsType: { x: "number" },
|
|
1539
|
+
returnsType: "number"
|
|
1540
|
+
});
|
|
1541
|
+
var log = VmLib(build2(Math.log), {
|
|
1542
|
+
summary: "返回数值的自然对数(以 e 为底)",
|
|
1543
|
+
params: { x: "要取对数的数" },
|
|
1544
|
+
paramsType: { x: "number" },
|
|
1545
|
+
returnsType: "number"
|
|
1546
|
+
});
|
|
1547
|
+
var log10 = VmLib(build2(Math.log10), {
|
|
1548
|
+
summary: "返回数值的以 10 为底的对数",
|
|
1549
|
+
params: { x: "要取对数的数" },
|
|
1550
|
+
paramsType: { x: "number" },
|
|
1551
|
+
returnsType: "number"
|
|
1552
|
+
});
|
|
1553
|
+
var log1p = VmLib(build2(Math.log1p), {
|
|
1554
|
+
summary: "返回 1 加上数值的自然对数",
|
|
1555
|
+
params: { x: "要取对数的数" },
|
|
1556
|
+
paramsType: { x: "number" },
|
|
1557
|
+
returnsType: "number"
|
|
1558
|
+
});
|
|
1559
|
+
var log2 = VmLib(build2(Math.log2), {
|
|
1560
|
+
summary: "返回数值的以 2 为底的对数",
|
|
1561
|
+
params: { x: "要取对数的数" },
|
|
1562
|
+
paramsType: { x: "number" },
|
|
1563
|
+
returnsType: "number"
|
|
1564
|
+
});
|
|
1565
|
+
var sqrt = VmLib(build2(Math.sqrt), {
|
|
1566
|
+
summary: "返回数值的平方根",
|
|
1567
|
+
params: { x: "要开平方的数" },
|
|
1568
|
+
paramsType: { x: "number" },
|
|
1569
|
+
returnsType: "number"
|
|
1570
|
+
});
|
|
1571
|
+
var cbrt = VmLib(build2(Math.cbrt), {
|
|
1572
|
+
summary: "返回数值的立方根",
|
|
1573
|
+
params: { x: "要计算立方根的数" },
|
|
1574
|
+
paramsType: { x: "number" },
|
|
1575
|
+
returnsType: "number"
|
|
1576
|
+
});
|
|
1577
|
+
|
|
1578
|
+
// src/vm/lib/global/math-additional.ts
|
|
1579
|
+
var { sqrt: sqrt2, pow, exp: exp2 } = Math;
|
|
1580
|
+
var GAMMA_G = 4.7421875;
|
|
1581
|
+
var GAMMA_P = [
|
|
1582
|
+
0.9999999999999971,
|
|
1583
|
+
57.15623566586292,
|
|
1584
|
+
-59.59796035547549,
|
|
1585
|
+
14.136097974741746,
|
|
1586
|
+
-0.4919138160976202,
|
|
1587
|
+
3399464998481189e-20,
|
|
1588
|
+
4652362892704858e-20,
|
|
1589
|
+
-9837447530487956e-20,
|
|
1590
|
+
1580887032249125e-19,
|
|
1591
|
+
-21026444172410488e-20,
|
|
1592
|
+
21743961811521265e-20,
|
|
1593
|
+
-1643181065367639e-19,
|
|
1594
|
+
8441822398385275e-20,
|
|
1595
|
+
-26190838401581408e-21,
|
|
1596
|
+
36899182659531625e-22
|
|
1597
|
+
];
|
|
1598
|
+
var SQRT_2_PI = sqrt2(2 * Math.PI);
|
|
1599
|
+
var factorial = VmLib(
|
|
1600
|
+
(x) => {
|
|
1601
|
+
required("x", x, Number.NaN);
|
|
1602
|
+
let n = $ToNumber(x);
|
|
1603
|
+
if (isNaN(n) || n < 0) return Number.NaN;
|
|
1604
|
+
if (n >= 171) return Number.POSITIVE_INFINITY;
|
|
1605
|
+
if (isInteger(n)) {
|
|
1606
|
+
if (n === 0 || n === 1) return 1;
|
|
1607
|
+
let r = 1;
|
|
1608
|
+
for (let i = 2; i <= n; i++) {
|
|
1609
|
+
r *= i;
|
|
1610
|
+
}
|
|
1611
|
+
return r;
|
|
1612
|
+
}
|
|
1613
|
+
if (n > 85) {
|
|
1614
|
+
n = n + 1;
|
|
1615
|
+
const twoN = n * n;
|
|
1616
|
+
const threeN = twoN * n;
|
|
1617
|
+
const fourN = threeN * n;
|
|
1618
|
+
const fiveN = fourN * n;
|
|
1619
|
+
return sqrt2(2 * Math.PI / n) * pow(n / Math.E, n) * (1 + 1 / (12 * n) + 1 / (288 * twoN) - 139 / (51840 * threeN) - 571 / (2488320 * fourN) + 163879 / (209018880 * fiveN) + 5246819 / (75246796800 * fiveN * n));
|
|
1620
|
+
}
|
|
1621
|
+
let p = GAMMA_P[0];
|
|
1622
|
+
for (let i = 1; i < GAMMA_P.length; ++i) {
|
|
1623
|
+
p += GAMMA_P[i] / (n + i);
|
|
1624
|
+
}
|
|
1625
|
+
const t = n + GAMMA_G + 0.5;
|
|
1626
|
+
return SQRT_2_PI * pow(t, n + 0.5) * exp2(-t) * p;
|
|
1627
|
+
},
|
|
1628
|
+
{
|
|
1629
|
+
summary: "返回一个数的阶乘",
|
|
1630
|
+
params: { x: "要计算阶乘的数值" },
|
|
1631
|
+
paramsType: { x: "number" },
|
|
1632
|
+
returnsType: "number",
|
|
1633
|
+
examples: ["factorial(5) // 120"]
|
|
1634
|
+
}
|
|
1635
|
+
);
|
|
1636
|
+
|
|
1637
|
+
// src/vm/lib/global/math.ts
|
|
1638
|
+
var { atan2: _atan2, pow: _pow } = Math;
|
|
1639
|
+
var atan2 = VmLib((x, y) => _atan2($ToNumber(x), $ToNumber(y)), {
|
|
1640
|
+
summary: "返回从原点到点 (x, y) 的角度(弧度)",
|
|
1641
|
+
params: { x: "x 坐标", y: "y 坐标" },
|
|
1642
|
+
paramsType: { x: "number", y: "number" },
|
|
1643
|
+
returnsType: "number"
|
|
1644
|
+
});
|
|
1645
|
+
var pow2 = VmLib((x, y) => _pow($ToNumber(x), $ToNumber(y)), {
|
|
1646
|
+
summary: "返回 x 的 y 次幂",
|
|
1647
|
+
params: { x: "底数", y: "指数" },
|
|
1648
|
+
paramsType: { x: "number", y: "number" },
|
|
1649
|
+
returnsType: "number"
|
|
1650
|
+
});
|
|
1651
|
+
var random = VmLib(Math.random, {
|
|
1652
|
+
summary: "返回 0 到 1 之间的伪随机数",
|
|
1653
|
+
params: {},
|
|
1654
|
+
paramsType: {},
|
|
1655
|
+
returnsType: "number"
|
|
1656
|
+
});
|
|
1657
|
+
|
|
1658
|
+
// src/vm/lib/global/bit.ts
|
|
1659
|
+
var b_and = VmLib(
|
|
1660
|
+
(x, y) => {
|
|
1661
|
+
return $ToNumber(x) & $ToNumber(y);
|
|
1662
|
+
},
|
|
1663
|
+
{
|
|
1664
|
+
summary: "返回两个数的按位与",
|
|
1665
|
+
params: { x: "第一个操作数", y: "第二个操作数" },
|
|
1666
|
+
paramsType: { x: "number", y: "number" },
|
|
1667
|
+
returnsType: "number",
|
|
1668
|
+
examples: ["b_and(6, 3) // 2"]
|
|
1669
|
+
}
|
|
1670
|
+
);
|
|
1671
|
+
var b_or = VmLib(
|
|
1672
|
+
(x, y) => {
|
|
1673
|
+
return $ToNumber(x) | $ToNumber(y);
|
|
1674
|
+
},
|
|
1675
|
+
{
|
|
1676
|
+
summary: "返回两个数的按位或",
|
|
1677
|
+
params: { x: "第一个操作数", y: "第二个操作数" },
|
|
1678
|
+
paramsType: { x: "number", y: "number" },
|
|
1679
|
+
returnsType: "number",
|
|
1680
|
+
examples: ["b_or(5, 2) // 7"]
|
|
1681
|
+
}
|
|
1682
|
+
);
|
|
1683
|
+
var b_not = VmLib(
|
|
1684
|
+
(x) => {
|
|
1685
|
+
return ~$ToNumber(x);
|
|
1686
|
+
},
|
|
1687
|
+
{
|
|
1688
|
+
summary: "返回一个数的按位取反",
|
|
1689
|
+
params: { x: "操作数" },
|
|
1690
|
+
paramsType: { x: "number" },
|
|
1691
|
+
returnsType: "number",
|
|
1692
|
+
examples: ["b_not(0) // -1"]
|
|
1693
|
+
}
|
|
1694
|
+
);
|
|
1695
|
+
var b_xor = VmLib(
|
|
1696
|
+
(x, y) => {
|
|
1697
|
+
return $ToNumber(x) ^ $ToNumber(y);
|
|
1698
|
+
},
|
|
1699
|
+
{
|
|
1700
|
+
summary: "返回两个数的按位异或",
|
|
1701
|
+
params: { x: "第一个操作数", y: "第二个操作数" },
|
|
1702
|
+
paramsType: { x: "number", y: "number" },
|
|
1703
|
+
returnsType: "number",
|
|
1704
|
+
examples: ["b_xor(5, 3) // 6"]
|
|
1705
|
+
}
|
|
1706
|
+
);
|
|
1707
|
+
var shl = VmLib(
|
|
1708
|
+
(x, y) => {
|
|
1709
|
+
return $ToNumber(x) << $ToNumber(y);
|
|
1710
|
+
},
|
|
1711
|
+
{
|
|
1712
|
+
summary: "返回第一个操作数左移指定的位数",
|
|
1713
|
+
params: { x: "第一个操作数", y: "位数" },
|
|
1714
|
+
paramsType: { x: "number", y: "number" },
|
|
1715
|
+
returnsType: "number",
|
|
1716
|
+
examples: ["shl(3, 2) // 12"]
|
|
1717
|
+
}
|
|
1718
|
+
);
|
|
1719
|
+
var sar = VmLib(
|
|
1720
|
+
(x, y) => {
|
|
1721
|
+
return $ToNumber(x) >> $ToNumber(y);
|
|
1722
|
+
},
|
|
1723
|
+
{
|
|
1724
|
+
summary: "返回第一个操作数右移指定的位数",
|
|
1725
|
+
params: { x: "第一个操作数", y: "位数" },
|
|
1726
|
+
paramsType: { x: "number", y: "number" },
|
|
1727
|
+
returnsType: "number",
|
|
1728
|
+
examples: ["sar(-8, 1) // -4"]
|
|
1729
|
+
}
|
|
1730
|
+
);
|
|
1731
|
+
var shr = VmLib(
|
|
1732
|
+
(x, y) => {
|
|
1733
|
+
return $ToNumber(x) >>> $ToNumber(y);
|
|
1734
|
+
},
|
|
1735
|
+
{
|
|
1736
|
+
summary: "返回第一个操作数无符号右移指定的位数",
|
|
1737
|
+
params: { x: "第一个操作数", y: "位数" },
|
|
1738
|
+
paramsType: { x: "number", y: "number" },
|
|
1739
|
+
returnsType: "number",
|
|
1740
|
+
examples: ["shr(8, 1) // 4"]
|
|
1741
|
+
}
|
|
1742
|
+
);
|
|
1743
|
+
|
|
1744
|
+
// src/vm/lib/global/sequence/with.ts
|
|
1745
|
+
var _with = VmLib(
|
|
1746
|
+
(data, ...entries3) => {
|
|
1747
|
+
expectArrayOrRecord("data", data, data);
|
|
1748
|
+
if (entries3.length % 2 !== 0) {
|
|
1749
|
+
throwError("Expected even number of entries", data);
|
|
1750
|
+
}
|
|
1751
|
+
if (isVmArray(data)) {
|
|
1752
|
+
const result = [...data];
|
|
1753
|
+
for (let i = 0; i < entries3.length; i += 2) {
|
|
1754
|
+
const index = Math.trunc($ToNumber(entries3[i]));
|
|
1755
|
+
if (!isSafeInteger(index) || index < 0) continue;
|
|
1756
|
+
const value = entries3[i + 1];
|
|
1757
|
+
while (index > result.length) {
|
|
1758
|
+
result.push(null);
|
|
1759
|
+
}
|
|
1760
|
+
result[index] = Element(value);
|
|
1761
|
+
}
|
|
1762
|
+
return result;
|
|
1763
|
+
} else {
|
|
1764
|
+
const result = { ...data };
|
|
1765
|
+
for (let i = 0; i < entries3.length; i += 2) {
|
|
1766
|
+
const key = $ToString(entries3[i]);
|
|
1767
|
+
const value = entries3[i + 1];
|
|
1768
|
+
result[key] = Element(value);
|
|
1769
|
+
}
|
|
1770
|
+
return result;
|
|
1771
|
+
}
|
|
1772
|
+
},
|
|
1773
|
+
{
|
|
1774
|
+
summary: "在数组或记录中设置多个键值对",
|
|
1775
|
+
params: { data: "要设置的数组或记录", "..entries": "要设置的键值对,成对出现" },
|
|
1776
|
+
paramsType: { data: "array | record", "..entries": "[..[string | number, any][]]" },
|
|
1777
|
+
returnsType: "type(data)",
|
|
1778
|
+
examples: ["with([10, 20], 2, 99) // [10, 20, 99]", 'with((a: 1), "b", 2) // (a: 1, b: 2)']
|
|
1779
|
+
}
|
|
1780
|
+
);
|
|
1781
|
+
|
|
1782
|
+
// src/vm/lib/global/sequence/entries.ts
|
|
1783
|
+
var keys2 = VmLib(
|
|
1784
|
+
(data) => {
|
|
1785
|
+
expectCompound("data", data, []);
|
|
1786
|
+
if (isVmArray(data)) {
|
|
1787
|
+
const arr = [];
|
|
1788
|
+
const len2 = data.length;
|
|
1789
|
+
for (let i = 0; i < len2; i++) {
|
|
1790
|
+
arr.push(i);
|
|
1791
|
+
}
|
|
1792
|
+
return arr;
|
|
1793
|
+
}
|
|
1794
|
+
if (isVmRecord(data)) {
|
|
1795
|
+
return keys(data);
|
|
1796
|
+
}
|
|
1797
|
+
return data.keys();
|
|
1798
|
+
},
|
|
1799
|
+
{
|
|
1800
|
+
summary: "返回数组、记录、外部对象或模块的键列表",
|
|
1801
|
+
params: { data: "要获取键的数组、记录、外部对象或模块" },
|
|
1802
|
+
paramsType: { data: "array | record | extern | module" },
|
|
1803
|
+
returnsType: "(string | number)[]",
|
|
1804
|
+
examples: ["keys([10, 20]) // [0, 1]", 'keys((10, 20)) // ["0", "1"]']
|
|
1805
|
+
}
|
|
1806
|
+
);
|
|
1807
|
+
var values2 = VmLib(
|
|
1808
|
+
(data) => {
|
|
1809
|
+
expectArrayOrRecord("data", data, []);
|
|
1810
|
+
if (isVmArray(data)) {
|
|
1811
|
+
return data;
|
|
1812
|
+
}
|
|
1813
|
+
return values(data);
|
|
1814
|
+
},
|
|
1815
|
+
{
|
|
1816
|
+
summary: "返回数组或记录的值列表",
|
|
1817
|
+
params: { data: "要获取值的数组或记录" },
|
|
1818
|
+
paramsType: { data: "array | record" },
|
|
1819
|
+
returnsType: "array",
|
|
1820
|
+
examples: ["values((a: 1, b: 2)) // [1, 2]"]
|
|
1821
|
+
}
|
|
1822
|
+
);
|
|
1823
|
+
var entries2 = VmLib(
|
|
1824
|
+
(data) => {
|
|
1825
|
+
expectArrayOrRecord("data", data, []);
|
|
1826
|
+
if (isVmArray(data)) {
|
|
1827
|
+
const arr = [];
|
|
1828
|
+
const len2 = data.length;
|
|
1829
|
+
for (let i = 0; i < len2; i++) {
|
|
1830
|
+
arr.push({ 0: i, 1: data[i] ?? null });
|
|
1831
|
+
}
|
|
1832
|
+
return arr;
|
|
1833
|
+
}
|
|
1834
|
+
return entries(data).map(([key, value]) => ({ 0: key, 1: value ?? null }));
|
|
1835
|
+
},
|
|
1836
|
+
{
|
|
1837
|
+
summary: "返回数组或记录的键值对列表",
|
|
1838
|
+
params: { data: "要获取键值对的数组或记录" },
|
|
1839
|
+
paramsType: { data: "array | record" },
|
|
1840
|
+
returnsType: "(string | number, any)[]",
|
|
1841
|
+
examples: ["entries([1]) // [(0, 1)]", 'entries((a: 1)) // [("a", 1)]']
|
|
1842
|
+
}
|
|
1843
|
+
);
|
|
1844
|
+
|
|
1845
|
+
// src/vm/lib/global/sequence/len.ts
|
|
1846
|
+
var len = VmLib(
|
|
1847
|
+
(arr) => {
|
|
1848
|
+
expectArray("arr", arr, Number.NaN);
|
|
1849
|
+
return arr.length;
|
|
1850
|
+
},
|
|
1851
|
+
{
|
|
1852
|
+
summary: "返回数组的长度",
|
|
1853
|
+
params: { arr: "要求长度的数组" },
|
|
1854
|
+
paramsType: { arr: "array" },
|
|
1855
|
+
returnsType: "number",
|
|
1856
|
+
examples: ["len([1, 2, 3]) // 3"]
|
|
1857
|
+
}
|
|
1858
|
+
);
|
|
1859
|
+
|
|
1860
|
+
// src/vm/lib/global/sequence/map-filter.ts
|
|
1861
|
+
function mapImplWrapped(data, fnName, fn, mapper) {
|
|
1862
|
+
expectConst("data", data, null);
|
|
1863
|
+
expectCallable(fnName, fn, data);
|
|
1864
|
+
return map(data, (value, index, data2) => {
|
|
1865
|
+
const ret = mapper(fn, value, index, data2);
|
|
1866
|
+
if (ret === void 0 || isVmConst(ret)) return ret;
|
|
1867
|
+
return null;
|
|
1868
|
+
});
|
|
1869
|
+
}
|
|
1870
|
+
var map2 = VmLib(
|
|
1871
|
+
(data, f) => mapImplWrapped(data, "f", f, (fn, value, key, data2) => $Call(fn, [value, key, data2])),
|
|
1872
|
+
{
|
|
1873
|
+
summary: "对数组或记录中的每个元素应用函数,并返回结果",
|
|
1874
|
+
params: {
|
|
1875
|
+
data: "要映射的数组或记录",
|
|
1876
|
+
f: "应用于每个元素的函数"
|
|
1877
|
+
},
|
|
1878
|
+
paramsType: {
|
|
1879
|
+
data: "array | record",
|
|
1880
|
+
f: "fn(value: any, key: number | string | nil, input: type(data)) -> any"
|
|
1881
|
+
},
|
|
1882
|
+
returnsType: "type(data)",
|
|
1883
|
+
examples: ["map([1, 2, 3], fn (v) { v * v }) // [1, 4, 9]"]
|
|
1884
|
+
}
|
|
1885
|
+
);
|
|
1886
|
+
var filter = VmLib(
|
|
1887
|
+
(data, predicate) => mapImplWrapped(data, "predicate", predicate, (fn, value, key, data2) => {
|
|
1888
|
+
const ret = $Call(fn, [value, key, data2]);
|
|
1889
|
+
return $ToBoolean(ret) ? value : void 0;
|
|
1890
|
+
}),
|
|
1891
|
+
{
|
|
1892
|
+
summary: "过滤数组或记录中的元素,返回满足条件的元素",
|
|
1893
|
+
params: {
|
|
1894
|
+
data: "要过滤的数组或记录",
|
|
1895
|
+
predicate: "用于测试每个元素的函数,返回 true 或 false"
|
|
1896
|
+
},
|
|
1897
|
+
paramsType: {
|
|
1898
|
+
data: "array | record",
|
|
1899
|
+
predicate: "fn(value: any, key: number | string | nil, input: type(data)) -> boolean"
|
|
1900
|
+
},
|
|
1901
|
+
returnsType: "type(data)",
|
|
1902
|
+
examples: ["filter([1, 2, 3, 4], fn (v) { v % 2 == 0 }) // [2, 4]"]
|
|
1903
|
+
}
|
|
1904
|
+
);
|
|
1905
|
+
var filter_map = VmLib(
|
|
1906
|
+
(data, f) => mapImplWrapped(data, "f", f, (fn, value, key, data2) => {
|
|
1907
|
+
const ret = $Call(fn, [value, key, data2]);
|
|
1908
|
+
return ret ?? void 0;
|
|
1909
|
+
}),
|
|
1910
|
+
{
|
|
1911
|
+
summary: "对数组或记录中的每个元素应用函数,并返回非 nil 的结果",
|
|
1912
|
+
params: {
|
|
1913
|
+
data: "要映射的数组或记录",
|
|
1914
|
+
f: "应用于每个元素的函数,返回 nil 或非 nil 的值"
|
|
1915
|
+
},
|
|
1916
|
+
paramsType: {
|
|
1917
|
+
data: "array | record",
|
|
1918
|
+
f: "fn(value: any, key: number | string | nil, input: type(data)) -> any | nil"
|
|
1919
|
+
},
|
|
1920
|
+
returnsType: "type(data)",
|
|
1921
|
+
examples: ["filter_map([1, 2, 3], fn (v) { if v % 2 == 0 { v * v } else { nil } }) // [4]"]
|
|
1922
|
+
}
|
|
1923
|
+
);
|
|
1924
|
+
|
|
1925
|
+
// src/vm/lib/global/sequence/find.ts
|
|
1926
|
+
var find = VmLib(
|
|
1927
|
+
(data, predicate) => {
|
|
1928
|
+
expectArrayOrRecord("data", data, null);
|
|
1929
|
+
expectCallable("predicate", predicate, data);
|
|
1930
|
+
const p = (value, key, data2) => {
|
|
1931
|
+
const ret = $Call(predicate, [value, key, data2]);
|
|
1932
|
+
return $ToBoolean(ret);
|
|
1933
|
+
};
|
|
1934
|
+
if (isVmArray(data)) {
|
|
1935
|
+
const { length } = data;
|
|
1936
|
+
for (let i = 0; i < length; i++) {
|
|
1937
|
+
Cp();
|
|
1938
|
+
const value = data[i] ?? null;
|
|
1939
|
+
const ret = p(value, i, data);
|
|
1940
|
+
if (!ret) continue;
|
|
1941
|
+
return { 0: i, 1: value };
|
|
1942
|
+
}
|
|
1943
|
+
return null;
|
|
1944
|
+
} else {
|
|
1945
|
+
for (const [key, v] of entries(data)) {
|
|
1946
|
+
Cp();
|
|
1947
|
+
const value = v ?? null;
|
|
1948
|
+
const ret = p(value, key, data);
|
|
1949
|
+
if (!ret) continue;
|
|
1950
|
+
return { 0: key, 1: value };
|
|
1951
|
+
}
|
|
1952
|
+
return null;
|
|
1953
|
+
}
|
|
1954
|
+
},
|
|
1955
|
+
{
|
|
1956
|
+
summary: "查找数组或记录中的键值对,返回第一个满足条件的键值对",
|
|
1957
|
+
params: {
|
|
1958
|
+
data: "查的数组或记录",
|
|
1959
|
+
predicate: "用于测试每个键值对的函数,返回 true 或 false"
|
|
1960
|
+
},
|
|
1961
|
+
paramsType: {
|
|
1962
|
+
data: "array | record",
|
|
1963
|
+
predicate: "fn(value: any, key: number | string | nil, input: type(data)) -> boolean"
|
|
1964
|
+
},
|
|
1965
|
+
returnsType: "(string | number, any) | nil",
|
|
1966
|
+
examples: ["find([3, 5, 8], fn (v) { v % 2 == 0 }) // (2, 8)"]
|
|
1967
|
+
}
|
|
1968
|
+
);
|
|
1969
|
+
|
|
1970
|
+
// src/vm/lib/global/sequence/flatten.ts
|
|
1971
|
+
var flatten = VmLib(
|
|
1972
|
+
(data, depth = 1) => {
|
|
1973
|
+
expectArray("data", data, data);
|
|
1974
|
+
return data.flat($ToNumber(depth));
|
|
1975
|
+
},
|
|
1976
|
+
{
|
|
1977
|
+
summary: "将数组扁平化",
|
|
1978
|
+
params: { data: "要扁平化的数组", depth: "扁平化的深度,默认为 1" },
|
|
1979
|
+
paramsType: { data: "array", depth: "number" },
|
|
1980
|
+
returnsType: "array",
|
|
1981
|
+
examples: ["flatten([[1, 2], [3, [4]]], 2) // [1, 2, 3, 4]"]
|
|
1982
|
+
}
|
|
1983
|
+
);
|
|
1984
|
+
|
|
1985
|
+
// src/vm/lib/global/sequence/reverse.ts
|
|
1986
|
+
var reverse = VmLib(
|
|
1987
|
+
(arr) => {
|
|
1988
|
+
expectArray("arr", arr, null);
|
|
1989
|
+
const dup = [...arr];
|
|
1990
|
+
dup.reverse();
|
|
1991
|
+
return dup;
|
|
1992
|
+
},
|
|
1993
|
+
{
|
|
1994
|
+
summary: "返回数组的反转副本",
|
|
1995
|
+
params: { arr: "要反转的数组" },
|
|
1996
|
+
paramsType: { arr: "array" },
|
|
1997
|
+
returnsType: "array",
|
|
1998
|
+
examples: ["reverse([1, 2, 3]) // [3, 2, 1]"]
|
|
1999
|
+
}
|
|
2000
|
+
);
|
|
2001
|
+
|
|
2002
|
+
// src/vm/lib/global/sequence/zip.ts
|
|
2003
|
+
var zip = VmLib(
|
|
2004
|
+
(data) => {
|
|
2005
|
+
const ets = entries2(data);
|
|
2006
|
+
let len2 = 0;
|
|
2007
|
+
for (const { 0: key, 1: arr } of ets) {
|
|
2008
|
+
if (!isVmArray(arr)) {
|
|
2009
|
+
throwError(`data[${serialize(key)}] is not an array`, null);
|
|
2010
|
+
}
|
|
2011
|
+
len2 = Math.max(len2, arr.length);
|
|
2012
|
+
}
|
|
2013
|
+
if (len2 === 0) return [];
|
|
2014
|
+
const result = [];
|
|
2015
|
+
const isArr = isVmArray(data);
|
|
2016
|
+
for (let i = 0; i < len2; i++) {
|
|
2017
|
+
Cp();
|
|
2018
|
+
const obj = isArr ? [] : {};
|
|
2019
|
+
for (const { 0: key, 1: arr } of ets) {
|
|
2020
|
+
obj[key] = arr[i] ?? null;
|
|
2021
|
+
}
|
|
2022
|
+
result.push(obj);
|
|
2023
|
+
}
|
|
2024
|
+
return result;
|
|
2025
|
+
},
|
|
2026
|
+
{
|
|
2027
|
+
summary: "将数组的数组/记录转换为数组/记录的数组",
|
|
2028
|
+
params: { data: "要转换的数组/记录" },
|
|
2029
|
+
paramsType: { data: "array | record" },
|
|
2030
|
+
returnsType: "(array | record)[]",
|
|
2031
|
+
examples: [
|
|
2032
|
+
'zip((x: [1, 2], y: ["a", "b"])) // [(x: 1, y: "a"), (x: 2, y: "b")]',
|
|
2033
|
+
`zip([[1, 2], ["a", "b"]]) // [[1, "a"], [2, "b"]]`
|
|
2034
|
+
]
|
|
2035
|
+
}
|
|
2036
|
+
);
|
|
2037
|
+
|
|
2038
|
+
// src/vm/lib/global/sequence/all-any.ts
|
|
2039
|
+
var all = VmLib(
|
|
2040
|
+
(data, predicate) => {
|
|
2041
|
+
expectArrayOrRecord("data", data, null);
|
|
2042
|
+
expectCallable("predicate", predicate, data);
|
|
2043
|
+
if (isVmArray(data)) {
|
|
2044
|
+
for (let i = 0; i < data.length; i++) {
|
|
2045
|
+
Cp();
|
|
2046
|
+
const value = data[i] ?? null;
|
|
2047
|
+
const ret = $Call(predicate, [value, i, data]);
|
|
2048
|
+
if (!$ToBoolean(ret)) return false;
|
|
2049
|
+
}
|
|
2050
|
+
return true;
|
|
2051
|
+
} else {
|
|
2052
|
+
for (const [key, v] of entries(data)) {
|
|
2053
|
+
Cp();
|
|
2054
|
+
const value = v ?? null;
|
|
2055
|
+
const ret = $Call(predicate, [value, key, data]);
|
|
2056
|
+
if (!$ToBoolean(ret)) return false;
|
|
2057
|
+
}
|
|
2058
|
+
return true;
|
|
2059
|
+
}
|
|
2060
|
+
},
|
|
2061
|
+
{
|
|
2062
|
+
summary: "检查数组或记录中的所有键值对是否都满足条件",
|
|
2063
|
+
params: { data: "要检查的数组或记录", predicate: "用于测试每个键值对的函数,返回 true 或 false" },
|
|
2064
|
+
paramsType: {
|
|
2065
|
+
data: "array | record",
|
|
2066
|
+
predicate: "fn(value: any, key: number | string, input: type(data)) -> boolean"
|
|
2067
|
+
},
|
|
2068
|
+
returnsType: "boolean",
|
|
2069
|
+
examples: ["all([1, 2, 3], fn { it > 0 }) // true"]
|
|
2070
|
+
}
|
|
2071
|
+
);
|
|
2072
|
+
var any = VmLib(
|
|
2073
|
+
(data, predicate) => {
|
|
2074
|
+
expectArrayOrRecord("data", data, null);
|
|
2075
|
+
expectCallable("predicate", predicate, data);
|
|
2076
|
+
if (isVmArray(data)) {
|
|
2077
|
+
for (let i = 0; i < data.length; i++) {
|
|
2078
|
+
Cp();
|
|
2079
|
+
const value = data[i] ?? null;
|
|
2080
|
+
const ret = $Call(predicate, [value, i, data]);
|
|
2081
|
+
if ($ToBoolean(ret)) return true;
|
|
2082
|
+
}
|
|
2083
|
+
return false;
|
|
2084
|
+
} else {
|
|
2085
|
+
for (const [key, v] of entries(data)) {
|
|
2086
|
+
Cp();
|
|
2087
|
+
const value = v ?? null;
|
|
2088
|
+
const ret = $Call(predicate, [value, key, data]);
|
|
2089
|
+
if ($ToBoolean(ret)) return true;
|
|
2090
|
+
}
|
|
2091
|
+
return false;
|
|
2092
|
+
}
|
|
2093
|
+
},
|
|
2094
|
+
{
|
|
2095
|
+
summary: "检查数组或记录中的是否存在满足条件的键值对",
|
|
2096
|
+
params: { data: "要检查的数组或记录", predicate: "用于测试每个键值对的函数,返回 true 或 false" },
|
|
2097
|
+
paramsType: {
|
|
2098
|
+
data: "array | record",
|
|
2099
|
+
predicate: "fn(value: any, key: number | string, input: type(data)) -> boolean"
|
|
2100
|
+
},
|
|
2101
|
+
returnsType: "boolean",
|
|
2102
|
+
examples: ["any([0, 1, 2], fn { it > 1 }) // true"]
|
|
2103
|
+
}
|
|
2104
|
+
);
|
|
2105
|
+
|
|
2106
|
+
// src/vm/lib/global/sequence/sort.ts
|
|
2107
|
+
function defaultCompare(a, b) {
|
|
2108
|
+
a ??= "";
|
|
2109
|
+
b ??= "";
|
|
2110
|
+
if (typeof a == "string" && typeof b == "string") {
|
|
2111
|
+
if (a < b) return -1;
|
|
2112
|
+
if (a > b) return 1;
|
|
2113
|
+
return 0;
|
|
2114
|
+
}
|
|
2115
|
+
if (Object.is(a, b)) return 0;
|
|
2116
|
+
const an = $ToNumber(a) || 0;
|
|
2117
|
+
const bn = $ToNumber(b) || 0;
|
|
2118
|
+
return an - bn;
|
|
2119
|
+
}
|
|
2120
|
+
function cmp(comparator, recovered) {
|
|
2121
|
+
if (comparator == null) return defaultCompare;
|
|
2122
|
+
expectCallable("comparator", comparator, recovered);
|
|
2123
|
+
return (a, b) => {
|
|
2124
|
+
const ret = $Call(comparator, [a, b]);
|
|
2125
|
+
return $ToNumber(ret);
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2128
|
+
var sort = VmLib(
|
|
2129
|
+
(data, comparator) => {
|
|
2130
|
+
expectArray("data", data, null);
|
|
2131
|
+
const compare = cmp(comparator, data);
|
|
2132
|
+
const arr = [];
|
|
2133
|
+
for (const v of data) {
|
|
2134
|
+
arr.push(v ?? null);
|
|
2135
|
+
}
|
|
2136
|
+
arr.sort(compare);
|
|
2137
|
+
return arr;
|
|
2138
|
+
},
|
|
2139
|
+
{
|
|
2140
|
+
summary: "对数组中的元素进行排序,并返回排序后的结果",
|
|
2141
|
+
params: {
|
|
2142
|
+
data: "要排序的数组",
|
|
2143
|
+
comparator: "用于比较两个元素的函数,返回一个数字,表示它们的相对顺序,默认按升序排列"
|
|
2144
|
+
},
|
|
2145
|
+
paramsType: {
|
|
2146
|
+
data: "array",
|
|
2147
|
+
comparator: "fn(a: any, b: any) -> number"
|
|
2148
|
+
},
|
|
2149
|
+
returnsType: "array",
|
|
2150
|
+
examples: ['sort(["c", "a", "b"]) // ["a", "b", "c"]']
|
|
2151
|
+
}
|
|
2152
|
+
);
|
|
2153
|
+
var sort_by = VmLib(
|
|
2154
|
+
(data, key_fn, comparator) => {
|
|
2155
|
+
expectArray("data", data, null);
|
|
2156
|
+
expectCallable("key_fn", key_fn, data);
|
|
2157
|
+
const compare = cmp(comparator, data);
|
|
2158
|
+
const arr = [];
|
|
2159
|
+
const len2 = data.length;
|
|
2160
|
+
for (let i = 0; i < len2; i++) {
|
|
2161
|
+
const v = data[i] ?? null;
|
|
2162
|
+
arr.push({
|
|
2163
|
+
o: v,
|
|
2164
|
+
k: $Call(key_fn, [v, i, data])
|
|
2165
|
+
});
|
|
2166
|
+
}
|
|
2167
|
+
arr.sort((a, b) => compare(a.k, b.k));
|
|
2168
|
+
return arr.map((e) => e.o);
|
|
2169
|
+
},
|
|
2170
|
+
{
|
|
2171
|
+
summary: "根据键函数对数组中的元素进行排序,并返回排序后的结果",
|
|
2172
|
+
params: {
|
|
2173
|
+
data: "要排序的数组",
|
|
2174
|
+
key_fn: "用于提取排序键的函数,接受一个元素并返回其排序键",
|
|
2175
|
+
comparator: "用于比较两个排序键的函数,返回一个数字,表示它们的相对顺序,默认按升序排列"
|
|
2176
|
+
},
|
|
2177
|
+
paramsType: {
|
|
2178
|
+
data: "array",
|
|
2179
|
+
key_fn: "fn(value: any, index: number, arr: type(data)) -> any",
|
|
2180
|
+
comparator: "fn(a: any, b: any) -> number"
|
|
2181
|
+
},
|
|
2182
|
+
returnsType: "array",
|
|
2183
|
+
examples: ['sort_by([(0, "x"), (2, "y"), (1, "z")], fn (item) { item[0] }) // [(0, "x"), (1, "z"), (2, "y")]']
|
|
2184
|
+
}
|
|
2185
|
+
);
|
|
2186
|
+
|
|
2187
|
+
// src/vm/lib/global/sequence/repeat.ts
|
|
2188
|
+
var repeat = VmLib(
|
|
2189
|
+
(data, times) => {
|
|
2190
|
+
expectConst("data", data, []);
|
|
2191
|
+
required("times", times, []);
|
|
2192
|
+
const n = arrayLen($ToNumber(times));
|
|
2193
|
+
const result = [];
|
|
2194
|
+
result.length = n;
|
|
2195
|
+
result.fill(data);
|
|
2196
|
+
return result;
|
|
2197
|
+
},
|
|
2198
|
+
{
|
|
2199
|
+
summary: "创建一个包含重复元素的数组",
|
|
2200
|
+
params: {
|
|
2201
|
+
data: "要重复的元素",
|
|
2202
|
+
times: "重复的次数,必须是非负整数"
|
|
2203
|
+
},
|
|
2204
|
+
paramsType: {
|
|
2205
|
+
data: "any",
|
|
2206
|
+
times: "number"
|
|
2207
|
+
},
|
|
2208
|
+
returnsType: "type(data)[]",
|
|
2209
|
+
examples: ["repeat(0, 5) // [0, 0, 0, 0, 0]", 'repeat("a", 3) // ["a", "a", "a"]']
|
|
2210
|
+
}
|
|
2211
|
+
);
|
|
2212
|
+
|
|
2213
|
+
// src/vm/lib/global/debug.ts
|
|
2214
|
+
var debug_print = VmLib(
|
|
2215
|
+
(...args) => {
|
|
2216
|
+
console.log("\x1B[46;30m MiraScript \x1B[0m", ...args);
|
|
2217
|
+
},
|
|
2218
|
+
{
|
|
2219
|
+
summary: "打印调试信息到控制台",
|
|
2220
|
+
params: { "..args": "要打印的调试信息,可以是任意类型" },
|
|
2221
|
+
paramsType: { "..args": "any[]" },
|
|
2222
|
+
returnsType: "nil",
|
|
2223
|
+
examples: ['debug_print("value:", 42);']
|
|
2224
|
+
}
|
|
2225
|
+
);
|
|
2226
|
+
var panic = VmLib(
|
|
2227
|
+
(message) => {
|
|
2228
|
+
if (message === void 0) console.error("\x1B[41;37m MiraScript \x1B[0m");
|
|
2229
|
+
else console.error("\x1B[41;37m MiraScript \x1B[0m", message);
|
|
2230
|
+
const error = message == null ? "panic" : "panic: " + $ToString(message);
|
|
2231
|
+
throw new VmError(error, void 0);
|
|
2232
|
+
},
|
|
2233
|
+
{
|
|
2234
|
+
summary: "产生错误,并打印错误信息到控制台",
|
|
2235
|
+
params: { message: "要打印的错误信息" },
|
|
2236
|
+
paramsType: { message: "string" },
|
|
2237
|
+
returnsType: "never",
|
|
2238
|
+
examples: ['panic("boom");']
|
|
2239
|
+
}
|
|
2240
|
+
);
|
|
2241
|
+
|
|
2242
|
+
// src/vm/lib/global/json.ts
|
|
2243
|
+
var { parse, stringify } = JSON;
|
|
2244
|
+
var to_json = VmLib(
|
|
2245
|
+
(data) => {
|
|
2246
|
+
required("data", data, null);
|
|
2247
|
+
if (isVmExtern(data) || isVmModule(data)) {
|
|
2248
|
+
try {
|
|
2249
|
+
return stringify(data.value) ?? null;
|
|
2250
|
+
} catch (ex) {
|
|
2251
|
+
rethrowError("Failed to convert extern to JSON", ex, "{}");
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
if (typeof data == "function") return null;
|
|
2255
|
+
return stringify(data);
|
|
2256
|
+
},
|
|
2257
|
+
{
|
|
2258
|
+
summary: "将数据转换为 JSON 字符串",
|
|
2259
|
+
params: { data: "要转换为 JSON 的数据" },
|
|
2260
|
+
paramsType: { data: "any" },
|
|
2261
|
+
returnsType: "string",
|
|
2262
|
+
examples: ['to_json([1, 2, 3]) // "[1,2,3]"']
|
|
2263
|
+
}
|
|
2264
|
+
);
|
|
2265
|
+
var from_json = VmLib(
|
|
2266
|
+
(json, fallback) => {
|
|
2267
|
+
required("json", json, null);
|
|
2268
|
+
if (typeof json != "string") return json;
|
|
2269
|
+
try {
|
|
2270
|
+
return parse(json);
|
|
2271
|
+
} catch (ex) {
|
|
2272
|
+
if (fallback != null) return fallback;
|
|
2273
|
+
rethrowError("Invalid JSON", ex, null);
|
|
2274
|
+
}
|
|
2275
|
+
},
|
|
2276
|
+
{
|
|
2277
|
+
summary: "将 JSON 字符串转换为数据",
|
|
2278
|
+
params: { json: "要转换的 JSON 字符串", fallback: "如果转换失败,返回的默认值" },
|
|
2279
|
+
paramsType: { json: "string", fallback: "any" },
|
|
2280
|
+
returnsType: "any",
|
|
2281
|
+
examples: [`from_json('{"a":1}') // (a: 1)`]
|
|
2282
|
+
}
|
|
2283
|
+
);
|
|
2284
|
+
|
|
2285
|
+
// src/vm/lib/global/to-primitive.ts
|
|
2286
|
+
var to_string = VmLib(
|
|
2287
|
+
(data) => {
|
|
2288
|
+
required("data", data, "");
|
|
2289
|
+
return $ToString(data);
|
|
2290
|
+
},
|
|
2291
|
+
{
|
|
2292
|
+
summary: "将数据转换为字符串",
|
|
2293
|
+
params: { data: "要转换的数据" },
|
|
2294
|
+
paramsType: { data: "any" },
|
|
2295
|
+
returnsType: "string",
|
|
2296
|
+
examples: ['to_string([1, 2]) // "1, 2"']
|
|
2297
|
+
}
|
|
2298
|
+
);
|
|
2299
|
+
var to_number = VmLib(
|
|
2300
|
+
(data) => {
|
|
2301
|
+
required("data", data, Number.NaN);
|
|
2302
|
+
return $ToNumber(data);
|
|
2303
|
+
},
|
|
2304
|
+
{
|
|
2305
|
+
summary: "将数据转换为数字",
|
|
2306
|
+
params: { data: "要转换的数据" },
|
|
2307
|
+
paramsType: { data: "any" },
|
|
2308
|
+
returnsType: "number",
|
|
2309
|
+
examples: ['to_number("1.5") // 1.5']
|
|
2310
|
+
}
|
|
2311
|
+
);
|
|
2312
|
+
var to_boolean = VmLib(
|
|
2313
|
+
(data) => {
|
|
2314
|
+
required("data", data, false);
|
|
2315
|
+
return $ToBoolean(data);
|
|
2316
|
+
},
|
|
2317
|
+
{
|
|
2318
|
+
summary: "将数据转换为布尔值",
|
|
2319
|
+
params: { data: "要转换的数据" },
|
|
2320
|
+
paramsType: { data: "any" },
|
|
2321
|
+
returnsType: "boolean",
|
|
2322
|
+
examples: ["to_boolean(nil) // false"]
|
|
2323
|
+
}
|
|
2324
|
+
);
|
|
2325
|
+
var format = VmLib(
|
|
2326
|
+
(data, format2) => {
|
|
2327
|
+
required("data", data, "");
|
|
2328
|
+
return $Format(data, format2);
|
|
2329
|
+
},
|
|
2330
|
+
{
|
|
2331
|
+
summary: "将数据格式化为指定格式的字符串",
|
|
2332
|
+
params: { data: "要格式化的数据", format: "格式字符串" },
|
|
2333
|
+
paramsType: { data: "any", format: "string" },
|
|
2334
|
+
returnsType: "string",
|
|
2335
|
+
examples: ['format(12, ".3") // "12.000"']
|
|
2336
|
+
}
|
|
2337
|
+
);
|
|
2338
|
+
|
|
2339
|
+
// src/vm/lib/global/string.ts
|
|
2340
|
+
var chars = VmLib(
|
|
2341
|
+
(str) => {
|
|
2342
|
+
required("str", str, null);
|
|
2343
|
+
return [...$ToString(str)];
|
|
2344
|
+
},
|
|
2345
|
+
{
|
|
2346
|
+
summary: "将字符串转换为字符数组",
|
|
2347
|
+
params: { str: "要转换的字符串" },
|
|
2348
|
+
paramsType: { str: "string" },
|
|
2349
|
+
returnsType: "string[]",
|
|
2350
|
+
examples: ['chars("Mira") // ["M", "i", "r", "a"]']
|
|
2351
|
+
}
|
|
2352
|
+
);
|
|
2353
|
+
var starts_with = VmLib(
|
|
2354
|
+
(str, search) => {
|
|
2355
|
+
required("str", str, null);
|
|
2356
|
+
required("search", search, null);
|
|
2357
|
+
return $ToString(str).startsWith($ToString(search));
|
|
2358
|
+
},
|
|
2359
|
+
{
|
|
2360
|
+
summary: "检查字符串是否以指定子串开头",
|
|
2361
|
+
params: { str: "要检查的字符串", search: "要匹配的子串" },
|
|
2362
|
+
paramsType: { str: "string", search: "string" },
|
|
2363
|
+
returnsType: "boolean",
|
|
2364
|
+
examples: ['starts_with("mira", "mi") // true']
|
|
2365
|
+
}
|
|
2366
|
+
);
|
|
2367
|
+
var ends_with = VmLib(
|
|
2368
|
+
(str, search) => {
|
|
2369
|
+
required("str", str, null);
|
|
2370
|
+
required("search", search, null);
|
|
2371
|
+
return $ToString(str).endsWith($ToString(search));
|
|
2372
|
+
},
|
|
2373
|
+
{
|
|
2374
|
+
summary: "检查字符串是否以指定子串结尾",
|
|
2375
|
+
params: { str: "要检查的字符串", search: "要匹配的子串" },
|
|
2376
|
+
paramsType: { str: "string", search: "string" },
|
|
2377
|
+
returnsType: "boolean",
|
|
2378
|
+
examples: ['ends_with("mira", "ra") // true']
|
|
2379
|
+
}
|
|
2380
|
+
);
|
|
2381
|
+
var contains = VmLib(
|
|
2382
|
+
(str, search) => {
|
|
2383
|
+
required("str", str, null);
|
|
2384
|
+
required("search", search, null);
|
|
2385
|
+
return $ToString(str).includes($ToString(search));
|
|
2386
|
+
},
|
|
2387
|
+
{
|
|
2388
|
+
summary: "检查字符串是否包含指定子串",
|
|
2389
|
+
params: { str: "要检查的字符串", search: "要匹配的子串" },
|
|
2390
|
+
paramsType: { str: "string", search: "string" },
|
|
2391
|
+
returnsType: "boolean",
|
|
2392
|
+
examples: ['contains("hello", "ll") // true']
|
|
2393
|
+
}
|
|
2394
|
+
);
|
|
2395
|
+
var trim_start = VmLib(
|
|
2396
|
+
(str) => {
|
|
2397
|
+
required("str", str, null);
|
|
2398
|
+
return $ToString(str).trimStart();
|
|
2399
|
+
},
|
|
2400
|
+
{
|
|
2401
|
+
summary: "去除字符串开头的空白字符",
|
|
2402
|
+
params: { str: "要处理的字符串" },
|
|
2403
|
+
paramsType: { str: "string" },
|
|
2404
|
+
returnsType: "string",
|
|
2405
|
+
examples: ['trim_start(" mira") // "mira"']
|
|
2406
|
+
}
|
|
2407
|
+
);
|
|
2408
|
+
var trim_end = VmLib(
|
|
2409
|
+
(str) => {
|
|
2410
|
+
required("str", str, null);
|
|
2411
|
+
return $ToString(str).trimEnd();
|
|
2412
|
+
},
|
|
2413
|
+
{
|
|
2414
|
+
summary: "去除字符串结尾的空白字符",
|
|
2415
|
+
params: { str: "要处理的字符串" },
|
|
2416
|
+
paramsType: { str: "string" },
|
|
2417
|
+
returnsType: "string",
|
|
2418
|
+
examples: ['trim_end("mira ") // "mira"']
|
|
2419
|
+
}
|
|
2420
|
+
);
|
|
2421
|
+
var trim = VmLib(
|
|
2422
|
+
(str) => {
|
|
2423
|
+
required("str", str, null);
|
|
2424
|
+
return $ToString(str).trim();
|
|
2425
|
+
},
|
|
2426
|
+
{
|
|
2427
|
+
summary: "去除字符串两端的空白字符",
|
|
2428
|
+
params: { str: "要处理的字符串" },
|
|
2429
|
+
paramsType: { str: "string" },
|
|
2430
|
+
returnsType: "string",
|
|
2431
|
+
examples: ['trim(" mira ") // "mira"']
|
|
2432
|
+
}
|
|
2433
|
+
);
|
|
2434
|
+
var replace = VmLib(
|
|
2435
|
+
(str, search, replacement = "") => {
|
|
2436
|
+
required("str", str, null);
|
|
2437
|
+
required("search", search, str);
|
|
2438
|
+
return $ToString(str).replaceAll($ToString(search), $ToString(replacement));
|
|
2439
|
+
},
|
|
2440
|
+
{
|
|
2441
|
+
summary: "替换字符串中的指定子串",
|
|
2442
|
+
params: { str: "要处理的字符串", search: "要替换的子串", replacement: "替换后的字符串" },
|
|
2443
|
+
paramsType: { str: "string", search: "string", replacement: "string" },
|
|
2444
|
+
returnsType: "string",
|
|
2445
|
+
examples: ['replace("foo bar foo", "foo", "baz") // "baz bar baz"']
|
|
2446
|
+
}
|
|
2447
|
+
);
|
|
2448
|
+
var split = VmLib(
|
|
2449
|
+
(str, separator = "") => {
|
|
2450
|
+
required("str", str, null);
|
|
2451
|
+
const s = $ToString(str);
|
|
2452
|
+
const p = $ToString(separator);
|
|
2453
|
+
if (!p) return [...s];
|
|
2454
|
+
return s.split(p);
|
|
2455
|
+
},
|
|
2456
|
+
{
|
|
2457
|
+
summary: "将字符串拆分为子串数组",
|
|
2458
|
+
params: { str: "要拆分的字符串", separator: "分隔符" },
|
|
2459
|
+
paramsType: { str: "string", separator: "string" },
|
|
2460
|
+
returnsType: "string[]",
|
|
2461
|
+
examples: ['split("a,b,c", ",") // ["a", "b", "c"]']
|
|
2462
|
+
}
|
|
2463
|
+
);
|
|
2464
|
+
var join = VmLib(
|
|
2465
|
+
(arr, separator = "") => {
|
|
2466
|
+
expectArray("arr", arr, null);
|
|
2467
|
+
const s = $ToString(separator);
|
|
2468
|
+
return arr.map((v) => $ToString(v)).join(s);
|
|
2469
|
+
},
|
|
2470
|
+
{
|
|
2471
|
+
summary: "将字符串数组连接为单个字符串",
|
|
2472
|
+
params: { arr: "要连接的字符串数组", separator: "分隔符" },
|
|
2473
|
+
paramsType: { arr: "string[]", separator: "string" },
|
|
2474
|
+
returnsType: "string",
|
|
2475
|
+
examples: ['join(["a", "b", "c"], "-") // "a-b-c"']
|
|
2476
|
+
}
|
|
2477
|
+
);
|
|
2478
|
+
|
|
2479
|
+
// src/vm/lib/global/time.ts
|
|
2480
|
+
var to_timestamp = VmLib(
|
|
2481
|
+
(datetime) => {
|
|
2482
|
+
if (datetime == null) {
|
|
2483
|
+
return Date.now();
|
|
2484
|
+
}
|
|
2485
|
+
if (typeof datetime == "number") {
|
|
2486
|
+
return new Date(datetime).getTime();
|
|
2487
|
+
}
|
|
2488
|
+
const str = $ToString(datetime);
|
|
2489
|
+
if (!str) return Number.NaN;
|
|
2490
|
+
const num2 = $ToNumber(str);
|
|
2491
|
+
if (isFinite(num2)) return num2;
|
|
2492
|
+
return Date.parse(str);
|
|
2493
|
+
},
|
|
2494
|
+
{
|
|
2495
|
+
summary: "将数据转换为 Unix 毫秒时间戳",
|
|
2496
|
+
params: { datetime: "要转换的数据,默认为当前时间" },
|
|
2497
|
+
paramsType: { datetime: "string | number" },
|
|
2498
|
+
returnsType: "number",
|
|
2499
|
+
examples: ['to_timestamp("1970-01-01T00:00:00Z") // 0']
|
|
2500
|
+
}
|
|
2501
|
+
);
|
|
2502
|
+
var to_datetime = VmLib(
|
|
2503
|
+
(datetime, offset) => {
|
|
2504
|
+
const timestamp = to_timestamp(datetime);
|
|
2505
|
+
if (!isFinite(timestamp)) return null;
|
|
2506
|
+
const o = $ToNumber(offset ?? 0) || 0;
|
|
2507
|
+
const dateOffset = new Date(timestamp + o * 1e3 * 60 * 60);
|
|
2508
|
+
return {
|
|
2509
|
+
year: dateOffset.getUTCFullYear(),
|
|
2510
|
+
month: dateOffset.getUTCMonth() + 1,
|
|
2511
|
+
day: dateOffset.getUTCDate(),
|
|
2512
|
+
hour: dateOffset.getUTCHours(),
|
|
2513
|
+
minute: dateOffset.getUTCMinutes(),
|
|
2514
|
+
second: dateOffset.getUTCSeconds(),
|
|
2515
|
+
millisecond: dateOffset.getUTCMilliseconds(),
|
|
2516
|
+
dayOfWeek: dateOffset.getUTCDay(),
|
|
2517
|
+
offset: o
|
|
2518
|
+
};
|
|
2519
|
+
},
|
|
2520
|
+
{
|
|
2521
|
+
summary: "将数据转换为 Date 对象",
|
|
2522
|
+
params: {
|
|
2523
|
+
datetime: "要转换的数据,默认为当前时间",
|
|
2524
|
+
offset: "时区偏移量(单位:小时),默认为 0"
|
|
2525
|
+
},
|
|
2526
|
+
paramsType: { datetime: "string | number", offset: "number" },
|
|
2527
|
+
returnsType: "Date",
|
|
2528
|
+
examples: [
|
|
2529
|
+
"to_datetime(0) // (year: 1970, month: 1, day: 1, hour: 0, minute: 0, second: 0, millisecond: 0, dayOfWeek: 4, offset: 0)"
|
|
2530
|
+
]
|
|
2531
|
+
}
|
|
2532
|
+
);
|
|
2533
|
+
var to_iso8601 = VmLib(
|
|
2534
|
+
(datetime) => {
|
|
2535
|
+
const timestamp = to_timestamp(datetime);
|
|
2536
|
+
if (!isFinite(timestamp)) return null;
|
|
2537
|
+
return new Date(timestamp).toISOString();
|
|
2538
|
+
},
|
|
2539
|
+
{
|
|
2540
|
+
summary: "将数据转换为 ISO 8601 格式的字符串",
|
|
2541
|
+
params: { datetime: "要转换的数据,默认为当前时间" },
|
|
2542
|
+
paramsType: { datetime: "string | number" },
|
|
2543
|
+
returnsType: "string",
|
|
2544
|
+
examples: ['to_iso8601(0) // "1970-01-01T00:00:00.000Z"']
|
|
2545
|
+
}
|
|
2546
|
+
);
|
|
2547
|
+
|
|
2548
|
+
// src/vm/lib/global/mod/matrix.ts
|
|
2549
|
+
var matrix_exports = {};
|
|
2550
|
+
__export(matrix_exports, {
|
|
2551
|
+
add: () => add,
|
|
2552
|
+
diagonal: () => diagonal,
|
|
2553
|
+
entrywise: () => entrywise,
|
|
2554
|
+
entrywise_divide: () => entrywise_divide,
|
|
2555
|
+
entrywise_multiply: () => entrywise_multiply,
|
|
2556
|
+
identity: () => identity,
|
|
2557
|
+
invert: () => invert,
|
|
2558
|
+
multiply: () => multiply,
|
|
2559
|
+
ones: () => ones,
|
|
2560
|
+
size: () => size,
|
|
2561
|
+
subtract: () => subtract,
|
|
2562
|
+
transpose: () => transpose,
|
|
2563
|
+
zeros: () => zeros
|
|
2564
|
+
});
|
|
2565
|
+
function sizeImpl(matrix2) {
|
|
2566
|
+
if (!isVmArray(matrix2)) return [];
|
|
2567
|
+
if (matrix2.length === 0) return [0];
|
|
2568
|
+
const numRows = matrix2.length;
|
|
2569
|
+
let numCols = 0;
|
|
2570
|
+
for (const row of matrix2) {
|
|
2571
|
+
if (isVmArray(row)) {
|
|
2572
|
+
numCols = Math.max(numCols, row.length);
|
|
2573
|
+
} else {
|
|
2574
|
+
return [numRows];
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
return [numRows, numCols];
|
|
2578
|
+
}
|
|
2579
|
+
function num(v) {
|
|
2580
|
+
return $ToNumber(v ?? null);
|
|
2581
|
+
}
|
|
2582
|
+
var size = VmLib(
|
|
2583
|
+
(matrix2) => {
|
|
2584
|
+
required("matrix", matrix2, []);
|
|
2585
|
+
return sizeImpl(matrix2);
|
|
2586
|
+
},
|
|
2587
|
+
{
|
|
2588
|
+
summary: "获取矩阵尺寸",
|
|
2589
|
+
params: { matrix: "要获取尺寸的矩阵" },
|
|
2590
|
+
paramsType: { matrix: "any[][]" },
|
|
2591
|
+
returnsType: "[number, number]",
|
|
2592
|
+
examples: ["matrix.size([[1, 2], [3, 4]]) // [2, 2]"]
|
|
2593
|
+
}
|
|
2594
|
+
);
|
|
2595
|
+
var transpose = VmLib(
|
|
2596
|
+
(matrix2) => {
|
|
2597
|
+
required("matrix", matrix2, []);
|
|
2598
|
+
const [numRows, numCols] = sizeImpl(matrix2);
|
|
2599
|
+
if (numRows == null || numCols == null) return matrix2;
|
|
2600
|
+
const transposed = [];
|
|
2601
|
+
for (let j = 0; j < numCols; j++) {
|
|
2602
|
+
Cp();
|
|
2603
|
+
const tj = [];
|
|
2604
|
+
for (let i = 0; i < numRows; i++) {
|
|
2605
|
+
const row = matrix2[i] ?? null;
|
|
2606
|
+
const item = row?.[j] ?? null;
|
|
2607
|
+
tj[i] = item;
|
|
2608
|
+
}
|
|
2609
|
+
transposed[j] = tj;
|
|
2610
|
+
}
|
|
2611
|
+
return transposed;
|
|
2612
|
+
},
|
|
2613
|
+
{
|
|
2614
|
+
summary: "转置矩阵",
|
|
2615
|
+
params: { matrix: "要转置的矩阵" },
|
|
2616
|
+
paramsType: { matrix: "any[][]" },
|
|
2617
|
+
returnsType: "any[][]",
|
|
2618
|
+
examples: ["matrix.transpose([[1, 2], [3, 4]]) // [[1, 3], [2, 4]]"]
|
|
2619
|
+
}
|
|
2620
|
+
);
|
|
2621
|
+
function entrywiseImpl(a, b, f, vvf, mmf, vmf, mvf) {
|
|
2622
|
+
let [ar, ac] = sizeImpl(a);
|
|
2623
|
+
let [br, bc] = sizeImpl(b);
|
|
2624
|
+
if (ar == null) {
|
|
2625
|
+
if (br == null) {
|
|
2626
|
+
return f(a, b);
|
|
2627
|
+
} else if (bc == null) {
|
|
2628
|
+
const result2 = [];
|
|
2629
|
+
for (let r = 0; r < br; r++) {
|
|
2630
|
+
const bItem = b[r] ?? null;
|
|
2631
|
+
result2[r] = f(a, bItem);
|
|
2632
|
+
}
|
|
2633
|
+
return result2;
|
|
2634
|
+
} else {
|
|
2635
|
+
const result2 = [];
|
|
2636
|
+
for (let r = 0; r < br; r++) {
|
|
2637
|
+
const bRow = b[r] ?? [];
|
|
2638
|
+
const rRow = [];
|
|
2639
|
+
result2[r] = rRow;
|
|
2640
|
+
for (let c = 0; c < bc; c++) {
|
|
2641
|
+
const bItem = bRow[c] ?? null;
|
|
2642
|
+
rRow[c] = f(a, bItem);
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
return result2;
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
if (br == null) {
|
|
2649
|
+
if (ac == null) {
|
|
2650
|
+
const result2 = [];
|
|
2651
|
+
for (let r = 0; r < ar; r++) {
|
|
2652
|
+
const aItem = a[r] ?? null;
|
|
2653
|
+
result2[r] = f(aItem, b);
|
|
2654
|
+
}
|
|
2655
|
+
return result2;
|
|
2656
|
+
} else {
|
|
2657
|
+
const result2 = [];
|
|
2658
|
+
for (let r = 0; r < ar; r++) {
|
|
2659
|
+
const aRow = a[r] ?? [];
|
|
2660
|
+
const rRow = [];
|
|
2661
|
+
result2[r] = rRow;
|
|
2662
|
+
for (let c = 0; c < ac; c++) {
|
|
2663
|
+
const aItem = aRow[c] ?? null;
|
|
2664
|
+
rRow[c] = f(aItem, b);
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
return result2;
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
if (ac == null && bc == null) {
|
|
2671
|
+
if (vvf != null) {
|
|
2672
|
+
return vvf(a, b, ar, br);
|
|
2673
|
+
}
|
|
2674
|
+
const rr2 = Math.max(ar, br);
|
|
2675
|
+
const result2 = [];
|
|
2676
|
+
for (let r = 0; r < rr2; r++) {
|
|
2677
|
+
const aItem = a[r] ?? null;
|
|
2678
|
+
const bItem = b[r] ?? null;
|
|
2679
|
+
result2[r] = f(aItem, bItem);
|
|
2680
|
+
}
|
|
2681
|
+
return result2;
|
|
2682
|
+
}
|
|
2683
|
+
if (ac == null) {
|
|
2684
|
+
if (vmf != null) {
|
|
2685
|
+
return vmf(a, b, ar, br, bc);
|
|
2686
|
+
}
|
|
2687
|
+
ac = ar;
|
|
2688
|
+
ar = 1;
|
|
2689
|
+
a = [a];
|
|
2690
|
+
}
|
|
2691
|
+
if (bc == null) {
|
|
2692
|
+
if (mvf != null) {
|
|
2693
|
+
return mvf(a, b, ar, ac, br);
|
|
2694
|
+
}
|
|
2695
|
+
bc = br;
|
|
2696
|
+
br = 1;
|
|
2697
|
+
b = [b];
|
|
2698
|
+
}
|
|
2699
|
+
if (mmf != null) {
|
|
2700
|
+
return mmf(a, b, ar, ac, br, bc);
|
|
2701
|
+
}
|
|
2702
|
+
const rr = Math.max(ar, br);
|
|
2703
|
+
const rc = Math.max(ac, bc);
|
|
2704
|
+
const result = [];
|
|
2705
|
+
for (let r = 0; r < rr; r++) {
|
|
2706
|
+
const rRow = [];
|
|
2707
|
+
result[r] = rRow;
|
|
2708
|
+
for (let c = 0; c < rc; c++) {
|
|
2709
|
+
const aItem = a[ar === 1 ? 0 : r]?.[ac === 1 ? 0 : c] ?? null;
|
|
2710
|
+
const bItem = b[br === 1 ? 0 : r]?.[bc === 1 ? 0 : c] ?? null;
|
|
2711
|
+
rRow[c] = f(aItem, bItem);
|
|
2712
|
+
}
|
|
2713
|
+
}
|
|
2714
|
+
return result;
|
|
2715
|
+
}
|
|
2716
|
+
var entrywise = VmLib(
|
|
2717
|
+
(a, b, f) => {
|
|
2718
|
+
expectConst("a", a, null);
|
|
2719
|
+
expectConst("b", b, null);
|
|
2720
|
+
expectCallable("f", f, null);
|
|
2721
|
+
return entrywiseImpl(a, b, (a2, b2) => {
|
|
2722
|
+
Cp();
|
|
2723
|
+
const ret = $Call(f, [a2, b2]);
|
|
2724
|
+
if (!isVmConst(ret)) return null;
|
|
2725
|
+
return ret;
|
|
2726
|
+
});
|
|
2727
|
+
},
|
|
2728
|
+
{
|
|
2729
|
+
summary: "逐项操作",
|
|
2730
|
+
params: { a: "第一个操作数", b: "第二个操作数", f: "操作函数" },
|
|
2731
|
+
paramsType: { a: "any | any[] | any[][]", b: "any | any[] | any[][]", f: "fn(a: any, b: any) -> any" },
|
|
2732
|
+
returnsType: "any | any[] | any[][]",
|
|
2733
|
+
examples: [`matrix.entrywise([1, 2], [3, 4], fn (x, y) { x + y }) // [4, 6]`]
|
|
2734
|
+
}
|
|
2735
|
+
);
|
|
2736
|
+
var add = VmLib(
|
|
2737
|
+
(a, b) => {
|
|
2738
|
+
expectConst("a", a, null);
|
|
2739
|
+
expectConst("b", b, null);
|
|
2740
|
+
return entrywiseImpl(a, b, $Add);
|
|
2741
|
+
},
|
|
2742
|
+
{
|
|
2743
|
+
summary: "逐项相加",
|
|
2744
|
+
params: { a: "第一个操作数", b: "第二个操作数" },
|
|
2745
|
+
paramsType: { a: "number | number[] | number[][]", b: "number | number[] | number[][]" },
|
|
2746
|
+
returnsType: "number | number[] | number[][]",
|
|
2747
|
+
examples: ["matrix.add([1, 2], [3, 4]) // [4, 6]"]
|
|
2748
|
+
}
|
|
2749
|
+
);
|
|
2750
|
+
var subtract = VmLib(
|
|
2751
|
+
(a, b) => {
|
|
2752
|
+
expectConst("a", a, null);
|
|
2753
|
+
expectConst("b", b, null);
|
|
2754
|
+
return entrywiseImpl(a, b, $Sub);
|
|
2755
|
+
},
|
|
2756
|
+
{
|
|
2757
|
+
summary: "逐项相减",
|
|
2758
|
+
params: { a: "第一个操作数", b: "第二个操作数" },
|
|
2759
|
+
paramsType: { a: "number | number[] | number[][]", b: "number | number[] | number[][]" },
|
|
2760
|
+
returnsType: "number | number[] | number[][]",
|
|
2761
|
+
examples: ["matrix.subtract([3, 4], [1, 2]) // [2, 2]"]
|
|
2762
|
+
}
|
|
2763
|
+
);
|
|
2764
|
+
var entrywise_multiply = VmLib(
|
|
2765
|
+
(a, b) => {
|
|
2766
|
+
expectConst("a", a, null);
|
|
2767
|
+
expectConst("b", b, null);
|
|
2768
|
+
return entrywiseImpl(a, b, $Mul);
|
|
2769
|
+
},
|
|
2770
|
+
{
|
|
2771
|
+
summary: "逐项相乘",
|
|
2772
|
+
params: { a: "第一个操作数", b: "第二个操作数" },
|
|
2773
|
+
paramsType: { a: "number | number[] | number[][]", b: "number | number[] | number[][]" },
|
|
2774
|
+
returnsType: "number | number[] | number[][]",
|
|
2775
|
+
examples: ["matrix.entrywise_multiply([1, 2], [3, 4]) // [3, 8]"]
|
|
2776
|
+
}
|
|
2777
|
+
);
|
|
2778
|
+
var entrywise_divide = VmLib(
|
|
2779
|
+
(a, b) => {
|
|
2780
|
+
expectConst("a", a, null);
|
|
2781
|
+
expectConst("b", b, null);
|
|
2782
|
+
return entrywiseImpl(a, b, $Div);
|
|
2783
|
+
},
|
|
2784
|
+
{
|
|
2785
|
+
summary: "逐项相除",
|
|
2786
|
+
params: { a: "第一个操作数", b: "第二个操作数" },
|
|
2787
|
+
paramsType: { a: "number | number[] | number[][]", b: "number | number[] | number[][]" },
|
|
2788
|
+
returnsType: "number | number[] | number[][]",
|
|
2789
|
+
examples: ["matrix.entrywise_divide([4, 6], [2, 3]) // [2, 2]"]
|
|
2790
|
+
}
|
|
2791
|
+
);
|
|
2792
|
+
var multiply = VmLib(
|
|
2793
|
+
(a, b) => {
|
|
2794
|
+
expectConst("a", a, null);
|
|
2795
|
+
expectConst("b", b, null);
|
|
2796
|
+
return entrywiseImpl(
|
|
2797
|
+
a,
|
|
2798
|
+
b,
|
|
2799
|
+
$Mul,
|
|
2800
|
+
(a2, b2, al, bl) => {
|
|
2801
|
+
const l = Math.max(al, bl);
|
|
2802
|
+
let s = 0;
|
|
2803
|
+
for (let i = 0; i < l; i++) {
|
|
2804
|
+
s += num(a2[i]) * num(b2[i]);
|
|
2805
|
+
}
|
|
2806
|
+
return s;
|
|
2807
|
+
},
|
|
2808
|
+
(a2, b2, ar, ac, br, bc) => {
|
|
2809
|
+
if (ac !== br) throwError(`Incompatible matrix dimensions`, null);
|
|
2810
|
+
const result = [];
|
|
2811
|
+
for (let r = 0; r < ar; r++) {
|
|
2812
|
+
const rRow = [];
|
|
2813
|
+
result[r] = rRow;
|
|
2814
|
+
for (let c = 0; c < bc; c++) {
|
|
2815
|
+
let item = 0;
|
|
2816
|
+
for (let k = 0; k < ac; k++) {
|
|
2817
|
+
item += num(a2[r]?.[k]) * num(b2[k]?.[c]);
|
|
2818
|
+
}
|
|
2819
|
+
rRow[c] = item;
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
return result;
|
|
2823
|
+
},
|
|
2824
|
+
(a2, b2, al, br, bc) => {
|
|
2825
|
+
if (al !== br) throwError(`Incompatible matrix dimensions`, null);
|
|
2826
|
+
const result = [];
|
|
2827
|
+
for (let c = 0; c < bc; c++) {
|
|
2828
|
+
let item = 0;
|
|
2829
|
+
for (let k = 0; k < al; k++) {
|
|
2830
|
+
item += num(a2[k]) * num(b2[k]?.[c]);
|
|
2831
|
+
}
|
|
2832
|
+
result[c] = item;
|
|
2833
|
+
}
|
|
2834
|
+
return result;
|
|
2835
|
+
},
|
|
2836
|
+
(a2, b2, ar, ac, bl) => {
|
|
2837
|
+
if (ac !== bl) throwError(`Incompatible matrix dimensions`, null);
|
|
2838
|
+
const result = [];
|
|
2839
|
+
for (let r = 0; r < ar; r++) {
|
|
2840
|
+
let item = 0;
|
|
2841
|
+
for (let k = 0; k < ac; k++) {
|
|
2842
|
+
item += num(a2[r]?.[k]) * num(b2[k]);
|
|
2843
|
+
}
|
|
2844
|
+
result[r] = item;
|
|
2845
|
+
}
|
|
2846
|
+
return result;
|
|
2847
|
+
}
|
|
2848
|
+
);
|
|
2849
|
+
},
|
|
2850
|
+
{
|
|
2851
|
+
summary: "矩阵相乘",
|
|
2852
|
+
params: { a: "第一个操作数", b: "第二个操作数" },
|
|
2853
|
+
paramsType: { a: "number | number[] | number[][]", b: "number | number[] | number[][]" },
|
|
2854
|
+
returnsType: "number | number[] | number[][]",
|
|
2855
|
+
examples: ["matrix.multiply([[1, 2], [3, 4]], [5, 6]) // [17, 39]"]
|
|
2856
|
+
}
|
|
2857
|
+
);
|
|
2858
|
+
var invert = VmLib(
|
|
2859
|
+
(a) => {
|
|
2860
|
+
expectConst("a", a, null);
|
|
2861
|
+
const [rows, cols] = sizeImpl(a);
|
|
2862
|
+
if (rows == null) return 1 / num(a);
|
|
2863
|
+
if (cols == null) return map(a, (v) => 1 / num(v));
|
|
2864
|
+
if (rows !== cols) throwError(`Matrix must be square`, a);
|
|
2865
|
+
const m = a;
|
|
2866
|
+
if (rows === 1) {
|
|
2867
|
+
const e = num(m[0]?.[0]);
|
|
2868
|
+
return [[1 / e]];
|
|
2869
|
+
}
|
|
2870
|
+
if (rows === 2) {
|
|
2871
|
+
const a2 = num(m[0]?.[0]);
|
|
2872
|
+
const b = num(m[0]?.[1]);
|
|
2873
|
+
const c = num(m[1]?.[0]);
|
|
2874
|
+
const d = num(m[1]?.[1]);
|
|
2875
|
+
const det = a2 * d - b * c;
|
|
2876
|
+
return [
|
|
2877
|
+
[d / det, -b / det],
|
|
2878
|
+
[-c / det, a2 / det]
|
|
2879
|
+
];
|
|
2880
|
+
}
|
|
2881
|
+
const A = [];
|
|
2882
|
+
const B = [];
|
|
2883
|
+
for (let r = 0; r < rows; r++) {
|
|
2884
|
+
const Ar = [];
|
|
2885
|
+
const Br = [];
|
|
2886
|
+
A[r] = Ar;
|
|
2887
|
+
B[r] = Br;
|
|
2888
|
+
for (let c = 0; c < cols; c++) {
|
|
2889
|
+
Ar[c] = num(m[r]?.[c]);
|
|
2890
|
+
Br[c] = r === c ? 1 : 0;
|
|
2891
|
+
}
|
|
2892
|
+
}
|
|
2893
|
+
for (let c = 0; c < cols; c++) {
|
|
2894
|
+
let ABig = Math.abs(A[c][c]);
|
|
2895
|
+
let rBig = c;
|
|
2896
|
+
let r = c + 1;
|
|
2897
|
+
while (r < rows) {
|
|
2898
|
+
if (Math.abs(A[r][c]) > ABig) {
|
|
2899
|
+
ABig = Math.abs(A[r][c]);
|
|
2900
|
+
rBig = r;
|
|
2901
|
+
}
|
|
2902
|
+
r++;
|
|
2903
|
+
}
|
|
2904
|
+
r = rBig;
|
|
2905
|
+
if (r !== c) {
|
|
2906
|
+
const temp1 = A[c];
|
|
2907
|
+
A[c] = A[r];
|
|
2908
|
+
A[r] = temp1;
|
|
2909
|
+
const temp2 = B[c];
|
|
2910
|
+
B[c] = B[r];
|
|
2911
|
+
B[r] = temp2;
|
|
2912
|
+
}
|
|
2913
|
+
const Ac = A[c];
|
|
2914
|
+
const Bc = B[c];
|
|
2915
|
+
for (r = 0; r < rows; r++) {
|
|
2916
|
+
const Ar = A[r];
|
|
2917
|
+
const Br = B[r];
|
|
2918
|
+
if (r !== c) {
|
|
2919
|
+
if (Ar[c] !== 0) {
|
|
2920
|
+
const f = -Ar[c] / Ac[c];
|
|
2921
|
+
for (let s = c; s < cols; s++) {
|
|
2922
|
+
Ar[s] = Ar[s] + f * Ac[s];
|
|
2923
|
+
}
|
|
2924
|
+
for (let s = 0; s < cols; s++) {
|
|
2925
|
+
Br[s] = Br[s] + f * Bc[s];
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
} else {
|
|
2929
|
+
const f = Ac[c];
|
|
2930
|
+
for (let s = c; s < cols; s++) {
|
|
2931
|
+
Ar[s] = Ar[s] / f;
|
|
2932
|
+
}
|
|
2933
|
+
for (let s = 0; s < cols; s++) {
|
|
2934
|
+
Br[s] = Br[s] / f;
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
return B;
|
|
2940
|
+
},
|
|
2941
|
+
{
|
|
2942
|
+
summary: "矩阵求逆",
|
|
2943
|
+
params: { a: "待求逆的矩阵" },
|
|
2944
|
+
paramsType: { a: "number | number[][]" },
|
|
2945
|
+
returnsType: "number | number[][]",
|
|
2946
|
+
examples: ["matrix.invert([[1, 2], [3, 4]]) // [[-2, 1], [1.5, -0.5]]"]
|
|
2947
|
+
}
|
|
2948
|
+
);
|
|
2949
|
+
function filled(size2, value) {
|
|
2950
|
+
const s = getNumbers(size2);
|
|
2951
|
+
if (s.length === 0) return [];
|
|
2952
|
+
while (s.length > 0) {
|
|
2953
|
+
const repeat2 = arrayLen(s.pop());
|
|
2954
|
+
Cp();
|
|
2955
|
+
const data = [];
|
|
2956
|
+
data.length = repeat2;
|
|
2957
|
+
data.fill(value);
|
|
2958
|
+
value = data;
|
|
2959
|
+
}
|
|
2960
|
+
return value;
|
|
2961
|
+
}
|
|
2962
|
+
var zeros = VmLib((...size2) => filled(size2, 0), {
|
|
2963
|
+
summary: "创建一个全零的矩阵",
|
|
2964
|
+
params: { "..size": "矩阵的维度" },
|
|
2965
|
+
paramsType: { "..size": "number[]" },
|
|
2966
|
+
returnsType: "number[][]",
|
|
2967
|
+
examples: ["matrix.zeros(2, 3) // [[0, 0, 0], [0, 0, 0]]"]
|
|
2968
|
+
});
|
|
2969
|
+
var ones = VmLib((...size2) => filled(size2, 1), {
|
|
2970
|
+
summary: "创建一个全一的矩阵",
|
|
2971
|
+
params: { "..size": "矩阵的维度" },
|
|
2972
|
+
paramsType: { "..size": "number[]" },
|
|
2973
|
+
returnsType: "number[][]",
|
|
2974
|
+
examples: ["matrix.ones(2, 2) // [[1, 1], [1, 1]]"]
|
|
2975
|
+
});
|
|
2976
|
+
var identity = VmLib(
|
|
2977
|
+
(...size2) => {
|
|
2978
|
+
let s = getNumbers(size2);
|
|
2979
|
+
if (s.length === 0) return [];
|
|
2980
|
+
if (s.length > 2) throwError("Invalid matrix size", []);
|
|
2981
|
+
if (s.length === 1) s = [s[0], s[0]];
|
|
2982
|
+
const m = arrayLen(s[0]);
|
|
2983
|
+
const n = arrayLen(s[1]);
|
|
2984
|
+
const ret = [];
|
|
2985
|
+
for (let i = 0; i < m; i++) {
|
|
2986
|
+
const row = [];
|
|
2987
|
+
ret[i] = row;
|
|
2988
|
+
row.length = n;
|
|
2989
|
+
row.fill(0);
|
|
2990
|
+
if (i < n) row[i] = 1;
|
|
2991
|
+
}
|
|
2992
|
+
return ret;
|
|
2993
|
+
},
|
|
2994
|
+
{
|
|
2995
|
+
summary: "创建一个单位矩阵",
|
|
2996
|
+
params: { "..size": "矩阵的维度" },
|
|
2997
|
+
paramsType: { "..size": "[number] | [number, number]" },
|
|
2998
|
+
returnsType: "number[][]",
|
|
2999
|
+
examples: ["matrix.identity(3) // [[1, 0, 0], [0, 1, 0], [0, 0, 1]]"]
|
|
3000
|
+
}
|
|
3001
|
+
);
|
|
3002
|
+
var diagonal = VmLib(
|
|
3003
|
+
(x, k = 0) => {
|
|
3004
|
+
expectArray("x", x, []);
|
|
3005
|
+
const fk = Math.round($ToNumber(k) || 0);
|
|
3006
|
+
if (x.every((e) => isArray(e))) {
|
|
3007
|
+
const diag = [];
|
|
3008
|
+
for (let i = 0; i < x.length; i++) {
|
|
3009
|
+
const row = x[i];
|
|
3010
|
+
const r = i + fk;
|
|
3011
|
+
if (r < 0) continue;
|
|
3012
|
+
if (!row || r >= row.length) break;
|
|
3013
|
+
diag.push(row[r] ?? null);
|
|
3014
|
+
}
|
|
3015
|
+
return diag;
|
|
3016
|
+
}
|
|
3017
|
+
const l = x.length;
|
|
3018
|
+
const m = arrayLen(fk < 0 ? l - fk : l);
|
|
3019
|
+
const n = arrayLen(fk > 0 ? l + fk : l);
|
|
3020
|
+
const result = [];
|
|
3021
|
+
for (let i = 0; i < m; i++) {
|
|
3022
|
+
const row = [];
|
|
3023
|
+
result[i] = row;
|
|
3024
|
+
row.length = n;
|
|
3025
|
+
row.fill(0);
|
|
3026
|
+
for (let j = 0; j < n; j++) {
|
|
3027
|
+
if (i + fk === j) {
|
|
3028
|
+
row[j] = x[fk >= 0 ? i : j] ?? null;
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
3031
|
+
}
|
|
3032
|
+
return result;
|
|
3033
|
+
},
|
|
3034
|
+
{
|
|
3035
|
+
summary: "创建一个对角矩阵或获取矩阵的对角线",
|
|
3036
|
+
params: { x: "对角线元素或要获取对角线的矩阵", k: "对角线偏移量,默认为 0" },
|
|
3037
|
+
paramsType: { x: "number[] | number[][]", k: "number" },
|
|
3038
|
+
returnsType: "number[][] | number[]",
|
|
3039
|
+
examples: [
|
|
3040
|
+
"matrix.diagonal([1, 2, 3]) // [[1, 0, 0], [0, 2, 0], [0, 0, 3]]",
|
|
3041
|
+
"matrix.diagonal([[1, 2], [3, 4]]) // [1, 4]"
|
|
3042
|
+
]
|
|
3043
|
+
}
|
|
3044
|
+
);
|
|
3045
|
+
|
|
3046
|
+
// src/vm/lib/global/mod/index.ts
|
|
3047
|
+
var matrix = createModule("matrix", matrix_exports);
|
|
3048
|
+
|
|
3049
|
+
// src/vm/lib/_loader.ts
|
|
3050
|
+
for (const [name, value] of entries(global_exports)) {
|
|
3051
|
+
VmSharedContext[name] = wrapEntry(name, value);
|
|
3052
|
+
}
|
|
3053
|
+
function wrapEntry(name, value) {
|
|
3054
|
+
if (typeof value == "function") {
|
|
3055
|
+
if (value.name !== name) {
|
|
3056
|
+
defineProperty(value, "name", {
|
|
3057
|
+
value: name,
|
|
3058
|
+
configurable: true
|
|
3059
|
+
});
|
|
3060
|
+
}
|
|
3061
|
+
return VmFunction(value, {
|
|
3062
|
+
isLib: true,
|
|
3063
|
+
injectCp: true,
|
|
3064
|
+
fullName: `global.${name}`,
|
|
3065
|
+
...value
|
|
3066
|
+
});
|
|
3067
|
+
} else {
|
|
3068
|
+
return value;
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
function createModule(name, lib2) {
|
|
3072
|
+
const mod = create(null);
|
|
3073
|
+
for (const [key, value] of entries(lib2)) {
|
|
3074
|
+
mod[key] = wrapEntry(key, value);
|
|
3075
|
+
}
|
|
3076
|
+
return new VmModule(name, mod);
|
|
3077
|
+
}
|
|
3078
|
+
var lib = global_exports;
|
|
3079
|
+
|
|
3080
|
+
// src/helpers/serialize.ts
|
|
3081
|
+
var REG_IDENTIFIER_FULL = new RegExp(`^${REG_IDENTIFIER.source}$`, REG_IDENTIFIER.flags);
|
|
3082
|
+
var REG_ORDINAL_FULL = new RegExp(`^${REG_ORDINAL.source}$`, REG_ORDINAL.flags);
|
|
3083
|
+
var DEFAULT_OPTIONS = Object.freeze({
|
|
3084
|
+
maxDepth: 128,
|
|
3085
|
+
serializeNil,
|
|
3086
|
+
serializeBoolean,
|
|
3087
|
+
serializeNumber,
|
|
3088
|
+
serializeString: serializeStringImpl,
|
|
3089
|
+
serializeStringQuote: (value) => value,
|
|
3090
|
+
serializeStringEscape: (value) => value,
|
|
3091
|
+
serializeStringContent: (value) => value,
|
|
3092
|
+
serializeArray,
|
|
3093
|
+
serializeRecord,
|
|
3094
|
+
serializePropName: String,
|
|
3095
|
+
serializeFunction: serializeNil,
|
|
3096
|
+
serializeModule: serializeNil,
|
|
3097
|
+
serializeExtern: serializeNil
|
|
3098
|
+
});
|
|
3099
|
+
function getSerializeOptions(options) {
|
|
3100
|
+
if (options == null) return DEFAULT_OPTIONS;
|
|
3101
|
+
const opt = { ...DEFAULT_OPTIONS };
|
|
3102
|
+
for (const key in options) {
|
|
3103
|
+
const el = options[key];
|
|
3104
|
+
if (el != null) {
|
|
3105
|
+
opt[key] = el;
|
|
3106
|
+
}
|
|
3107
|
+
}
|
|
3108
|
+
return Object.freeze(opt);
|
|
3109
|
+
}
|
|
3110
|
+
function serializeStringImpl(value, options) {
|
|
3111
|
+
if (!/[\p{C}'"`$\\]/u.test(value)) {
|
|
3112
|
+
const oq = options.serializeStringQuote(`'`, true, options);
|
|
3113
|
+
const cq = options.serializeStringQuote(`'`, false, options);
|
|
3114
|
+
const c = options.serializeStringContent(value, options);
|
|
3115
|
+
return oq + c + cq;
|
|
3116
|
+
}
|
|
3117
|
+
let ret = options.serializeStringQuote(`'`, true, options);
|
|
3118
|
+
for (const char of value) {
|
|
3119
|
+
if (char === "'") {
|
|
3120
|
+
ret += options.serializeStringEscape(String.raw`\'`, options);
|
|
3121
|
+
} else if (char === "\0") {
|
|
3122
|
+
ret += options.serializeStringEscape(String.raw`\0`, options);
|
|
3123
|
+
} else if (char === "\n") {
|
|
3124
|
+
ret += options.serializeStringEscape(String.raw`\n`, options);
|
|
3125
|
+
} else if (char === "\r") {
|
|
3126
|
+
ret += options.serializeStringEscape(String.raw`\r`, options);
|
|
3127
|
+
} else if (char === " ") {
|
|
3128
|
+
ret += options.serializeStringEscape(String.raw`\t`, options);
|
|
3129
|
+
} else if (char === "\b") {
|
|
3130
|
+
ret += options.serializeStringEscape(String.raw`\b`, options);
|
|
3131
|
+
} else if (char === "\f") {
|
|
3132
|
+
ret += options.serializeStringEscape(String.raw`\f`, options);
|
|
3133
|
+
} else if (char === "\v") {
|
|
3134
|
+
ret += options.serializeStringEscape(String.raw`\v`, options);
|
|
3135
|
+
} else if (char === "\\") {
|
|
3136
|
+
ret += options.serializeStringEscape(String.raw`\\`, options);
|
|
3137
|
+
} else if (char === "$") {
|
|
3138
|
+
ret += options.serializeStringEscape(String.raw`\$`, options);
|
|
3139
|
+
} else if (/\p{C}/u.test(char)) {
|
|
3140
|
+
const code = char.codePointAt(0);
|
|
3141
|
+
if (code <= 127) {
|
|
3142
|
+
ret += options.serializeStringEscape(String.raw`\x${code.toString(16).padStart(2, "0")}`, options);
|
|
3143
|
+
} else if (code >= 55296 && code <= 57343) {
|
|
3144
|
+
ret += options.serializeStringContent("�", options);
|
|
3145
|
+
} else {
|
|
3146
|
+
ret += options.serializeStringEscape(String.raw`\u{${code.toString(16)}}`, options);
|
|
3147
|
+
}
|
|
3148
|
+
} else {
|
|
3149
|
+
ret += options.serializeStringContent(char, options);
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
ret += options.serializeStringQuote(`'`, false, options);
|
|
3153
|
+
return ret;
|
|
3154
|
+
}
|
|
3155
|
+
function serializeString(value, options) {
|
|
3156
|
+
return serializeStringImpl(value, getSerializeOptions(options));
|
|
3157
|
+
}
|
|
3158
|
+
function serializePropNameImpl(value, options) {
|
|
3159
|
+
if (REG_ORDINAL_FULL.test(value)) {
|
|
3160
|
+
return options.serializePropName(Number(value), options);
|
|
3161
|
+
}
|
|
3162
|
+
if (REG_IDENTIFIER_FULL.test(value)) {
|
|
3163
|
+
return options.serializePropName(value, options);
|
|
3164
|
+
}
|
|
3165
|
+
return options.serializeString(value, options);
|
|
3166
|
+
}
|
|
3167
|
+
function serializePropName(value, options) {
|
|
3168
|
+
return serializePropNameImpl(value, getSerializeOptions(options));
|
|
3169
|
+
}
|
|
3170
|
+
function serializeNil() {
|
|
3171
|
+
return "nil";
|
|
3172
|
+
}
|
|
3173
|
+
function serializeBoolean(value) {
|
|
3174
|
+
return value ? "true" : "false";
|
|
3175
|
+
}
|
|
3176
|
+
function serializeNumber(value) {
|
|
3177
|
+
if (isNaN(value)) return "nan";
|
|
3178
|
+
if (!isFinite(value)) return value < 0 ? "-inf" : "inf";
|
|
3179
|
+
if (value === 0) {
|
|
3180
|
+
if (1 / value < 0) return "-0";
|
|
3181
|
+
return "0";
|
|
3182
|
+
}
|
|
3183
|
+
return String(value);
|
|
3184
|
+
}
|
|
3185
|
+
function serializeArray(value, depth, options) {
|
|
3186
|
+
if (depth > options.maxDepth) return `[]`;
|
|
3187
|
+
if (value.length === 0) return "[]";
|
|
3188
|
+
let str = "[";
|
|
3189
|
+
for (let i = 0; i < value.length; i++) {
|
|
3190
|
+
if (i > 0) str += ", ";
|
|
3191
|
+
str += serializeImpl(value[i], depth, options);
|
|
3192
|
+
}
|
|
3193
|
+
str += "]";
|
|
3194
|
+
return str;
|
|
3195
|
+
}
|
|
3196
|
+
var { valueOf } = Object.prototype;
|
|
3197
|
+
function customValueOf(value) {
|
|
3198
|
+
const thisValueOf = value.valueOf;
|
|
3199
|
+
if (typeof thisValueOf != "function" || thisValueOf === valueOf) {
|
|
3200
|
+
return void 0;
|
|
3201
|
+
}
|
|
3202
|
+
const customValue = thisValueOf.call(value);
|
|
3203
|
+
if (customValue === value) return void 0;
|
|
3204
|
+
return customValue;
|
|
3205
|
+
}
|
|
3206
|
+
function serializeRecord(value, depth, options) {
|
|
3207
|
+
const customValue = customValueOf(value);
|
|
3208
|
+
if (customValue !== void 0) {
|
|
3209
|
+
return serializeImpl(customValue, depth - 1, options);
|
|
3210
|
+
}
|
|
3211
|
+
if (depth > options.maxDepth) return `()`;
|
|
3212
|
+
const e = entries(value);
|
|
3213
|
+
if (e.length === 0) return "()";
|
|
3214
|
+
if (e.length === 1) {
|
|
3215
|
+
const [k, v] = e[0];
|
|
3216
|
+
if (k === "0") {
|
|
3217
|
+
return `(${serializeImpl(v, depth, options)},)`;
|
|
3218
|
+
}
|
|
3219
|
+
return `(${serializePropNameImpl(k, options)}: ${serializeImpl(v, depth, options)})`;
|
|
3220
|
+
}
|
|
3221
|
+
const omitKey = e.length < 10 && e.every(([key], index) => key === String(index));
|
|
3222
|
+
let str = "(";
|
|
3223
|
+
for (const [key, val] of e) {
|
|
3224
|
+
if (str.length > 1) str += ", ";
|
|
3225
|
+
if (omitKey) {
|
|
3226
|
+
str += serializeImpl(val, depth, options);
|
|
3227
|
+
} else {
|
|
3228
|
+
str += `${serializePropNameImpl(key, options)}: ${serializeImpl(val, depth, options)}`;
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
str += ")";
|
|
3232
|
+
return str;
|
|
3233
|
+
}
|
|
3234
|
+
function serializeImpl(value, depth, options) {
|
|
3235
|
+
if (value == null) {
|
|
3236
|
+
return options.serializeNil(options);
|
|
3237
|
+
}
|
|
3238
|
+
if (typeof value == "boolean") {
|
|
3239
|
+
return options.serializeBoolean(value, options);
|
|
3240
|
+
}
|
|
3241
|
+
if (typeof value == "number") {
|
|
3242
|
+
return options.serializeNumber(value, options);
|
|
3243
|
+
}
|
|
3244
|
+
if (typeof value == "string") {
|
|
3245
|
+
return options.serializeString(value, options);
|
|
3246
|
+
}
|
|
3247
|
+
if (isVmFunction(value)) {
|
|
3248
|
+
return options.serializeFunction(value, options);
|
|
3249
|
+
}
|
|
3250
|
+
if (isVmModule(value)) {
|
|
3251
|
+
return options.serializeModule(value, depth + 1, options);
|
|
3252
|
+
}
|
|
3253
|
+
if (isVmExtern(value)) {
|
|
3254
|
+
return options.serializeExtern(value, depth + 1, options);
|
|
3255
|
+
}
|
|
3256
|
+
if (isVmArray(value)) {
|
|
3257
|
+
return options.serializeArray(value, depth + 1, options);
|
|
3258
|
+
}
|
|
3259
|
+
if (isVmRecord(value)) {
|
|
3260
|
+
return options.serializeRecord(value, depth + 1, options);
|
|
3261
|
+
}
|
|
3262
|
+
value;
|
|
3263
|
+
return options.serializeNil(options);
|
|
3264
|
+
}
|
|
3265
|
+
function serialize(value, options) {
|
|
3266
|
+
return serializeImpl(value, 0, getSerializeOptions(options));
|
|
3267
|
+
}
|
|
3268
|
+
|
|
3269
|
+
// src/compiler/diagnostic.ts
|
|
3270
|
+
import { DiagnosticCode, wasm } from "@mirascript/wasm";
|
|
3271
|
+
var diagnosticMessages = /* @__PURE__ */ new Map();
|
|
3272
|
+
function getDiagnosticMessage(code) {
|
|
3273
|
+
if (!isSafeInteger(code) || code < 0 || code >= 65535) {
|
|
3274
|
+
throw new RangeError(`Invalid DiagnosticCode: ${code}`);
|
|
3275
|
+
}
|
|
3276
|
+
if (diagnosticMessages.has(code)) {
|
|
3277
|
+
return diagnosticMessages.get(code);
|
|
3278
|
+
}
|
|
3279
|
+
const msg = wasm.get_diagnostic_message(code);
|
|
3280
|
+
diagnosticMessages.set(code, msg);
|
|
3281
|
+
return msg;
|
|
3282
|
+
}
|
|
3283
|
+
function parseDiagnostics(source, diagnostics) {
|
|
3284
|
+
const parsed = [];
|
|
3285
|
+
const bufLen = diagnostics.length;
|
|
3286
|
+
for (let i = 0; i < bufLen; i += 5) {
|
|
3287
|
+
const startLineNumber = diagnostics[i];
|
|
3288
|
+
const startColumn = diagnostics[i + 1];
|
|
3289
|
+
const endLineNumber = diagnostics[i + 2];
|
|
3290
|
+
const endColumn = diagnostics[i + 3];
|
|
3291
|
+
const error = diagnostics[i + 4];
|
|
3292
|
+
parsed.push({
|
|
3293
|
+
code: error,
|
|
3294
|
+
range: {
|
|
3295
|
+
startLineNumber,
|
|
3296
|
+
startColumn,
|
|
3297
|
+
endLineNumber,
|
|
3298
|
+
endColumn
|
|
3299
|
+
}
|
|
3300
|
+
});
|
|
3301
|
+
}
|
|
3302
|
+
const _errors = [];
|
|
3303
|
+
const _warnings = [];
|
|
3304
|
+
const _infos = [];
|
|
3305
|
+
const _hints = [];
|
|
3306
|
+
const _tags = [];
|
|
3307
|
+
const _references = [];
|
|
3308
|
+
const _tagsReferences = [];
|
|
3309
|
+
for (let i = 0; i < parsed.length; i++) {
|
|
3310
|
+
const diagnostic = parsed[i];
|
|
3311
|
+
const { code } = diagnostic;
|
|
3312
|
+
if (code > DiagnosticCode.ErrorStart && code < DiagnosticCode.ErrorEnd) {
|
|
3313
|
+
_errors.push(diagnostic);
|
|
3314
|
+
} else if (code > DiagnosticCode.WarningStart && code < DiagnosticCode.WarningEnd) {
|
|
3315
|
+
_warnings.push(diagnostic);
|
|
3316
|
+
} else if (code > DiagnosticCode.InfoStart && code < DiagnosticCode.InfoEnd) {
|
|
3317
|
+
_infos.push(diagnostic);
|
|
3318
|
+
} else if (code > DiagnosticCode.HintStart && code < DiagnosticCode.HintEnd) {
|
|
3319
|
+
_hints.push(diagnostic);
|
|
3320
|
+
} else if (code > DiagnosticCode.TagStart && code < DiagnosticCode.TagEnd) {
|
|
3321
|
+
_tags.push(diagnostic);
|
|
3322
|
+
} else {
|
|
3323
|
+
continue;
|
|
3324
|
+
}
|
|
3325
|
+
diagnostic.references = [];
|
|
3326
|
+
while (i + 1 < parsed.length) {
|
|
3327
|
+
const ref = parsed[i + 1];
|
|
3328
|
+
let isRef = false;
|
|
3329
|
+
if (ref.code > DiagnosticCode.TagRefStart && ref.code < DiagnosticCode.TagRefEnd) {
|
|
3330
|
+
isRef = true;
|
|
3331
|
+
_tagsReferences.push(ref);
|
|
3332
|
+
}
|
|
3333
|
+
if (ref.code > DiagnosticCode.ReferenceStart && ref.code < DiagnosticCode.ReferenceEnd) {
|
|
3334
|
+
isRef = true;
|
|
3335
|
+
_references.push(ref);
|
|
3336
|
+
}
|
|
3337
|
+
if (!isRef) {
|
|
3338
|
+
break;
|
|
3339
|
+
}
|
|
3340
|
+
i++;
|
|
3341
|
+
ref.diagnostic = diagnostic;
|
|
3342
|
+
diagnostic.references.push(ref);
|
|
3343
|
+
}
|
|
3344
|
+
}
|
|
3345
|
+
return {
|
|
3346
|
+
errors: _errors,
|
|
3347
|
+
warnings: _warnings,
|
|
3348
|
+
infos: _infos,
|
|
3349
|
+
hints: _hints,
|
|
3350
|
+
tags: _tags,
|
|
3351
|
+
references: _references,
|
|
3352
|
+
tagsReferences: _tagsReferences
|
|
3353
|
+
};
|
|
3354
|
+
}
|
|
3355
|
+
function formatRange(range) {
|
|
3356
|
+
if (range.startLineNumber === range.endLineNumber) {
|
|
3357
|
+
if (range.startColumn === range.endColumn) {
|
|
3358
|
+
return `${range.startLineNumber}:${range.startColumn}`;
|
|
3359
|
+
}
|
|
3360
|
+
return `${range.startLineNumber}:${range.startColumn}-${range.endColumn}`;
|
|
3361
|
+
}
|
|
3362
|
+
return `${range.startLineNumber}:${range.startColumn}-${range.endLineNumber}:${range.endColumn}`;
|
|
3363
|
+
}
|
|
3364
|
+
function formatDiagnostic(diagnostic) {
|
|
3365
|
+
const range = formatRange(diagnostic.range);
|
|
3366
|
+
const codeName = DiagnosticCode[diagnostic.code] || `Unknown(${diagnostic.code})`;
|
|
3367
|
+
let message = getDiagnosticMessage(diagnostic.code);
|
|
3368
|
+
for (const ref of diagnostic.references) {
|
|
3369
|
+
const refRange = formatRange(ref.range);
|
|
3370
|
+
message += `
|
|
3371
|
+
(${refRange}): ${getDiagnosticMessage(ref.code)}`;
|
|
3372
|
+
}
|
|
3373
|
+
return ` ${codeName}(${range}): ${message}`;
|
|
3374
|
+
}
|
|
3375
|
+
|
|
3376
|
+
export {
|
|
3377
|
+
isFinite,
|
|
3378
|
+
entries,
|
|
3379
|
+
defineProperty,
|
|
3380
|
+
VmError,
|
|
3381
|
+
operations_exports,
|
|
3382
|
+
VmSharedContext,
|
|
3383
|
+
defineVmContextValue,
|
|
3384
|
+
DefaultVmContext,
|
|
3385
|
+
createVmContext,
|
|
3386
|
+
isVmContext,
|
|
3387
|
+
configCheckpoint,
|
|
3388
|
+
GlobalFallback,
|
|
3389
|
+
helpers_exports,
|
|
3390
|
+
isVmFunction,
|
|
3391
|
+
getVmFunctionInfo,
|
|
3392
|
+
VmFunction,
|
|
3393
|
+
wrapToVmValue,
|
|
3394
|
+
unwrapFromVmValue,
|
|
3395
|
+
VmExtern,
|
|
3396
|
+
VmModule,
|
|
3397
|
+
isVmScript,
|
|
3398
|
+
isVmConst,
|
|
3399
|
+
isVmImmutable,
|
|
3400
|
+
isVmValue,
|
|
3401
|
+
isVmAny,
|
|
3402
|
+
isVmArray,
|
|
3403
|
+
isVmRecord,
|
|
3404
|
+
isVmPrimitive,
|
|
3405
|
+
isVmExtern,
|
|
3406
|
+
isVmModule,
|
|
3407
|
+
VM_ARRAY_MAX_LENGTH,
|
|
3408
|
+
constants_exports,
|
|
3409
|
+
DiagnosticCode,
|
|
3410
|
+
getDiagnosticMessage,
|
|
3411
|
+
parseDiagnostics,
|
|
3412
|
+
formatDiagnostic,
|
|
3413
|
+
debug_print,
|
|
3414
|
+
lib,
|
|
3415
|
+
serializeString,
|
|
3416
|
+
serializePropName,
|
|
3417
|
+
serialize
|
|
3418
|
+
};
|
|
3419
|
+
//# sourceMappingURL=chunk-DCXIWIW5.js.map
|