@mirascript/mirascript 0.1.14 → 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-Q74RKZ7O.js → chunk-LU4ZKFF6.js} +1420 -607
  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-55FKP56O.js → chunk-YZGL3D7L.js} +741 -1361
  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 +15 -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 +14 -5
  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 +4 -6
  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 +18 -12
  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} +18 -202
  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 +18 -1
  132. package/src/helpers/convert.ts +128 -0
  133. package/src/{vm → helpers}/error.ts +1 -1
  134. package/src/helpers/serialize.ts +72 -25
  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 +3 -3
  150. package/src/vm/lib/global/sequence/find.ts +8 -7
  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 +7 -6
  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 +22 -21
  158. package/src/vm/lib/global/sequence/zip.ts +4 -4
  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 +33 -128
  168. package/src/vm/types/boundary.ts +10 -13
  169. package/src/vm/types/context.ts +36 -28
  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-55FKP56O.js.map +0 -6
  177. package/dist/chunk-Q74RKZ7O.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
@@ -1,28 +1,12 @@
1
- import { VmError } from './error.js';
2
- import {
3
- isVmPrimitive,
4
- isVmArray,
5
- isVmRecord,
6
- isVmFunction,
7
- isVmExtern,
8
- isVmModule,
9
- isVmWrapper,
10
- getVmFunctionInfo,
11
- type TypeName,
12
- type VmAny,
13
- type VmImmutable,
14
- type VmRecord,
15
- type VmValue,
16
- type VmArray,
17
- type VmConst,
18
- type VmPrimitive,
19
- type VmFunction,
20
- } from './types/index.js';
1
+ import { VmError } from '../helpers/error.js';
21
2
  import { hasOwnEnumerable, isNaN, isSafeInteger, keys, create } from '../helpers/utils.js';
3
+ import { toNumber, toString, toBoolean, toFormat } from '../helpers/convert.js';
4
+ import { display } from '../helpers/serialize.js';
5
+ import { isVmPrimitive, isVmArray, isVmRecord, isVmFunction, isVmExtern, isVmWrapper } from '../helpers/types.js';
6
+ import type { TypeName, VmAny, VmImmutable, VmRecord, VmValue, VmArray, VmConst } from './types/index.js';
22
7
 
23
8
  const { abs, min, trunc, ceil } = Math;
24
9
  const { slice, at } = Array.prototype;
25
- const { POSITIVE_INFINITY, NEGATIVE_INFINITY } = Number;
26
10
 
