@mirascript/mirascript 0.1.15 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/dist/{chunk-NT235HY3.js → chunk-LU4ZKFF6.js} +1411 -608
  2. package/dist/chunk-LU4ZKFF6.js.map +6 -0
  3. package/dist/chunk-RIT53WVY.js +1 -0
  4. package/dist/chunk-RLWIIOH5.js +12 -0
  5. package/dist/chunk-RLWIIOH5.js.map +6 -0
  6. package/dist/{chunk-JVFUK7AN.js → chunk-YZGL3D7L.js} +739 -1366
  7. package/dist/chunk-YZGL3D7L.js.map +6 -0
  8. package/dist/cli/index.js +11 -67
  9. package/dist/cli/index.js.map +2 -2
  10. package/dist/compiler/compile-fast.d.ts +1 -1
  11. package/dist/compiler/compile-fast.d.ts.map +1 -1
  12. package/dist/compiler/create-script.d.ts +10 -1
  13. package/dist/compiler/create-script.d.ts.map +1 -1
  14. package/dist/compiler/diagnostic.d.ts +1 -1
  15. package/dist/compiler/diagnostic.d.ts.map +1 -1
  16. package/dist/compiler/emit/constants.d.ts +3 -0
  17. package/dist/compiler/emit/constants.d.ts.map +1 -0
  18. package/dist/compiler/emit/consts.d.ts +6 -0
  19. package/dist/compiler/emit/consts.d.ts.map +1 -0
  20. package/dist/compiler/emit/globals.d.ts +17 -0
  21. package/dist/compiler/emit/globals.d.ts.map +1 -0
  22. package/dist/compiler/emit/index.d.ts +58 -0
  23. package/dist/compiler/emit/index.d.ts.map +1 -0
  24. package/dist/compiler/emit/sourcemap.d.ts +6 -0
  25. package/dist/compiler/emit/sourcemap.d.ts.map +1 -0
  26. package/dist/compiler/index.d.ts +3 -2
  27. package/dist/compiler/index.d.ts.map +1 -1
  28. package/dist/compiler/worker.js +1 -1
  29. package/dist/helpers/constants.d.ts +10 -0
  30. package/dist/helpers/constants.d.ts.map +1 -1
  31. package/dist/helpers/convert.d.ts +12 -0
  32. package/dist/helpers/convert.d.ts.map +1 -0
  33. package/dist/{vm → helpers}/error.d.ts +1 -1
  34. package/dist/helpers/error.d.ts.map +1 -0
  35. package/dist/helpers/serialize.d.ts +13 -4
  36. package/dist/helpers/serialize.d.ts.map +1 -1
  37. package/dist/helpers/types.d.ts +54 -0
  38. package/dist/helpers/types.d.ts.map +1 -0
  39. package/dist/index.js +11 -17
  40. package/dist/subtle.d.ts +3 -2
  41. package/dist/subtle.d.ts.map +1 -1
  42. package/dist/subtle.js +21 -15
  43. package/dist/vm/checkpoint.d.ts +9 -0
  44. package/dist/vm/checkpoint.d.ts.map +1 -0
  45. package/dist/vm/helpers.d.ts +4 -10
  46. package/dist/vm/helpers.d.ts.map +1 -1
  47. package/dist/vm/index.d.ts +3 -3
  48. package/dist/vm/index.d.ts.map +1 -1
  49. package/dist/vm/lib/global/bit.d.ts +7 -7
  50. package/dist/vm/lib/global/bit.d.ts.map +1 -1
  51. package/dist/vm/lib/global/debug.d.ts +2 -2
  52. package/dist/vm/lib/global/debug.d.ts.map +1 -1
  53. package/dist/vm/lib/global/index.d.ts +0 -1
  54. package/dist/vm/lib/global/index.d.ts.map +1 -1
  55. package/dist/vm/lib/global/json.d.ts +2 -2
  56. package/dist/vm/lib/global/json.d.ts.map +1 -1
  57. package/dist/vm/lib/global/math-additional.d.ts +1 -1
  58. package/dist/vm/lib/global/math-additional.d.ts.map +1 -1
  59. package/dist/vm/lib/global/math-arr.d.ts +5 -5
  60. package/dist/vm/lib/global/math-arr.d.ts.map +1 -1
  61. package/dist/vm/lib/global/math-unary.d.ts +26 -26
  62. package/dist/vm/lib/global/math-unary.d.ts.map +1 -1
  63. package/dist/vm/lib/global/math.d.ts +3 -3
  64. package/dist/vm/lib/global/math.d.ts.map +1 -1
  65. package/dist/vm/lib/global/sequence/all-any.d.ts +2 -2
  66. package/dist/vm/lib/global/sequence/all-any.d.ts.map +1 -1
  67. package/dist/vm/lib/global/sequence/entries.d.ts +5 -5
  68. package/dist/vm/lib/global/sequence/entries.d.ts.map +1 -1
  69. package/dist/vm/lib/global/sequence/find.d.ts +3 -3
  70. package/dist/vm/lib/global/sequence/find.d.ts.map +1 -1
  71. package/dist/vm/lib/global/sequence/flatten.d.ts +1 -1
  72. package/dist/vm/lib/global/sequence/flatten.d.ts.map +1 -1
  73. package/dist/vm/lib/global/sequence/len.d.ts +1 -1
  74. package/dist/vm/lib/global/sequence/len.d.ts.map +1 -1
  75. package/dist/vm/lib/global/sequence/map-filter.d.ts +3 -3
  76. package/dist/vm/lib/global/sequence/map-filter.d.ts.map +1 -1
  77. package/dist/vm/lib/global/sequence/repeat.d.ts +1 -1
  78. package/dist/vm/lib/global/sequence/repeat.d.ts.map +1 -1
  79. package/dist/vm/lib/global/sequence/reverse.d.ts +1 -1
  80. package/dist/vm/lib/global/sequence/reverse.d.ts.map +1 -1
  81. package/dist/vm/lib/global/sequence/sort.d.ts +2 -2
  82. package/dist/vm/lib/global/sequence/sort.d.ts.map +1 -1
  83. package/dist/vm/lib/global/sequence/with.d.ts +2 -2
  84. package/dist/vm/lib/global/sequence/with.d.ts.map +1 -1
  85. package/dist/vm/lib/global/sequence/zip.d.ts +1 -1
  86. package/dist/vm/lib/global/sequence/zip.d.ts.map +1 -1
  87. package/dist/vm/lib/global/string.d.ts +10 -10
  88. package/dist/vm/lib/global/string.d.ts.map +1 -1
  89. package/dist/vm/lib/global/time.d.ts +3 -13
  90. package/dist/vm/lib/global/time.d.ts.map +1 -1
  91. package/dist/vm/lib/global/to-primitive.d.ts +4 -4
  92. package/dist/vm/lib/global/to-primitive.d.ts.map +1 -1
  93. package/dist/vm/lib/helpers.d.ts +53 -0
  94. package/dist/vm/lib/helpers.d.ts.map +1 -0
  95. package/dist/vm/lib/index.d.ts +4 -0
  96. package/dist/vm/lib/index.d.ts.map +1 -0
  97. package/dist/vm/lib/{_loader.d.ts → loader.d.ts} +5 -5
  98. package/dist/vm/lib/loader.d.ts.map +1 -0
  99. package/dist/vm/lib/mod/index.d.ts +2 -0
  100. package/dist/vm/lib/mod/index.d.ts.map +1 -0
  101. package/dist/vm/lib/mod/matrix.d.ts +15 -0
  102. package/dist/vm/lib/mod/matrix.d.ts.map +1 -0
  103. package/dist/vm/operations.d.ts +2 -4
  104. package/dist/vm/operations.d.ts.map +1 -1
  105. package/dist/vm/types/boundary.d.ts +1 -1
  106. package/dist/vm/types/boundary.d.ts.map +1 -1
  107. package/dist/vm/types/context.d.ts +10 -9
  108. package/dist/vm/types/context.d.ts.map +1 -1
  109. package/dist/vm/types/extern.d.ts +1 -3
  110. package/dist/vm/types/extern.d.ts.map +1 -1
  111. package/dist/vm/types/function.d.ts +1 -6
  112. package/dist/vm/types/function.d.ts.map +1 -1
  113. package/dist/vm/types/index.d.ts +31 -17
  114. package/dist/vm/types/index.d.ts.map +1 -1
  115. package/dist/vm/types/module.d.ts +2 -4
  116. package/dist/vm/types/module.d.ts.map +1 -1
  117. package/dist/vm/types/wrapper.d.ts +0 -2
  118. package/dist/vm/types/wrapper.d.ts.map +1 -1
  119. package/package.json +7 -3
  120. package/src/cli/index.ts +1 -1
  121. package/src/compiler/compile-fast.ts +1 -2
  122. package/src/compiler/create-script.ts +12 -2
  123. package/src/compiler/diagnostic.ts +17 -8
  124. package/src/compiler/emit/constants.ts +2 -0
  125. package/src/compiler/emit/consts.ts +47 -0
  126. package/src/compiler/emit/globals.ts +39 -0
  127. package/src/compiler/{emit.ts → emit/index.ts} +16 -200
  128. package/src/compiler/emit/sourcemap.ts +163 -0
  129. package/src/compiler/index.ts +9 -9
  130. package/src/compiler/worker.ts +1 -1
  131. package/src/helpers/constants.ts +12 -0
  132. package/src/helpers/convert.ts +128 -0
  133. package/src/{vm → helpers}/error.ts +1 -1
  134. package/src/helpers/serialize.ts +71 -24
  135. package/src/helpers/types.ts +267 -0
  136. package/src/subtle.ts +3 -1
  137. package/src/vm/checkpoint.ts +42 -0
  138. package/src/vm/helpers.ts +9 -53
  139. package/src/vm/index.ts +3 -3
  140. package/src/vm/lib/global/bit.ts +8 -9
  141. package/src/vm/lib/global/debug.ts +5 -4
  142. package/src/vm/lib/global/index.ts +0 -1
  143. package/src/vm/lib/global/json.ts +2 -2
  144. package/src/vm/lib/global/math-additional.ts +2 -4
  145. package/src/vm/lib/global/math-arr.ts +1 -1
  146. package/src/vm/lib/global/math-unary.ts +2 -4
  147. package/src/vm/lib/global/math.ts +3 -4
  148. package/src/vm/lib/global/sequence/all-any.ts +11 -6
  149. package/src/vm/lib/global/sequence/entries.ts +1 -1
  150. package/src/vm/lib/global/sequence/find.ts +4 -3
  151. package/src/vm/lib/global/sequence/flatten.ts +2 -3
  152. package/src/vm/lib/global/sequence/len.ts +1 -1
  153. package/src/vm/lib/global/sequence/map-filter.ts +4 -3
  154. package/src/vm/lib/global/sequence/repeat.ts +2 -4
  155. package/src/vm/lib/global/sequence/reverse.ts +1 -1
  156. package/src/vm/lib/global/sequence/sort.ts +6 -5
  157. package/src/vm/lib/global/sequence/with.ts +21 -20
  158. package/src/vm/lib/global/sequence/zip.ts +3 -3
  159. package/src/vm/lib/global/string.ts +16 -27
  160. package/src/vm/lib/global/time.ts +59 -30
  161. package/src/vm/lib/global/to-primitive.ts +27 -18
  162. package/src/vm/lib/{_helpers.ts → helpers.ts} +129 -41
  163. package/src/vm/lib/index.ts +16 -0
  164. package/src/vm/lib/{_loader.ts → loader.ts} +3 -11
  165. package/src/vm/lib/mod/index.ts +1 -0
  166. package/src/vm/lib/{global/mod → mod}/matrix.ts +9 -7
  167. package/src/vm/operations.ts +31 -126
  168. package/src/vm/types/boundary.ts +10 -13
  169. package/src/vm/types/context.ts +17 -24
  170. package/src/vm/types/extern.ts +8 -15
  171. package/src/vm/types/function.ts +4 -19
  172. package/src/vm/types/index.ts +47 -25
  173. package/src/vm/types/module.ts +3 -7
  174. package/src/vm/types/wrapper.ts +1 -5
  175. package/dist/chunk-35JGBXRE.js +0 -1
  176. package/dist/chunk-JVFUK7AN.js.map +0 -6
  177. package/dist/chunk-NT235HY3.js.map +0 -6
  178. package/dist/compiler/emit.d.ts +0 -5
  179. package/dist/compiler/emit.d.ts.map +0 -1
  180. package/dist/vm/error.d.ts.map +0 -1
  181. package/dist/vm/lib/_helpers.d.ts +0 -35
  182. package/dist/vm/lib/_helpers.d.ts.map +0 -1
  183. package/dist/vm/lib/_loader.d.ts.map +0 -1
  184. package/dist/vm/lib/global/mod/index.d.ts +0 -3
  185. package/dist/vm/lib/global/mod/index.d.ts.map +0 -1
  186. package/dist/vm/lib/global/mod/matrix.d.ts +0 -15
  187. package/dist/vm/lib/global/mod/matrix.d.ts.map +0 -1
  188. package/dist/vm/types/any.d.ts +0 -10
  189. package/dist/vm/types/any.d.ts.map +0 -1
  190. package/dist/vm/types/array.d.ts +0 -12
  191. package/dist/vm/types/array.d.ts.map +0 -1
  192. package/dist/vm/types/callable.d.ts +0 -5
  193. package/dist/vm/types/callable.d.ts.map +0 -1
  194. package/dist/vm/types/const.d.ts +0 -15
  195. package/dist/vm/types/const.d.ts.map +0 -1
  196. package/dist/vm/types/immutable.d.ts +0 -15
  197. package/dist/vm/types/immutable.d.ts.map +0 -1
  198. package/dist/vm/types/primitive.d.ts +0 -7
  199. package/dist/vm/types/primitive.d.ts.map +0 -1
  200. package/dist/vm/types/record.d.ts +0 -20
  201. package/dist/vm/types/record.d.ts.map +0 -1
  202. package/dist/vm/types/script.d.ts +0 -14
  203. package/dist/vm/types/script.d.ts.map +0 -1
  204. package/dist/vm/types/value.d.ts +0 -14
  205. package/dist/vm/types/value.d.ts.map +0 -1
  206. package/src/vm/lib/global/mod/index.ts +0 -4
  207. package/src/vm/types/any.ts +0 -33
  208. package/src/vm/types/array.ts +0 -19
  209. package/src/vm/types/callable.ts +0 -10
  210. package/src/vm/types/const.ts +0 -109
  211. package/src/vm/types/immutable.ts +0 -22
  212. package/src/vm/types/primitive.ts +0 -14
  213. package/src/vm/types/record.ts +0 -53
  214. package/src/vm/types/script.ts +0 -18
  215. package/src/vm/types/value.ts +0 -22
  216. /package/dist/{chunk-35JGBXRE.js.map → chunk-RIT53WVY.js.map} +0 -0
