@mirascript/mirascript 0.1.76 → 0.1.79

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.
Files changed (182) hide show
  1. package/dist/{chunk-ZRLBJK6A.js → chunk-BPFOJ4Q6.js} +499 -470
  2. package/dist/chunk-BPFOJ4Q6.js.map +6 -0
  3. package/dist/{chunk-VI74OKFU.js → chunk-LSPCAN32.js} +291 -226
  4. package/dist/chunk-LSPCAN32.js.map +6 -0
  5. package/dist/compiler/emit/constants.d.ts +1 -1
  6. package/dist/compiler/emit/constants.d.ts.map +1 -1
  7. package/dist/compiler/emit/consts.d.ts.map +1 -1
  8. package/dist/compiler/emit/index.d.ts.map +1 -1
  9. package/dist/compiler/emit-script.d.ts.map +1 -1
  10. package/dist/compiler/worker.js +1 -1
  11. package/dist/helpers/convert/{to-boolean.d.ts → boolean.d.ts} +1 -1
  12. package/dist/helpers/convert/boolean.d.ts.map +1 -0
  13. package/dist/helpers/convert/{to-format.d.ts → format.d.ts} +1 -1
  14. package/dist/helpers/convert/format.d.ts.map +1 -0
  15. package/dist/helpers/convert/index.d.ts +4 -4
  16. package/dist/helpers/convert/index.d.ts.map +1 -1
  17. package/dist/helpers/convert/{to-number.d.ts → number.d.ts} +1 -1
  18. package/dist/helpers/convert/number.d.ts.map +1 -0
  19. package/dist/helpers/convert/{to-string.d.ts → string.d.ts} +3 -1
  20. package/dist/helpers/convert/string.d.ts.map +1 -0
  21. package/dist/helpers/error.d.ts +1 -0
  22. package/dist/helpers/error.d.ts.map +1 -1
  23. package/dist/helpers/serialize.d.ts.map +1 -1
  24. package/dist/helpers/types/array-like.d.ts +8 -0
  25. package/dist/helpers/types/array-like.d.ts.map +1 -0
  26. package/dist/helpers/types/basic.d.ts +26 -0
  27. package/dist/helpers/types/basic.d.ts.map +1 -0
  28. package/dist/helpers/types/composed.d.ts +12 -0
  29. package/dist/helpers/types/composed.d.ts.map +1 -0
  30. package/dist/helpers/types/const.d.ts +6 -0
  31. package/dist/helpers/types/const.d.ts.map +1 -0
  32. package/dist/helpers/types/get-type.d.ts +6 -0
  33. package/dist/helpers/types/get-type.d.ts.map +1 -0
  34. package/dist/helpers/types/index.d.ts +6 -0
  35. package/dist/helpers/types/index.d.ts.map +1 -0
  36. package/dist/helpers/types/proto.d.ts +5 -0
  37. package/dist/helpers/types/proto.d.ts.map +1 -0
  38. package/dist/helpers/utils.d.ts +9 -0
  39. package/dist/helpers/utils.d.ts.map +1 -1
  40. package/dist/index.js +3 -3
  41. package/dist/index.js.map +1 -1
  42. package/dist/subtle.js +3 -3
  43. package/dist/vm/lib/global/debug.d.ts.map +1 -1
  44. package/dist/vm/lib/global/json.d.ts +3 -2
  45. package/dist/vm/lib/global/json.d.ts.map +1 -1
  46. package/dist/vm/lib/global/math/tgamma.d.ts.map +1 -1
  47. package/dist/vm/lib/global/sequence/entries.d.ts +1 -1
  48. package/dist/vm/lib/global/sequence/entries.d.ts.map +1 -1
  49. package/dist/vm/lib/global/sequence/fold.d.ts +3 -0
  50. package/dist/vm/lib/global/sequence/fold.d.ts.map +1 -0
  51. package/dist/vm/lib/global/sequence/group.d.ts +3 -0
  52. package/dist/vm/lib/global/sequence/group.d.ts.map +1 -0
  53. package/dist/vm/lib/global/sequence/index.d.ts +2 -0
  54. package/dist/vm/lib/global/sequence/index.d.ts.map +1 -1
  55. package/dist/vm/lib/global/sequence/new.d.ts.map +1 -1
  56. package/dist/vm/lib/global/sequence/zip.d.ts +2 -2
  57. package/dist/vm/lib/global/sequence/zip.d.ts.map +1 -1
  58. package/dist/vm/lib/helpers.d.ts +2 -2
  59. package/dist/vm/lib/helpers.d.ts.map +1 -1
  60. package/dist/vm/lib/mod/index.d.ts +1 -1
  61. package/dist/vm/lib/mod/index.d.ts.map +1 -1
  62. package/dist/vm/lib/mod/matrix/bin-ops.d.ts +8 -0
  63. package/dist/vm/lib/mod/matrix/bin-ops.d.ts.map +1 -0
  64. package/dist/vm/lib/mod/matrix/fill.d.ts +6 -0
  65. package/dist/vm/lib/mod/matrix/fill.d.ts.map +1 -0
  66. package/dist/vm/lib/mod/matrix/helpers.d.ts +6 -0
  67. package/dist/vm/lib/mod/matrix/helpers.d.ts.map +1 -0
  68. package/dist/vm/lib/mod/matrix/index.d.ts +6 -0
  69. package/dist/vm/lib/mod/matrix/index.d.ts.map +1 -0
  70. package/dist/vm/lib/mod/matrix/invert.d.ts +3 -0
  71. package/dist/vm/lib/mod/matrix/invert.d.ts.map +1 -0
  72. package/dist/vm/lib/mod/matrix/size.d.ts +2 -0
  73. package/dist/vm/lib/mod/matrix/size.d.ts.map +1 -0
  74. package/dist/vm/lib/mod/matrix/transpose.d.ts +2 -0
  75. package/dist/vm/lib/mod/matrix/transpose.d.ts.map +1 -0
  76. package/dist/vm/operations/array-range.d.ts +3 -3
  77. package/dist/vm/operations/array-range.d.ts.map +1 -1
  78. package/dist/vm/operations/call.d.ts +1 -1
  79. package/dist/vm/operations/call.d.ts.map +1 -1
  80. package/dist/vm/operations/compound.d.ts +1 -13
  81. package/dist/vm/operations/compound.d.ts.map +1 -1
  82. package/dist/vm/operations/index.d.ts +3 -0
  83. package/dist/vm/operations/index.d.ts.map +1 -1
  84. package/dist/vm/operations/iterable.d.ts +6 -0
  85. package/dist/vm/operations/iterable.d.ts.map +1 -0
  86. package/dist/vm/operations/record.d.ts +6 -0
  87. package/dist/vm/operations/record.d.ts.map +1 -0
  88. package/dist/vm/operations/slice.d.ts.map +1 -1
  89. package/dist/vm/operations/spread.d.ts +6 -0
  90. package/dist/vm/operations/spread.d.ts.map +1 -0
  91. package/dist/vm/operations/utils.d.ts.map +1 -1
  92. package/dist/vm/types/extern/access.d.ts +5 -0
  93. package/dist/vm/types/extern/access.d.ts.map +1 -0
  94. package/dist/vm/types/{extern.d.ts → extern/index.d.ts} +3 -3
  95. package/dist/vm/types/extern/index.d.ts.map +1 -0
  96. package/dist/vm/types/extern/tag.d.ts +3 -0
  97. package/dist/vm/types/extern/tag.d.ts.map +1 -0
  98. package/dist/vm/types/extern/utils.d.ts +13 -0
  99. package/dist/vm/types/extern/utils.d.ts.map +1 -0
  100. package/dist/vm/types/index.d.ts +3 -3
  101. package/dist/vm/types/index.d.ts.map +1 -1
  102. package/package.json +6 -6
  103. package/src/compiler/compile-fast.ts +1 -1
  104. package/src/compiler/diagnostic.ts +2 -2
  105. package/src/compiler/emit/constants.ts +1 -1
  106. package/src/compiler/emit/consts.ts +0 -1
  107. package/src/compiler/emit/index.ts +1 -7
  108. package/src/compiler/emit/sourcemap.ts +1 -1
  109. package/src/compiler/emit-script.ts +1 -0
  110. package/src/compiler/load-module.ts +5 -1
  111. package/src/helpers/convert/{to-boolean.ts → boolean.ts} +1 -1
  112. package/src/helpers/convert/{to-format.ts → format.ts} +1 -1
  113. package/src/helpers/convert/index.ts +4 -4
  114. package/src/helpers/convert/{to-number.ts → number.ts} +16 -32
  115. package/src/helpers/convert/{to-string.ts → string.ts} +5 -4
  116. package/src/helpers/error.ts +3 -1
  117. package/src/helpers/serialize.ts +45 -44
  118. package/src/helpers/types/array-like.ts +32 -0
  119. package/src/helpers/types/basic.ts +82 -0
  120. package/src/helpers/types/composed.ts +27 -0
  121. package/src/helpers/types/const.ts +44 -0
  122. package/src/helpers/types/get-type.ts +16 -0
  123. package/src/helpers/types/index.ts +5 -0
  124. package/src/helpers/types/proto.ts +21 -0
  125. package/src/helpers/utils.ts +33 -0
  126. package/src/vm/lib/global/debug.ts +4 -8
  127. package/src/vm/lib/global/json.ts +21 -9
  128. package/src/vm/lib/global/math/tgamma.ts +8 -14
  129. package/src/vm/lib/global/sequence/all-any.ts +1 -1
  130. package/src/vm/lib/global/sequence/entries.ts +6 -1
  131. package/src/vm/lib/global/sequence/find.ts +1 -1
  132. package/src/vm/lib/global/sequence/fold.ts +30 -0
  133. package/src/vm/lib/global/sequence/group.ts +37 -0
  134. package/src/vm/lib/global/sequence/index.ts +2 -0
  135. package/src/vm/lib/global/sequence/map-filter.ts +3 -3
  136. package/src/vm/lib/global/sequence/new.ts +9 -3
  137. package/src/vm/lib/global/sequence/sort.ts +1 -1
  138. package/src/vm/lib/global/sequence/unique.ts +1 -1
  139. package/src/vm/lib/global/sequence/with.ts +5 -5
  140. package/src/vm/lib/global/sequence/zip.ts +21 -10
  141. package/src/vm/lib/global/time.ts +1 -1
  142. package/src/vm/lib/helpers.ts +12 -5
  143. package/src/vm/lib/mod/index.ts +1 -1
  144. package/src/vm/lib/mod/matrix/bin-ops.ts +291 -0
  145. package/src/vm/lib/mod/matrix/fill.ts +109 -0
  146. package/src/vm/lib/mod/matrix/helpers.ts +26 -0
  147. package/src/vm/lib/mod/matrix/index.ts +5 -0
  148. package/src/vm/lib/mod/matrix/invert.ts +122 -0
  149. package/src/vm/lib/mod/matrix/size.ts +15 -0
  150. package/src/vm/lib/mod/matrix/transpose.ts +32 -0
  151. package/src/vm/operations/array-range.ts +15 -27
  152. package/src/vm/operations/call.ts +2 -2
  153. package/src/vm/operations/compound.ts +5 -125
  154. package/src/vm/operations/helpers.ts +1 -1
  155. package/src/vm/operations/index.ts +3 -0
  156. package/src/vm/operations/iterable.ts +40 -0
  157. package/src/vm/operations/record.ts +33 -0
  158. package/src/vm/operations/slice.ts +23 -22
  159. package/src/vm/operations/spread.ts +57 -0
  160. package/src/vm/operations/type-check.ts +1 -1
  161. package/src/vm/operations/utils.ts +45 -37
  162. package/src/vm/types/boundary.ts +2 -2
  163. package/src/vm/types/extern/access.ts +24 -0
  164. package/src/vm/types/extern/index.ts +124 -0
  165. package/src/vm/types/extern/tag.ts +58 -0
  166. package/src/vm/types/extern/utils.ts +55 -0
  167. package/src/vm/types/function.ts +1 -1
  168. package/src/vm/types/index.ts +3 -3
  169. package/dist/chunk-VI74OKFU.js.map +0 -6
  170. package/dist/chunk-ZRLBJK6A.js.map +0 -6
  171. package/dist/helpers/convert/to-boolean.d.ts.map +0 -1
  172. package/dist/helpers/convert/to-format.d.ts.map +0 -1
  173. package/dist/helpers/convert/to-number.d.ts.map +0 -1
  174. package/dist/helpers/convert/to-string.d.ts.map +0 -1
  175. package/dist/helpers/types.d.ts +0 -58
  176. package/dist/helpers/types.d.ts.map +0 -1
  177. package/dist/vm/lib/mod/matrix.d.ts +0 -15
  178. package/dist/vm/lib/mod/matrix.d.ts.map +0 -1
  179. package/dist/vm/types/extern.d.ts.map +0 -1
  180. package/src/helpers/types.ts +0 -283
  181. package/src/vm/lib/mod/matrix.ts +0 -590
  182. package/src/vm/types/extern.ts +0 -197