27
11
  const isSame = (a: VmValue, b: VmValue): boolean => {
28
12
  // Check for NaN
@@ -60,7 +44,10 @@ const isSame = (a: VmValue, b: VmValue): boolean => {
60
44
  if (!hasOwnEnumerable(b, key)) {
61
45
  return false;
62
46
  }
63
- if (!isSame(a[key] ?? null, b[key] ?? null)) {
47
+ /* c8 ignore next 2 */
48
+ const av = a[key] ?? null;
49
+ const bv = b[key] ?? null;
50
+ if (!isSame(av, bv)) {
64
51
  return false;
65
52
  }
66
53
  }
@@ -180,28 +167,25 @@ export const $In = (value: VmAny, iterable: VmAny): boolean => {
180
167
  $AssertInit(value);
181
168
  $AssertInit(iterable);
182
169
  if (iterable == null) return false;
170
+ if (typeof iterable != 'object') return false;
183
171
  if (isVmArray(iterable)) {
184
172
  if (value == null) {
185
173
  // array may have empty slots
186
- for (const item of iterable) {
187
- if (item == null) return true;
188
- }
174
+ for (const item of iterable) if (item == null) return true;
189
175
  return false;
190
176
  }
191
177
  // JS %SameValueZero is same with `isSame` in this context
192
178
  if (isVmPrimitive(value)) return iterable.includes(value);
193
179
  // value is not null here, so it's ok to skip empty slots, since `isSame(null, something)` is always false
194
- value satisfies NonNullable<VmValue>;
195
- return iterable.some((item = null) => isSame(item, value));
180
+ return iterable.some((item = null) => isSame(item, value satisfies NonNullable<VmValue>));
196
181
  }
197
182
  // iterable is a record or an extern here, value should be a string
198
- if (isVmWrapper(iterable)) return iterable.has($ToString(value));
199
- if (typeof iterable == 'object') return hasOwnEnumerable(iterable, $ToString(value));
200
- iterable satisfies VmPrimitive | VmFunction;
201
- return false;
183
+ const key = toString(value, undefined);
184
+ if (isVmWrapper(iterable)) return iterable.has(key);
185
+ return hasOwnEnumerable(iterable satisfies VmRecord, key);
202
186
  };
203
- export const $Concat = (...args: string[]): string => {
204
- return args.map($Format).join('');
187
+ export const $Concat = (...args: readonly string[]): string => {
188
+ return args.map((a) => toFormat(a, null)).join('');
205
189
  };
206
190
  export const $Pos = (a: VmAny): number => {
207
191
  return $ToNumber(a);
@@ -221,7 +205,7 @@ export const $Length = (value: VmAny): number => {
221
205
  }
222
206
  return Number.NaN;
223
207
  };
224
- export const $Omit = (value: VmAny, omitted: ReadonlyArray<string | number>): VmRecord => {
208
+ export const $Omit = (value: VmAny, omitted: ReadonlyArray<number | string>): VmRecord => {
225
209
  $AssertInit(value);
226
210
  if (value == null || !isVmRecord(value)) return {};
227
211
  const result: Record<string, VmConst> = {};
@@ -229,12 +213,13 @@ export const $Omit = (value: VmAny, omitted: ReadonlyArray<string | number>): Vm
229
213
  const omittedSet = new Set(omitted.map($ToString));
230
214
  for (const key of valueKeys) {
231
215
  if (!omittedSet.has(key)) {
216
+ /* c8 ignore next */
232
217
  result[key] = value[key] ?? null;
233
218
  }
234
219
  }
235
220
  return result;
236
221
  };
237
- export const $Pick = (value: VmAny, picked: ReadonlyArray<string | number>): VmRecord => {
222
+ export const $Pick = (value: VmAny, picked: ReadonlyArray<number | string>): VmRecord => {
238
223
  $AssertInit(value);
239
224
  if (value == null || !isVmRecord(value)) return {};
240
225
  const result: Record<string, VmConst> = {};
@@ -290,82 +275,30 @@ export const $Call = (func: VmValue, args: readonly VmAny[]): VmValue => {
290
275
  if (isVmFunction(func)) {
291
276
  return func(...(args as readonly VmValue[])) ?? null;
292
277
  }
293
- throw new VmError(`Expected callable, got ${$Type(func)}`, null);
278
+ throw new VmError(`Value is not callable: ${display(func)}`, null);
294
279
  };
295
280
  export const $Type = (value: VmAny): TypeName => {
296
- if (value === undefined || value === null) return 'nil';
297
- if (isVmExtern(value)) return 'extern';
298
- if (isVmModule(value)) return 'module';
281
+ // 允许未初始化值通过
282
+ if (value == null) return 'nil';
283
+ if (isVmWrapper(value)) return value.type;
299
284
  if (isVmArray(value)) return 'array';
300
285
  if (typeof value == 'object') return 'record';
301
286
  return typeof value as TypeName;
302
287
  };
303
288
  export const $ToBoolean = (value: VmAny): boolean => {
289
+ if (typeof value == 'boolean') return value;
304
290
  $AssertInit(value);
305
- return value != null && value !== false;
306
- };
307
- /** 将值转为字符串 */
308
- function numberToString(value: number): string {
309
- if (isNaN(value)) return 'nan';
310
- if (value === Infinity) return 'inf';
311
- if (value === -Infinity) return '-inf';
312
- return String(value);
313
- }
314
-
315
- /** 将值转为字符串 */
316
- export function $InnerToString(value: VmAny, useBraces: boolean): string {
317
- if (value == null) return 'nil';
318
- if (isVmWrapper(value)) return value.toString(useBraces);
319
- if (typeof value == 'function') {
320
- const name = getVmFunctionInfo(value)?.fullName;
321
- return name ? `<function ${name}>` : `<function>`;
322
- }
323
- if (isVmArray(value)) {
324
- const strings: string[] = [];
325
- for (const item of value) {
326
- strings.push($InnerToString(item, true));
327
- }
328
- // 在 join 过程中会自动把 null/undefined 和 empty slot 转为 ''
329
- // 与 innerToString 行为不一致
330
- const results = strings.join(', ');
331
- if (!useBraces) return results;
332
- return `[${results}]`;
333
- }
334
- if (typeof value == 'object') {
335
- const entries = keys(value)
336
- .map((key) => `${key}: ${$InnerToString(value[key], true)}`)
337
- .join(', ');
338
- if (!useBraces) return entries;
339
- return `(${entries})`;
340
- }
341
- if (typeof value == 'number') {
342
- return numberToString(value);
343
- }
344
- return String(value);
345
- }
291
+ return toBoolean(value, undefined);
292
+ };
346
293
  export const $ToString = (value: VmAny): string => {
347
- $AssertInit(value);
348
294
  if (typeof value == 'string') return value;
349
- if (value === null) return '';
350
- return $InnerToString(value, false);
295
+ $AssertInit(value);
296
+ return toString(value, undefined);
351
297
  };
352
298
  export const $ToNumber = (value: VmAny): number => {
353
- $AssertInit(value);
354
299
  if (typeof value == 'number') return value;
355
- if (value == null) return 0;
356
- if (typeof value == 'string') {
357
- value = value.trim();
358
- if (value === '') return 0;
359
- if (value === 'inf' || value === '+inf' || value === 'Infinity' || value === '+Infinity') {
360
- return POSITIVE_INFINITY;
361
- }
362
- if (value === '-inf' || value === '-Infinity') {
363
- return NEGATIVE_INFINITY;
364
- }
365
- return Number(value);
366
- }
367
- if (typeof value == 'boolean') return value ? 1 : 0;
368
- return Number.NaN;
300
+ $AssertInit(value);
301
+ return toNumber(value, undefined);
369
302
  };
370
303
  export const $IsBoolean = (value: VmAny): value is boolean => {
371
304
  $AssertInit(value);
@@ -473,36 +406,8 @@ export const $ArraySpread = (array: VmAny): Iterable<VmConst | undefined> => {
473
406
  throw new VmError(`Expected array, iterable extern or nil, got ${$Type(array)}`, []);
474
407
  };
475
408
 
476
- /** 渲染数字 */
477
- function formatNumber(value: number): string {
478
- if (!Number.isFinite(value)) return numberToString(value);
479
- if (value === 0) return '0';
480
- const s = value.toString();
481
- let ps;
482
- const abs = Math.abs(value);
483
- if (abs >= 1000 || abs < 0.001) {
484
- const ps1 = value.toExponential();
485
- const ps2 = value.toExponential(5);
486
- ps = ps1.length < ps2.length ? ps1 : ps2;
487
- } else {
488
- ps = value.toPrecision(6);
489
- }
490
- return ps.length < s.length ? ps : s;
491
- }
492
-
493
409
  export const $Format = (value: VmAny, format: VmAny): string => {
494
410
  $AssertInit(value);
495
- const f = format == null ? '' : typeof format == 'string' ? format.trim() : $ToString(format);
496
-
497
- if (typeof value == 'number') {
498
- if (/^\.\d+$/.test(f)) {
499
- let digits = Math.trunc(Number(f.slice(1)));
500
- if (!(digits <= 100)) digits = 100;
501
- return value.toFixed(digits);
502
- } else {
503
- return formatNumber(value);
504
- }
505
- }
506
-
507
- return $ToString(value);
411
+ const f = format == null ? '' : $ToString(format);
412
+ return toFormat(value, f);
508
413
  };
@@ -1,17 +1,14 @@
1
- import { isVmFunction, type VmFunctionLike, type VmFunction } from './function.js';
2
- import { isVmExtern, VmExtern } from './extern.js';
3
- import { isVmWrapper } from './wrapper.js';
1
+ import { defineProperty, apply } from '../../helpers/utils.js';
2
+ import { isVmExtern, isVmFunction, isVmWrapper } from '../../helpers/types.js';
3
+ import { kVmFunctionProxy } from '../../helpers/constants.js';
4
+ import type { VmFunctionLike, VmFunction } from './function.js';
5
+ import { VmExtern } from './extern.js';
4
6
  import type { VmAny, VmConst, VmModule, VmPrimitive, VmValue } from './index.js';
5
7
  import { $Call } from '../operations.js';
6
- import { defineProperty, apply } from '../../helpers/utils.js';
7
-
8
- const kProxy = Symbol.for('mirascript.vm.function.proxy');
9
8
 
10
9
  /** 创建 Mirascript 函数在宿主语言运行的代理 */
11
10
  export function toVmFunctionProxy<T extends VmFunctionLike>(fn: VmFunction<T>): T {
12
- if (!isVmFunction(fn)) return fn;
13
-
14
- const cached = (fn as unknown as { [kProxy]?: T })[kProxy];
11
+ const cached = (fn as unknown as { [kVmFunctionProxy]?: T })[kVmFunctionProxy];
15
12
  if (cached != null) return cached;
16
13
 
17
14
  const proxy = (...args: unknown[]) => {
@@ -22,8 +19,8 @@ export function toVmFunctionProxy<T extends VmFunctionLike>(fn: VmFunction<T>):
22
19
  );
23
20
  return unwrapFromVmValue(ret);
24
21
  };
25
- defineProperty(fn, kProxy, { value: proxy });
26
- defineProperty(proxy, kProxy, { value: fn });
22
+ defineProperty(fn, kVmFunctionProxy, { value: proxy });
23
+ defineProperty(proxy, kVmFunctionProxy, { value: fn });
27
24
  defineProperty(proxy, 'name', {
28
25
  value: fn.name,
29
26
  configurable: true,
@@ -35,7 +32,7 @@ export function toVmFunctionProxy<T extends VmFunctionLike>(fn: VmFunction<T>):
35
32
  export function fromVmFunctionProxy<T extends VmFunctionLike>(fn: T): VmFunction<T> | undefined {
36
33
  if (isVmFunction(fn)) return fn;
37
34
 
38
- const original = (fn as unknown as { [kProxy]?: VmFunction<T> })[kProxy];
35
+ const original = (fn as unknown as { [kVmFunctionProxy]?: VmFunction<T> })[kVmFunctionProxy];
39
36
  if (original && isVmFunction(original)) return original;
40
37
 
41
38
  return undefined;
@@ -76,7 +73,7 @@ export function wrapToVmValue(
76
73
 
77
74
  /** 取消宿主语言的值的 Mirascript 包装 */
78
75
  export function unwrapFromVmValue(value: VmAny): unknown {
79
- if (typeof value == 'function') {
76
+ if (isVmFunction(value)) {
80
77
  return toVmFunctionProxy(value);
81
78
  }
82
79
  if (value == null || typeof value != 'object') return value;
@@ -1,26 +1,26 @@
1
- import {
2
- VmFunction,
3
- type VmAny,
4
- type VmImmutable,
5
- type VmValue,
6
- wrapToVmValue,
7
- isVmAny,
8
- type VmFunctionLike,
9
- } from './index.js';
10
1
  import { create, entries, keys } from '../../helpers/utils.js';
11
- import type * as global from '../lib/global/index.js';
2
+ import { isVmAny } from '../../helpers/types.js';
3
+ import { VmError } from '../../helpers/error.js';
4
+ import { kVmContext } from '../../helpers/constants.js';
5
+ import type { lib } from '../lib/index.js';
6
+ import type { VmAny, VmImmutable, VmValue, VmFunctionLike, VmModule } from './index.js';
7
+ import { wrapToVmValue } from './boundary.js';
8
+ import { VmFunction } from './function.js';
12
9
 
13
- /** 全局导入的标准库 */
14
- type GlobalKeys = keyof typeof global;
15
10
  /** 全局导入的标准库值 */
16
- type ToGlobalValue<T extends GlobalKeys> = (typeof global)[T] extends VmFunctionLike
17
- ? VmFunction<(typeof global)[T]>
18
- : (typeof global)[T];
11
+ type ToLibValue<V> = V extends VmFunctionLike
12
+ ? VmFunction<V>
13
+ : V extends Record<string, VmImmutable | VmFunctionLike>
14
+ ? ToLibModule<V>
15
+ : V;
16
+ /** 全局导入的标准库值 */
17
+ type ToLibModule<V extends Record<string, VmImmutable | VmFunctionLike>> = VmModule<{
18
+ [key in keyof V]: ToLibValue<V[key]>;
19
+ }>;
19
20
  /** 全局导入的标准库 */
20
21
  type VmContextBase = {
21
- [key in GlobalKeys]: ToGlobalValue<key>;
22
+ [key in keyof typeof lib]: ToLibValue<(typeof lib)[key]>;
22
23
  };
23
- const kVmContext = Symbol.for('mirascript.vm.context');
24
24
  /** MiraScript 执行上下文的基础,仅包含标准库 */
25
25
  export type VmSharedContext = VmContextBase & Record<string, VmImmutable>;
26
26
  /** MiraScript 执行上下文 */
@@ -31,17 +31,27 @@ export interface VmContext {
31
31
  keys(): Iterable<string>;
32
32
  /** 描述值,返回 MarkDown 文本,仅在 LSP 中使用 */
33
33
  describe?(key: string): string | undefined;
34
- /** 获取指定 key 的值 `global[key]` */
34
+ /**
35
+ * 获取指定 key 的值 `global[key]`
36
+ * @throws {VmError} 如果值不存在则抛出异常
37
+ */
35
38
  get(key: string): VmValue;
36
39
  /** 查找指定 key 是否存在 `key in global` */
37
40
  has(key: string): boolean;
38
41
  }
39
42
  /** MiraScript 执行上下文 */
40
- export type VmContextRecord = Record<string, VmValue | undefined>;
43
+ export type VmContextRecord = Record<string, VmValue>;
44
+ /** MiraScript 执行上下文 */
45
+ export type VmContextRecordLoose = Record<string, VmValue | undefined>;
41
46
  export const VmSharedContext = create(null) as VmSharedContext;
42
47
 
43
48
  let VmSharedContextKeys: readonly string[] | null = null;
44
49
 
50
+ /** 全局变量未找到 */
51
+ function globalVarNotFound(name: string): never {
52
+ throw new VmError(`Global variable '${name}' is not defined.`, null);
53
+ }
54
+
45
55
  /** 定义在所有 MiraScript 执行上下文中共享的全局变量 */
46
56
  export function defineVmContextValue(
47
57
  name: string,
@@ -72,7 +82,9 @@ export const DefaultVmContext: VmContext = Object.freeze({
72
82
  },
73
83
  /** @inheritdoc */
74
84
  get(key: string): VmValue {
75
- return VmSharedContext[key] ?? null;
85
+ const val = VmSharedContext[key];
86
+ if (val === undefined) globalVarNotFound(key);
87
+ return val;
76
88
  },
77
89
  /** @inheritdoc */
78
90
  has(key: string): boolean {
@@ -91,7 +103,9 @@ class ValueVmContext implements VmContext {
91
103
  }
92
104
  /** @inheritdoc */
93
105
  get(key: string): VmValue {
94
- return this.env[key] ?? null;
106
+ const val = this.env[key];
107
+ if (val === undefined) globalVarNotFound(key);
108
+ return val;
95
109
  }
96
110
  /** @inheritdoc */
97
111
  has(key: string): boolean {
@@ -132,7 +146,7 @@ class FactoryVmContext implements VmContext {
132
146
 
133
147
  /** 以值为后备的实现 */
134
148
  type CreateVmContextWithValues = readonly [
135
- vmValues?: VmContextRecord | null | undefined,
149
+ vmValues?: VmContextRecordLoose | null | undefined,
136
150
  externValues?: Record<string, unknown> | null | undefined,
137
151
  describer?: ((key: string) => string | undefined) | null | undefined,
138
152
  ];
@@ -169,9 +183,3 @@ export function createVmContext(...args: CreateVmContextWithValues | CreateVmCon
169
183
  }
170
184
  return new ValueVmContext(env, describer ?? undefined);
171
185
  }
172
-
173
- /** 检查是否为执行上下文 */
174
- export function isVmContext(context: unknown): context is VmContext {
175
- if (context == null || typeof context != 'object') return false;
176
- return (context as VmContext)[kVmContext] === true;
177
- }
@@ -1,9 +1,11 @@
1
- import { VmError } from '../error.js';
2
- import { VmWrapper } from './wrapper.js';
3
- import type { TypeName, VmAny, VmConst, VmPrimitive, VmValue } from './index.js';
1
+ import { VmError } from '../../helpers/error.js';
4
2
  import { getPrototypeOf, hasOwn, apply, isArray } from '../../helpers/utils.js';
3
+ import { innerToString } from '../../helpers/convert.js';
4
+ import { isVmExtern } from '../../helpers/types.js';
5
+ import { kVmExtern } from '../../helpers/constants.js';
6
+ import type { TypeName, VmAny, VmConst, VmPrimitive, VmValue } from './index.js';
7
+ import { VmWrapper } from './wrapper.js';
5
8
  import { unwrapFromVmValue, wrapToVmValue } from './boundary.js';
6
- import { $InnerToString } from '../operations.js';
7
9
 
8
10
  const ObjectPrototype = Object.prototype;
9
11
  // eslint-disable-next-line @typescript-eslint/unbound-method
@@ -100,17 +102,13 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
100
102
  if (toString === ArrayToString && isArray(this.value)) {
101
103
  const mapped = ArrayMap.call(this.value, (item: unknown) => {
102
104
  if (item === undefined) return '';
103
- return $InnerToString(wrapToVmValue(item ?? null, null), true);
105
+ return innerToString(wrapToVmValue(item ?? null, null), true);
104
106
  });
105
107
  const str = mapped.join(', ');
106
108
  if (useBraces) return `[${str}]`;
107
109
  return str;
108
110
  }
109
- try {
110
- return String(this.value);
111
- } catch {
112
- return super.toString(useBraces);
113
- }
111
+ return String(this.value);
114
112
  }
115
113
  /** @inheritdoc */
116
114
  override get type(): TypeName {
@@ -157,9 +155,4 @@ export class VmExtern<const T extends object = object> extends VmWrapper<T> {
157
155
  }
158
156
  }
159
157
 
160
- const kVmExtern = Symbol.for('mirascript.vm.extern');
161
158
  Object.defineProperty(VmExtern.prototype, kVmExtern, { value: true });
162
- /** 检查值是否为 Mirascript 外部值 */
163
- export function isVmExtern<T extends object>(value: unknown): value is VmExtern<T> {
164
- return value != null && typeof value == 'object' && kVmExtern in value;
165
- }
@@ -1,10 +1,9 @@
1
1
  import type { Writable } from 'type-fest';
2
2
  import { defineProperty } from '../../helpers/utils.js';
3
- import { CpEnter, CpExit } from '../helpers.js';
3
+ import { kVmFunction, VM_FUNCTION_ANONYMOUS_NAME } from '../../helpers/constants.js';
4
4
  import type { VmAny, VmValue } from './index.js';
5
5
  import { fromVmFunctionProxy } from './boundary.js';
6
-
7
- const kVmFunction = Symbol.for('mirascript.vm.function');
6
+ import { CpEnter, CpExit } from '../checkpoint.js';
8
7
 
9
8
  /**
10
9
  * Mirascript 函数签名
@@ -46,17 +45,6 @@ export type VmFunctionOption = Partial<
46
45
  }
47
46
  >;
48
47
 
49
- /** 检查是否为 Mirascript 函数 */
50
- export function isVmFunction<T extends VmFunctionLike>(value: unknown): value is VmFunction<T> {
51
- return getVmFunctionInfo(value) != null;
52
- }
53
-
54
- /** 检查是否为 Mirascript 函数,并获取其信息 */
55
- export function getVmFunctionInfo(value: unknown): VmFunctionInfo | undefined {
56
- if (typeof value != 'function') return undefined;
57
- return (value as VmFunction)[kVmFunction];
58
- }
59
-
60
48
  /** 创建 Mirascript 函数 */
61
49
  export function VmFunction<T extends VmFunctionLike>(fn: T, option: VmFunctionOption = {}): VmFunction<T> {
62
50
  if (typeof fn != 'function') {
@@ -68,7 +56,7 @@ export function VmFunction<T extends VmFunctionLike>(fn: T, option: VmFunctionOp
68
56
  if (exists) return exists;
69
57
 
70
58
  const info: Writable<VmFunctionInfo> = {
71
- fullName: option.fullName ?? fn.name,
59
+ fullName: option.fullName ?? (fn.name === VM_FUNCTION_ANONYMOUS_NAME ? '' : fn.name),
72
60
  isLib: option.isLib ?? false,
73
61
  summary: option.summary || undefined,
74
62
  params: option.params,
@@ -89,10 +77,7 @@ export function VmFunction<T extends VmFunctionLike>(fn: T, option: VmFunctionOp
89
77
  CpExit();
90
78
  }
91
79
  }) as typeof fn;
92
- defineProperty(fn, 'name', {
93
- value: original.name,
94
- configurable: true,
95
- });
80
+ defineProperty(fn, 'name', { value: original.name });
96
81
  }
97
82
  defineProperty(fn, kVmFunction, {
98
83
  value: Object.freeze(info),
@@ -1,12 +1,36 @@
1
- import type { VmArray } from './array.js';
2
1
  import type { VmExtern } from './extern.js';
3
2
  import type { VmFunction } from './function.js';
4
3
  import type { VmModule } from './module.js';
5
- import type { VmRecord } from './record.js';
6
4
 
7
5
  /** 类型名称 */
8
6
  export type TypeName = keyof VmValueMap;
9
7
 
8
+ /** Mirascript 虚拟机内的未初始化变量 */
9
+ export type VmUninitialized = undefined;
10
+ /** Mirascript 原始值 */
11
+ export type VmPrimitive = null | number | string | boolean;
12
+ /**
13
+ * Mirascript 数组
14
+ * 数组中的 `undefined`、`null` 及 <empty slot> 均视作 `nil`
15
+ */
16
+ export type VmArray = ReadonlyArray<VmConst | undefined>;
17
+ /**
18
+ * Mirascript 记录
19
+ * 仅拥有且可枚举的字符串键视作存在
20
+ * 字段值 `undefined` 和 `null` 均视作 `nil`
21
+ */
22
+ export type VmRecord = {
23
+ readonly [key: string]: VmConst | undefined;
24
+ };
25
+ /** Mirascript 虚拟机内的值语义值 */
26
+ export type VmConst = VmPrimitive | VmRecord | VmArray;
27
+ /** Mirascript 虚拟机内的不可变值 */
28
+ export type VmImmutable = VmConst | VmFunction | VmModule;
29
+ /** Mirascript 虚拟机内的合法值 */
30
+ export type VmValue = VmImmutable | VmExtern;
31
+ /** Mirascript 虚拟机内的值(包括未初始化变量) */
32
+ export type VmAny = VmValue | VmUninitialized;
33
+
10
34
  /** 类型名称映射 */
11
35
  export interface VmValueMap {
12
36
  /** 空值 */
@@ -29,32 +53,30 @@ export interface VmValueMap {
29
53
  module: VmModule;
30
54
  }
31
55
 
32
- export { wrapToVmValue, unwrapFromVmValue, toVmFunctionProxy, fromVmFunctionProxy } from './boundary.js';
33
- export { type VmContext, type VmSharedContext, isVmContext, defineVmContextValue, createVmContext } from './context.js';
34
- export { type VmScript, isVmScript } from './script.js';
35
- export { isVmCallable } from './callable.js';
36
-
37
- export { type VmArray, VM_ARRAY_MAX_LENGTH, isVmArray } from './array.js';
38
56
  export {
39
- type VmRecord,
40
- isVmRecord,
57
+ isVmAny,
58
+ isVmArray,
41
59
  isVmArrayLikeRecord,
42
60
  isVmArrayLikeRecordByEntires,
43
61
  isVmArrayLikeRecordByKeys,
44
- } from './record.js';
45
- export { type VmPrimitive, isVmPrimitive } from './primitive.js';
46
- export { type VmConst, isVmConst } from './const.js';
47
- export { type VmImmutable, isVmImmutable } from './immutable.js';
48
- export { VmExtern, isVmExtern } from './extern.js';
49
- export {
50
- VmFunction,
62
+ isVmCallable,
63
+ isVmConst,
64
+ isVmContext,
65
+ isVmExtern,
51
66
  isVmFunction,
67
+ isVmImmutable,
68
+ isVmModule,
69
+ isVmPrimitive,
70
+ isVmRecord,
71
+ isVmScript,
72
+ isVmValue,
73
+ isVmWrapper,
52
74
  getVmFunctionInfo,
53
- type VmFunctionInfo,
54
- type VmFunctionLike,
55
- type VmFunctionOption,
56
- } from './function.js';
57
- export { VmModule, isVmModule } from './module.js';
58
- export { isVmWrapper } from './wrapper.js';
59
- export { type VmValue, isVmValue } from './value.js';
60
- export { type VmAny, type VmUninitialized, isVmAny } from './any.js';
75
+ } from '../../helpers/types.js';
76
+
77
+ export { wrapToVmValue, unwrapFromVmValue } from './boundary.js';
78
+
79
+ export { type VmContext, type VmSharedContext, defineVmContextValue, createVmContext } from './context.js';
80
+ export { VmExtern } from './extern.js';
81
+ export { VmFunction, type VmFunctionInfo, type VmFunctionLike, type VmFunctionOption } from './function.js';
82
+ export { VmModule } from './module.js';
@@ -1,9 +1,10 @@
1
+ import { kVmModule } from '../../helpers/constants.js';
1
2
  import { hasOwnEnumerable, keys } from '../../helpers/utils.js';
2
- import type { TypeName, VmAny, VmValue } from './index.js';
3
+ import type { TypeName, VmAny, VmImmutable } from './index.js';
3
4
  import { VmWrapper } from './wrapper.js';
4
5
 
5
6
  /** Mirascript 模块 */
6
- export class VmModule<const T extends Record<string, VmValue> = Record<string, VmValue>> extends VmWrapper<T> {
7
+ export class VmModule<const T extends Record<string, VmImmutable> = Record<string, VmImmutable>> extends VmWrapper<T> {
7
8
  constructor(
8
9
  /** 模块名称 */
9
10
  readonly name: string,
@@ -39,9 +40,4 @@ export class VmModule<const T extends Record<string, VmValue> = Record<string, V
39
40
  }
40
41
  }
41
42
 
42
- const kVmModule = Symbol.for('mirascript.vm.module');
43
43
  Object.defineProperty(VmModule.prototype, kVmModule, { value: true });
44
- /** 检查值是否为 Mirascript 模块 */
45
- export function isVmModule<T extends Record<string, VmValue>>(value: unknown): value is VmModule<T> {
46
- return value != null && typeof value == 'object' && kVmModule in value;
47
- }
@@ -1,3 +1,4 @@
1
+ import { kVmWrapper } from '../../helpers/constants.js';
1
2
  import type { TypeName, VmAny } from './index.js';
2
3
 
3
4
  /**
@@ -29,9 +30,4 @@ export abstract class VmWrapper<T extends object> {
29
30
  }
30
31
  }
31
32
 
32
- const kVmWrapper = Symbol.for('mirascript.vm.wrapper');
33
33
  Object.defineProperty(VmWrapper.prototype, kVmWrapper, { value: true });
34
- /** 检查值是否为 MiraScript 包装器 */
35
- export function isVmWrapper<T extends object>(value: unknown): value is VmWrapper<T> {
36
- return value != null && typeof value == 'object' && kVmWrapper in value;
37
- }
@@ -1 +0,0 @@
1
- //# sourceMappingURL=chunk-35JGBXRE.js.map