package/src/vm/helpers.ts CHANGED
@@ -1,16 +1,13 @@
1
+ import { defineProperty, isFinite } from '../helpers/utils.js';
2
+ import { VM_ARRAY_MAX_LENGTH, VM_FUNCTION_ANONYMOUS_NAME } from '../helpers/constants.js';
3
+ import { isVmConst } from '../helpers/types.js';
1
4
  import { $AssertInit, $ToNumber } from './operations.js';
2
5
  import type { VmFunctionLike } from './types/function.js';
3
6
  import { DefaultVmContext, type VmContext } from './types/context.js';
4
- import {
5
- isVmConst,
6
- VmFunction,
7
- type VmConst,
8
- type VmAny,
9
- type VmArray,
10
- type VmValue,
11
- VM_ARRAY_MAX_LENGTH,
12
- } from './types/index.js';
13
- import { isFinite } from '../helpers/utils.js';
7
+ import type { VmConst, VmAny, VmArray, VmValue } from './types/index.js';
8
+ import { VmFunction } from './types/function.js';
9
+
10
+ export { Cp, CpEnter, CpExit } from './checkpoint.js';
14
11
 
15
12
  export const Vargs = (varags: VmAny[]): VmArray => {
16
13
  for (let i = 0, l = varags.length; i < l; i++) {
@@ -33,7 +30,8 @@ export const ElementOpt = (key: string, value: VmAny): VmConst => {
33
30
  return { [key]: value };
34
31
  };
35
32
 
36
- export const Function = (fn: VmFunctionLike): VmFunction => {
33
+ export const Function = (fn: VmFunctionLike, name = VM_FUNCTION_ANONYMOUS_NAME): VmFunction => {
34
+ defineProperty(fn, 'name', { value: name });
37
35
  return VmFunction(fn, { isLib: false, injectCp: false });
38
36
  };
39
37
 
@@ -73,48 +71,6 @@ export const ArrayRangeExclusive = (start: VmAny, end: VmAny): VmArray => {
73
71
  return arr;
74
72
  };
75
73
 
76
- const MAX_DEPTH = 128;
77
-
78
- let cpDepth = 0;
79
- let cp = Number.NaN;
80
- let cpTimeout = 100; // Default timeout in milliseconds
81
- /** 检查点 */
82
- export function Cp(): void {
83
- if (!cp) {
84
- cp = Date.now();
85
- } else if (Date.now() - cp > cpTimeout) {
86
- throw new RangeError('Execution timeout');
87
- }
88
- }
89
- /** 检查点 */
90
- export function CpEnter(): void {
91
- cpDepth++;
92
- if (cpDepth <= 1) {
93
- cp = Date.now();
94
- cpDepth = 1;
95
- } else if (cpDepth > MAX_DEPTH) {
96
- throw new RangeError('Maximum call depth exceeded');
97
- } else {
98
- Cp();
99
- }
100
- }
101
- /** 检查点 */
102
- export function CpExit(): void {
103
- cpDepth--;
104
- if (cpDepth < 1) {
105
- cp = Number.NaN;
106
- cpDepth = 0;
107
- } else {
108
- Cp();
109
- }
110
- }
111
- /** 设置检查点超时时间 */
112
- export function configCheckpoint(timeout = 100): void {
113
- if (typeof timeout !== 'number' || timeout <= 0 || Number.isNaN(timeout)) {
114
- throw new RangeError('Invalid timeout value');
115
- }
116
- cpTimeout = timeout;
117
- }
118
74
  /** 默认执行上下文 */
119
75
  export function GlobalFallback(): VmContext {
120
76
  return DefaultVmContext;
package/src/vm/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- import './lib/_loader.js';
1
+ import './lib/index.js';
2
2
 
3
- export * from './error.js';
3
+ export { VmError } from '../helpers/error.js';
4
4
  export * from './types/index.js';
5
- export { configCheckpoint } from './helpers.js';
5
+ export { configCheckpoint } from './checkpoint.js';
@@ -1,9 +1,8 @@
1
- import { $ToNumber } from '../../operations.js';
2
- import { VmLib } from '../_helpers.js';
1
+ import { VmLib, expectNumber } from '../helpers.js';
3
2
 
4
3
  export const b_and = VmLib(
5
4
  (x, y) => {
6
- return $ToNumber(x) & $ToNumber(y);
5
+ return expectNumber(0, x) & expectNumber(1, y);
7
6
  },
8
7
  {
9
8
  summary: '返回两个数的按位与',
@@ -16,7 +15,7 @@ export const b_and = VmLib(
16
15
 
17
16
  export const b_or = VmLib(
18
17
  (x, y) => {
19
- return $ToNumber(x) | $ToNumber(y);
18
+ return expectNumber(0, x) | expectNumber(1, y);
20
19
  },
21
20
  {
22
21
  summary: '返回两个数的按位或',
@@ -29,7 +28,7 @@ export const b_or = VmLib(
29
28
 
30
29
  export const b_not = VmLib(
31
30
  (x) => {
32
- return ~$ToNumber(x);
31
+ return ~expectNumber('x', x);
33
32
  },
34
33
  {
35
34
  summary: '返回一个数的按位取反',
@@ -42,7 +41,7 @@ export const b_not = VmLib(
42
41
 
43
42
  export const b_xor = VmLib(
44
43
  (x, y) => {
45
- return $ToNumber(x) ^ $ToNumber(y);
44
+ return expectNumber(0, x) ^ expectNumber(1, y);
46
45
  },
47
46
  {
48
47
  summary: '返回两个数的按位异或',
@@ -55,7 +54,7 @@ export const b_xor = VmLib(
55
54
 
56
55
  export const shl = VmLib(
57
56
  (x, y) => {
58
- return $ToNumber(x) << $ToNumber(y);
57
+ return expectNumber(0, x) << expectNumber(1, y);
59
58
  },
60
59
  {
61
60
  summary: '返回第一个操作数左移指定的位数',
@@ -68,7 +67,7 @@ export const shl = VmLib(
68
67
 
69
68
  export const sar = VmLib(
70
69
  (x, y) => {
71
- return $ToNumber(x) >> $ToNumber(y);
70
+ return expectNumber(0, x) >> expectNumber(1, y);
72
71
  },
73
72
  {
74
73
  summary: '返回第一个操作数右移指定的位数',
@@ -81,7 +80,7 @@ export const sar = VmLib(
81
80
 
82
81
  export const shr = VmLib(
83
82
  (x, y) => {
84
- return $ToNumber(x) >>> $ToNumber(y);
83
+ return expectNumber(0, x) >>> expectNumber(1, y);
85
84
  },
86
85
  {
87
86
  summary: '返回第一个操作数无符号右移指定的位数',
@@ -1,8 +1,8 @@
1
1
  import supportsColor from 'supports-color';
2
- import { VmError } from '../../error.js';
3
- import { $ToString } from '../../operations.js';
2
+ import { VmError } from '../../../helpers/error.js';
3
+ import { toString } from '../../../helpers/convert.js';
4
4
  import type { VmAny } from '../../types/index.js';
5
- import { VmLib } from '../_helpers.js';
5
+ import { VmLib } from '../helpers.js';
6
6
 
7
7
  export const debug_print = VmLib(
8
8
  (...args) => {
@@ -27,7 +27,8 @@ export const panic = VmLib(
27
27
  if (message === undefined) console.error(...panic.prefix);
28
28
  // eslint-disable-next-line no-console
29
29
  else console.error(...panic.prefix, message);
30
- const error = message == null ? 'panic' : 'panic: ' + $ToString(message);
30
+ const mgsStr = toString(message, null);
31
+ const error = !mgsStr ? 'panic' : 'panic: ' + mgsStr;
31
32
  throw new VmError(error, undefined);
32
33
  },
33
34
  {
@@ -6,4 +6,3 @@ export * from './json.js';
6
6
  export * from './to-primitive.js';
7
7
  export * from './string.js';
8
8
  export * from './time.js';
9
- export * from './mod/index.js';
@@ -1,5 +1,5 @@
1
1
  import { isVmExtern, isVmModule } from '../../types/index.js';
2
- import { required, rethrowError, VmLib } from '../_helpers.js';
2
+ import { required, rethrowError, VmLib } from '../helpers.js';
3
3
  const { parse, stringify } = JSON;
4
4
 
5
5
  export const to_json = VmLib(
@@ -31,7 +31,7 @@ export const from_json = VmLib(
31
31
  try {
32
32
  return parse(json);
33
33
  } catch (ex) {
34
- if (fallback != null) return fallback;
34
+ if (fallback !== undefined) return fallback;
35
35
  rethrowError('Invalid JSON', ex, null);
36
36
  }
37
37
  },
@@ -1,7 +1,6 @@
1
1
  /* eslint-disable no-loss-of-precision */
2
2
  import { isInteger, isNaN } from '../../../helpers/utils.js';
3
- import { $ToNumber } from '../../operations.js';
4
- import { required, VmLib } from '../_helpers.js';
3
+ import { expectNumber, VmLib } from '../helpers.js';
5
4
  const { sqrt, pow, exp } = Math;
6
5
 
7
6
  const GAMMA_G = 4.742_187_5;
@@ -18,8 +17,7 @@ const SQRT_2_PI = sqrt(2 * Math.PI);
18
17
 
19
18
  export const factorial = VmLib(
20
19
  (x): number => {
21
- required('x', x, Number.NaN);
22
- let n = $ToNumber(x);
20
+ let n = expectNumber('x', x);
23
21
  if (isNaN(n) || n < 0) return Number.NaN;
24
22
  if (n >= 171) return Number.POSITIVE_INFINITY; // will overflow
25
23
 
@@ -1,5 +1,5 @@
1
1
  import type { VmAny } from '../../types/index.js';
2
- import { getNumbers, VmLib } from '../_helpers.js';
2
+ import { getNumbers, VmLib } from '../helpers.js';
3
3
 
4
4
  /** 生成函数 */
5
5
  function build(f: (...values: readonly number[]) => number): (...values: readonly VmAny[]) => number {
@@ -1,12 +1,10 @@
1
1
  import type { VmAny } from '../../index.js';
2
- import { $ToNumber } from '../../operations.js';
3
- import { required, VmLib } from '../_helpers.js';
2
+ import { expectNumber, VmLib } from '../helpers.js';
4
3
 
5
4
  /** 生成函数 */
6
5
  function build(f: (x: number) => number): (x: VmAny) => number {
7
6
  return (x) => {
8
- required('x', x, Number.NaN);
9
- return f($ToNumber(x));
7
+ return f(expectNumber('x', x));
10
8
  };
11
9
  }
12
10
 
@@ -1,14 +1,13 @@
1
- import { $ToNumber } from '../../operations.js';
2
- import { VmLib } from '../_helpers.js';
1
+ import { expectNumber, VmLib } from '../helpers.js';
3
2
  const { atan2: _atan2, pow: _pow } = Math;
4
3
 
5
- export const atan2 = VmLib((x, y) => _atan2($ToNumber(x), $ToNumber(y)), {
4
+ export const atan2 = VmLib((x, y) => _atan2(expectNumber(0, x), expectNumber(1, y)), {
6
5
  summary: '返回从原点到点 (x, y) 的角度(弧度)',
7
6
  params: { x: 'x 坐标', y: 'y 坐标' },
8
7
  paramsType: { x: 'number', y: 'number' },
9
8
  returnsType: 'number',
10
9
  });
11
- export const pow = VmLib((x, y) => _pow($ToNumber(x), $ToNumber(y)), {
10
+ export const pow = VmLib((x, y) => _pow(expectNumber(0, x), expectNumber(1, y)), {
12
11
  summary: '返回 x 的 y 次幂',
13
12
  params: { x: '底数', y: '指数' },
14
13
  paramsType: { x: 'number', y: 'number' },
@@ -1,8 +1,9 @@
1
+ import { toBoolean } from '../../../../helpers/convert.js';
1
2
  import { entries } from '../../../../helpers/utils.js';
2
3
  import { Cp } from '../../../helpers.js';
3
- import { $Call, $ToBoolean } from '../../../operations.js';
4
+ import { $Call } from '../../../operations.js';
4
5
  import { isVmArray } from '../../../types/index.js';
5
- import { expectArrayOrRecord, expectCallable, VmLib } from '../../_helpers.js';
6
+ import { expectArrayOrRecord, expectCallable, VmLib } from '../../helpers.js';
6
7
 
7
8
  export const all = VmLib(
8
9
  (data, predicate) => {
@@ -11,17 +12,19 @@ export const all = VmLib(
11
12
  if (isVmArray(data)) {
12
13
  for (let i = 0; i < data.length; i++) {
13
14
  Cp();
15
+ /* c8 ignore next */
14
16
  const value = data[i] ?? null;
15
17
  const ret = $Call(predicate, [value, i, data]);
16
- if (!$ToBoolean(ret)) return false;
18
+ if (!toBoolean(ret, undefined)) return false;
17
19
  }
18
20
  return true;
19
21
  } else {
20
22
  for (const [key, v] of entries(data)) {
21
23
  Cp();
24
+ /* c8 ignore next */
22
25
  const value = v ?? null;
23
26
  const ret = $Call(predicate, [value, key, data]);
24
- if (!$ToBoolean(ret)) return false;
27
+ if (!toBoolean(ret, undefined)) return false;
25
28
  }
26
29
  return true;
27
30
  }
@@ -45,17 +48,19 @@ export const any = VmLib(
45
48
  if (isVmArray(data)) {
46
49
  for (let i = 0; i < data.length; i++) {
47
50
  Cp();
51
+ /* c8 ignore next */
48
52
  const value = data[i] ?? null;
49
53
  const ret = $Call(predicate, [value, i, data]);
50
- if ($ToBoolean(ret)) return true;
54
+ if (toBoolean(ret, undefined)) return true;
51
55
  }
52
56
  return false;
53
57
  } else {
54
58
  for (const [key, v] of entries(data)) {
55
59
  Cp();
60
+ /* c8 ignore next */
56
61
  const value = v ?? null;
57
62
  const ret = $Call(predicate, [value, key, data]);
58
- if ($ToBoolean(ret)) return true;
63
+ if (toBoolean(ret, undefined)) return true;
59
64
  }
60
65
  return false;
61
66
  }
@@ -1,5 +1,5 @@
1
1
  import { isVmArray, isVmRecord, type VmConst } from '../../../types/index.js';
2
- import { VmLib, expectArrayOrRecord, expectCompound } from '../../_helpers.js';
2
+ import { VmLib, expectArrayOrRecord, expectCompound } from '../../helpers.js';
3
3
  import { keys as _keys, values as _values, entries as _entries } from '../../../../helpers/utils.js';
4
4
 
5
5
  export const keys = VmLib(
@@ -1,8 +1,9 @@
1
+ import { toBoolean } from '../../../../helpers/convert.js';
1
2
  import { entries } from '../../../../helpers/utils.js';
2
3
  import { Cp } from '../../../helpers.js';
3
- import { $Call, $Same, $ToBoolean } from '../../../operations.js';
4
+ import { $Call, $Same } from '../../../operations.js';
4
5
  import { type VmValue, isVmArray, isVmCallable } from '../../../types/index.js';
5
- import { VmLib, expectArrayOrRecord, required } from '../../_helpers.js';
6
+ import { VmLib, expectArrayOrRecord, required } from '../../helpers.js';
6
7
 
7
8
  export const find = VmLib(
8
9
  (data, predicate) => {
@@ -11,7 +12,7 @@ export const find = VmLib(
11
12
  const p = isVmCallable(predicate)
12
13
  ? (value: VmValue, key: number | string, data: VmValue) => {
13
14
  const ret = $Call(predicate, [value, key, data]);
14
- return $ToBoolean(ret);
15
+ return toBoolean(ret, undefined);
15
16
  }
16
17
  : (value: VmValue) => $Same(predicate, value);
17
18
  if (isVmArray(data)) {
@@ -1,10 +1,9 @@
1
- import { $ToNumber } from '../../../operations.js';
2
- import { VmLib, expectArray } from '../../_helpers.js';
1
+ import { VmLib, expectArray, expectNumber } from '../../helpers.js';
3
2
 
4
3
  export const flatten = VmLib(
5
4
  (data, depth = 1) => {
6
5
  expectArray('data', data, data);
7
- return data.flat($ToNumber(depth) as 1);
6
+ return data.flat(expectNumber('depth', depth) as 1);
8
7
  },
9
8
  {
10
9
  summary: '将数组扁平化',
@@ -1,4 +1,4 @@
1
- import { VmLib, expectArray } from '../../_helpers.js';
1
+ import { VmLib, expectArray } from '../../helpers.js';
2
2
 
3
3
  export const len = VmLib(
4
4
  (arr) => {
@@ -1,6 +1,7 @@
1
- import { $Call, $ToBoolean } from '../../../operations.js';
1
+ import { toBoolean } from '../../../../helpers/convert.js';
2
+ import { $Call } from '../../../operations.js';
2
3
  import { isVmConst, type VmAny, type VmValue } from '../../../types/index.js';
3
- import { VmLib, expectCallable, expectConst, map as mapImpl } from '../../_helpers.js';
4
+ import { VmLib, expectCallable, expectConst, map as mapImpl } from '../../helpers.js';
4
5
 
5
6
  export * from './with.js';
6
7
  export * from './entries.js';
@@ -43,7 +44,7 @@ export const filter = VmLib(
43
44
  (data, predicate) =>
44
45
  mapImplWrapped(data, 'predicate', predicate, (fn, value, key, data) => {
45
46
  const ret = $Call(fn, [value, key, data]);
46
- return $ToBoolean(ret) ? value : undefined;
47
+ return toBoolean(ret, undefined) ? value : undefined;
47
48
  }),
48
49
  {
49
50
  summary: '过滤数组或记录中的元素,返回满足条件的元素',
@@ -1,12 +1,10 @@
1
- import { $ToNumber } from '../../../operations.js';
2
1
  import type { VmConst } from '../../../types/index.js';
3
- import { arrayLen, expectConst, required, VmLib } from '../../_helpers.js';
2
+ import { arrayLen, expectConst, expectNumber, VmLib } from '../../helpers.js';
4
3
 
5
4
  export const repeat = VmLib(
6
5
  (data, times) => {
7
6
  expectConst('data', data, []);
8
- required('times', times, []);
9
- const n = arrayLen($ToNumber(times));
7
+ const n = arrayLen(expectNumber('times', times));
10
8
  const result: VmConst[] = [];
11
9
  result.length = n;
12
10
  result.fill(data);
@@ -1,4 +1,4 @@
1
- import { VmLib, expectArray } from '../../_helpers.js';
1
+ import { VmLib, expectArray } from '../../helpers.js';
2
2
 
3
3
  export const reverse = VmLib(
4
4
  (arr) => {
@@ -1,6 +1,7 @@
1
- import { $Call, $ToNumber } from '../../../operations.js';
1
+ import { toNumber } from '../../../../helpers/convert.js';
2
+ import { $Call } from '../../../operations.js';
2
3
  import type { VmAny, VmConst, VmValue } from '../../../types/index.js';
3
- import { VmLib, expectArray, expectCallable } from '../../_helpers.js';
4
+ import { VmLib, expectArray, expectCallable } from '../../helpers.js';
4
5
 
5
6
  /** 默认比较 */
6
7
  function defaultCompare(a: VmValue = null, b: VmValue = null): number {
@@ -13,8 +14,8 @@ function defaultCompare(a: VmValue = null, b: VmValue = null): number {
13
14
  return 0;
14
15
  }
15
16
  // nan is treated as 0
16
- const an = $ToNumber(a) || 0;
17
- const bn = $ToNumber(b) || 0;
17
+ const an = toNumber(a, 0) || 0;
18
+ const bn = toNumber(b, 0) || 0;
18
19
  if (an < bn) return -1;
19
20
  if (an > bn) return 1;
20
21
  return 0;
@@ -26,7 +27,7 @@ function cmp(comparator: VmAny, recovered: VmValue): typeof defaultCompare {
26
27
  expectCallable('comparator', comparator, recovered);
27
28
  return (a: VmValue = null, b: VmValue = null) => {
28
29
  const ret = $Call(comparator, [a, b]);
29
- return $ToNumber(ret);
30
+ return toNumber(ret, 0);
30
31
  };
31
32
  }
32
33
 
@@ -1,24 +1,27 @@
1
- import { isArray, isSafeInteger } from '../../../../helpers/utils.js';
1
+ import { VM_ARRAY_MAX_LENGTH } from '../../../../helpers/constants.js';
2
+ import { toNumber, toString } from '../../../../helpers/convert.js';
3
+ import { isVmArray, isVmRecord } from '../../../../helpers/types.js';
4
+ import { isArray, isInteger, isNaN } from '../../../../helpers/utils.js';
2
5
  import { Element } from '../../../helpers.js';
3
- import { $ToNumber, $ToString } from '../../../operations.js';
4
- import {
5
- isVmArray,
6
- isVmRecord,
7
- VM_ARRAY_MAX_LENGTH,
8
- type VmArray,
9
- type VmConst,
10
- type VmValue,
11
- } from '../../../types/index.js';
12
- import { VmLib, expectArrayOrRecord, expectConst, throwError } from '../../_helpers.js';
6
+ import type { VmArray, VmConst, VmValue } from '../../../types/index.js';
7
+ import { VmLib, expectArrayOrRecord, expectConst, throwError } from '../../helpers.js';
13
8
 
14
9
  const arrIndex = (index: NonNullable<VmConst>): number => {
15
- const idx = Math.trunc($ToNumber(index));
16
- if (!isSafeInteger(idx) || idx < 0 || idx >= VM_ARRAY_MAX_LENGTH) {
17
- return -1;
10
+ const idx = Math.trunc(toNumber(index, Number.NaN));
11
+ if (isNaN(idx) || idx < 0) {
12
+ throwError('Array index must be a non-negative integer', index);
13
+ }
14
+ if (idx >= VM_ARRAY_MAX_LENGTH) {
15
+ throwError(`Array index exceeds maximum limit of ${VM_ARRAY_MAX_LENGTH}`, index);
18
16
  }
19
17
  return idx;
20
18
  };
21
19
 
20
+ const isArrIndex = (key: NonNullable<VmConst>): key is number => {
21
+ if (typeof key != 'number') return false;
22
+ return isInteger(key) && key >= 0 && key < VM_ARRAY_MAX_LENGTH;
23
+ };
24
+
22
25
  const withInner = (obj: VmConst | undefined, key: VmArray, keyIndex: number, value: VmConst): VmConst => {
23
26
  if (keyIndex >= key.length) {
24
27
  return value;
@@ -29,7 +32,7 @@ const withInner = (obj: VmConst | undefined, key: VmArray, keyIndex: number, val
29
32
  result = [...obj];
30
33
  } else if (isVmRecord(obj)) {
31
34
  result = { ...obj };
32
- } else if (arrIndex(k) === k) {
35
+ } else if (isArrIndex(k)) {
33
36
  result = [];
34
37
  } else {
35
38
  result = {};
@@ -41,7 +44,7 @@ const withInner = (obj: VmConst | undefined, key: VmArray, keyIndex: number, val
41
44
  }
42
45
  result[index] = withInner(result[index], key, keyIndex + 1, value);
43
46
  } else {
44
- const prop = $ToString(k);
47
+ const prop = toString(k, undefined);
45
48
  result[prop] = withInner(result[prop], key, keyIndex + 1, value);
46
49
  }
47
50
  return result;
@@ -86,11 +89,9 @@ const _with = VmLib(
86
89
  let val: VmConst;
87
90
  if (isVmArray(key)) {
88
91
  index = arrIndex(key[0]!);
89
- if (index < 0) continue;
90
92
  val = withInner(result[index], key, 1, value);
91
93
  } else {
92
94
  index = arrIndex(key);
93
- if (index < 0) continue;
94
95
  val = value;
95
96
  }
96
97
  while (index > result.length) {
@@ -106,10 +107,10 @@ const _with = VmLib(
106
107
  let val: VmConst;
107
108
  if (isVmArray(key)) {
108
109
  const firstKey = key[0]!;
109
- prop = $ToString(firstKey);
110
+ prop = toString(firstKey, undefined);
110
111
  val = withInner(result[prop], key, 1, value);
111
112
  } else {
112
- prop = $ToString(key);
113
+ prop = toString(key, undefined);
113
114
  val = value;
114
115
  }
115
116
  result[prop] = val;
@@ -1,7 +1,7 @@
1
- import { serialize } from '../../../../subtle.js';
1
+ import { display } from '../../../../helpers/serialize.js';
2
2
  import { Cp } from '../../../helpers.js';
3
3
  import { isVmArray, type VmConst, type VmArray } from '../../../types/index.js';
4
- import { VmLib, throwError } from '../../_helpers.js';
4
+ import { VmLib, throwError } from '../../helpers.js';
5
5
  import { entries } from './entries.js';
6
6
 
7
7
  export const zip = VmLib(
@@ -10,7 +10,7 @@ export const zip = VmLib(
10
10
  let len = 0;
11
11
  for (const { 0: key, 1: arr } of ets) {
12
12
  if (!isVmArray(arr)) {
13
- throwError(`data[${serialize(key)}] is not an array`, null);
13
+ throwError(`data[${display(key)}] is not an array: ${display(arr)}`, null);
14
14
  }
15
15
  len = Math.max(len, arr.length);
16
16
  }
@@ -1,10 +1,8 @@
1
- import { $ToString } from '../../operations.js';
2
- import { expectArray, required, VmLib } from '../_helpers.js';
1
+ import { expectArray, expectString, VmLib } from '../helpers.js';
3
2
 
4
3
  export const chars = VmLib(
5
4
  (str) => {
6
- required('str', str, null);
7
- return [...$ToString(str)];
5
+ return [...expectString('str', str)];
8
6
  },
9
7
  {
10
8
  summary: '将字符串转换为字符数组',
@@ -17,9 +15,7 @@ export const chars = VmLib(
17
15
 
18
16
  export const starts_with = VmLib(
19
17
  (str, search) => {
20
- required('str', str, null);
21
- required('search', search, null);
22
- return $ToString(str).startsWith($ToString(search));
18
+ return expectString('str', str).startsWith(expectString('search', search));
23
19
  },
24
20
  {
25
21
  summary: '检查字符串是否以指定子串开头',
@@ -31,9 +27,7 @@ export const starts_with = VmLib(
31
27
  );
32
28
  export const ends_with = VmLib(
33
29
  (str, search) => {
34
- required('str', str, null);
35
- required('search', search, null);
36
- return $ToString(str).endsWith($ToString(search));
30
+ return expectString('str', str).endsWith(expectString('search', search));
37
31
  },
38
32
  {
39
33
  summary: '检查字符串是否以指定子串结尾',
@@ -46,9 +40,7 @@ export const ends_with = VmLib(
46
40
 
47
41
  export const contains = VmLib(
48
42
  (str, search) => {
49
- required('str', str, null);
50
- required('search', search, null);
51
- return $ToString(str).includes($ToString(search));
43
+ return expectString('str', str).includes(expectString('search', search));
52
44
  },
53
45
  {
54
46
  summary: '检查字符串是否包含指定子串',
@@ -61,8 +53,7 @@ export const contains = VmLib(
61
53
 
62
54
  export const trim_start = VmLib(
63
55
  (str) => {
64
- required('str', str, null);
65
- return $ToString(str).trimStart();
56
+ return expectString('str', str).trimStart();
66
57
  },
67
58
  {
68
59
  summary: '去除字符串开头的空白字符',
@@ -75,8 +66,7 @@ export const trim_start = VmLib(
75
66
 
76
67
  export const trim_end = VmLib(
77
68
  (str) => {
78
- required('str', str, null);
79
- return $ToString(str).trimEnd();
69
+ return expectString('str', str).trimEnd();
80
70
  },
81
71
  {
82
72
  summary: '去除字符串结尾的空白字符',
@@ -89,8 +79,7 @@ export const trim_end = VmLib(
89
79
 
90
80
  export const trim = VmLib(
91
81
  (str) => {
92
- required('str', str, null);
93
- return $ToString(str).trim();
82
+ return expectString('str', str).trim();
94
83
  },
95
84
  {
96
85
  summary: '去除字符串两端的空白字符',
@@ -103,9 +92,10 @@ export const trim = VmLib(
103
92
 
104
93
  export const replace = VmLib(
105
94
  (str, search, replacement = '') => {
106
- required('str', str, null);
107
- required('search', search, str);
108
- return $ToString(str).replaceAll($ToString(search), $ToString(replacement));
95
+ return expectString('str', str).replaceAll(
96
+ expectString('search', search),
97
+ expectString('replacement', replacement),
98
+ );
109
99
  },
110
100
  {
111
101
  summary: '替换字符串中的指定子串',
@@ -118,9 +108,8 @@ export const replace = VmLib(
118
108
 
119
109
  export const split = VmLib(
120
110
  (str, separator = '') => {
121
- required('str', str, null);
122
- const s = $ToString(str);
123
- const p = $ToString(separator);
111
+ const s = expectString('str', str);
112
+ const p = expectString('separator', separator);
124
113
  if (!p) return [...s];
125
114
  return s.split(p);
126
115
  },
@@ -136,8 +125,8 @@ export const split = VmLib(
136
125
  export const join = VmLib(
137
126
  (arr, separator = '') => {
138
127
  expectArray('arr', arr, null);
139
- const s = $ToString(separator);
140
- return arr.map((v) => $ToString(v)).join(s);
128
+ const s = expectString('separator', separator);
129
+ return arr.map((v) => expectString(null, v)).join(s);
141
130
  },
142
131
  {
143
132
  summary: '将字符串数组连接为单个字符串',