@@ -1,7 +1,13 @@
1
1
  import type { VmArray, VmConst, VmRecord } from '../../../types/index.js';
2
- import { toString } from '../../../../helpers/convert/to-string.js';
2
+ import { toString } from '../../../../helpers/convert/index.js';
3
3
  import { VM_ARRAY_MAX_LENGTH } from '../../../../helpers/constants.js';
4
- import { keys as _keys, values as _values, entries as _entries, PositiveInfinity } from '../../../../helpers/utils.js';
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[toString(key)] = value;
24
+ setRecord(result, toString(key), value);
19
25
  }
20
26
  return result;
21
27
  },
@@ -1,4 +1,4 @@
1
- import { toNumber } from '../../../../helpers/convert/to-number.js';
1
+ import { toNumber } from '../../../../helpers/convert/index.js';
2
2
  import { $Call } from '../../../operations/index.js';
3
3
  import type { VmAny, VmConst, VmValue } from '../../../types/index.js';
4
4
  import { VmLib, expectArray, expectCallable } from '../../helpers.js';
@@ -1,4 +1,4 @@
1
- import { toBoolean } from '../../../../helpers/convert/to-boolean.js';
1
+ import { toBoolean } from '../../../../helpers/convert/index.js';
2
2
  import { $Call } from '../../../operations/call.js';
