@mirascript/mirascript 0.1.74 → 0.1.78
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-VI74OKFU.js → chunk-BITOQYYQ.js} +99 -89
- package/dist/chunk-BITOQYYQ.js.map +6 -0
- package/dist/{chunk-GONOUVUN.js → chunk-VNQQF2W7.js} +143 -58
- package/dist/chunk-VNQQF2W7.js.map +6 -0
- package/dist/compiler/emit/index.d.ts.map +1 -1
- package/dist/compiler/emit-script.d.ts.map +1 -1
- package/dist/compiler/worker.js +1 -1
- package/dist/helpers/convert/to-number.d.ts.map +1 -1
- package/dist/helpers/convert/to-string.d.ts +2 -0
- package/dist/helpers/convert/to-string.d.ts.map +1 -1
- package/dist/helpers/error.d.ts +1 -0
- package/dist/helpers/error.d.ts.map +1 -1
- package/dist/helpers/serialize.d.ts.map +1 -1
- package/dist/helpers/utils.d.ts +9 -0
- package/dist/helpers/utils.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/subtle.js +2 -2
- package/dist/vm/lib/global/debug.d.ts.map +1 -1
- package/dist/vm/lib/global/json.d.ts +3 -2
- package/dist/vm/lib/global/json.d.ts.map +1 -1
- package/dist/vm/lib/global/math/index.d.ts +2 -2
- package/dist/vm/lib/global/math/index.d.ts.map +1 -1
- package/dist/vm/lib/global/math/{gamma.d.ts → tgamma.d.ts} +1 -1
- package/dist/vm/lib/global/math/tgamma.d.ts.map +1 -0
- package/dist/vm/lib/global/math/{round.d.ts → to-int.d.ts} +1 -1
- package/dist/vm/lib/global/math/to-int.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/entries.d.ts +1 -1
- package/dist/vm/lib/global/sequence/entries.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/fold.d.ts +3 -0
- package/dist/vm/lib/global/sequence/fold.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/group.d.ts +3 -0
- package/dist/vm/lib/global/sequence/group.d.ts.map +1 -0
- package/dist/vm/lib/global/sequence/index.d.ts +2 -0
- package/dist/vm/lib/global/sequence/index.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/new.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/with.d.ts.map +1 -1
- package/dist/vm/lib/global/sequence/zip.d.ts +2 -2
- package/dist/vm/lib/global/sequence/zip.d.ts.map +1 -1
- package/dist/vm/lib/helpers.d.ts +2 -2
- package/dist/vm/lib/helpers.d.ts.map +1 -1
- package/dist/vm/operations/array-range.d.ts.map +1 -1
- package/dist/vm/operations/compound.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/compiler/compile-fast.ts +1 -1
- package/src/compiler/emit/index.ts +0 -6
- package/src/compiler/emit-script.ts +1 -0
- package/src/helpers/convert/to-number.ts +5 -10
- package/src/helpers/convert/to-string.ts +3 -2
- package/src/helpers/error.ts +3 -1
- package/src/helpers/serialize.ts +4 -9
- package/src/helpers/types.ts +1 -1
- package/src/helpers/utils.ts +27 -0
- package/src/vm/lib/global/debug.ts +4 -8
- package/src/vm/lib/global/json.ts +21 -9
- package/src/vm/lib/global/math/index.ts +2 -2
- package/src/vm/lib/global/math/{gamma.ts → tgamma.ts} +8 -14
- package/src/vm/lib/global/sequence/entries.ts +6 -1
- package/src/vm/lib/global/sequence/fold.ts +30 -0
- package/src/vm/lib/global/sequence/group.ts +37 -0
- package/src/vm/lib/global/sequence/index.ts +2 -0
- package/src/vm/lib/global/sequence/map-filter.ts +2 -2
- package/src/vm/lib/global/sequence/new.ts +8 -2
- package/src/vm/lib/global/sequence/with.ts +7 -6
- package/src/vm/lib/global/sequence/zip.ts +21 -10
- package/src/vm/lib/helpers.ts +6 -6
- package/src/vm/lib/mod/matrix.ts +2 -2
- package/src/vm/operations/array-range.ts +10 -6
- package/src/vm/operations/compound.ts +13 -6
- package/src/vm/types/extern.ts +1 -1
- package/dist/chunk-GONOUVUN.js.map +0 -6
- package/dist/chunk-VI74OKFU.js.map +0 -6
- package/dist/vm/lib/global/math/gamma.d.ts.map +0 -1
- package/dist/vm/lib/global/math/round.d.ts.map +0 -1
- /package/src/vm/lib/global/math/{round.ts → to-int.ts} +0 -0
|
@@ -1,19 +1,31 @@
|
|
|
1
|
-
import { isVmExtern, isVmModule } from '../../types/index.js';
|
|
1
|
+
import { isVmExtern, isVmModule, type VmValue } from '../../types/index.js';
|
|
2
2
|
import { expectString, required, rethrowError, VmLib } from '../helpers.js';
|
|
3
3
|
const { parse, stringify } = JSON;
|
|
4
4
|
|
|
5
5
|
export const to_json = VmLib(
|
|
6
6
|
(data) => {
|
|
7
7
|
required('data', data, null);
|
|
8
|
-
if (isVmExtern(data) || isVmModule(data)) {
|
|
9
|
-
try {
|
|
10
|
-
return stringify(data.value) ?? null;
|
|
11
|
-
} catch (ex) {
|
|
12
|
-
rethrowError('Failed to convert extern to JSON', ex, '{}');
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
8
|
if (typeof data == 'function') return null;
|
|
16
|
-
return stringify(data)
|
|
9
|
+
return stringify(data, (key, value: VmValue) => {
|
|
10
|
+
if (typeof value == 'function') {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
if (isVmModule(value)) {
|
|
14
|
+
return value.value as JSONValue;
|
|
15
|
+
}
|
|
16
|
+
if (isVmExtern(value)) {
|
|
17
|
+
const extern = value.value;
|
|
18
|
+
if ('toJSON' in extern && typeof extern.toJSON == 'function') {
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
20
|
+
return extern.toJSON() as JSONValue;
|
|
21
|
+
}
|
|
22
|
+
if (typeof extern == 'function') {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return extern as JSONValue;
|
|
26
|
+
}
|
|
27
|
+
return value as JSONValue;
|
|
28
|
+
});
|
|
17
29
|
},
|
|
18
30
|
{
|
|
19
31
|
summary: '将数据转换为 JSON 字符串',
|
|
@@ -26,5 +26,5 @@ export const random = VmLib(() => _random(), {
|
|
|
26
26
|
export * from './arr.js';
|
|
27
27
|
export * from './const.js';
|
|
28
28
|
export * from './unary.js';
|
|
29
|
-
export * from './
|
|
30
|
-
export { gamma, factorial } from './
|
|
29
|
+
export * from './to-int.js';
|
|
30
|
+
export { gamma, factorial } from './tgamma.js';
|
|
@@ -81,22 +81,16 @@ function sinpi(x: number): number {
|
|
|
81
81
|
const N = 12;
|
|
82
82
|
|
|
83
83
|
// static const double g = 6.024680040776729583740234375;
|
|
84
|
-
const GMHALF = 5.
|
|
84
|
+
const GMHALF = 5.524680040776729583740234375 as const;
|
|
85
85
|
|
|
86
86
|
const SNUM = [
|
|
87
|
-
23_531_376_880.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
31_426_415.585_400_194_380_614_231_628_318_205_362_874_684_987_64,
|
|
95
|
-
2_876_370.628_935_372_441_225_409_051_620_849_613_599_114_537_876_8,
|
|
96
|
-
186_056.265_395_223_495_040_294_989_716_045_699_282_207_842_363_28,
|
|
97
|
-
8071.672_002_365_816_210_638_002_902_272_250_613_821_851_632_502_4,
|
|
98
|
-
210.824_277_751_579_345_872_509_733_920_713_362_711_669_695_802_91,
|
|
99
|
-
2.506_628_274_631_000_270_164_908_177_133_837_338_626_431_079_340_8,
|
|
87
|
+
23_531_376_880.41075968857200767445163675473484680494, 42_919_803_642.649098768957899047001988850926355848959,
|
|
88
|
+
35_711_959_237.355668049440185451547166705960488635843, 17_921_034_426.03720969991975575445893111267140326539,
|
|
89
|
+
6_039_542_586.3520280050642916443072979210699388420708, 1_439_720_407.3117216736632230727949123939715485786772,
|
|
90
|
+
248_874_557.86205415651146038641322942321632125127801, 31_426_415.58540019438061423162831820536287468498764,
|
|
91
|
+
2_876_370.6289353724412254090516208496135991145378768, 186_056.26539522349504029498971604569928220784236328,
|
|
92
|
+
8071.6720023658162106380029022722506138218516325024, 210.82427775157934587250973392071336271166969580291,
|
|
93
|
+
2.5066282746310002701649081771338373386264310793408,
|
|
100
94
|
] as const;
|
|
101
95
|
|
|
102
96
|
const SDEN = [
|
|
@@ -56,8 +56,13 @@ export const entries = VmLib(
|
|
|
56
56
|
arr.push({ 0: i, 1: data[i] ?? null });
|
|
57
57
|
}
|
|
58
58
|
return arr;
|
|
59
|
+
} else {
|
|
60
|
+
const arr: Array<{ 0: string; 1: VmConst }> = [];
|
|
61
|
+
for (const [key, value] of _entries(data)) {
|
|
62
|
+
arr.push({ 0: key, 1: value ?? null });
|
|
63
|
+
}
|
|
64
|
+
return arr;
|
|
59
65
|
}
|
|
60
|
-
return _entries(data).map(([key, value]) => ({ 0: key, 1: value ?? null }));
|
|
61
66
|
},
|
|
62
67
|
{
|
|
63
68
|
summary: '返回数组或记录的键值对列表',
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { $Call } from '../../../operations/index.js';
|
|
2
|
+
import type { VmValue } from '../../../types/index.js';
|
|
3
|
+
import { VmLib, expectCallable, expectConst, iterate, required } from '../../helpers.js';
|
|
4
|
+
|
|
5
|
+
export const fold = VmLib(
|
|
6
|
+
(data, initial, f) => {
|
|
7
|
+
required('initial', initial, null);
|
|
8
|
+
expectConst('data', data, null);
|
|
9
|
+
expectCallable('f', f, data);
|
|
10
|
+
|
|
11
|
+
let acc: VmValue = initial;
|
|
12
|
+
iterate(data, (value, index, data) => {
|
|
13
|
+
acc = $Call(f, [acc, value, index, data]);
|
|
14
|
+
});
|
|
15
|
+
return acc;
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
summary: '对数组或记录中的每个元素应用函数,并返回累积结果',
|
|
19
|
+
params: {
|
|
20
|
+
data: { type: 'array | record', description: '要折叠的数组或记录' },
|
|
21
|
+
initial: { type: 'any', description: '初始累积值' },
|
|
22
|
+
f: {
|
|
23
|
+
type: 'fn(acc: type(initial), value: any, key: number | string, input: type(data)) -> type(initial)',
|
|
24
|
+
description: '应用于每个元素的函数',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
returns: { type: 'type(initial)' },
|
|
28
|
+
examples: ['fold([1, 2, 3], 0, fn (acc, x) { acc + x }) // 6'],
|
|
29
|
+
},
|
|
30
|
+
);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { toString } from '../../../../helpers/convert/to-string.js';
|
|
2
|
+
import { fromEntries } from '../../../../helpers/utils.js';
|
|
3
|
+
import { $Call } from '../../../operations/call.js';
|
|
4
|
+
import type { VmConst } from '../../../types/index.js';
|
|
5
|
+
import { VmLib, expectArray, expectCallable } from '../../helpers.js';
|
|
6
|
+
|
|
7
|
+
export const group_by = VmLib(
|
|
8
|
+
(data, key) => {
|
|
9
|
+
expectArray('data', data, null);
|
|
10
|
+
expectCallable('key', key, data);
|
|
11
|
+
const result = new Map<string, VmConst[]>();
|
|
12
|
+
const len = data.length;
|
|
13
|
+
for (let i = 0; i < len; i++) {
|
|
14
|
+
const v = data[i] ?? null;
|
|
15
|
+
const k = toString($Call(key, [v, i, data]), undefined);
|
|
16
|
+
let arr = result.get(k);
|
|
17
|
+
if (!arr) {
|
|
18
|
+
arr = [];
|
|
19
|
+
result.set(k, arr);
|
|
20
|
+
}
|
|
21
|
+
arr.push(v);
|
|
22
|
+
}
|
|
23
|
+
return fromEntries(result);
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
summary: '根据指定的键函数对数组进行分组',
|
|
27
|
+
params: {
|
|
28
|
+
data: { type: 'array', description: '要分组的数组' },
|
|
29
|
+
key: {
|
|
30
|
+
type: 'fn(value: any, index: number, arr: type(data)) -> string',
|
|
31
|
+
description: '用于生成分组键的函数',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
returns: { type: 'record' },
|
|
35
|
+
examples: ['group_by([1, 2, 3, 4], fn { it % 2 }) // ("0": [2, 4], "1": [1, 3])'],
|
|
36
|
+
},
|
|
37
|
+
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { toBoolean } from '../../../../helpers/convert/to-boolean.js';
|
|
2
2
|
import { $Call } from '../../../operations/index.js';
|
|
3
3
|
import { isVmConst, type VmAny, type VmValue } from '../../../types/index.js';
|
|
4
|
-
import { VmLib, expectCallable, expectConst,
|
|
4
|
+
import { VmLib, expectCallable, expectConst, iterate } from '../../helpers.js';
|
|
5
5
|
|
|
6
6
|
export * from './with.js';
|
|
7
7
|
export * from './entries.js';
|
|
@@ -16,7 +16,7 @@ function mapImplWrapped(
|
|
|
16
16
|
): VmValue {
|
|
17
17
|
expectConst('data', data, null);
|
|
18
18
|
expectCallable(fnName, fn, data);
|
|
19
|
-
return
|
|
19
|
+
return iterate(data, (value, index, data) => {
|
|
20
20
|
const ret = mapper(fn, value, index, data);
|
|
21
21
|
if (ret === undefined || isVmConst(ret)) return ret;
|
|
22
22
|
return null;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { VmArray, VmConst, VmRecord } from '../../../types/index.js';
|
|
2
2
|
import { toString } from '../../../../helpers/convert/to-string.js';
|
|
3
3
|
import { VM_ARRAY_MAX_LENGTH } from '../../../../helpers/constants.js';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
keys as _keys,
|
|
6
|
+
values as _values,
|
|
7
|
+
entries as _entries,
|
|
8
|
+
PositiveInfinity,
|
|
9
|
+
setRecord,
|
|
10
|
+
} from '../../../../helpers/utils.js';
|
|
5
11
|
import { $Call, $El, $Get } from '../../../operations/index.js';
|
|
6
12
|
import { VmLib, expectCallable, expectIntegerRange } from '../../helpers.js';
|
|
7
13
|
|
|
@@ -15,7 +21,7 @@ export const new_record = VmLib(
|
|
|
15
21
|
if (entry == null) continue;
|
|
16
22
|
const key = $Get(entry, 0);
|
|
17
23
|
const value = $El($Get(entry, 1));
|
|
18
|
-
result
|
|
24
|
+
setRecord(result, toString(key), value);
|
|
19
25
|
}
|
|
20
26
|
return result;
|
|
21
27
|
},
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { VM_ARRAY_MAX_LENGTH } from '../../../../helpers/constants.js';
|
|
2
2
|
import { toNumber, toString } from '../../../../helpers/convert/index.js';
|
|
3
3
|
import { isVmArray, isVmRecord } from '../../../../helpers/types.js';
|
|
4
|
-
import { isArray, isInteger,
|
|
4
|
+
import { isArray, isInteger, isFinite, NotNumber, setRecord, getRecord } from '../../../../helpers/utils.js';
|
|
5
5
|
import { $El } from '../../../operations/helpers.js';
|
|
6
6
|
import type { VmArray, VmConst, VmValue } from '../../../types/index.js';
|
|
7
7
|
import { VmLib, expectArrayOrRecord, expectConst, throwError } from '../../helpers.js';
|
|
8
8
|
|
|
9
9
|
const arrIndex = (index: NonNullable<VmConst>): number => {
|
|
10
|
-
const
|
|
11
|
-
if (
|
|
10
|
+
const num = toNumber(index, NotNumber);
|
|
11
|
+
if (!isFinite(num) || num < 0) {
|
|
12
12
|
throwError('Array index must be a non-negative integer', index);
|
|
13
13
|
}
|
|
14
|
+
const idx = Math.trunc(num);
|
|
14
15
|
if (idx >= VM_ARRAY_MAX_LENGTH) {
|
|
15
16
|
throwError(`Array index exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`, index);
|
|
16
17
|
}
|
|
@@ -45,7 +46,7 @@ const withInner = (obj: VmConst | undefined, key: VmArray, keyIndex: number, val
|
|
|
45
46
|
result[index] = withInner(result[index], key, keyIndex + 1, value);
|
|
46
47
|
} else {
|
|
47
48
|
const prop = toString(k, undefined);
|
|
48
|
-
result
|
|
49
|
+
setRecord(result, prop, withInner(result[prop], key, keyIndex + 1, value));
|
|
49
50
|
}
|
|
50
51
|
return result;
|
|
51
52
|
};
|
|
@@ -109,12 +110,12 @@ const _with = VmLib(
|
|
|
109
110
|
if (isVmArray(key)) {
|
|
110
111
|
const firstKey = key[0]!;
|
|
111
112
|
prop = toString(firstKey, undefined);
|
|
112
|
-
val = withInner(result
|
|
113
|
+
val = withInner(getRecord(result, prop), key, 1, value);
|
|
113
114
|
} else {
|
|
114
115
|
prop = toString(key, undefined);
|
|
115
116
|
val = value;
|
|
116
117
|
}
|
|
117
|
-
result
|
|
118
|
+
setRecord(result, prop, val);
|
|
118
119
|
}
|
|
119
120
|
return result;
|
|
120
121
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { display } from '../../../../helpers/serialize.js';
|
|
2
|
+
import { setRecord } from '../../../../helpers/utils.js';
|
|
2
3
|
import { Cp } from '../../../checkpoint.js';
|
|
3
|
-
import { isVmArray, type VmConst, type VmArray } from '../../../types/index.js';
|
|
4
|
+
import { isVmArray, type VmConst, type VmArray, type VmRecord } from '../../../types/index.js';
|
|
4
5
|
import { VmLib, throwError } from '../../helpers.js';
|
|
5
6
|
import { entries } from './entries.js';
|
|
6
7
|
|
|
7
8
|
export const zip = VmLib(
|
|
8
9
|
(data) => {
|
|
9
|
-
const ets = entries(data);
|
|
10
|
+
const ets = entries(data) as Array<{ 0: string | number; 1: VmArray }>;
|
|
10
11
|
let length = 0;
|
|
11
12
|
for (const { 0: key, 1: arr } of ets) {
|
|
12
13
|
if (!isVmArray(arr)) {
|
|
@@ -15,15 +16,25 @@ export const zip = VmLib(
|
|
|
15
16
|
length = Math.max(length, arr.length);
|
|
16
17
|
}
|
|
17
18
|
if (length === 0) return [];
|
|
18
|
-
const result: Array<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
const result: Array<VmArray | VmRecord> = [];
|
|
20
|
+
if (isVmArray(data)) {
|
|
21
|
+
for (let i = 0; i < length; i++) {
|
|
22
|
+
Cp();
|
|
23
|
+
const obj: VmConst[] = [];
|
|
24
|
+
for (const { 0: key, 1: arr } of ets) {
|
|
25
|
+
obj[key as number] = arr[i] ?? null;
|
|
26
|
+
}
|
|
27
|
+
result.push(obj);
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
for (let i = 0; i < length; i++) {
|
|
31
|
+
Cp();
|
|
32
|
+
const obj: Record<string, VmConst> = {};
|
|
33
|
+
for (const { 0: key, 1: arr } of ets) {
|
|
34
|
+
setRecord(obj, key as string, arr[i]);
|
|
35
|
+
}
|
|
36
|
+
result.push(obj);
|
|
25
37
|
}
|
|
26
|
-
result.push(obj);
|
|
27
38
|
}
|
|
28
39
|
return result;
|
|
29
40
|
},
|
package/src/vm/lib/helpers.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VM_ARRAY_MAX_LENGTH } from '../../helpers/constants.js';
|
|
2
|
-
import {
|
|
2
|
+
import { NotNumber, entries, fromEntries, isSafeInteger, isFinite } from '../../helpers/utils.js';
|
|
3
3
|
import { toBoolean, toNumber, toString } from '../../helpers/convert/index.js';
|
|
4
4
|
import { display } from '../../helpers/serialize.js';
|
|
5
5
|
import { isVmArray, isVmFunction, isVmPrimitive, isVmConst, isVmCallable, isVmRecord } from '../../helpers/types.js';
|
|
@@ -229,7 +229,7 @@ export function getNumbers(args: readonly VmAny[]): number[] {
|
|
|
229
229
|
|
|
230
230
|
/** 将值转为数组长度 */
|
|
231
231
|
export function arrayLen(len: number | null | undefined): number {
|
|
232
|
-
if (len == null ||
|
|
232
|
+
if (len == null || !isFinite(len) || len <= -1) {
|
|
233
233
|
throwError('Array length must be a non-negative integer', null);
|
|
234
234
|
}
|
|
235
235
|
len = Math.trunc(len);
|
|
@@ -240,10 +240,10 @@ export function arrayLen(len: number | null | undefined): number {
|
|
|
240
240
|
}
|
|
241
241
|
|
|
242
242
|
/** 应用映射函数 */
|
|
243
|
-
export function
|
|
244
|
-
data:
|
|
243
|
+
export function iterate<T extends VmConst>(
|
|
244
|
+
data: T,
|
|
245
245
|
/** 返回 `undefined` 表示跳过该元素 */
|
|
246
|
-
mapper: (value: VmConst, index: number | string | null, data:
|
|
246
|
+
mapper: (value: VmConst, index: number | string | null, data: T) => VmConst | undefined,
|
|
247
247
|
): VmConst {
|
|
248
248
|
if (isVmPrimitive(data)) {
|
|
249
249
|
return mapper(data, null, data) ?? null;
|
|
@@ -260,7 +260,7 @@ export function map(
|
|
|
260
260
|
return result;
|
|
261
261
|
} else {
|
|
262
262
|
const e: Array<[string, VmConst]> = [];
|
|
263
|
-
for (const [key, value] of entries(data)) {
|
|
263
|
+
for (const [key, value] of entries<string, VmConst | undefined>(data)) {
|
|
264
264
|
Cp();
|
|
265
265
|
const ret = mapper(value ?? null, key, data);
|
|
266
266
|
if (ret === undefined) continue;
|
package/src/vm/lib/mod/matrix.ts
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
throwError,
|
|
13
13
|
getNumbers,
|
|
14
14
|
arrayLen,
|
|
15
|
-
|
|
15
|
+
iterate,
|
|
16
16
|
expectInteger,
|
|
17
17
|
} from '../helpers.js';
|
|
18
18
|
|
|
@@ -370,7 +370,7 @@ export const invert = VmLib(
|
|
|
370
370
|
expectConst('a', a, null);
|
|
371
371
|
const [rows, cols] = sizeImpl(a);
|
|
372
372
|
if (rows == null) return 1 / num(a); // 标量取倒数
|
|
373
|
-
if (cols == null) return
|
|
373
|
+
if (cols == null) return iterate(a, (v) => 1 / num(v)); // 向量按元素取倒数
|
|
374
374
|
|
|
375
375
|
if (rows !== cols) throwError(`Matrix must be square`, a);
|
|
376
376
|
const m = a as VmConst[][];
|
|
@@ -16,10 +16,12 @@ export const $ArrayRange = (start: VmAny, end: VmAny): VmArray => {
|
|
|
16
16
|
const s = $ToNumber(start);
|
|
17
17
|
const e = $ToNumber(end);
|
|
18
18
|
if (isEmptyRange(s, e)) return [];
|
|
19
|
-
|
|
19
|
+
const n = Math.floor(e - s + 1);
|
|
20
|
+
assertArrayLength(n);
|
|
20
21
|
const arr = [];
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
arr.length = n;
|
|
23
|
+
for (let i = 0; i < n; i++) {
|
|
24
|
+
arr[i] = s + i;
|
|
23
25
|
}
|
|
24
26
|
return arr;
|
|
25
27
|
};
|
|
@@ -28,10 +30,12 @@ export const $ArrayRangeExclusive = (start: VmAny, end: VmAny): VmArray => {
|
|
|
28
30
|
const s = $ToNumber(start);
|
|
29
31
|
const e = $ToNumber(end);
|
|
30
32
|
if (isEmptyRange(s, e)) return [];
|
|
31
|
-
|
|
33
|
+
const n = Math.ceil(e - s);
|
|
34
|
+
assertArrayLength(n);
|
|
32
35
|
const arr = [];
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
arr.length = n;
|
|
37
|
+
for (let i = 0; i < n; i++) {
|
|
38
|
+
arr[i] = s + i;
|
|
35
39
|
}
|
|
36
40
|
return arr;
|
|
37
41
|
};
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { VmError } from '../../helpers/error.js';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
hasOwnEnumerable,
|
|
4
|
+
NotNumber,
|
|
5
|
+
keys,
|
|
6
|
+
create,
|
|
7
|
+
isFinite,
|
|
8
|
+
keysLength,
|
|
9
|
+
getRecord,
|
|
10
|
+
setRecord,
|
|
11
|
+
} from '../../helpers/utils.js';
|
|
3
12
|
import { toNumber, toString } from '../../helpers/convert/index.js';
|
|
4
13
|
import { display } from '../../helpers/serialize.js';
|
|
5
14
|
import {
|
|
@@ -63,8 +72,7 @@ export const $Omit = (value: VmAny, omitted: ReadonlyArray<number | string>): Vm
|
|
|
63
72
|
const omittedSet = new Set(omitted.map($ToString));
|
|
64
73
|
for (const key of valueKeys) {
|
|
65
74
|
if (!omittedSet.has(key)) {
|
|
66
|
-
|
|
67
|
-
result[key] = value[key] ?? null;
|
|
75
|
+
setRecord(result, key, value[key]);
|
|
68
76
|
}
|
|
69
77
|
}
|
|
70
78
|
return result;
|
|
@@ -78,7 +86,7 @@ export const $Pick = (value: VmAny, picked: ReadonlyArray<number | string>): VmR
|
|
|
78
86
|
for (const key of picked) {
|
|
79
87
|
const k = $ToString(key);
|
|
80
88
|
if (hasOwnEnumerable(value, k)) {
|
|
81
|
-
result
|
|
89
|
+
setRecord(result, k, value[k]);
|
|
82
90
|
}
|
|
83
91
|
}
|
|
84
92
|
return result;
|
|
@@ -114,8 +122,7 @@ export const $Get = (obj: VmAny, key: VmAny): VmValue => {
|
|
|
114
122
|
}
|
|
115
123
|
return obj.get(pk) ?? null;
|
|
116
124
|
}
|
|
117
|
-
|
|
118
|
-
return $El(obj[pk] ?? null);
|
|
125
|
+
return $El(getRecord(obj, pk) ?? null);
|
|
119
126
|
};
|
|
120
127
|
/** 设置字段 */
|
|
121
128
|
export const $Set = (obj: VmAny, key: VmAny, value: VmAny): void => {
|
package/src/vm/types/extern.ts
CHANGED
|
@@ -140,7 +140,7 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
|
|
|
140
140
|
override toString(useBraces: boolean): string {
|
|
141
141
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
142
142
|
const { toString } = this.value;
|
|
143
|
-
if (typeof toString
|
|
143
|
+
if (typeof toString !== 'function' || toString === ObjectToString || toString === FunctionToString) {
|
|
144
144
|
// When the toString method is not overridden or invalid, provide a better default representation
|
|
145
145
|
return super.toString(useBraces);
|
|
146
146
|
}
|