3
3
  import { isSame } from '../../../operations/utils.js';
4
4
  import type { VmAny, VmConst, VmValue } from '../../../types/index.js';
@@ -1,7 +1,7 @@
1
1
  import { VM_ARRAY_MAX_LENGTH } from '../../../../helpers/constants.js';
2
2
  import { toNumber, toString } from '../../../../helpers/convert/index.js';
3
- import { isVmArray, isVmRecord } from '../../../../helpers/types.js';
4
- import { isArray, isInteger, isFinite, NotNumber } from '../../../../helpers/utils.js';
3
+ import { isVmArray, isVmRecord } from '../../../../helpers/types/index.js';
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';
@@ -46,7 +46,7 @@ const withInner = (obj: VmConst | undefined, key: VmArray, keyIndex: number, val
46
46
  result[index] = withInner(result[index], key, keyIndex + 1, value);
47
47
  } else {
48
48
  const prop = toString(k, undefined);
49
- result[prop] = withInner(result[prop], key, keyIndex + 1, value);
49
+ setRecord(result, prop, withInner(result[prop], key, keyIndex + 1, value));
50
50
  }
51
51
  return result;
52
52
  };
@@ -110,12 +110,12 @@ const _with = VmLib(
110
110
  if (isVmArray(key)) {
111
111
  const firstKey = key[0]!;
112
112
  prop = toString(firstKey, undefined);
113
- val = withInner(result[prop], key, 1, value);
113
+ val = withInner(getRecord(result, prop), key, 1, value);
114
114
  } else {
115
115
  prop = toString(key, undefined);
116
116
  val = value;
117
117
  }
118
- result[prop] = val;
118
+ setRecord(result, prop, val);
119
119
  }
120
120
  return result;
121
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<Record<number | string, VmConst>> = [];
19
- const isArr = isVmArray(data);
20
- for (let i = 0; i < length; i++) {
21
- Cp();
22
- const obj: Record<number | string, VmConst> = isArr ? ([] as Record<number, VmConst>) : {};
23
- for (const { 0: key, 1: arr } of ets) {
24
- obj[key] = (arr as VmArray)[i] ?? null;
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
  },
@@ -1,6 +1,6 @@
1
1
  import { describeParam, expectNumberRange, throwError, throwUnexpectedTypeError, VmLib } from '../helpers.js';
2
2
  import { isNaN, NotNumber, isFinite } from '../../../helpers/utils.js';
3
- import { toNumber } from '../../../helpers/convert/to-number.js';
3
+ import { toNumber } from '../../../helpers/convert/index.js';
4
4
  import { display } from '../../../helpers/serialize.js';
5
5
  import type { VmAny } from '../../types/index.js';
6
6
 
@@ -2,7 +2,14 @@ import { VM_ARRAY_MAX_LENGTH } from '../../helpers/constants.js';
2
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
- import { isVmArray, isVmFunction, isVmPrimitive, isVmConst, isVmCallable, isVmRecord } from '../../helpers/types.js';
5
+ import {
6
+ isVmArray,
7
+ isVmFunction,
8
+ isVmPrimitive,
9
+ isVmConst,
10
+ isVmCallable,
11
+ isVmRecord,
12
+ } from '../../helpers/types/index.js';
6
13
  import { VmError } from '../../helpers/error.js';
7
14
  import type {
8
15
  VmExtern,
@@ -240,10 +247,10 @@ export function arrayLen(len: number | null | undefined): number {
240
247
  }
241
248
 
242
249
  /** 应用映射函数 */
243
- export function map(
244
- data: VmConst,
250
+ export function iterate<T extends VmConst>(
251
+ data: T,
245
252
  /** 返回 `undefined` 表示跳过该元素 */
246
- mapper: (value: VmConst, index: number | string | null, data: VmConst) => VmConst | undefined,
253
+ mapper: (value: VmConst, index: number | string | null, data: T) => VmConst | undefined,
247
254
  ): VmConst {
248
255
  if (isVmPrimitive(data)) {
249
256
  return mapper(data, null, data) ?? null;
@@ -260,7 +267,7 @@ export function map(
260
267
  return result;
261
268
  } else {
262
269
  const e: Array<[string, VmConst]> = [];
263
- for (const [key, value] of entries(data)) {
270
+ for (const [key, value] of entries<string, VmConst | undefined>(data)) {
264
271
  Cp();
265
272
  const ret = mapper(value ?? null, key, data);
266
273
  if (ret === undefined) continue;
@@ -1 +1 @@
1
- export * as matrix from './matrix.js';
1
+ export * as matrix from './matrix/index.js';
@@ -0,0 +1,291 @@
1
+ import { Cp } from '../../../checkpoint.js';
2
+ import { $Add, $Call, $Div, $Mul, $Sub } from '../../../operations/index.js';
3
+ import { isVmConst, type VmConst } from '../../../types/index.js';
4
+ import { VmLib, expectCallable, expectConst, throwError } from '../../helpers.js';
5
+ import { num, size } from './helpers.js';
6
+ const { max } = Math;
7
+
8
+ /** 逐项操作 */
9
+ function entrywiseImpl(
10
+ a: VmConst,
11
+ b: VmConst,
12
+ f: (a: VmConst, b: VmConst) => VmConst,
13
+ vvf?: (va: readonly VmConst[], vb: readonly VmConst[], ar: number, br: number) => VmConst,
14
+ mmf?: (
15
+ ma: readonly VmConst[][],
16
+ mb: readonly VmConst[][],
17
+ ar: number,
18
+ ac: number,
19
+ br: number,
20
+ bc: number,
21
+ ) => VmConst,
22
+ vmf?: (va: readonly VmConst[], mb: readonly VmConst[][], al: number, br: number, bc: number) => VmConst,
23
+ mvf?: (ma: readonly VmConst[][], vb: readonly VmConst[], ar: number, ac: number, bl: number) => VmConst,
24
+ ): VmConst {
25
+ let [ar, ac] = size(a);
26
+ let [br, bc] = size(b);
27
+
28
+ if (ar == null) {
29
+ if (br == null) {
30
+ // s/s
31
+ return f(a, b);
32
+ } else if (bc == null) {
33
+ // s/v
34
+ const result: VmConst[] = [];
35
+ for (let r = 0; r < br; r++) {
36
+ const bItem = (b as VmConst[])[r] ?? null;
37
+ result[r] = f(a, bItem);
38
+ }
39
+ return result;
40
+ } else {
41
+ // s/m
42
+ const result: VmConst[][] = [];
43
+ for (let r = 0; r < br; r++) {
44
+ const bRow = (b as VmConst[][])[r] ?? [];
45
+ const rRow: VmConst[] = [];
46
+ result[r] = rRow;
47
+ for (let c = 0; c < bc; c++) {
48
+ const bItem = bRow[c] ?? null;
49
+ rRow[c] = f(a, bItem);
50
+ }
51
+ }
52
+ return result;
53
+ }
54
+ }
55
+ if (br == null) {
56
+ if (ac == null) {
57
+ // v/s
58
+ const result: VmConst[] = [];
59
+ for (let r = 0; r < ar; r++) {
60
+ const aItem = (a as VmConst[])[r] ?? null;
61
+ result[r] = f(aItem, b);
62
+ }
63
+ return result;
64
+ } else {
65
+ // m/s
66
+ const result: VmConst[][] = [];
67
+ for (let r = 0; r < ar; r++) {
68
+ const aRow = (a as VmConst[][])[r] ?? [];
69
+ const rRow: VmConst[] = [];
70
+ result[r] = rRow;
71
+ for (let c = 0; c < ac; c++) {
72
+ const aItem = aRow[c] ?? null;
73
+ rRow[c] = f(aItem, b);
74
+ }
75
+ }
76
+ return result;
77
+ }
78
+ }
79
+ if (ac == null && bc == null) {
80
+ // v/v
81
+ if (vvf != null) {
82
+ return vvf(a as VmConst[], b as VmConst[], ar, br);
83
+ }
84
+ const rr = max(ar, br);
85
+ const result: VmConst[] = [];
86
+ for (let r = 0; r < rr; r++) {
87
+ const aItem = (a as VmConst[])[r] ?? null;
88
+ const bItem = (b as VmConst[])[r] ?? null;
89
+ result[r] = f(aItem, bItem);
90
+ }
91
+ return result;
92
+ }
93
+
94
+ // m/m (m/v v/m)
95
+ if (ac == null) {
96
+ // v/m
97
+ if (vmf != null) {
98
+ return vmf(a as VmConst[], b as VmConst[][], ar, br, bc!);
99
+ }
100
+ ac = ar!;
101
+ ar = 1;
102
+ a = [a];
103
+ }
104
+ if (bc == null) {
105
+ // m/v
106
+ if (mvf != null) {
107
+ return mvf(a as VmConst[][], b as VmConst[], ar, ac, br);
108
+ }
109
+ bc = br!;
110
+ br = 1;
111
+ b = [b];
112
+ }
113
+
114
+ if (mmf != null) {
115
+ return mmf(a as VmConst[][], b as VmConst[][], ar, ac, br, bc);
116
+ }
117
+ const rr = max(ar, br);
118
+ const rc = max(ac, bc);
119
+ const result: VmConst[][] = [];
120
+ for (let r = 0; r < rr; r++) {
121
+ const rRow: VmConst[] = [];
122
+ result[r] = rRow;
123
+ for (let c = 0; c < rc; c++) {
124
+ const aItem = (a as VmConst[][])[ar === 1 ? 0 : r]?.[ac === 1 ? 0 : c] ?? null;
125
+ const bItem = (b as VmConst[][])[br === 1 ? 0 : r]?.[bc === 1 ? 0 : c] ?? null;
126
+ rRow[c] = f(aItem, bItem);
127
+ }
128
+ }
129
+ return result;
130
+ }
131
+
132
+ export const entrywise = VmLib(
133
+ (a, b, f) => {
134
+ expectConst('a', a, null);
135
+ expectConst('b', b, null);
136
+ expectCallable('f', f, null);
137
+ return entrywiseImpl(a, b, (a, b) => {
138
+ Cp();
139
+ const ret = $Call(f, [a, b]);
140
+ if (!isVmConst(ret)) return null;
141
+ return ret;
142
+ });
143
+ },
144
+ {
145
+ summary: '逐项操作',
146
+ params: {
147
+ a: { type: 'any | any[] | any[][]', description: '第一个操作数' },
148
+ b: { type: 'any | any[] | any[][]', description: '第二个操作数' },
149
+ f: { type: 'fn(a: any, b: any) -> any', description: '操作函数' },
150
+ },
151
+ returns: { type: 'any | any[] | any[][]' },
152
+ examples: [`matrix.entrywise([1, 2], [3, 4], fn (x, y) { x + y }) // [4, 6]`],
153
+ },
154
+ );
155
+
156
+ export const add = VmLib(
157
+ (a, b) => {
158
+ expectConst('a', a, null);
159
+ expectConst('b', b, null);
160
+ return entrywiseImpl(a, b, $Add);
161
+ },
162
+ {
163
+ summary: '逐项相加',
164
+ params: {
165
+ a: { type: 'number | number[] | number[][]', description: '第一个操作数' },
166
+ b: { type: 'number | number[] | number[][]', description: '第二个操作数' },
167
+ },
168
+ returns: { type: 'number | number[] | number[][]' },
169
+ examples: ['matrix.add([1, 2], [3, 4]) // [4, 6]'],
170
+ },
171
+ );
172
+
173
+ export const subtract = VmLib(
174
+ (a, b) => {
175
+ expectConst('a', a, null);
176
+ expectConst('b', b, null);
177
+ return entrywiseImpl(a, b, $Sub);
178
+ },
179
+ {
180
+ summary: '逐项相减',
181
+ params: {
182
+ a: { type: 'number | number[] | number[][]', description: '第一个操作数' },
183
+ b: { type: 'number | number[] | number[][]', description: '第二个操作数' },
184
+ },
185
+ returns: { type: 'number | number[] | number[][]' },
186
+ examples: ['matrix.subtract([3, 4], [1, 2]) // [2, 2]'],
187
+ },
188
+ );
189
+
190
+ export const entrywise_multiply = VmLib(
191
+ (a, b) => {
192
+ expectConst('a', a, null);
193
+ expectConst('b', b, null);
194
+ return entrywiseImpl(a, b, $Mul);
195
+ },
196
+ {
197
+ summary: '逐项相乘',
198
+ params: {
199
+ a: { type: 'number | number[] | number[][]', description: '第一个操作数' },
200
+ b: { type: 'number | number[] | number[][]', description: '第二个操作数' },
201
+ },
202
+ returns: { type: 'number | number[] | number[][]' },
203
+ examples: ['matrix.entrywise_multiply([1, 2], [3, 4]) // [3, 8]'],
204
+ },
205
+ );
206
+
207
+ export const entrywise_divide = VmLib(
208
+ (a, b) => {
209
+ expectConst('a', a, null);
210
+ expectConst('b', b, null);
211
+ return entrywiseImpl(a, b, $Div);
212
+ },
213
+ {
214
+ summary: '逐项相除',
215
+ params: {
216
+ a: { type: 'number | number[] | number[][]', description: '第一个操作数' },
217
+ b: { type: 'number | number[] | number[][]', description: '第二个操作数' },
218
+ },
219
+ returns: { type: 'number | number[] | number[][]' },
220
+ examples: ['matrix.entrywise_divide([4, 6], [2, 3]) // [2, 2]'],
221
+ },
222
+ );
223
+
224
+ export const multiply = VmLib(
225
+ (a, b) => {
226
+ expectConst('a', a, null);
227
+ expectConst('b', b, null);
228
+ return entrywiseImpl(
229
+ a,
230
+ b,
231
+ $Mul,
232
+ (a, b, al, bl) => {
233
+ const l = max(al, bl);
234
+ let s = 0;
235
+ for (let i = 0; i < l; i++) {
236
+ s += num(a[i]) * num(b[i]);
237
+ }
238
+ return s;
239
+ },
240
+ (a, b, ar, ac, br, bc) => {
241
+ if (ac !== br) throwError(`Incompatible matrix dimensions`, null);
242
+ const result: VmConst[][] = [];
243
+ for (let r = 0; r < ar; r++) {
244
+ const rRow: VmConst[] = [];
245
+ result[r] = rRow;
246
+ for (let c = 0; c < bc; c++) {
247
+ let item = 0;
248
+ for (let k = 0; k < ac; k++) {
249
+ item += num((a as VmConst[][])[r]?.[k]) * num((b as VmConst[][])[k]?.[c]);
250
+ }
251
+ rRow[c] = item;
252
+ }
253
+ }
254
+ return result;
255
+ },
256
+ (a, b, al, br, bc) => {
257
+ if (al !== br) throwError(`Incompatible matrix dimensions`, null);
258
+ const result: VmConst[] = [];
259
+ for (let c = 0; c < bc; c++) {
260
+ let item = 0;
261
+ for (let k = 0; k < al; k++) {
262
+ item += num(a[k]) * num((b as VmConst[][])[k]?.[c]);
263
+ }
264
+ result[c] = item;
265
+ }
266
+ return result;
267
+ },
268
+ (a, b, ar, ac, bl) => {
269
+ if (ac !== bl) throwError(`Incompatible matrix dimensions`, null);
270
+ const result: VmConst[] = [];
271
+ for (let r = 0; r < ar; r++) {
272
+ let item = 0;
273
+ for (let k = 0; k < ac; k++) {
274
+ item += num((a as VmConst[][])[r]?.[k]) * num(b[k]);
275
+ }
276
+ result[r] = item;
277
+ }
278
+ return result;
279
+ },
280
+ );
281
+ },
282
+ {
283
+ summary: '矩阵相乘',
284
+ params: {
285
+ a: { type: 'number | number[] | number[][]', description: '第一个操作数' },
286
+ b: { type: 'number | number[] | number[][]', description: '第二个操作数' },
287
+ },
288
+ returns: { type: 'number | number[] | number[][]' },
289
+ examples: ['matrix.multiply([[1, 2], [3, 4]], [5, 6]) // [17, 39]'],
290
+ },
291
+ );
@@ -0,0 +1,109 @@
1
+ import { isArray } from '../../../../helpers/utils.js';
2
+ import { Cp } from '../../../checkpoint.js';
3
+ import type { VmAny, VmArray, VmConst } from '../../../types/index.js';
4
+ import { VmLib, expectArray, throwError, getNumbers, arrayLen, expectInteger } from '../../helpers.js';
5
+
6
+ /** 填充 */
7
+ function filled(size: readonly VmAny[], value: VmConst): VmArray {
8
+ const s = getNumbers(size);
9
+ if (s.length === 0) return [];
10
+ while (s.length > 0) {
11
+ const repeat = arrayLen(s.pop());
12
+ Cp();
13
+ const data: VmConst[] = [];
14
+ data.length = repeat;
15
+ // 从 MiraScript 语义而言,可以使用同一个引用
16
+ data.fill(value);
17
+ value = data;
18
+ }
19
+ return value as VmArray;
20
+ }
21
+
22
+ export const zeros = VmLib((...size) => filled(size, 0), {
23
+ summary: '创建一个全零的矩阵',
24
+ params: { '..size': { type: 'number[]', description: '矩阵的维度' } },
25
+ returns: { type: 'number[][]' },
26
+ examples: ['matrix.zeros(2, 3) // [[0, 0, 0], [0, 0, 0]]'],
27
+ });
28
+
29
+ export const ones = VmLib((...size) => filled(size, 1), {
30
+ summary: '创建一个全一的矩阵',
31
+ params: { '..size': { type: 'number[]', description: '矩阵的维度' } },
32
+ returns: { type: 'number[][]' },
33
+ examples: ['matrix.ones(2, 2) // [[1, 1], [1, 1]]'],
34
+ });
35
+
36
+ export const identity = VmLib(
37
+ (...size) => {
38
+ let s = getNumbers(size);
39
+ if (s.length === 0) return [];
40
+ if (s.length > 2) throwError('Invalid matrix size', []);
41
+ if (s.length === 1) s = [s[0]!, s[0]!];
42
+ const m = arrayLen(s[0]);
43
+ const n = arrayLen(s[1]);
44
+ // 由于 `filled` 函数返回只读数组,其每行为相同引用,这里需要手动创建每行
45
+ const ret: number[][] = [];
46
+ for (let i = 0; i < m; i++) {
47
+ const row: number[] = [];
48
+ ret[i] = row;
49
+ row.length = n;
50
+ row.fill(0);
51
+ if (i < n) row[i] = 1;
52
+ }
53
+ return ret;
54
+ },
55
+ {
56
+ summary: '创建一个单位矩阵',
57
+ params: { '..size': { type: '[number] | [number, number]', description: '矩阵的维度' } },
58
+ returns: { type: 'number[][]' },
59
+ examples: ['matrix.identity(3) // [[1, 0, 0], [0, 1, 0], [0, 0, 1]]'],
60
+ },
61
+ );
62
+
63
+ export const diagonal = VmLib(
64
+ (x, k = 0) => {
65
+ expectArray('x', x, []);
66
+ const fk = expectInteger('k', k);
67
+ if (x.every((e) => isArray(e))) {
68
+ // 获取对角线元素
69
+ const diag: VmConst[] = [];
70
+ for (let i = 0; i < x.length; i++) {
71
+ const row = x[i] as VmArray | undefined;
72
+ const r = i + fk;
73
+ if (r < 0) continue;
74
+ if (!row || r >= row.length) break;
75
+ diag.push(row[r] ?? null);
76
+ }
77
+ return diag;
78
+ }
79
+ // 创建对角矩阵
80
+ const l = x.length;
81
+ const m = arrayLen(fk < 0 ? l - fk : l);
82
+ const n = arrayLen(fk > 0 ? l + fk : l);
83
+ const result: VmConst[][] = [];
84
+ for (let i = 0; i < m; i++) {
85
+ const row: VmConst[] = [];
86
+ result[i] = row;
87
+ row.length = n;
88
+ row.fill(0);
89
+ for (let j = 0; j < n; j++) {
90
+ if (i + fk === j) {
91
+ row[j] = x[fk >= 0 ? i : j] ?? null;
92
+ }
93
+ }
94
+ }
95
+ return result;
96
+ },
97
+ {
98
+ summary: '创建一个对角矩阵或获取矩阵的对角线',
99
+ params: {
100
+ x: { type: 'number[] | number[][]', description: '对角线元素或要获取对角线的矩阵' },
101
+ k: { type: 'number', description: '对角线偏移量,默认为 0' },
102
+ },
103
+ returns: { type: 'number[][] | number[]' },
104
+ examples: [
105
+ 'matrix.diagonal([1, 2, 3]) // [[1, 0, 0], [0, 2, 0], [0, 0, 3]]',
106
+ 'matrix.diagonal([[1, 2], [3, 4]]) // [1, 4]',
107
+ ],
108
+ },
109
+ );
@@ -0,0 +1,26 @@
1
+ import { toNumber } from '../../../../helpers/convert/index.js';
2
+ import { isVmArray, type VmConst, type VmValue } from '../../../types/index.js';
3
+
4
+ /** 计算尺寸 */
5
+ export function size(matrix: VmValue): [] | [number] | [number, number] {
6
+ if (!isVmArray(matrix)) return [];
7
+ if (matrix.length === 0) return [0];
8
+
9
+ const numRows = matrix.length;
10
+ let numCols = 0;
11
+
12
+ for (const row of matrix) {
13
+ if (isVmArray(row)) {
14
+ numCols = Math.max(numCols, row.length);
15
+ } else {
16
+ return [numRows];
17
+ }
18
+ }
19
+
20
+ return [numRows, numCols];
21
+ }
22
+
23
+ /** 数组元素转为 number */
24
+ export function num(v: VmConst | undefined): number {
25
+ return toNumber(v, undefined);
26
+ }
@@ -0,0 +1,5 @@
1
+ export * from './bin-ops.js';
2
+ export * from './fill.js';
3
+ export * from './invert.js';
4
+ export * from './size.js';
5
+ export * from './transpose.js';