zuzu-js 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +113 -0
  3. package/bin/zuzu +17 -0
  4. package/bin/zuzu-build-browser-bundle +57 -0
  5. package/bin/zuzu-generate-browser-stdlib +584 -0
  6. package/bin/zuzu-js +23 -0
  7. package/bin/zuzu-js-compile +152 -0
  8. package/bin/zuzu-js-electron +19 -0
  9. package/dist/zuzu-browser-worker.js +45574 -0
  10. package/dist/zuzu-browser.js +45362 -0
  11. package/lib/browser-bundle-entry.js +160 -0
  12. package/lib/browser-gui-renderer.js +387 -0
  13. package/lib/browser-runtime.js +167 -0
  14. package/lib/browser-worker-entry.js +413 -0
  15. package/lib/browser-ztests/runner.html +103 -0
  16. package/lib/browser-ztests/runner.js +369 -0
  17. package/lib/cli.js +350 -0
  18. package/lib/collections.js +367 -0
  19. package/lib/compiler.js +303 -0
  20. package/lib/electron/launcher.js +70 -0
  21. package/lib/electron/main.js +956 -0
  22. package/lib/electron/preload.js +80 -0
  23. package/lib/electron/renderer.html +122 -0
  24. package/lib/electron/renderer.js +24 -0
  25. package/lib/execution-metadata.js +18 -0
  26. package/lib/gui/dom-renderer.js +778 -0
  27. package/lib/host/browser-host.js +278 -0
  28. package/lib/host/capabilities.js +47 -0
  29. package/lib/host/electron-host.js +15 -0
  30. package/lib/host/node-host.js +74 -0
  31. package/lib/paths.js +150 -0
  32. package/lib/runtime-entrypoints.js +60 -0
  33. package/lib/runtime-helpers.js +886 -0
  34. package/lib/runtime.js +3529 -0
  35. package/lib/tap.js +37 -0
  36. package/lib/transpiler-new/ast.js +23 -0
  37. package/lib/transpiler-new/codegen.js +2455 -0
  38. package/lib/transpiler-new/errors.js +28 -0
  39. package/lib/transpiler-new/index.js +26 -0
  40. package/lib/transpiler-new/lexer.js +834 -0
  41. package/lib/transpiler-new/parser.js +2332 -0
  42. package/lib/transpiler-new/validate-bindings.js +326 -0
  43. package/lib/transpiler-utils.js +95 -0
  44. package/lib/transpiler.js +33 -0
  45. package/lib/zuzu.js +53 -0
  46. package/modules/javascript.js +193 -0
  47. package/modules/std/archive.js +603 -0
  48. package/modules/std/clib.js +338 -0
  49. package/modules/std/data/csv.js +1331 -0
  50. package/modules/std/data/json.js +531 -0
  51. package/modules/std/data/xml.js +441 -0
  52. package/modules/std/data/yaml.js +256 -0
  53. package/modules/std/db-worker.js +250 -0
  54. package/modules/std/db.js +664 -0
  55. package/modules/std/digest/_hash.js +443 -0
  56. package/modules/std/digest/md5.js +26 -0
  57. package/modules/std/digest/sha.js +72 -0
  58. package/modules/std/eval.js +10 -0
  59. package/modules/std/gui/objects.js +1519 -0
  60. package/modules/std/internals.js +571 -0
  61. package/modules/std/io/socks-worker.js +318 -0
  62. package/modules/std/io/socks.js +186 -0
  63. package/modules/std/io.js +475 -0
  64. package/modules/std/marshal/cbor.js +463 -0
  65. package/modules/std/marshal/graph.js +1624 -0
  66. package/modules/std/marshal.js +87 -0
  67. package/modules/std/math/bignum.js +91 -0
  68. package/modules/std/math.js +79 -0
  69. package/modules/std/net/dns.js +306 -0
  70. package/modules/std/net/http.js +820 -0
  71. package/modules/std/net/smtp.js +943 -0
  72. package/modules/std/net/url.js +109 -0
  73. package/modules/std/proc.js +602 -0
  74. package/modules/std/secure.js +3724 -0
  75. package/modules/std/string/base64.js +138 -0
  76. package/modules/std/string.js +299 -0
  77. package/modules/std/task.js +914 -0
  78. package/modules/std/time.js +579 -0
  79. package/modules/std/tui.js +188 -0
  80. package/modules/std/worker-thread.js +246 -0
  81. package/modules/std/worker.js +790 -0
  82. package/package.json +67 -0
  83. package/stdlib/modules/javascript.zzm +99 -0
  84. package/stdlib/modules/perl.zzm +105 -0
  85. package/stdlib/modules/std/archive.zzm +132 -0
  86. package/stdlib/modules/std/cache/lru.zzm +174 -0
  87. package/stdlib/modules/std/clib.zzm +112 -0
  88. package/stdlib/modules/std/colour.zzm +220 -0
  89. package/stdlib/modules/std/config.zzm +818 -0
  90. package/stdlib/modules/std/data/cbor.zzm +497 -0
  91. package/stdlib/modules/std/data/csv.zzm +285 -0
  92. package/stdlib/modules/std/data/ini.zzm +472 -0
  93. package/stdlib/modules/std/data/json/schema/core.zzm +573 -0
  94. package/stdlib/modules/std/data/json/schema/format.zzm +581 -0
  95. package/stdlib/modules/std/data/json/schema/model.zzm +255 -0
  96. package/stdlib/modules/std/data/json/schema/output.zzm +272 -0
  97. package/stdlib/modules/std/data/json/schema/relative_pointer.zzm +299 -0
  98. package/stdlib/modules/std/data/json/schema/validation.zzm +1503 -0
  99. package/stdlib/modules/std/data/json/schema.zzm +306 -0
  100. package/stdlib/modules/std/data/json.zzm +102 -0
  101. package/stdlib/modules/std/data/kdl/json.zzm +460 -0
  102. package/stdlib/modules/std/data/kdl/xml.zzm +387 -0
  103. package/stdlib/modules/std/data/kdl.zzm +1631 -0
  104. package/stdlib/modules/std/data/toml.zzm +756 -0
  105. package/stdlib/modules/std/data/toon.zzm +1017 -0
  106. package/stdlib/modules/std/data/xml/escape.zzm +156 -0
  107. package/stdlib/modules/std/data/xml.zzm +276 -0
  108. package/stdlib/modules/std/data/yaml.zzm +94 -0
  109. package/stdlib/modules/std/db.zzm +173 -0
  110. package/stdlib/modules/std/defer.zzm +75 -0
  111. package/stdlib/modules/std/digest/crc32.zzm +196 -0
  112. package/stdlib/modules/std/digest/md5.zzm +54 -0
  113. package/stdlib/modules/std/digest/sha.zzm +83 -0
  114. package/stdlib/modules/std/dump.zzm +317 -0
  115. package/stdlib/modules/std/eval.zzm +63 -0
  116. package/stdlib/modules/std/getopt.zzm +432 -0
  117. package/stdlib/modules/std/gui/dialogue.zzm +592 -0
  118. package/stdlib/modules/std/gui/objects.zzm +123 -0
  119. package/stdlib/modules/std/gui.zzm +1914 -0
  120. package/stdlib/modules/std/internals.zzm +139 -0
  121. package/stdlib/modules/std/io/socks.zzm +139 -0
  122. package/stdlib/modules/std/io.zzm +157 -0
  123. package/stdlib/modules/std/lingua/en.zzm +347 -0
  124. package/stdlib/modules/std/log.zzm +169 -0
  125. package/stdlib/modules/std/mail.zzm +2726 -0
  126. package/stdlib/modules/std/marshal.zzm +138 -0
  127. package/stdlib/modules/std/math/bignum.zzm +98 -0
  128. package/stdlib/modules/std/math/range.zzm +116 -0
  129. package/stdlib/modules/std/math/roman.zzm +156 -0
  130. package/stdlib/modules/std/math.zzm +141 -0
  131. package/stdlib/modules/std/net/dns.zzm +93 -0
  132. package/stdlib/modules/std/net/http.zzm +278 -0
  133. package/stdlib/modules/std/net/smtp.zzm +257 -0
  134. package/stdlib/modules/std/net/url.zzm +69 -0
  135. package/stdlib/modules/std/path/jsonpointer.zzm +526 -0
  136. package/stdlib/modules/std/path/kdl.zzm +1003 -0
  137. package/stdlib/modules/std/path/simple.zzm +520 -0
  138. package/stdlib/modules/std/path/z/context.zzm +147 -0
  139. package/stdlib/modules/std/path/z/evaluate.zzm +549 -0
  140. package/stdlib/modules/std/path/z/functions.zzm +874 -0
  141. package/stdlib/modules/std/path/z/lexer.zzm +490 -0
  142. package/stdlib/modules/std/path/z/node.zzm +1455 -0
  143. package/stdlib/modules/std/path/z/operators.zzm +445 -0
  144. package/stdlib/modules/std/path/z/parser.zzm +359 -0
  145. package/stdlib/modules/std/path/z.zzm +403 -0
  146. package/stdlib/modules/std/path/zz/functions.zzm +828 -0
  147. package/stdlib/modules/std/path/zz/operators.zzm +1036 -0
  148. package/stdlib/modules/std/path/zz.zzm +100 -0
  149. package/stdlib/modules/std/proc.zzm +155 -0
  150. package/stdlib/modules/std/result.zzm +149 -0
  151. package/stdlib/modules/std/secure.zzm +606 -0
  152. package/stdlib/modules/std/string/base64.zzm +66 -0
  153. package/stdlib/modules/std/string/quoted_printable.zzm +485 -0
  154. package/stdlib/modules/std/string.zzm +179 -0
  155. package/stdlib/modules/std/task.zzm +221 -0
  156. package/stdlib/modules/std/template/z.zzm +531 -0
  157. package/stdlib/modules/std/template/zz.zzm +62 -0
  158. package/stdlib/modules/std/time.zzm +188 -0
  159. package/stdlib/modules/std/tui.zzm +89 -0
  160. package/stdlib/modules/std/uuid.zzm +223 -0
  161. package/stdlib/modules/std/web/session.zzm +388 -0
  162. package/stdlib/modules/std/web/static.zzm +329 -0
  163. package/stdlib/modules/std/web.zzm +1942 -0
  164. package/stdlib/modules/std/worker.zzm +202 -0
  165. package/stdlib/modules/std/zuzuzoo.zzm +3960 -0
  166. package/stdlib/modules/test/more.zzm +528 -0
  167. package/stdlib/modules/test/parser.zzm +209 -0
package/lib/runtime.js ADDED
@@ -0,0 +1,3529 @@
1
+ 'use strict';
2
+
3
+ const { capabilitiesForModule } = require( './host/capabilities' );
4
+ const { setCompiledSource } = require( './execution-metadata' );
5
+
6
+ const {
7
+ DEFAULT_TRANSPILER,
8
+ normalizeTranspilerName,
9
+ transpile,
10
+ stripPod,
11
+ } = require( './transpiler' );
12
+ const {
13
+ collectTopLevelDeclarations,
14
+ runSwitch,
15
+ runMatch,
16
+ contains,
17
+ collectionUnion,
18
+ collectionIntersection,
19
+ collectionDifference,
20
+ collectionSubsetOf,
21
+ collectionSupersetOf,
22
+ collectionEquivalentOf,
23
+ makeArray,
24
+ makeSet,
25
+ makeBag,
26
+ makePairList,
27
+ makeTemporaryPairList,
28
+ lengthOf,
29
+ operatorString,
30
+ operatorRegexp,
31
+ ZuzuBinary,
32
+ BinaryString,
33
+ Pair,
34
+ PairList,
35
+ withArrayMethods,
36
+ ZuzuBag,
37
+ isPairListLike,
38
+ isWeakableValue,
39
+ makeWeakValue,
40
+ resolveWeakValue,
41
+ retainValue,
42
+ releaseValue,
43
+ retainCollectionValue,
44
+ releaseCollectionValue,
45
+ releaseCollectionValues,
46
+ addSetValue,
47
+ assignStrongValue,
48
+ assignWeakValue,
49
+ } = require( './runtime-helpers' );
50
+ const taskRuntime = require( '../modules/std/task' );
51
+
52
+ const textEncoder = new TextEncoder();
53
+ const utf8Decoder = new TextDecoder( 'utf-8', { fatal: true } );
54
+ const ZUZU_SKIP_BUILD = Symbol.for( 'zuzu.skip_build' );
55
+
56
+ function defaultModuleSearchRoots( host, repoRoot, includePaths ) {
57
+ if ( host.name === 'browser' ) {
58
+ return [
59
+ host.join( repoRoot, 'modules' ),
60
+ ...includePaths,
61
+ ];
62
+ }
63
+ const pathsModule = './' + 'paths';
64
+ return require( pathsModule ).defaultModuleSearchRoots( {
65
+ includePaths,
66
+ packageRoot: repoRoot,
67
+ initialCwd: host.cwd(),
68
+ } );
69
+ }
70
+
71
+ function installHostCollectionMethods() {
72
+ withArrayMethods();
73
+ const define = ( proto, name, fn ) => {
74
+ if ( !Object.prototype.hasOwnProperty.call( proto, name ) ) {
75
+ const desc = Object.create( null );
76
+ desc.value = fn;
77
+ desc.enumerable = false;
78
+ desc.configurable = true;
79
+ desc.writable = true;
80
+ Object.defineProperty( proto, name, desc );
81
+ }
82
+ };
83
+ define( Array.prototype, 'push_weak', function _pushWeak( ...values ) {
84
+ this.push( ...values.map( makeWeakValue ) );
85
+ return this;
86
+ } );
87
+ define( Array.prototype, 'unshift_weak', function _unshiftWeak( ...values ) {
88
+ this.unshift( ...values.map( makeWeakValue ) );
89
+ return this;
90
+ } );
91
+ define( Array.prototype, 'set_weak', function _setWeak( index, value ) {
92
+ releaseCollectionValue( this, this[index] );
93
+ this[index] = makeWeakValue( value );
94
+ return this;
95
+ } );
96
+ define( Set.prototype, 'add_weak', function _addWeak( value ) {
97
+ this.add( makeWeakValue( value ) );
98
+ return this;
99
+ } );
100
+ define( Set.prototype, 'copy', function _copy() {
101
+ return makeSet( this );
102
+ } );
103
+ define( ZuzuBag.prototype, 'add_weak', function _addWeak( ...values ) {
104
+ this.items.push( ...values.map( makeWeakValue ) );
105
+ return this;
106
+ } );
107
+ define( ZuzuBag.prototype, 'push_weak', function _pushWeak( ...values ) {
108
+ return this.add_weak( ...values );
109
+ } );
110
+ define( PairList.prototype, 'add_weak', function _addWeak( key, value ) {
111
+ this.list.push( [ String( key ), makeWeakValue( value ) ] );
112
+ return this;
113
+ } );
114
+ define( PairList.prototype, 'set_weak', function _setWeak( key, value ) {
115
+ return this.add_weak( key, value );
116
+ } );
117
+ Object.defineProperty( ZuzuBag.prototype, 'contains', {
118
+ value: function _containsWeakAware( value ) {
119
+ const resolved = resolveWeakValue( value );
120
+ return this.items.some( (item) => resolveWeakValue( item ) === resolved ) ? 1 : 0;
121
+ },
122
+ enumerable: false,
123
+ configurable: true,
124
+ writable: true,
125
+ } );
126
+ Object.defineProperty( Set.prototype, 'contains', {
127
+ value: function _containsWeakAware( value ) {
128
+ const resolved = resolveWeakValue( value );
129
+ for ( const item of this ) {
130
+ if ( resolveWeakValue( item ) === resolved ) {
131
+ return 1;
132
+ }
133
+ }
134
+ return 0;
135
+ },
136
+ enumerable: false,
137
+ configurable: true,
138
+ writable: true,
139
+ } );
140
+ }
141
+
142
+ function createObjectFacade() {
143
+ function ZuzuContextObject( value ) {
144
+ if ( new.target ) {
145
+ return undefined;
146
+ }
147
+ return Object( value );
148
+ }
149
+ Object.setPrototypeOf( ZuzuContextObject, Object );
150
+ Object.defineProperty( ZuzuContextObject, 'prototype', {
151
+ value: Object.prototype,
152
+ enumerable: false,
153
+ configurable: false,
154
+ writable: false,
155
+ } );
156
+ return ZuzuContextObject;
157
+ }
158
+
159
+ function zuzuStringify( value ) {
160
+ value = resolveWeakValue( value );
161
+ if ( value == null ) {
162
+ return '';
163
+ }
164
+ if ( typeof value === 'boolean' ) {
165
+ return value ? '1' : '0';
166
+ }
167
+ if ( value instanceof RegExp ) {
168
+ return value.source;
169
+ }
170
+ if ( value instanceof ZuzuBinary ) {
171
+ return value.to_String();
172
+ }
173
+ if ( value && typeof value.to_String === 'function' ) {
174
+ return String( value.to_String() );
175
+ }
176
+ if ( value instanceof Error ) {
177
+ return value.message || value.name || String( value );
178
+ }
179
+ return String( value );
180
+ }
181
+
182
+ function zuzuOperatorString( value ) {
183
+ return operatorString( value );
184
+ }
185
+
186
+ function binaryFromLiteral( value ) {
187
+ const text = String( value ?? '' );
188
+ const bytes = [];
189
+ for ( let i = 0; i < text.length; i++ ) {
190
+ bytes.push( text.charCodeAt( i ) & 0xff );
191
+ }
192
+ return new BinaryString( bytes );
193
+ }
194
+
195
+ function toBinaryValue( value ) {
196
+ value = resolveWeakValue( value );
197
+ if ( value instanceof ZuzuBinary ) {
198
+ return new BinaryString( value );
199
+ }
200
+ if ( typeof value === 'string' ) {
201
+ return new BinaryString( textEncoder.encode( value ) );
202
+ }
203
+ throw new Error( `TypeException: expected String for to_binary, got ${zuzuTypeof( value )}` );
204
+ }
205
+
206
+ function toStringValue( value ) {
207
+ value = resolveWeakValue( value );
208
+ if ( typeof value === 'string' ) {
209
+ return value;
210
+ }
211
+ if ( value instanceof ZuzuBinary ) {
212
+ try {
213
+ return utf8Decoder.decode( value.bytes );
214
+ }
215
+ catch ( err ) {
216
+ return Array.from( value.bytes, (byte) => String.fromCharCode( byte ) ).join( '' );
217
+ }
218
+ }
219
+ throw new Error( `TypeException: expected BinaryString for to_string, got ${zuzuTypeof( value )}` );
220
+ }
221
+
222
+ function stringCompare( left, right, options = {} ) {
223
+ const l = options.insensitive
224
+ ? zuzuOperatorString( left ).toLowerCase()
225
+ : zuzuOperatorString( left );
226
+ const r = options.insensitive
227
+ ? zuzuOperatorString( right ).toLowerCase()
228
+ : zuzuOperatorString( right );
229
+ return l.localeCompare( r );
230
+ }
231
+
232
+ function parseNumericString( value ) {
233
+ const text = String( value ).trim();
234
+ const match = text.match( /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/ );
235
+ if ( !match ) {
236
+ throw new Error( `TypeException: cannot coerce String to Number: ${JSON.stringify( String( value ) )}` );
237
+ }
238
+ const parsed = Number( text );
239
+ if ( Number.isNaN( parsed ) ) {
240
+ throw new Error( `TypeException: cannot coerce String to Number: ${JSON.stringify( String( value ) )}` );
241
+ }
242
+ return parsed;
243
+ }
244
+
245
+ function zuzuToNumber( value ) {
246
+ value = resolveWeakValue( value );
247
+ if ( value == null ) {
248
+ return 0;
249
+ }
250
+ if ( typeof value === 'number' || Object.prototype.toString.call( value ) === '[object Number]' ) {
251
+ return Number( value );
252
+ }
253
+ if ( typeof value === 'boolean' || Object.prototype.toString.call( value ) === '[object Boolean]' ) {
254
+ return value.valueOf() ? 1 : 0;
255
+ }
256
+ if ( typeof value === 'string' || Object.prototype.toString.call( value ) === '[object String]' ) {
257
+ return parseNumericString( value );
258
+ }
259
+ if ( typeof value === 'function' ) {
260
+ throw new Error( `TypeException: cannot coerce ${zuzuTypeof( value )} to Number` );
261
+ }
262
+ if ( value && typeof value.to_Number === 'function' ) {
263
+ return zuzuToNumber( value.to_Number() );
264
+ }
265
+ throw new Error( `TypeException: cannot coerce ${zuzuTypeof( value )} to Number` );
266
+ }
267
+
268
+ function zuzuTruthy( value ) {
269
+ value = resolveWeakValue( value );
270
+ if ( value == null ) {
271
+ return false;
272
+ }
273
+ if ( value && typeof value.to_Boolean === 'function' ) {
274
+ return zuzuTruthy( value.to_Boolean() );
275
+ }
276
+ if ( value instanceof ZuzuBinary ) {
277
+ return value.byteLength() > 0;
278
+ }
279
+ if ( typeof value === 'boolean' || Object.prototype.toString.call( value ) === '[object Boolean]' ) {
280
+ return value.valueOf() === true;
281
+ }
282
+ if ( typeof value === 'number' || Object.prototype.toString.call( value ) === '[object Number]' ) {
283
+ return Number( value ) !== 0;
284
+ }
285
+ if ( typeof value === 'string' || Object.prototype.toString.call( value ) === '[object String]' ) {
286
+ return String( value ) !== '';
287
+ }
288
+ if ( Array.isArray( value ) ) {
289
+ return value.length > 0;
290
+ }
291
+ if ( isPairListLike( value ) ) {
292
+ return value.length() > 0;
293
+ }
294
+ if ( value instanceof ZuzuBag ) {
295
+ return value.length() > 0;
296
+ }
297
+ if ( isSetLike( value ) ) {
298
+ return value.size > 0;
299
+ }
300
+ const ctorName = value && value.constructor && value.constructor.name;
301
+ if ( value && typeof value === 'object' && ( ctorName === 'Object' || ctorName == null ) ) {
302
+ return Object.keys( value ).length > 0;
303
+ }
304
+ return Boolean( value );
305
+ }
306
+
307
+ function defaultOperator( leftInput, rightInput ) {
308
+ const left = resolveWeakValue( leftInput );
309
+ const right = resolveWeakValue( rightInput );
310
+ const leftType = zuzuTypeof( left );
311
+ if ( left != null && leftType !== 'Dict' && !isPairListLike( left ) ) {
312
+ throw new Error(
313
+ `TypeException: default operator left operand expects Dict, PairList, or Null, got ${leftType}`
314
+ );
315
+ }
316
+ if ( zuzuTypeof( right ) !== 'Dict' && !isPairListLike( right ) ) {
317
+ throw new Error(
318
+ `TypeException: default operator right operand expects Dict or PairList, got ${zuzuTypeof( right )}`
319
+ );
320
+ }
321
+
322
+ if ( leftType === 'Dict' ) {
323
+ const result = {};
324
+ for ( const key of Object.keys( left ) ) {
325
+ result[key] = left[key];
326
+ }
327
+ if ( isPairListLike( right ) ) {
328
+ for ( const [ key, value ] of right.list ) {
329
+ if ( !Object.prototype.hasOwnProperty.call( result, key ) ) {
330
+ result[key] = value;
331
+ }
332
+ }
333
+ }
334
+ else {
335
+ for ( const key of Object.keys( right ).sort() ) {
336
+ if ( !Object.prototype.hasOwnProperty.call( result, key ) ) {
337
+ result[key] = right[key];
338
+ }
339
+ }
340
+ }
341
+ return result;
342
+ }
343
+
344
+ const values = isPairListLike( left )
345
+ ? left.list.map( ([ key, value ]) => [ key, value ] )
346
+ : [];
347
+ const originalKeys = new Set( values.map( ([ key ]) => key ) );
348
+ if ( isPairListLike( right ) ) {
349
+ for ( const [ key, value ] of right.list ) {
350
+ if ( !originalKeys.has( key ) ) {
351
+ values.push( [ key, value ] );
352
+ }
353
+ }
354
+ }
355
+ else {
356
+ for ( const key of Object.keys( right ).sort() ) {
357
+ if ( !originalKeys.has( key ) ) {
358
+ values.push( [ key, right[key] ] );
359
+ }
360
+ }
361
+ }
362
+ return makePairList( values );
363
+ }
364
+
365
+ function isNumericComparable( value ) {
366
+ value = resolveWeakValue( value );
367
+ if ( value == null ) {
368
+ return true;
369
+ }
370
+ if (
371
+ typeof value === 'number'
372
+ || typeof value === 'string'
373
+ || typeof value === 'boolean'
374
+ ) {
375
+ return true;
376
+ }
377
+ const tag = Object.prototype.toString.call( value );
378
+ if (
379
+ tag === '[object Number]'
380
+ || tag === '[object String]'
381
+ || tag === '[object Boolean]'
382
+ ) {
383
+ return true;
384
+ }
385
+ return Boolean( value && typeof value.to_Number === 'function' );
386
+ }
387
+
388
+ function numericEqual( left, right ) {
389
+ const leftNum = zuzuToNumber( left );
390
+ const rightNum = zuzuToNumber( right );
391
+ if ( Object.is( leftNum, rightNum ) ) {
392
+ return true;
393
+ }
394
+ if ( Number.isInteger( leftNum ) && Number.isInteger( rightNum ) ) {
395
+ return false;
396
+ }
397
+ const scale = Math.max( 1, Math.abs( leftNum ), Math.abs( rightNum ) );
398
+ return Math.abs( leftNum - rightNum ) <= ( Number.EPSILON * 16 * scale );
399
+ }
400
+
401
+ function isExhaustedIteratorError( err ) {
402
+ if ( !err ) {
403
+ return false;
404
+ }
405
+ const name = String( err.name || err.constructor && err.constructor.name || '' );
406
+ if ( name === 'ExhaustedException' ) {
407
+ return true;
408
+ }
409
+ const message = String( err.message || '' );
410
+ if ( /\bExhaustedException\b/.test( message ) ) {
411
+ return true;
412
+ }
413
+ const stack = String( err.stack || '' );
414
+ return /\bExhaustedException\b/.test( stack );
415
+ }
416
+
417
+ function formatRuntimeError( err ) {
418
+ if ( err && err.name === 'SyntaxError' && typeof err.stack === 'string' && err.stack.trim() ) {
419
+ return `${err.stack}\n`;
420
+ }
421
+ if ( err && err.name && err.message ) {
422
+ return `${err.name}: ${err.message}\n`;
423
+ }
424
+ return `${String( err )}\n`;
425
+ }
426
+
427
+ async function runSwitchAsync( value, comparator, cases, defaultBody ) {
428
+ const cmp = (left, right) => {
429
+ switch ( comparator ) {
430
+ case 'eq':
431
+ return stringCompare( left, right ) === 0;
432
+ case 'ne':
433
+ return stringCompare( left, right ) !== 0;
434
+ case '=':
435
+ return numericEqual( zuzuToNumber( left ), zuzuToNumber( right ) );
436
+ case '==':
437
+ default:
438
+ return !!zuzuEqual( left, right );
439
+ }
440
+ };
441
+ let runNext = false;
442
+ for ( const section of cases ) {
443
+ const matched = section.values.some( (item) => cmp( value, item ) );
444
+ if ( matched || runNext ) {
445
+ const result = await taskRuntime.awaitValue( section.body() );
446
+ runNext = result === true;
447
+ if ( !runNext && result && typeof result === 'object' && result.__zuzu_return ) {
448
+ return result;
449
+ }
450
+ if ( !runNext ) {
451
+ return null;
452
+ }
453
+ }
454
+ }
455
+ if ( defaultBody ) {
456
+ const result = await taskRuntime.awaitValue( defaultBody() );
457
+ if ( result && typeof result === 'object' && result.__zuzu_return ) {
458
+ return result;
459
+ }
460
+ }
461
+ return null;
462
+ }
463
+
464
+ function concatValue( left, right ) {
465
+ left = resolveWeakValue( left );
466
+ right = resolveWeakValue( right );
467
+ if ( left instanceof ZuzuBinary && right instanceof ZuzuBinary ) {
468
+ const merged = new Uint8Array( left.length + right.length );
469
+ merged.set( left.bytes, 0 );
470
+ merged.set( right.bytes, left.length );
471
+ return new BinaryString( merged );
472
+ }
473
+ if ( typeof left === 'string' && typeof right === 'string' ) {
474
+ return left + right;
475
+ }
476
+ if ( left instanceof ZuzuBinary && typeof right === 'string' ) {
477
+ if ( !left.isAscii() ) {
478
+ throw new Error( 'TypeException: Cannot implicitly concatenate non-ASCII BinaryString with String' );
479
+ }
480
+ return left.to_String() + right;
481
+ }
482
+ if ( typeof left === 'string' && right instanceof ZuzuBinary ) {
483
+ if ( !right.isAscii() ) {
484
+ throw new Error( 'TypeException: Cannot implicitly concatenate non-ASCII BinaryString with String' );
485
+ }
486
+ return left + right.to_String();
487
+ }
488
+ return zuzuOperatorString( left ) + zuzuOperatorString( right );
489
+ }
490
+
491
+ function operatorLength( value ) {
492
+ value = resolveWeakValue( value );
493
+ if ( value instanceof ZuzuBinary ) {
494
+ return value.byteLength();
495
+ }
496
+ if (
497
+ Array.isArray( value )
498
+ || isPairListLike( value )
499
+ || value instanceof ZuzuBag
500
+ || isSetLike( value )
501
+ || ( value && typeof value === 'object' && value.constructor && value.constructor.name === 'Object' )
502
+ ) {
503
+ return lengthOf( value );
504
+ }
505
+ return [ ...zuzuOperatorString( value ) ].length;
506
+ }
507
+
508
+ function regexReplaceValue( current, pattern, replacement ) {
509
+ const source = zuzuOperatorString( current );
510
+ const regex = operatorRegexp( pattern );
511
+ return source.replace( regex, replacement );
512
+ }
513
+
514
+ function bitwiseBinaryPair( left, right, opName ) {
515
+ if ( left.length !== right.length ) {
516
+ throw new Error( 'Exception: BinaryString bitwise operands must be equal length' );
517
+ }
518
+ const out = new Uint8Array( left.length );
519
+ for ( let i = 0; i < left.length; i++ ) {
520
+ const a = left.bytes[i];
521
+ const b = right.bytes[i];
522
+ if ( opName === 'and' ) {
523
+ out[i] = a & b;
524
+ }
525
+ else if ( opName === 'or' ) {
526
+ out[i] = a | b;
527
+ }
528
+ else {
529
+ out[i] = a ^ b;
530
+ }
531
+ }
532
+ return new BinaryString( out );
533
+ }
534
+
535
+ function bitwiseAnd( left, right ) {
536
+ if ( left instanceof ZuzuBinary && right instanceof ZuzuBinary ) {
537
+ return bitwiseBinaryPair( left, right, 'and' );
538
+ }
539
+ return ( ( zuzuToNumber( left ) >>> 0 ) & ( zuzuToNumber( right ) >>> 0 ) ) >>> 0;
540
+ }
541
+
542
+ function bitwiseOr( left, right ) {
543
+ if ( left instanceof ZuzuBinary && right instanceof ZuzuBinary ) {
544
+ return bitwiseBinaryPair( left, right, 'or' );
545
+ }
546
+ return ( ( zuzuToNumber( left ) >>> 0 ) | ( zuzuToNumber( right ) >>> 0 ) ) >>> 0;
547
+ }
548
+
549
+ function bitwiseXor( left, right ) {
550
+ if ( left instanceof ZuzuBinary && right instanceof ZuzuBinary ) {
551
+ return bitwiseBinaryPair( left, right, 'xor' );
552
+ }
553
+ return ( ( zuzuToNumber( left ) >>> 0 ) ^ ( zuzuToNumber( right ) >>> 0 ) ) >>> 0;
554
+ }
555
+
556
+ function bitwiseNot( value ) {
557
+ value = resolveWeakValue( value );
558
+ if ( value instanceof ZuzuBinary ) {
559
+ const out = new Uint8Array( value.length );
560
+ for ( let i = 0; i < value.length; i++ ) {
561
+ out[i] = ( ~value.bytes[i] ) & 0xff;
562
+ }
563
+ return new BinaryString( out );
564
+ }
565
+ return ( ~( zuzuToNumber( value ) >>> 0 ) ) >>> 0;
566
+ }
567
+
568
+ function zuzuComparableValue( value ) {
569
+ value = resolveWeakValue( value );
570
+ if ( typeof value === 'function' && value.length === 0 ) {
571
+ try {
572
+ return value();
573
+ }
574
+ catch ( _err ) {
575
+ return value;
576
+ }
577
+ }
578
+ return value;
579
+ }
580
+
581
+ function zuzuEqual( left, right ) {
582
+ const a = zuzuComparableValue( left );
583
+ const b = zuzuComparableValue( right );
584
+ if ( a === b ) {
585
+ return 1;
586
+ }
587
+ if ( a == null || b == null ) {
588
+ return 0;
589
+ }
590
+ if ( a instanceof ZuzuBinary && b instanceof ZuzuBinary ) {
591
+ if ( a.bytes.length !== b.bytes.length ) {
592
+ return 0;
593
+ }
594
+ for ( let i = 0; i < a.bytes.length; i++ ) {
595
+ if ( a.bytes[i] !== b.bytes[i] ) {
596
+ return 0;
597
+ }
598
+ }
599
+ return 1;
600
+ }
601
+ if ( Array.isArray( a ) && Array.isArray( b ) ) {
602
+ if ( a.length !== b.length ) {
603
+ return 0;
604
+ }
605
+ for ( let i = 0; i < a.length; i++ ) {
606
+ if ( !zuzuEqual( a[i], b[i] ) ) {
607
+ return 0;
608
+ }
609
+ }
610
+ return 1;
611
+ }
612
+ if ( isSetLike( a ) && isSetLike( b ) ) {
613
+ return collectionEquivalentOf( a, b ) ? 1 : 0;
614
+ }
615
+ if ( isBagLike( a ) && isBagLike( b ) ) {
616
+ return zuzuEqual( a.to_Array(), b.to_Array() );
617
+ }
618
+ if ( isPairListLike( a ) && isPairListLike( b ) ) {
619
+ if ( a.list.length !== b.list.length ) {
620
+ return 0;
621
+ }
622
+ for ( let i = 0; i < a.list.length; i++ ) {
623
+ if ( a.list[i][0] !== b.list[i][0] ) {
624
+ return 0;
625
+ }
626
+ if ( !zuzuEqual( a.list[i][1], b.list[i][1] ) ) {
627
+ return 0;
628
+ }
629
+ }
630
+ return 1;
631
+ }
632
+ if ( isPlainObjectLike( a ) && isPlainObjectLike( b ) ) {
633
+ const keysA = Object.keys( a ).sort();
634
+ const keysB = Object.keys( b ).sort();
635
+ if ( !zuzuEqual( keysA, keysB ) ) {
636
+ return 0;
637
+ }
638
+ for ( const key of keysA ) {
639
+ if ( !zuzuEqual( a[key], b[key] ) ) {
640
+ return 0;
641
+ }
642
+ }
643
+ return 1;
644
+ }
645
+ return 0;
646
+ }
647
+
648
+ function isSetLike( value ) {
649
+ return Object.prototype.toString.call( value ) === '[object Set]';
650
+ }
651
+
652
+ function isBagLike( value ) {
653
+ return value instanceof ZuzuBag || ( value && value.constructor && value.constructor.name === 'ZuzuBag' );
654
+ }
655
+
656
+ function isPlainObjectLike( value ) {
657
+ return Object.prototype.toString.call( value ) === '[object Object]'
658
+ && !( value.constructor && value.constructor.__zuzu_class_name );
659
+ }
660
+
661
+ function isDictMethodReceiver( value ) {
662
+ return value
663
+ && typeof value === 'object'
664
+ && !Array.isArray( value )
665
+ && !isPairListLike( value )
666
+ && !isSetLike( value )
667
+ && !isBagLike( value );
668
+ }
669
+
670
+ function normalizeDictKey( key ) {
671
+ key = resolveWeakValue( key );
672
+ if ( key == null ) {
673
+ return '';
674
+ }
675
+ if ( typeof key === 'string' ) {
676
+ return key;
677
+ }
678
+ if ( key instanceof ZuzuBinary ) {
679
+ return key.to_String();
680
+ }
681
+ if ( key && typeof key.to_String === 'function' ) {
682
+ return String( key.to_String() );
683
+ }
684
+ return String( key );
685
+ }
686
+
687
+ const DICT_METHODS = Object.freeze( {
688
+ length( self ) {
689
+ return isDictMethodReceiver( self ) ? Object.keys( self ).length : 0;
690
+ },
691
+ keys( self ) {
692
+ return isDictMethodReceiver( self ) ? Object.keys( self ).sort() : [];
693
+ },
694
+ values( self ) {
695
+ if ( !isDictMethodReceiver( self ) ) {
696
+ return [];
697
+ }
698
+ return DICT_METHODS.keys( self ).map( (key) => resolveWeakValue( self[key] ) );
699
+ },
700
+ copy( self ) {
701
+ if ( !isDictMethodReceiver( self ) ) {
702
+ return {};
703
+ }
704
+ const out = {};
705
+ for ( const key of Object.keys( self ) ) {
706
+ out[key] = retainCollectionValue( out, self[key] );
707
+ }
708
+ return out;
709
+ },
710
+ enumerate( self ) {
711
+ if ( !isDictMethodReceiver( self ) ) {
712
+ return [];
713
+ }
714
+ return DICT_METHODS.keys( self ).map(
715
+ (key) => new Pair( { pair: [ key, resolveWeakValue( self[key] ) ] } )
716
+ );
717
+ },
718
+ has( self, key ) {
719
+ return isDictMethodReceiver( self )
720
+ && Object.prototype.hasOwnProperty.call( self, normalizeDictKey( key ) )
721
+ ? 1
722
+ : 0;
723
+ },
724
+ contains( self, key ) {
725
+ return DICT_METHODS.has( self, key );
726
+ },
727
+ exists( self, key ) {
728
+ return DICT_METHODS.has( self, key );
729
+ },
730
+ defined( self, key ) {
731
+ const normalized = normalizeDictKey( key );
732
+ return isDictMethodReceiver( self )
733
+ && resolveWeakValue( self[normalized] ) != null ? 1 : 0;
734
+ },
735
+ get( self, key, fallback = null ) {
736
+ const normalized = normalizeDictKey( key );
737
+ return DICT_METHODS.has( self, normalized )
738
+ ? resolveWeakValue( self[normalized] )
739
+ : fallback;
740
+ },
741
+ add( self, key, value ) {
742
+ if ( !isDictMethodReceiver( self ) || key instanceof Pair ) {
743
+ return self;
744
+ }
745
+ const normalized = normalizeDictKey( key );
746
+ releaseCollectionValue( self, self[normalized] );
747
+ self[normalized] = retainCollectionValue( self, value );
748
+ return self;
749
+ },
750
+ set( self, key, value ) {
751
+ return DICT_METHODS.add( self, key, value );
752
+ },
753
+ add_weak( self, key, value ) {
754
+ if ( !isDictMethodReceiver( self ) || key instanceof Pair ) {
755
+ return self;
756
+ }
757
+ const normalized = normalizeDictKey( key );
758
+ releaseCollectionValue( self, self[normalized] );
759
+ self[normalized] = makeWeakValue( value );
760
+ return self;
761
+ },
762
+ set_weak( self, key, value ) {
763
+ return DICT_METHODS.add_weak( self, key, value );
764
+ },
765
+ kv( self ) {
766
+ if ( !isDictMethodReceiver( self ) ) {
767
+ return [];
768
+ }
769
+ const out = [];
770
+ for ( const key of DICT_METHODS.keys( self ) ) {
771
+ out.push( key, resolveWeakValue( self[key] ) );
772
+ }
773
+ return out;
774
+ },
775
+ sorted_keys( self ) {
776
+ return DICT_METHODS.keys( self );
777
+ },
778
+ remove( self, key ) {
779
+ if ( !isDictMethodReceiver( self ) ) {
780
+ return self;
781
+ }
782
+ if ( typeof key === 'function' ) {
783
+ for ( const [ k, v ] of Object.entries( self ) ) {
784
+ if ( key( new Pair( { pair: [ k, v ] } ) ) ) {
785
+ releaseCollectionValue( self, self[k] );
786
+ delete self[k];
787
+ }
788
+ }
789
+ return self;
790
+ }
791
+ if ( key instanceof Pair ) {
792
+ return self;
793
+ }
794
+ const normalized = normalizeDictKey( key );
795
+ releaseCollectionValue( self, self[normalized] );
796
+ delete self[normalized];
797
+ return self;
798
+ },
799
+ count( self ) {
800
+ return DICT_METHODS.length( self );
801
+ },
802
+ empty( self ) {
803
+ return DICT_METHODS.length( self ) === 0 ? 1 : 0;
804
+ },
805
+ is_empty( self ) {
806
+ return DICT_METHODS.empty( self );
807
+ },
808
+ to_Array( self ) {
809
+ return DICT_METHODS.enumerate( self );
810
+ },
811
+ to_Iterator( self ) {
812
+ return DICT_METHODS.keys( self )[Symbol.iterator]();
813
+ },
814
+ for_each_key( self, fn ) {
815
+ for ( const key of DICT_METHODS.keys( self ) ) {
816
+ fn( key );
817
+ }
818
+ return self;
819
+ },
820
+ for_each_value( self, fn ) {
821
+ for ( const value of DICT_METHODS.values( self ) ) {
822
+ fn( value );
823
+ }
824
+ return self;
825
+ },
826
+ for_each_pair( self, fn ) {
827
+ for ( const pair of DICT_METHODS.enumerate( self ) ) {
828
+ fn( pair );
829
+ }
830
+ return self;
831
+ },
832
+ clear( self ) {
833
+ if ( isDictMethodReceiver( self ) ) {
834
+ for ( const key of Object.keys( self ) ) {
835
+ releaseCollectionValue( self, self[key] );
836
+ delete self[key];
837
+ }
838
+ }
839
+ return self;
840
+ },
841
+ } );
842
+
843
+ const DICT_ZERO_ARG_METHODS = new Set( [
844
+ 'clear',
845
+ 'copy',
846
+ 'count',
847
+ 'empty',
848
+ 'enumerate',
849
+ 'is_empty',
850
+ 'keys',
851
+ 'kv',
852
+ 'length',
853
+ 'sorted_keys',
854
+ 'to_Array',
855
+ 'to_Iterator',
856
+ 'values',
857
+ ] );
858
+
859
+ function getDictMethod( object, property ) {
860
+ if ( typeof property === 'symbol' ) {
861
+ return null;
862
+ }
863
+ const name = String( property );
864
+ if (
865
+ !isDictMethodReceiver( object )
866
+ || Object.prototype.hasOwnProperty.call( object, name )
867
+ || !Object.prototype.hasOwnProperty.call( DICT_METHODS, name )
868
+ ) {
869
+ return null;
870
+ }
871
+ return function zuzuDictMethod( ...args ) {
872
+ return DICT_METHODS[name]( object, ...args );
873
+ };
874
+ }
875
+
876
+ class ZuzuMethod {
877
+ constructor( name, fn ) {
878
+ this.name = String( name || '' );
879
+ this.fn = fn;
880
+ }
881
+
882
+ invoke( self, args = [] ) {
883
+ return this.fn.apply( self, args );
884
+ }
885
+
886
+ to_String() {
887
+ return this.name;
888
+ }
889
+ }
890
+
891
+ function zuzuBoundMethod( receiver, name, fn ) {
892
+ const methodName = String( name || '' );
893
+ const bound = function __zuzu_bound_method( ...args ) {
894
+ return fn.apply( receiver, args );
895
+ };
896
+ Object.defineProperty( bound, '__zuzu_method', {
897
+ value: true,
898
+ enumerable: false,
899
+ configurable: true,
900
+ } );
901
+ Object.defineProperty( bound, '__zuzu_bound_receiver', {
902
+ value: receiver,
903
+ enumerable: false,
904
+ configurable: true,
905
+ } );
906
+ Object.defineProperty( bound, '__zuzu_bound_method_name', {
907
+ value: methodName,
908
+ enumerable: false,
909
+ configurable: true,
910
+ } );
911
+ bound.invoke = function invoke( _self, args = [] ) {
912
+ return fn.apply( receiver, args );
913
+ };
914
+ bound.to_String = function to_String() {
915
+ return methodName;
916
+ };
917
+ return bound;
918
+ }
919
+
920
+ function zuzuTypeof( value ) {
921
+ value = resolveWeakValue( value );
922
+ if ( value == null ) {
923
+ return 'Null';
924
+ }
925
+ if ( value && value.__zuzu_method ) {
926
+ return 'Method';
927
+ }
928
+ if ( value instanceof ZuzuMethod ) {
929
+ return 'Method';
930
+ }
931
+ if ( isPairListLike( value ) ) {
932
+ return 'PairList';
933
+ }
934
+ if (
935
+ value
936
+ && ( typeof value === 'object' || typeof value === 'function' )
937
+ && typeof value.__zuzu_type_name === 'string'
938
+ ) {
939
+ return value.__zuzu_type_name;
940
+ }
941
+ if ( isBagLike( value ) ) {
942
+ return 'Bag';
943
+ }
944
+ if ( isSetLike( value ) ) {
945
+ return 'Set';
946
+ }
947
+ if ( Array.isArray( value ) ) {
948
+ return 'Array';
949
+ }
950
+ if ( value instanceof Pair ) {
951
+ return 'Pair';
952
+ }
953
+ if ( value instanceof RegExp ) {
954
+ return 'Regexp';
955
+ }
956
+ if ( Object.prototype.toString.call( value ) === '[object RegExp]' ) {
957
+ return 'Regexp';
958
+ }
959
+ if ( typeof value === 'boolean' ) {
960
+ return 'Boolean';
961
+ }
962
+ if ( typeof value === 'number' ) {
963
+ return 'Number';
964
+ }
965
+ if ( typeof value === 'string' ) {
966
+ return 'String';
967
+ }
968
+ if ( value instanceof ZuzuBinary ) {
969
+ return 'BinaryString';
970
+ }
971
+ if ( typeof value === 'function' ) {
972
+ const source = Function.prototype.toString.call( value );
973
+ if ( /^\s*class\b/.test( source ) ) {
974
+ return 'Class';
975
+ }
976
+ return 'Function';
977
+ }
978
+ if ( value && value.constructor ) {
979
+ const ctorName = value.constructor.name || 'Object';
980
+ if ( ctorName === 'Object' ) {
981
+ return 'Dict';
982
+ }
983
+ if ( ctorName === 'Error' ) {
984
+ return 'Exception';
985
+ }
986
+ return ctorName;
987
+ }
988
+ return 'Object';
989
+ }
990
+
991
+ function zuzuInstanceof( value, klass ) {
992
+ value = resolveWeakValue( value );
993
+ klass = resolveWeakValue( klass );
994
+ if ( klass == null ) {
995
+ return value == null ? 1 : 0;
996
+ }
997
+ const klassName = ( typeof klass === 'function' && klass.name ) ? klass.name : '';
998
+ if ( klassName === 'Any' ) {
999
+ return 1;
1000
+ }
1001
+ if ( klassName === 'Null' ) {
1002
+ return value == null ? 1 : 0;
1003
+ }
1004
+ if ( klassName === 'Boolean' || klass === Boolean ) {
1005
+ return ( typeof value === 'boolean' || Object.prototype.toString.call( value ) === '[object Boolean]' ) ? 1 : 0;
1006
+ }
1007
+ if ( klassName === 'Number' || klass === Number ) {
1008
+ return ( typeof value === 'number' || Object.prototype.toString.call( value ) === '[object Number]' ) ? 1 : 0;
1009
+ }
1010
+ if ( klassName === 'String' || klass === String ) {
1011
+ return ( typeof value === 'string' || Object.prototype.toString.call( value ) === '[object String]' ) ? 1 : 0;
1012
+ }
1013
+ if ( klassName === 'Array' || klass === Array ) {
1014
+ return Array.isArray( value ) ? 1 : 0;
1015
+ }
1016
+ if ( klassName === 'BinaryString' ) {
1017
+ return value instanceof ZuzuBinary ? 1 : 0;
1018
+ }
1019
+ if ( klassName === 'Function' || klass === Function ) {
1020
+ return typeof value === 'function' ? 1 : 0;
1021
+ }
1022
+ if ( klassName === 'Exception' ) {
1023
+ if ( value == null ) {
1024
+ return 0;
1025
+ }
1026
+ if ( value instanceof Error ) {
1027
+ return 1;
1028
+ }
1029
+ const valueName = String(
1030
+ value.name
1031
+ || value.constructor && value.constructor.name
1032
+ || ''
1033
+ );
1034
+ return [
1035
+ 'Exception',
1036
+ 'TypeException',
1037
+ 'ExhaustedException',
1038
+ 'CancelledException',
1039
+ 'TimeoutException',
1040
+ 'ChannelClosedException',
1041
+ ].includes( valueName ) ? 1 : 0;
1042
+ }
1043
+ if ( klassName === 'TypeException' ) {
1044
+ if ( value == null ) {
1045
+ return 0;
1046
+ }
1047
+ const valueName = String(
1048
+ value.name
1049
+ || value.constructor && value.constructor.name
1050
+ || ''
1051
+ );
1052
+ return valueName === 'TypeException' ? 1 : 0;
1053
+ }
1054
+ if ( klassName === 'ExhaustedException' ) {
1055
+ if ( value == null ) {
1056
+ return 0;
1057
+ }
1058
+ const valueName = String(
1059
+ value.name
1060
+ || value.constructor && value.constructor.name
1061
+ || ''
1062
+ );
1063
+ return valueName === 'ExhaustedException' ? 1 : 0;
1064
+ }
1065
+ if ( [
1066
+ 'CancelledException',
1067
+ 'TimeoutException',
1068
+ 'ChannelClosedException',
1069
+ ].includes( klassName ) ) {
1070
+ if ( value == null ) {
1071
+ return 0;
1072
+ }
1073
+ const valueName = String(
1074
+ value.name
1075
+ || value.constructor && value.constructor.name
1076
+ || ''
1077
+ );
1078
+ return valueName === klassName ? 1 : 0;
1079
+ }
1080
+ if ( klassName === 'Collection' ) {
1081
+ return (
1082
+ Array.isArray( value )
1083
+ || isSetLike( value )
1084
+ || isBagLike( value )
1085
+ || zuzuTypeof( value ) === 'Dict'
1086
+ ) ? 1 : 0;
1087
+ }
1088
+ if ( klassName === 'Dict' ) {
1089
+ return zuzuTypeof( value ) === 'Dict' ? 1 : 0;
1090
+ }
1091
+ if ( klassName === 'Set' ) {
1092
+ return isSetLike( value ) ? 1 : 0;
1093
+ }
1094
+ if ( klassName === 'Bag' ) {
1095
+ return isBagLike( value ) ? 1 : 0;
1096
+ }
1097
+ if ( klassName === 'Class' ) {
1098
+ return typeof value === 'function' ? 1 : 0;
1099
+ }
1100
+ if ( klassName === 'Object' || klass === Object ) {
1101
+ return ( value !== null && typeof value === 'object' ) ? 1 : 0;
1102
+ }
1103
+ try {
1104
+ return value instanceof klass ? 1 : 0;
1105
+ }
1106
+ catch ( _err ) {
1107
+ return 0;
1108
+ }
1109
+ }
1110
+
1111
+ function isNativeErrorConstructorName( name ) {
1112
+ return [
1113
+ 'Error',
1114
+ 'EvalError',
1115
+ 'RangeError',
1116
+ 'ReferenceError',
1117
+ 'SyntaxError',
1118
+ 'TypeError',
1119
+ 'URIError',
1120
+ ].includes( String( name || '' ) );
1121
+ }
1122
+
1123
+ function zuzuTrait( name, methods, source = null, captures = {} ) {
1124
+ const trait = {
1125
+ __zuzu_trait_name: String( name || '' ),
1126
+ __zuzu_trait_methods: methods || {},
1127
+ };
1128
+ if ( source != null ) {
1129
+ Object.defineProperty( trait, '__zuzu_marshal_meta', {
1130
+ value: {
1131
+ kind: 'trait',
1132
+ name: String( name || '' ),
1133
+ source: String( source ),
1134
+ captures: captures || {},
1135
+ },
1136
+ enumerable: false,
1137
+ configurable: true,
1138
+ writable: true,
1139
+ } );
1140
+ }
1141
+ return trait;
1142
+ }
1143
+
1144
+ const perObjectTraitClassCache = new WeakMap();
1145
+
1146
+ function isZuzuIdentifierName( name ) {
1147
+ return /^[A-Za-z_][A-Za-z0-9_]*$/u.test( String( name || '' ) );
1148
+ }
1149
+
1150
+ function zuzuClassWithTraits( base, traits ) {
1151
+ if ( typeof base !== 'function' ) {
1152
+ throw new Error( `TypeException: new with traits expects Class, got ${zuzuTypeof( base )}` );
1153
+ }
1154
+ const traitList = Array.isArray( traits ) ? traits : [];
1155
+ let node = perObjectTraitClassCache.get( base );
1156
+ if ( !node ) {
1157
+ node = new WeakMap();
1158
+ perObjectTraitClassCache.set( base, node );
1159
+ }
1160
+ for ( const trait of traitList ) {
1161
+ if ( !trait || !trait.__zuzu_trait_methods ) {
1162
+ throw new Error( `TypeException: new with traits expects Trait, got ${zuzuTypeof( trait )}` );
1163
+ }
1164
+ let next = node.get( trait );
1165
+ if ( !next ) {
1166
+ next = new WeakMap();
1167
+ node.set( trait, next );
1168
+ }
1169
+ node = next;
1170
+ }
1171
+ if ( node.__zuzu_class ) {
1172
+ return node.__zuzu_class;
1173
+ }
1174
+ const rawName = base.__zuzu_class_name || base.name || 'Object';
1175
+ const name = isZuzuIdentifierName( rawName ) ? rawName : '__zuzu_per_object_class';
1176
+ const captures = { __zuzu_per_object_base: base };
1177
+ const traitNames = traitList.map( (trait, index) => {
1178
+ const captureName = `__zuzu_per_object_trait_${index}`;
1179
+ captures[captureName] = trait;
1180
+ return captureName;
1181
+ } );
1182
+ const source = `class ${name} extends __zuzu_per_object_base with ${traitNames.join( ', ' )};`;
1183
+ const klass = defineZuzuClass( rawName, base, {
1184
+ marshalSource: source,
1185
+ marshalCaptures: captures,
1186
+ traits: traitList,
1187
+ fields: [],
1188
+ methods: {},
1189
+ statics: {},
1190
+ nested: {},
1191
+ } );
1192
+ Object.defineProperty( node, '__zuzu_class', {
1193
+ value: klass,
1194
+ enumerable: false,
1195
+ configurable: true,
1196
+ writable: true,
1197
+ } );
1198
+ return klass;
1199
+ }
1200
+
1201
+ function zuzuApplyTraits( klass, traits ) {
1202
+ if ( !klass || !klass.prototype || !Array.isArray( traits ) ) {
1203
+ return klass;
1204
+ }
1205
+ if ( !Object.prototype.hasOwnProperty.call( klass, '__zuzu_traits' ) ) {
1206
+ const desc = Object.create( null );
1207
+ desc.value = new Set();
1208
+ desc.enumerable = false;
1209
+ desc.configurable = true;
1210
+ desc.writable = true;
1211
+ Object.defineProperty( klass, '__zuzu_traits', desc );
1212
+ }
1213
+ for ( const trait of traits ) {
1214
+ if ( !trait || !trait.__zuzu_trait_methods ) {
1215
+ continue;
1216
+ }
1217
+ klass.__zuzu_traits.add( trait.__zuzu_trait_name || '' );
1218
+ for ( const [ name, fn ] of Object.entries( trait.__zuzu_trait_methods ) ) {
1219
+ if ( typeof fn !== 'function' ) {
1220
+ continue;
1221
+ }
1222
+ if ( Object.prototype.hasOwnProperty.call( klass.prototype, name )
1223
+ && typeof klass.prototype[name] === 'function' ) {
1224
+ klass.prototype[`__zuzu_trait_super__${name}`] = fn;
1225
+ }
1226
+ else {
1227
+ klass.prototype[name] = fn;
1228
+ }
1229
+ }
1230
+ }
1231
+ return klass;
1232
+ }
1233
+
1234
+ function zuzuDoes( value, trait ) {
1235
+ value = resolveWeakValue( value );
1236
+ if ( value == null || !trait ) {
1237
+ return 0;
1238
+ }
1239
+ const name = trait.__zuzu_trait_name || trait.name || String( trait );
1240
+ let ctor = value.constructor;
1241
+ while ( ctor ) {
1242
+ if ( ctor.__zuzu_traits instanceof Set && ctor.__zuzu_traits.has( name ) ) {
1243
+ return 1;
1244
+ }
1245
+ ctor = Object.getPrototypeOf( ctor );
1246
+ }
1247
+ return 0;
1248
+ }
1249
+
1250
+ function zuzuStoreField( object, field, value ) {
1251
+ const stored = field.isWeakStorage
1252
+ ? makeWeakValue( value )
1253
+ : retainValue( value );
1254
+ releaseValue( object[field.name] );
1255
+ object[field.name] = stored;
1256
+ return stored;
1257
+ }
1258
+
1259
+ function defineZuzuClass( name, base, spec = {} ) {
1260
+ const parent = typeof base === 'function' ? base : Object;
1261
+ const fields = Array.isArray( spec.fields ) ? spec.fields : [];
1262
+ const traits = Array.isArray( spec.traits ) ? spec.traits : [];
1263
+ const methods = spec.methods && typeof spec.methods === 'object' ? spec.methods : {};
1264
+ const statics = spec.statics && typeof spec.statics === 'object' ? spec.statics : {};
1265
+ const nested = spec.nested && typeof spec.nested === 'object' ? spec.nested : {};
1266
+ const ctor = {
1267
+ [name]: class extends parent {
1268
+ constructor( ...args ) {
1269
+ const skipBuild = args[0] === ZUZU_SKIP_BUILD;
1270
+ const ctorArgs = skipBuild ? args.slice( 1 ) : args;
1271
+ const superArgs = parent.__zuzu_class_name
1272
+ ? ( skipBuild ? args : [ ZUZU_SKIP_BUILD, ...ctorArgs ] )
1273
+ : ctorArgs;
1274
+ super( ...superArgs );
1275
+ if ( this instanceof Error ) {
1276
+ this.name = name;
1277
+ }
1278
+ for ( const field of fields ) {
1279
+ let value = null;
1280
+ if ( field.defaultValue && typeof field.defaultValue === 'function' ) {
1281
+ value = field.defaultValue.call( this );
1282
+ }
1283
+ zuzuStoreField( this, field, value );
1284
+ }
1285
+ let named = null;
1286
+ if ( ctorArgs.length === 1 && isPairListLike( ctorArgs[0] ) ) {
1287
+ named = ctorArgs[0];
1288
+ }
1289
+ else if (
1290
+ ctorArgs.length === 1
1291
+ && ctorArgs[0]
1292
+ && typeof ctorArgs[0] === 'object'
1293
+ && !Array.isArray( ctorArgs[0] )
1294
+ ) {
1295
+ named = ctorArgs[0];
1296
+ }
1297
+ const releaseTemporaryNamed = !skipBuild
1298
+ && isPairListLike( named )
1299
+ && named.__zuzu_temporary_call_args === true;
1300
+ try {
1301
+ if ( named ) {
1302
+ for ( const field of fields ) {
1303
+ const incoming = isPairListLike( named )
1304
+ ? named.get( field.name, resolveWeakValue( this[field.name] ) )
1305
+ : Object.prototype.hasOwnProperty.call( named, field.name )
1306
+ ? named[field.name]
1307
+ : resolveWeakValue( this[field.name] );
1308
+ if ( field.typeName && incoming != null && !zuzuTypeMatches( incoming, field.typeName ) ) {
1309
+ throw new Error( `TypeException: field '${field.name}' must be ${field.typeName}, got ${zuzuTypeof( incoming )}` );
1310
+ }
1311
+ zuzuStoreField( this, field, incoming );
1312
+ }
1313
+ }
1314
+ for ( const [ nestedName, nestedClass ] of Object.entries( nested ) ) {
1315
+ this[nestedName] = nestedClass;
1316
+ }
1317
+ if ( !skipBuild && typeof this.__build__ === 'function' ) {
1318
+ this.__build__();
1319
+ }
1320
+ }
1321
+ finally {
1322
+ if ( releaseTemporaryNamed ) {
1323
+ releaseCollectionValues( named );
1324
+ }
1325
+ }
1326
+ }
1327
+ },
1328
+ }[name];
1329
+ for ( const field of fields ) {
1330
+ if ( Array.isArray( field.accessors ) ) {
1331
+ if ( field.accessors.includes( 'get' ) && typeof ctor.prototype[`get_${field.name}`] !== 'function' ) {
1332
+ ctor.prototype[`get_${field.name}`] = function _get_field() {
1333
+ return resolveWeakValue( this[field.name] );
1334
+ };
1335
+ }
1336
+ if ( field.accessors.includes( 'set' ) && typeof ctor.prototype[`set_${field.name}`] !== 'function' ) {
1337
+ ctor.prototype[`set_${field.name}`] = function _set_field( value ) {
1338
+ if ( field.typeName && value != null && !zuzuTypeMatches( value, field.typeName ) ) {
1339
+ throw new Error( `TypeException: field '${field.name}' must be ${field.typeName}, got ${zuzuTypeof( value )}` );
1340
+ }
1341
+ zuzuStoreField( this, field, value );
1342
+ return this;
1343
+ };
1344
+ }
1345
+ if ( field.accessors.includes( 'clear' ) && typeof ctor.prototype[`clear_${field.name}`] !== 'function' ) {
1346
+ ctor.prototype[`clear_${field.name}`] = function _clear_field() {
1347
+ zuzuStoreField( this, field, null );
1348
+ return this;
1349
+ };
1350
+ }
1351
+ if ( field.accessors.includes( 'has' ) && typeof ctor.prototype[`has_${field.name}`] !== 'function' ) {
1352
+ ctor.prototype[`has_${field.name}`] = function _has_field() {
1353
+ return resolveWeakValue( this[field.name] ) != null ? 1 : 0;
1354
+ };
1355
+ }
1356
+ }
1357
+ }
1358
+ for ( const [ methodName, fn ] of Object.entries( methods ) ) {
1359
+ ctor.prototype[methodName] = fn;
1360
+ }
1361
+ for ( const [ methodName, fn ] of Object.entries( statics ) ) {
1362
+ ctor[methodName] = fn;
1363
+ }
1364
+ for ( const [ nestedName, nestedClass ] of Object.entries( nested ) ) {
1365
+ ctor[nestedName] = nestedClass;
1366
+ }
1367
+ zuzuApplyTraits( ctor, traits );
1368
+ Object.defineProperty( ctor, '__zuzu_class_name', {
1369
+ value: name,
1370
+ enumerable: false,
1371
+ configurable: true,
1372
+ writable: true,
1373
+ } );
1374
+ Object.defineProperty( ctor, '__zuzu_class_spec', {
1375
+ value: {
1376
+ fields: fields.map( (field) => ( { ...field } ) ),
1377
+ traits: traits.slice(),
1378
+ methods: { ...methods },
1379
+ statics: { ...statics },
1380
+ nested: { ...nested },
1381
+ },
1382
+ enumerable: false,
1383
+ configurable: true,
1384
+ writable: true,
1385
+ } );
1386
+ if ( typeof spec.marshalSource === 'string' ) {
1387
+ Object.defineProperty( ctor, '__zuzu_marshal_meta', {
1388
+ value: {
1389
+ kind: 'class',
1390
+ name,
1391
+ source: spec.marshalSource,
1392
+ captures: spec.marshalCaptures || {},
1393
+ },
1394
+ enumerable: false,
1395
+ configurable: true,
1396
+ writable: true,
1397
+ } );
1398
+ }
1399
+ return ctor;
1400
+ }
1401
+
1402
+ function zuzuGetMember( object, property ) {
1403
+ object = resolveWeakValue( object );
1404
+ if ( object == null ) {
1405
+ return null;
1406
+ }
1407
+ const value = resolveWeakValue( object[property] );
1408
+ if (
1409
+ typeof value === 'function'
1410
+ && value.length === 0
1411
+ && !value.__zuzu_marshal_meta
1412
+ ) {
1413
+ return value.call( object );
1414
+ }
1415
+ const dictMethod = getDictMethod( object, property );
1416
+ if ( dictMethod && DICT_ZERO_ARG_METHODS.has( String( property ) ) ) {
1417
+ return dictMethod();
1418
+ }
1419
+ if ( dictMethod ) {
1420
+ return dictMethod;
1421
+ }
1422
+ return resolveWeakValue( value );
1423
+ }
1424
+
1425
+ function zuzuResolveBraceKey( _object, literalProperty, _getDynamicProperty ) {
1426
+ const literal = String( literalProperty || '' );
1427
+ return literal;
1428
+ }
1429
+
1430
+ function zuzuGetBraceMember( object, literalProperty, getDynamicProperty ) {
1431
+ object = resolveWeakValue( object );
1432
+ if ( object == null ) {
1433
+ return null;
1434
+ }
1435
+ return zuzuGetIndex( object, zuzuResolveBraceKey( object, literalProperty, getDynamicProperty ) );
1436
+ }
1437
+
1438
+ function zuzuCallMember( object, property, ...args ) {
1439
+ object = resolveWeakValue( object );
1440
+ if ( object == null ) {
1441
+ throw new TypeError( `Cannot call member ${String( property )} of null` );
1442
+ }
1443
+ if ( property instanceof ZuzuMethod || ( property && property.__zuzu_method ) ) {
1444
+ return property.invoke( object, args );
1445
+ }
1446
+ const value = resolveWeakValue( object[property] );
1447
+ if ( typeof value === 'function' ) {
1448
+ return value.apply( object, args );
1449
+ }
1450
+ let proto = Object.getPrototypeOf( object );
1451
+ while ( proto ) {
1452
+ const descriptor = Object.getOwnPropertyDescriptor( proto, property );
1453
+ if ( descriptor && typeof descriptor.value === 'function' ) {
1454
+ return descriptor.value.apply( object, args );
1455
+ }
1456
+ proto = Object.getPrototypeOf( proto );
1457
+ }
1458
+ const dictMethod = getDictMethod( object, property );
1459
+ if ( dictMethod ) {
1460
+ return dictMethod( ...args );
1461
+ }
1462
+ if ( args.length === 0 ) {
1463
+ return value;
1464
+ }
1465
+ throw new TypeError( `${String( property )} is not a function` );
1466
+ }
1467
+
1468
+ function zuzuMaybeDemolish( value ) {
1469
+ const original = value;
1470
+ value = resolveWeakValue( value );
1471
+ let result = null;
1472
+ if ( value && typeof value.__demolish__ === 'function' ) {
1473
+ result = value.__demolish__();
1474
+ }
1475
+ releaseValue( original );
1476
+ return result;
1477
+ }
1478
+
1479
+ function zuzuCan( value, methodName ) {
1480
+ value = resolveWeakValue( value );
1481
+ if ( value == null ) {
1482
+ return 0;
1483
+ }
1484
+ const key = String( methodName || '' );
1485
+ if ( getDictMethod( value, key ) ) {
1486
+ return 1;
1487
+ }
1488
+ if ( typeof value[key] === 'function' ) {
1489
+ return 1;
1490
+ }
1491
+ let proto = Object.getPrototypeOf( value );
1492
+ while ( proto ) {
1493
+ const descriptor = Object.getOwnPropertyDescriptor( proto, key );
1494
+ if ( descriptor && typeof descriptor.value === 'function' ) {
1495
+ return 1;
1496
+ }
1497
+ proto = Object.getPrototypeOf( proto );
1498
+ }
1499
+ return 0;
1500
+ }
1501
+
1502
+ function zuzuSuperCall( self, klass, methodName, args = [] ) {
1503
+ const method = String( methodName || '' );
1504
+ const argv = Array.isArray( args ) ? args : [];
1505
+ if ( klass && self && typeof self[`__zuzu_trait_super__${method}`] === 'function' ) {
1506
+ return self[`__zuzu_trait_super__${method}`].apply( self, argv );
1507
+ }
1508
+ if ( !klass && self && self.constructor ) {
1509
+ klass = self.constructor;
1510
+ }
1511
+ if ( klass && klass.prototype ) {
1512
+ const parentProto = Object.getPrototypeOf( klass.prototype );
1513
+ if ( parentProto && typeof parentProto[method] === 'function' ) {
1514
+ return parentProto[method].apply( self, argv );
1515
+ }
1516
+ }
1517
+ return null;
1518
+ }
1519
+
1520
+ function zuzuSuperStaticCall( klass, methodName, args = [] ) {
1521
+ const method = String( methodName || '' );
1522
+ const argv = Array.isArray( args ) ? args : [];
1523
+ if ( !klass ) {
1524
+ return null;
1525
+ }
1526
+ const parentClass = Object.getPrototypeOf( klass );
1527
+ if ( parentClass && typeof parentClass[method] === 'function' ) {
1528
+ return parentClass[method].apply( klass, argv );
1529
+ }
1530
+ return null;
1531
+ }
1532
+
1533
+ function zuzuSuperDispatch( isStatic, self, klass, methodName, args = [] ) {
1534
+ return isStatic
1535
+ ? zuzuSuperStaticCall( klass, methodName, args )
1536
+ : zuzuSuperCall( self, klass, methodName, args );
1537
+ }
1538
+
1539
+ function refIndex( target, index ) {
1540
+ target = resolveWeakValue( target );
1541
+ return function refValue( maybeValue ) {
1542
+ if ( arguments.length === 0 ) {
1543
+ if ( target instanceof ZuzuBinary ) {
1544
+ return target.at( index );
1545
+ }
1546
+ return resolveWeakValue( target[index] );
1547
+ }
1548
+ if ( target instanceof ZuzuBinary ) {
1549
+ throw new Error( 'Exception: BinaryString index assignment is not supported' );
1550
+ }
1551
+ target[index] = maybeValue;
1552
+ return maybeValue;
1553
+ };
1554
+ }
1555
+
1556
+ function zuzuGetIndex( target, index ) {
1557
+ target = resolveWeakValue( target );
1558
+ if ( target == null ) {
1559
+ return null;
1560
+ }
1561
+ const key = String( index );
1562
+ if ( typeof target === 'function' && target.prototype ) {
1563
+ if ( typeof target.prototype[key] === 'function' ) {
1564
+ return new ZuzuMethod( key, target.prototype[key] );
1565
+ }
1566
+ }
1567
+ if ( target instanceof ZuzuBinary ) {
1568
+ return target.at( index );
1569
+ }
1570
+ if ( isPairListLike( target ) ) {
1571
+ return resolveWeakValue( target.get( index, null ) );
1572
+ }
1573
+ if ( typeof target === 'string' || Array.isArray( target ) ) {
1574
+ let resolved = Number( index );
1575
+ if ( Number.isFinite( resolved ) ) {
1576
+ if ( resolved < 0 ) {
1577
+ resolved = target.length + resolved;
1578
+ }
1579
+ return resolveWeakValue( target[resolved] );
1580
+ }
1581
+ }
1582
+ if (
1583
+ target
1584
+ && typeof target === 'object'
1585
+ && target.constructor
1586
+ && typeof target.constructor.__zuzu_class_name === 'string'
1587
+ && !Object.prototype.hasOwnProperty.call( target, key )
1588
+ && typeof target[key] === 'function'
1589
+ ) {
1590
+ return zuzuBoundMethod( target, key, target[key] );
1591
+ }
1592
+ return resolveWeakValue( target[index] );
1593
+ }
1594
+
1595
+ function zuzuAssignSlice( target, from, length, value ) {
1596
+ const hasLength = length != null;
1597
+ const span = hasLength ? Number( length ) : null;
1598
+ const replacement = value == null ? '' : value;
1599
+ if ( typeof target === 'string' ) {
1600
+ let start = Number( from );
1601
+ if ( start < 0 ) {
1602
+ start = target.length + start;
1603
+ }
1604
+ start = Math.max( 0, Math.min( target.length, start ) );
1605
+ const end = hasLength
1606
+ ? Math.max( 0, Math.min( target.length, span >= 0 ? start + span : target.length + span ) )
1607
+ : target.length;
1608
+ return target.slice( 0, start ) + String( replacement ) + target.slice( end );
1609
+ }
1610
+ const start = Number( from );
1611
+ if ( Array.isArray( target ) ) {
1612
+ const items = Array.isArray( replacement ) ? replacement : [ replacement ];
1613
+ if ( hasLength ) {
1614
+ target.splice( start, span, ...items );
1615
+ }
1616
+ else {
1617
+ target.splice( start, target.length - start, ...items );
1618
+ }
1619
+ return target;
1620
+ }
1621
+ if ( target instanceof ZuzuBinary ) {
1622
+ throw new Error( 'Exception: BinaryString slice assignment is not supported' );
1623
+ }
1624
+ throw new Error( `TypeException: slice assignment expects String or Array, got ${zuzuTypeof( target )}` );
1625
+ }
1626
+
1627
+ function refKey( target, key ) {
1628
+ target = resolveWeakValue( target );
1629
+ return function refValue( maybeValue ) {
1630
+ if ( arguments.length === 0 ) {
1631
+ return resolveWeakValue( target[key] );
1632
+ }
1633
+ target[key] = maybeValue;
1634
+ return maybeValue;
1635
+ };
1636
+ }
1637
+
1638
+ function assignIndexedValue( target, index, value, isWeakWrite = false, assignTarget = null ) {
1639
+ target = resolveWeakValue( target );
1640
+ if ( target == null ) {
1641
+ throw new Error( 'TypeException: cannot assign to null' );
1642
+ }
1643
+ if ( target instanceof ZuzuBinary ) {
1644
+ throw new Error( 'Exception: BinaryString index assignment is not supported' );
1645
+ }
1646
+ if ( typeof target === 'string' ) {
1647
+ let resolved = Number( index );
1648
+ if ( !Number.isFinite( resolved ) ) {
1649
+ throw new Error( 'TypeException: String index assignment expects numeric index' );
1650
+ }
1651
+ if ( resolved < 0 ) {
1652
+ resolved = target.length + resolved;
1653
+ }
1654
+ resolved = Math.max( 0, Math.min( target.length, resolved ) );
1655
+ const updated = target.slice( 0, resolved ) + String( value ?? '' ) + target.slice( resolved + 1 );
1656
+ return typeof assignTarget === 'function' ? assignTarget( updated ) : updated;
1657
+ }
1658
+ if ( isPairListLike( target ) ) {
1659
+ const stored = isWeakWrite ? makeWeakValue( value ) : retainCollectionValue( target, value );
1660
+ target.list.push( [ String( index ), stored ] );
1661
+ return stored;
1662
+ }
1663
+ const stored = isWeakWrite ? makeWeakValue( value ) : retainCollectionValue( target, value );
1664
+ releaseCollectionValue( target, target[index] );
1665
+ target[index] = stored;
1666
+ return stored;
1667
+ }
1668
+
1669
+ function refSlice( target, from, length ) {
1670
+ target = resolveWeakValue( target );
1671
+ return function refSliceValue( maybeValue ) {
1672
+ const start = Number( from );
1673
+ const hasLength = length != null;
1674
+ const span = hasLength ? Number( length ) : null;
1675
+ if ( arguments.length === 0 ) {
1676
+ const end = hasLength
1677
+ ? ( span >= 0 ? start + span : span )
1678
+ : undefined;
1679
+ if ( target instanceof ZuzuBinary ) {
1680
+ return target.slice( start, end );
1681
+ }
1682
+ return target.slice( start, end );
1683
+ }
1684
+ if ( target instanceof ZuzuBinary ) {
1685
+ throw new Error( 'Exception: BinaryString slice assignment is not supported' );
1686
+ }
1687
+ if ( !hasLength ) {
1688
+ target.splice( start, target.length - start, ...maybeValue );
1689
+ return maybeValue;
1690
+ }
1691
+ target.splice( start, span, ...maybeValue );
1692
+ return maybeValue;
1693
+ };
1694
+ }
1695
+
1696
+ function makePathOperator( runtime, filename ) {
1697
+ return function zuzuPathOp( haystack, pathSpec, mode = 'first' ) {
1698
+ const pathObj = resolvePathObject( runtime, filename, pathSpec );
1699
+ if ( mode === 'all' ) {
1700
+ return pathObj.query( haystack );
1701
+ }
1702
+ if ( mode === 'exists' ) {
1703
+ return pathObj.exists( haystack );
1704
+ }
1705
+ return pathObj.first( haystack, null );
1706
+ };
1707
+ }
1708
+
1709
+ function resolveActivePathClass( runtime, filename ) {
1710
+ const internals = runtime.loadModule( 'std/internals', filename );
1711
+ if ( !internals || typeof internals.getupperprop !== 'function' ) {
1712
+ return null;
1713
+ }
1714
+ return internals.getupperprop( 0, 'paths' );
1715
+ }
1716
+
1717
+ function resolvePathObject( runtime, filename, pathSpec ) {
1718
+ let PathClass = resolveActivePathClass( runtime, filename );
1719
+ const pathText = String( pathSpec ?? '' );
1720
+ if ( !PathClass ) {
1721
+ const zzpath = runtime.loadModule( 'std/path/zz', filename );
1722
+ PathClass = zzpath && zzpath.ZZPath ? zzpath.ZZPath : null;
1723
+ }
1724
+ if ( !PathClass ) {
1725
+ throw new Error( 'Exception: no path implementation available' );
1726
+ }
1727
+ return (
1728
+ pathSpec
1729
+ && typeof pathSpec === 'object'
1730
+ && typeof pathSpec.query === 'function'
1731
+ )
1732
+ ? pathSpec
1733
+ : new PathClass( { path: pathText } );
1734
+ }
1735
+
1736
+ function makePathAssignmentOperator( runtime, filename ) {
1737
+ return function zuzuPathAssign(
1738
+ haystack,
1739
+ pathSpec,
1740
+ value,
1741
+ mode = 'first',
1742
+ op = ':=',
1743
+ isWeakWrite = false
1744
+ ) {
1745
+ const pathObj = resolvePathObject( runtime, filename, pathSpec );
1746
+ const storedValue = isWeakWrite ? makeWeakValue( value ) : value;
1747
+ if ( mode === 'all' ) {
1748
+ return pathObj.assign_all( haystack, storedValue, op );
1749
+ }
1750
+ if ( mode === 'maybe' ) {
1751
+ return pathObj.assign_maybe( haystack, storedValue, op );
1752
+ }
1753
+ return pathObj.assign_first( haystack, storedValue, op );
1754
+ };
1755
+ }
1756
+
1757
+ function makePathReferenceOperator( runtime, filename ) {
1758
+ return function zuzuPathRef( haystack, pathSpec, mode = 'first' ) {
1759
+ const pathObj = resolvePathObject( runtime, filename, pathSpec );
1760
+ if ( mode === 'all' ) {
1761
+ return pathObj.ref_all( haystack );
1762
+ }
1763
+ if ( mode === 'maybe' ) {
1764
+ return pathObj.ref_maybe( haystack );
1765
+ }
1766
+ return pathObj.ref_first( haystack );
1767
+ };
1768
+ }
1769
+
1770
+ function callPathRef( refFn ) {
1771
+ if ( typeof refFn !== 'function' ) {
1772
+ throw new Error( 'Exception: path reference target is not assignable' );
1773
+ }
1774
+ return refFn();
1775
+ }
1776
+
1777
+ function setPathRef( refFn, value ) {
1778
+ if ( typeof refFn !== 'function' ) {
1779
+ throw new Error( 'Exception: path reference target is not assignable' );
1780
+ }
1781
+ return refFn( value );
1782
+ }
1783
+
1784
+ function makePathUpdateOperator( runtime, filename ) {
1785
+ return function zuzuPathUpdate( haystack, pathSpec, mode, operator, prefix ) {
1786
+ const pathObj = resolvePathObject( runtime, filename, pathSpec );
1787
+ if ( mode === 'all' ) {
1788
+ const refs = pathObj.ref_all( haystack );
1789
+ const oldValues = [];
1790
+ const newValues = [];
1791
+ for ( const refFn of refs ) {
1792
+ const oldValue = zuzuToNumber( callPathRef( refFn ) );
1793
+ const newValue = operator === '++' ? oldValue + 1 : oldValue - 1;
1794
+ setPathRef( refFn, newValue );
1795
+ oldValues.push( oldValue );
1796
+ newValues.push( newValue );
1797
+ }
1798
+ return prefix ? newValues : oldValues;
1799
+ }
1800
+ if ( mode === 'maybe' ) {
1801
+ const refFn = pathObj.ref_maybe( haystack );
1802
+ if ( refFn == null ) {
1803
+ return false;
1804
+ }
1805
+ const oldValue = zuzuToNumber( callPathRef( refFn ) );
1806
+ const newValue = operator === '++' ? oldValue + 1 : oldValue - 1;
1807
+ setPathRef( refFn, newValue );
1808
+ return true;
1809
+ }
1810
+ const refFn = pathObj.ref_first( haystack );
1811
+ const oldValue = zuzuToNumber( callPathRef( refFn ) );
1812
+ const newValue = operator === '++' ? oldValue + 1 : oldValue - 1;
1813
+ setPathRef( refFn, newValue );
1814
+ return prefix ? newValue : oldValue;
1815
+ };
1816
+ }
1817
+
1818
+ function zuzuTypeMatches( value, typeName ) {
1819
+ value = resolveWeakValue( value );
1820
+ if ( typeName === 'Any' ) {
1821
+ return 1;
1822
+ }
1823
+ if ( value == null ) {
1824
+ return 0;
1825
+ }
1826
+ if (
1827
+ typeName === 'Number'
1828
+ || typeName === 'String'
1829
+ || typeName === 'Array'
1830
+ || typeName === 'Dict'
1831
+ || typeName === 'Set'
1832
+ || typeName === 'Bag'
1833
+ || typeName === 'PairList'
1834
+ || typeName === 'Collection'
1835
+ || typeName === 'Class'
1836
+ || typeName === 'Function'
1837
+ || typeName === 'Object'
1838
+ || typeName === 'Exception'
1839
+ || typeName === 'Regexp'
1840
+ ) {
1841
+ if ( typeName === 'Collection' ) {
1842
+ return (
1843
+ Array.isArray( value )
1844
+ || isSetLike( value )
1845
+ || isBagLike( value )
1846
+ || isPairListLike( value )
1847
+ || zuzuTypeof( value ) === 'Dict'
1848
+ ) ? 1 : 0;
1849
+ }
1850
+ if ( typeName === 'Object' ) {
1851
+ return ( value !== null && typeof value === 'object' ) ? 1 : 0;
1852
+ }
1853
+ if ( typeName === 'PairList' ) {
1854
+ return isPairListLike( value ) ? 1 : 0;
1855
+ }
1856
+ return zuzuTypeof( value ) === typeName ? 1 : 0;
1857
+ }
1858
+ if ( typeName === 'BinaryString' ) {
1859
+ return value instanceof ZuzuBinary ? 1 : 0;
1860
+ }
1861
+ if ( typeName === 'Boolean' ) {
1862
+ if ( typeof value === 'boolean' || Object.prototype.toString.call( value ) === '[object Boolean]' ) {
1863
+ return 1;
1864
+ }
1865
+ if ( typeof value === 'number' ) {
1866
+ return ( value === 0 || value === 1 ) ? 1 : 0;
1867
+ }
1868
+ }
1869
+ if ( typeName === 'Regexp' ) {
1870
+ return Object.prototype.toString.call( value ) === '[object RegExp]' ? 1 : 0;
1871
+ }
1872
+ if ( zuzuTypeof( value ) === typeName ) {
1873
+ return 1;
1874
+ }
1875
+ if (
1876
+ Array.isArray( value.__zuzu_type_names )
1877
+ && value.__zuzu_type_names.includes( typeName )
1878
+ ) {
1879
+ return 1;
1880
+ }
1881
+ let proto = Object.getPrototypeOf( value );
1882
+ while ( proto ) {
1883
+ const ctor = proto.constructor;
1884
+ if ( ctor && ctor.name === typeName ) {
1885
+ return 1;
1886
+ }
1887
+ proto = Object.getPrototypeOf( proto );
1888
+ }
1889
+ const globalType = globalThis[typeName];
1890
+ if ( globalType == null ) {
1891
+ return 0;
1892
+ }
1893
+ return zuzuInstanceof( value, globalType ) ? 1 : 0;
1894
+ }
1895
+
1896
+ class ZuzuScript {
1897
+ constructor( options = {} ) {
1898
+ if ( options.host ) {
1899
+ this.host = options.host;
1900
+ }
1901
+ else {
1902
+ const { createNodeHost } = require( './host/' + 'node-host' );
1903
+ this.host = createNodeHost( options );
1904
+ }
1905
+ this.repoRoot = this.host.repoRoot;
1906
+ this.includePaths = this.host.includePaths;
1907
+ this.moduleSearchRoots = defaultModuleSearchRoots(
1908
+ this.host,
1909
+ this.repoRoot,
1910
+ this.includePaths
1911
+ );
1912
+ const allowCapabilities = new Set( Array.isArray( options.allowCapabilities )
1913
+ ? options.allowCapabilities.map( (item) => String( item ) )
1914
+ : [] );
1915
+ this.denyCapabilities = new Set( Array.isArray( options.denyCapabilities )
1916
+ ? options.denyCapabilities.map( (item) => String( item ) )
1917
+ : [] );
1918
+ for ( const capability of [ 'gui' ] ) {
1919
+ if (
1920
+ !allowCapabilities.has( capability )
1921
+ && !this.host.capabilities.has( capability )
1922
+ ) {
1923
+ this.denyCapabilities.add( capability );
1924
+ }
1925
+ }
1926
+ this.denyModules = new Set( Array.isArray( options.denyModules )
1927
+ ? options.denyModules.map( (item) => String( item ) )
1928
+ : [] );
1929
+ this.debugLevel = Number.isFinite( Number( options.debugLevel ) )
1930
+ ? Number( options.debugLevel )
1931
+ : 0;
1932
+ this.moduleCache = new Map();
1933
+ this.moduleLoading = new Set();
1934
+ this.evalCapabilityOverrides = null;
1935
+ this.outputLines = null;
1936
+ this.stdoutHandler = null;
1937
+ this.stderrHandler = null;
1938
+ this.executionTimeoutMs = Number.isFinite( Number( options.executionTimeoutMs ) )
1939
+ ? Number( options.executionTimeoutMs )
1940
+ : null;
1941
+ this.transpiler = normalizeTranspilerName(
1942
+ options.transpiler || DEFAULT_TRANSPILER
1943
+ );
1944
+ if ( typeof this.host.loadJsModule !== 'function' ) {
1945
+ this.host.loadJsModule = ( filename ) => require( filename );
1946
+ }
1947
+ }
1948
+
1949
+ transpile( source, options = {} ) {
1950
+ return transpile( source, {
1951
+ ...options,
1952
+ transpiler: options.transpiler || this.transpiler,
1953
+ } );
1954
+ }
1955
+
1956
+ getModuleSearchRoots() {
1957
+ return this.moduleSearchRoots.slice();
1958
+ }
1959
+
1960
+ isDeniedByCapability( moduleName ) {
1961
+ const required = capabilitiesForModule( moduleName );
1962
+ for ( const capability of required ) {
1963
+ if ( this.isCapabilityDenied( capability ) ) {
1964
+ return capability;
1965
+ }
1966
+ if ( !this.host.capabilities.has( capability ) ) {
1967
+ return capability;
1968
+ }
1969
+ }
1970
+ return null;
1971
+ }
1972
+
1973
+ isCapabilityDenied( capability ) {
1974
+ if ( this.denyCapabilities.has( capability ) ) {
1975
+ return true;
1976
+ }
1977
+ if ( this.evalCapabilityOverrides ) {
1978
+ const flagName = `deny_${capability}`;
1979
+ if ( this.evalCapabilityOverrides[flagName] ) {
1980
+ return true;
1981
+ }
1982
+ }
1983
+ return false;
1984
+ }
1985
+
1986
+ enforceModulePolicy( moduleName ) {
1987
+ if ( this.denyModules.has( moduleName ) ) {
1988
+ throw new Error( `Denied module: ${moduleName}` );
1989
+ }
1990
+ const capability = this.isDeniedByCapability( moduleName );
1991
+ if ( capability ) {
1992
+ if ( this.denyCapabilities.has( capability ) ) {
1993
+ throw new Error( `Denied capability '${capability}' blocks module '${moduleName}'` );
1994
+ }
1995
+ throw new Error( `Module '${moduleName}' requires unsupported capability '${capability}' on host '${this.host.name}'` );
1996
+ }
1997
+ }
1998
+
1999
+ fileValueForFilename( filename ) {
2000
+ if (
2001
+ this.isCapabilityDenied( 'fs' )
2002
+ || !this.host.capabilities.has( 'fs' )
2003
+ || !filename
2004
+ || String( filename ).startsWith( '<' )
2005
+ || String( filename ).startsWith( '(' )
2006
+ ) {
2007
+ return null;
2008
+ }
2009
+ const { Path } = require( '../modules/std/io.js' );
2010
+ return new Path( filename );
2011
+ }
2012
+
2013
+ resolveModulePath( moduleName, fromFile ) {
2014
+ const fromDir = fromFile ? this.host.dirname( fromFile ) : this.repoRoot;
2015
+ if ( !moduleName.startsWith( '.' ) && !moduleName.startsWith( '/' ) ) {
2016
+ const runtimeSupported = this.host.resolve(
2017
+ this.repoRoot,
2018
+ 'modules',
2019
+ `${moduleName}.js`
2020
+ );
2021
+ if ( this.host.fileExists( runtimeSupported ) ) {
2022
+ return runtimeSupported;
2023
+ }
2024
+ }
2025
+ const candidates = [];
2026
+ if ( moduleName.startsWith( '.' ) || moduleName.startsWith( '/' ) ) {
2027
+ candidates.push( this.host.resolve( fromDir, moduleName ) );
2028
+ }
2029
+ else {
2030
+ for ( const base of this.getModuleSearchRoots() ) {
2031
+ candidates.push( this.host.resolve( base, moduleName ) );
2032
+ }
2033
+ }
2034
+ const withExt = [];
2035
+ for ( const candidate of candidates ) {
2036
+ withExt.push( candidate, `${candidate}.zzs`, `${candidate}.zzm`, `${candidate}.js` );
2037
+ }
2038
+ for ( const candidate of withExt ) {
2039
+ if ( this.host.fileExists( candidate ) ) {
2040
+ return candidate;
2041
+ }
2042
+ }
2043
+ throw new Error( `Unable to resolve module: ${moduleName}` );
2044
+ }
2045
+
2046
+ buildContext( options = {} ) {
2047
+ const filename = options.filename;
2048
+ const runtime = this;
2049
+ taskRuntime.setDebugLevel( this.debugLevel );
2050
+ let context;
2051
+ const capabilityFlags = Object.create( null );
2052
+ for ( const name of this.host.capabilities ) {
2053
+ if ( !this.denyCapabilities.has( name ) ) {
2054
+ capabilityFlags[name] = 1;
2055
+ }
2056
+ }
2057
+ if ( this.evalCapabilityOverrides ) {
2058
+ for ( const [ flagName, denied ] of Object.entries( this.evalCapabilityOverrides ) ) {
2059
+ const capability = flagName.replace( /^deny_/, '' );
2060
+ if ( denied ) {
2061
+ delete capabilityFlags[capability];
2062
+ }
2063
+ else if (
2064
+ this.host.capabilities.has( capability )
2065
+ && !this.denyCapabilities.has( capability )
2066
+ ) {
2067
+ capabilityFlags[capability] = 1;
2068
+ }
2069
+ }
2070
+ }
2071
+ const moduleSearchRoots = this.getModuleSearchRoots();
2072
+ const emit = ( value ) => {
2073
+ const line = String( value );
2074
+ if ( this.outputLines ) {
2075
+ this.outputLines.push( line );
2076
+ }
2077
+ if ( typeof this.stdoutHandler === 'function' ) {
2078
+ this.stdoutHandler( `${line}\n` );
2079
+ }
2080
+ else if ( !this.outputLines ) {
2081
+ this.host.consoleLog( line );
2082
+ }
2083
+ };
2084
+ const emitStderr = ( value ) => {
2085
+ const line = String( value );
2086
+ if ( typeof this.stderrHandler === 'function' ) {
2087
+ this.stderrHandler( `${line}\n` );
2088
+ }
2089
+ else if ( typeof console !== 'undefined' && typeof console.warn === 'function' ) {
2090
+ console.warn( line );
2091
+ }
2092
+ };
2093
+ installHostCollectionMethods();
2094
+ const ZuzuException = class Exception extends Error {
2095
+ constructor( value = '' ) {
2096
+ if ( isPairListLike( value ) ) {
2097
+ super( value.get( 'message', '' ) );
2098
+ this.name = 'Exception';
2099
+ this.file = value.get( 'file', null );
2100
+ this.line = value.get( 'line', null );
2101
+ this.code = value.get( 'code', null );
2102
+ return;
2103
+ }
2104
+ if (
2105
+ value
2106
+ && typeof value === 'object'
2107
+ && !Array.isArray( value )
2108
+ && Object.prototype.hasOwnProperty.call( value, 'message' )
2109
+ ) {
2110
+ super( value.message );
2111
+ this.name = 'Exception';
2112
+ this.file = Object.prototype.hasOwnProperty.call( value, 'file' )
2113
+ ? value.file
2114
+ : null;
2115
+ this.line = Object.prototype.hasOwnProperty.call( value, 'line' )
2116
+ ? value.line
2117
+ : null;
2118
+ this.code = Object.prototype.hasOwnProperty.call( value, 'code' )
2119
+ ? value.code
2120
+ : null;
2121
+ return;
2122
+ }
2123
+ super( value );
2124
+ this.name = 'Exception';
2125
+ this.file = null;
2126
+ this.line = null;
2127
+ this.code = null;
2128
+ }
2129
+
2130
+ to_String() {
2131
+ const name = this.name || this.constructor.name || 'Exception';
2132
+ const message = String( this.message ?? '' );
2133
+ if ( message === name || message.startsWith( `${name}:` ) ) {
2134
+ return message;
2135
+ }
2136
+ return message === '' ? name : `${name}: ${message}`;
2137
+ }
2138
+
2139
+ message() {
2140
+ return String( this.message ?? '' );
2141
+ }
2142
+ };
2143
+ const ZuzuTypeException = class TypeException extends ZuzuException {
2144
+ constructor( value = '' ) {
2145
+ super( value );
2146
+ this.name = 'TypeException';
2147
+ }
2148
+ };
2149
+ const snapshotSpreadArg = ( input ) => {
2150
+ const value = resolveWeakValue( input );
2151
+ if ( Array.isArray( value ) ) {
2152
+ return {
2153
+ type: 'spread_positional',
2154
+ values: value.slice(),
2155
+ };
2156
+ }
2157
+ if ( isPairListLike( value ) ) {
2158
+ return {
2159
+ type: 'spread_named',
2160
+ entries: value.list.map( (pair) => [ pair[0], pair[1] ] ),
2161
+ };
2162
+ }
2163
+ if ( zuzuTypeof( value ) === 'Dict' ) {
2164
+ return {
2165
+ type: 'spread_named',
2166
+ entries: Object.keys( value ).sort().map( (key) => [ key, value[key] ] ),
2167
+ };
2168
+ }
2169
+ throw new ZuzuTypeException(
2170
+ `argument spread expects Array, Dict, or PairList, got ${zuzuTypeof( value )}`
2171
+ );
2172
+ };
2173
+ const unpackDeclarationSource = ( input ) => {
2174
+ const value = resolveWeakValue( input );
2175
+ if ( isPairListLike( value ) || zuzuTypeof( value ) === 'Dict' ) {
2176
+ return value;
2177
+ }
2178
+ throw new ZuzuTypeException(
2179
+ `Declaration unpacking expects Dict or PairList, got ${zuzuTypeof( value )}`
2180
+ );
2181
+ };
2182
+ const unpackDeclarationValue = (
2183
+ source,
2184
+ key,
2185
+ defaultThunk,
2186
+ name,
2187
+ typeName,
2188
+ isWeakStorage
2189
+ ) => {
2190
+ const valueSource = unpackDeclarationSource( source );
2191
+ const normalized = normalizeDictKey( key );
2192
+ let value;
2193
+ let found = false;
2194
+ if ( isPairListLike( valueSource ) ) {
2195
+ const pair = valueSource.list.find(
2196
+ (entry) => entry[0] === normalized
2197
+ );
2198
+ if ( pair ) {
2199
+ value = pair[1];
2200
+ found = true;
2201
+ }
2202
+ }
2203
+ else if ( Object.prototype.hasOwnProperty.call( valueSource, normalized ) ) {
2204
+ value = valueSource[normalized];
2205
+ found = true;
2206
+ }
2207
+ if ( !found ) {
2208
+ value = typeof defaultThunk === 'function' ? defaultThunk() : null;
2209
+ }
2210
+ if ( typeName && typeName !== 'Any' && !zuzuTypeMatches( value, typeName ) ) {
2211
+ throw new ZuzuTypeException(
2212
+ `'${name}' must be ${typeName}, got ${zuzuTypeof( value )}`
2213
+ );
2214
+ }
2215
+ return isWeakStorage ? makeWeakValue( value ) : retainValue( value );
2216
+ };
2217
+ const spreadCallArgs = ( parts ) => {
2218
+ const positional = [];
2219
+ const named = [];
2220
+ for ( const part of parts ) {
2221
+ if ( part.type === 'positional' ) {
2222
+ positional.push( part.value );
2223
+ continue;
2224
+ }
2225
+ if ( part.type === 'named' ) {
2226
+ named.push( part.value );
2227
+ continue;
2228
+ }
2229
+ if ( part.type === 'spread_positional' ) {
2230
+ positional.push( ...part.values );
2231
+ continue;
2232
+ }
2233
+ if ( part.type === 'spread_named' ) {
2234
+ for ( const entry of part.entries ) {
2235
+ named.push( entry );
2236
+ }
2237
+ continue;
2238
+ }
2239
+ throw new ZuzuTypeException( 'invalid call argument descriptor' );
2240
+ }
2241
+ if ( named.length > 0 ) {
2242
+ positional.push( makeTemporaryPairList( named ) );
2243
+ }
2244
+ return positional;
2245
+ };
2246
+ const normalizeZuzuException = ( err ) => {
2247
+ if ( err instanceof ZuzuException ) {
2248
+ return err;
2249
+ }
2250
+ if ( err && err.__zuzu_nonlocal_return ) {
2251
+ return err;
2252
+ }
2253
+ if (
2254
+ err instanceof Error
2255
+ && [
2256
+ 'CancelledException',
2257
+ 'TimeoutException',
2258
+ 'ChannelClosedException',
2259
+ ].includes( err.name )
2260
+ ) {
2261
+ return err;
2262
+ }
2263
+ if ( err && typeof err === 'object' ) {
2264
+ const ctorName = err.constructor && err.constructor.name;
2265
+ if ( !isNativeErrorConstructorName( ctorName ) ) {
2266
+ return err;
2267
+ }
2268
+ }
2269
+ const message = err && err.message != null ? String( err.message ) : String( err );
2270
+ if ( message.startsWith( 'TypeException:' ) ) {
2271
+ return new ZuzuTypeException( {
2272
+ message,
2273
+ file: err && err.file != null ? err.file : null,
2274
+ line: err && err.line != null ? err.line : null,
2275
+ code: err && err.code != null ? err.code : null,
2276
+ } );
2277
+ }
2278
+ return new ZuzuException( {
2279
+ message: message.startsWith( 'Exception: ' )
2280
+ ? message.slice( 'Exception: '.length )
2281
+ : message,
2282
+ file: err && err.file != null ? err.file : null,
2283
+ line: err && err.line != null ? err.line : null,
2284
+ code: err && err.code != null ? err.code : null,
2285
+ } );
2286
+ };
2287
+ const ZuzuExhaustedException = class ExhaustedException extends Error {
2288
+ constructor( message = '' ) {
2289
+ super( message );
2290
+ this.name = 'ExhaustedException';
2291
+ }
2292
+
2293
+ to_String() {
2294
+ const message = String( this.message ?? '' );
2295
+ if ( message === this.name || message.startsWith( `${this.name}:` ) ) {
2296
+ return message;
2297
+ }
2298
+ return message === '' ? this.name : `${this.name}: ${message}`;
2299
+ }
2300
+ };
2301
+ const defineRuntimeMethod = ( proto, name, fn ) => {
2302
+ const desc = Object.create( null );
2303
+ desc.value = fn;
2304
+ desc.enumerable = false;
2305
+ Object.defineProperty( proto, name, desc );
2306
+ };
2307
+ if ( !Number.prototype.contains ) {
2308
+ defineRuntimeMethod( Number.prototype, 'contains', function _containsNumber( value ) {
2309
+ return Number( this.valueOf() ) === Number( value ) ? 1 : 0;
2310
+ } );
2311
+ }
2312
+ if ( !Set.prototype.push ) {
2313
+ defineRuntimeMethod( Set.prototype, 'length', function _lengthSet() { return this.size; } );
2314
+ defineRuntimeMethod( Set.prototype, 'count', function _countSet() { return this.size; } );
2315
+ defineRuntimeMethod( Set.prototype, 'empty', function _emptySet() { return this.size === 0 ? 1 : 0; } );
2316
+ defineRuntimeMethod( Set.prototype, 'is_empty', function _isEmptySet() { return this.empty(); } );
2317
+ defineRuntimeMethod( Set.prototype, 'push', function _pushSet( ...values ) { for ( const v of values ) { addSetValue( this, v ); } return this; } );
2318
+ defineRuntimeMethod( Set.prototype, 'contains', function _containsSet( value ) { return contains( this, value ); } );
2319
+ defineRuntimeMethod( Set.prototype, 'remove', function _removeSet( value ) { const resolved = resolveWeakValue( value ); if ( this.delete( resolved ) ) { releaseCollectionValue( this, resolved ); } return this; } );
2320
+ defineRuntimeMethod( Set.prototype, 'to_Array', function _setToArray() { return makeArray( this ); } );
2321
+ defineRuntimeMethod( Set.prototype, 'to_Bag', function _setToBag() { return makeBag( [ ...this ] ); } );
2322
+ defineRuntimeMethod( Set.prototype, 'copy', function _setCopy() { return makeSet( this ); } );
2323
+ defineRuntimeMethod( Set.prototype, 'union', function _setUnion( other ) { return collectionUnion( this, other ); } );
2324
+ defineRuntimeMethod( Set.prototype, 'intersection', function _setIntersection( other ) { return collectionIntersection( this, other ); } );
2325
+ defineRuntimeMethod( Set.prototype, 'difference', function _setDifference( other ) { return collectionDifference( this, other ); } );
2326
+ defineRuntimeMethod( Set.prototype, 'symmetric_difference', function _setSymmetricDifference( other ) { return collectionDifference( this.union( other ), this.intersection( other ) ); } );
2327
+ defineRuntimeMethod( Set.prototype, 'is_subset', function _setIsSubset( other ) { return collectionSubsetOf( this, other ); } );
2328
+ defineRuntimeMethod( Set.prototype, 'is_superset', function _setIsSuperset( other ) { return collectionSupersetOf( this, other ); } );
2329
+ defineRuntimeMethod( Set.prototype, 'is_disjoint', function _setIsDisjoint( other ) { return this.intersection( other ).size === 0 ? 1 : 0; } );
2330
+ defineRuntimeMethod( Set.prototype, 'equals', function _setEquals( other ) { return collectionEquivalentOf( this, other ); } );
2331
+ defineRuntimeMethod( Set.prototype, 'sort', function _setSort( fn ) { return [ ...this ].sort( fn ); } );
2332
+ defineRuntimeMethod( Set.prototype, 'sortstr', function _setSortstr() { return [ ...this ].sort( (a, b) => String( a ).localeCompare( String( b ) ) ); } );
2333
+ defineRuntimeMethod( Set.prototype, 'sortnum', function _setSortnum() { return [ ...this ].map( (item) => Number( item ) ).sort( (a, b) => a - b ); } );
2334
+ defineRuntimeMethod( Set.prototype, 'map', function _setMap( fn ) { return new Set( [ ...this ].map( fn ) ); } );
2335
+ defineRuntimeMethod( Set.prototype, 'grep', function _setGrep( fn ) { return new Set( [ ...this ].filter( fn ) ); } );
2336
+ defineRuntimeMethod( Set.prototype, 'any', function _setAny( fn ) { return [ ...this ].some( fn ) ? 1 : 0; } );
2337
+ defineRuntimeMethod( Set.prototype, 'all', function _setAll( fn ) { return [ ...this ].every( fn ) ? 1 : 0; } );
2338
+ defineRuntimeMethod( Set.prototype, 'first', function _setFirst( fn ) { for ( const v of this ) { if ( fn( v ) ) { return v; } } return null; } );
2339
+ defineRuntimeMethod( Set.prototype, 'remove_if', function _setRemoveIf( fn ) { for ( const v of [ ...this ] ) { if ( fn( v ) ) { releaseCollectionValue( this, v ); this.delete( v ); } } return this; } );
2340
+ defineRuntimeMethod( Set.prototype, 'for_each_value', function _setForEachValue( fn ) { for ( const v of this ) { fn( v ); } return this; } );
2341
+ }
2342
+ const fallbackDoneTesting = function done_testing( n = null ) {
2343
+ if ( typeof globalThis._LEVEL === 'number' && globalThis._LEVEL > 0 ) {
2344
+ throw new Error( 'Unexpected done_testing() in subtest' );
2345
+ }
2346
+ let seen = 0;
2347
+ if ( Array.isArray( runtime.outputLines ) ) {
2348
+ for ( const line of runtime.outputLines ) {
2349
+ if ( /^ok\b/.test( line ) || /^not ok\b/.test( line ) ) {
2350
+ seen++;
2351
+ }
2352
+ }
2353
+ }
2354
+ if ( n != null && Number( n ) !== Number( seen ) ) {
2355
+ throw new Error( `Expected ${n} tests, but ran ${seen}` );
2356
+ }
2357
+ emit( `1..${seen}` );
2358
+ if ( typeof globalThis._FAILED === 'number' && globalThis._FAILED > 0 ) {
2359
+ throw new Error( `Failed ${globalThis._FAILED} tests` );
2360
+ }
2361
+ return true;
2362
+ };
2363
+ const systemGlobalSeed = {
2364
+ language_version: 0,
2365
+ runtime: 'zuzu-js',
2366
+ runtime_version: 'dev',
2367
+ platform: this.host.name,
2368
+ inc: Object.freeze( moduleSearchRoots.slice() ),
2369
+ deny_fs: capabilityFlags.fs ? false : true,
2370
+ deny_net: capabilityFlags.net ? false : true,
2371
+ deny_perl: true,
2372
+ deny_js: capabilityFlags.js ? false : true,
2373
+ deny_proc: capabilityFlags.proc ? false : true,
2374
+ deny_db: capabilityFlags.db ? false : true,
2375
+ deny_clib: capabilityFlags.clib ? false : true,
2376
+ deny_gui: capabilityFlags.gui ? false : true,
2377
+ deny_worker: capabilityFlags.worker ? false : true,
2378
+ };
2379
+ if ( this.host.name === 'node' && typeof process !== 'undefined' && process.versions ) {
2380
+ systemGlobalSeed.nodejs_version = String( process.versions.node || '' );
2381
+ }
2382
+ Object.freeze( systemGlobalSeed );
2383
+ const currentSystem = () => {
2384
+ const current = {
2385
+ ...systemGlobalSeed,
2386
+ deny_fs: this.isCapabilityDenied( 'fs' ) || !this.host.capabilities.has( 'fs' ),
2387
+ deny_net: this.isCapabilityDenied( 'net' ) || !this.host.capabilities.has( 'net' ),
2388
+ deny_perl: true,
2389
+ deny_js: this.isCapabilityDenied( 'js' ) || !this.host.capabilities.has( 'js' ),
2390
+ deny_proc: this.isCapabilityDenied( 'proc' ) || !this.host.capabilities.has( 'proc' ),
2391
+ deny_db: this.isCapabilityDenied( 'db' ) || !this.host.capabilities.has( 'db' ),
2392
+ deny_clib: this.isCapabilityDenied( 'clib' ) || !this.host.capabilities.has( 'clib' ),
2393
+ deny_gui: this.isCapabilityDenied( 'gui' ) || !this.host.capabilities.has( 'gui' ),
2394
+ deny_worker: this.isCapabilityDenied( 'worker' ) || !this.host.capabilities.has( 'worker' ),
2395
+ };
2396
+ return Object.freeze( current );
2397
+ };
2398
+ context = {
2399
+ ...( options.globals || {} ),
2400
+ __file__: this.fileValueForFilename( filename ),
2401
+ __zuzu_system_seed: systemGlobalSeed,
2402
+ __zuzu_current_system: currentSystem,
2403
+ DEBUG: this.debugLevel,
2404
+ __zuzu_host_capabilities: capabilityFlags,
2405
+ has_capability( name ) {
2406
+ const key = String( name );
2407
+ return capabilityFlags[key] ? 1 : 0;
2408
+ },
2409
+ outputLines: this.outputLines,
2410
+ done_testing: ( options.globals && typeof options.globals.done_testing === 'function' )
2411
+ ? options.globals.done_testing
2412
+ : fallbackDoneTesting,
2413
+ exports: options.exports,
2414
+ module: options.module,
2415
+ console: {
2416
+ log: ( value ) => this.host.consoleLog( value ),
2417
+ warn: ( value ) => emitStderr( value ),
2418
+ error: ( value ) => emitStderr( value ),
2419
+ },
2420
+ Bag: ZuzuBag,
2421
+ PairList,
2422
+ Exception: ZuzuException,
2423
+ TypeException: ZuzuTypeException,
2424
+ ExhaustedException: ZuzuExhaustedException,
2425
+ __zuzu_normalize_exception: normalizeZuzuException,
2426
+ Task: taskRuntime.Task,
2427
+ CancelledException: taskRuntime.CancelledException,
2428
+ TimeoutException: taskRuntime.TimeoutException,
2429
+ ChannelClosedException: taskRuntime.ChannelClosedException,
2430
+ Null: null,
2431
+ Any: function Any() {},
2432
+ Collection: function Collection() {},
2433
+ Class: function Class() {},
2434
+ BinaryString,
2435
+ say( value, ...parts ) {
2436
+ if ( Array.isArray( value ) && Object.prototype.hasOwnProperty.call( value, 'raw' ) ) {
2437
+ let out = '';
2438
+ for ( let i = 0; i < value.length; i++ ) {
2439
+ out += value[i];
2440
+ if ( i < parts.length ) {
2441
+ out += String( parts[i] );
2442
+ }
2443
+ }
2444
+ emit( out );
2445
+ return;
2446
+ }
2447
+ emit( value );
2448
+ },
2449
+ __zuzu_switch: runSwitch,
2450
+ __zuzu_switch_async: runSwitchAsync,
2451
+ __zuzu_match: runMatch,
2452
+ __zuzu_to_regexp: operatorRegexp,
2453
+ __zuzu_regex_replace: regexReplaceValue,
2454
+ __zuzu_contains: contains,
2455
+ __zuzu_union: collectionUnion,
2456
+ __zuzu_intersection: collectionIntersection,
2457
+ __zuzu_difference: collectionDifference,
2458
+ __zuzu_default: defaultOperator,
2459
+ __zuzu_subsetof: collectionSubsetOf,
2460
+ __zuzu_supersetof: collectionSupersetOf,
2461
+ __zuzu_equivalentof: collectionEquivalentOf,
2462
+ __zuzu_array: makeArray,
2463
+ __zuzu_set: makeSet,
2464
+ __zuzu_bag: makeBag,
2465
+ __zuzu_pairlist_literal: makePairList,
2466
+ __zuzu_temp_pairlist: makeTemporaryPairList,
2467
+ __zuzu_snapshot_spread_arg: snapshotSpreadArg,
2468
+ __zuzu_spread_call_args: spreadCallArgs,
2469
+ __zuzu_unpack_source: unpackDeclarationSource,
2470
+ __zuzu_unpack_value: unpackDeclarationValue,
2471
+ __zuzu_release_collection_values: releaseCollectionValues,
2472
+ __zuzu_path_op: makePathOperator( runtime, filename ),
2473
+ __zuzu_path_assign: makePathAssignmentOperator( runtime, filename ),
2474
+ __zuzu_path_ref: makePathReferenceOperator( runtime, filename ),
2475
+ __zuzu_path_update: makePathUpdateOperator( runtime, filename ),
2476
+ __zuzu_call_member: zuzuCallMember,
2477
+ __zuzu_is_weakable_value: isWeakableValue,
2478
+ __zuzu_is_pairlist: isPairListLike,
2479
+ __zuzu_make_weak_value: makeWeakValue,
2480
+ __zuzu_resolve_weak_value: resolveWeakValue,
2481
+ __zuzu_retain_value: retainValue,
2482
+ __zuzu_release_value: releaseValue,
2483
+ __zuzu_retain_collection_value: retainCollectionValue,
2484
+ __zuzu_release_collection_value: releaseCollectionValue,
2485
+ __zuzu_add_set_value: addSetValue,
2486
+ __zuzu_assign_strong: assignStrongValue,
2487
+ __zuzu_assign_weak: assignWeakValue,
2488
+ __zuzu_assign_index: assignIndexedValue,
2489
+ __zuzu_bodyless_function( name ) {
2490
+ let target = null;
2491
+ const fn = function __zuzu_bodyless_function_wrapper( ...args ) {
2492
+ if ( typeof target === 'function' ) {
2493
+ return target.apply( this, args );
2494
+ }
2495
+ throw new Error( `Exception: Function '${name}' has no body` );
2496
+ };
2497
+ Object.defineProperty( fn, '__zuzu_complete_body', {
2498
+ value( completed ) {
2499
+ target = completed;
2500
+ return fn;
2501
+ },
2502
+ enumerable: false,
2503
+ configurable: true,
2504
+ } );
2505
+ return fn;
2506
+ },
2507
+ __zuzu_complete_function( current, completed, meta ) {
2508
+ const value = completed;
2509
+ if ( value && ( typeof value === 'function' || typeof value === 'object' ) ) {
2510
+ Object.defineProperty( value, '__zuzu_marshal_meta', {
2511
+ value: meta || {},
2512
+ enumerable: false,
2513
+ configurable: true,
2514
+ writable: true,
2515
+ } );
2516
+ }
2517
+ if ( current && typeof current.__zuzu_complete_body === 'function' ) {
2518
+ return current.__zuzu_complete_body( value );
2519
+ }
2520
+ throw new Error( 'Exception: function predeclaration target is not bodyless' );
2521
+ },
2522
+ __zuzu_with_marshal_meta( value, meta ) {
2523
+ if ( value && ( typeof value === 'function' || typeof value === 'object' ) ) {
2524
+ Object.defineProperty( value, '__zuzu_marshal_meta', {
2525
+ value: meta || {},
2526
+ enumerable: false,
2527
+ configurable: true,
2528
+ writable: true,
2529
+ } );
2530
+ }
2531
+ return value;
2532
+ },
2533
+ __zuzu_await_value( value ) {
2534
+ return taskRuntime.awaitValue( value );
2535
+ },
2536
+ __zuzu_await_block( value ) {
2537
+ return taskRuntime.awaitBlock( value );
2538
+ },
2539
+ __zuzu_callsite( metadata, fn ) {
2540
+ return taskRuntime.withCallsite(
2541
+ {
2542
+ file: filename,
2543
+ ...( metadata || {} ),
2544
+ },
2545
+ fn,
2546
+ );
2547
+ },
2548
+ __zuzu_task( fn, metadata ) {
2549
+ return taskRuntime.task( fn, {
2550
+ file: filename,
2551
+ ...( metadata || {} ),
2552
+ } );
2553
+ },
2554
+ __zuzu_task_sync( fn, metadata ) {
2555
+ return taskRuntime.taskSync( fn, {
2556
+ file: filename,
2557
+ ...( metadata || {} ),
2558
+ } );
2559
+ },
2560
+ __zuzu_spawn( fn, metadata ) {
2561
+ return taskRuntime.spawn( fn, {
2562
+ file: filename,
2563
+ ...( metadata || {} ),
2564
+ } );
2565
+ },
2566
+ async __zuzu_collection_map_async( collection, fn ) {
2567
+ const out = [];
2568
+ for ( const item of collection || [] ) {
2569
+ out.push( await taskRuntime.awaitValue( fn( item ) ) );
2570
+ }
2571
+ return out;
2572
+ },
2573
+ async __zuzu_collection_grep_async( collection, fn ) {
2574
+ const out = [];
2575
+ for ( const item of collection || [] ) {
2576
+ if ( zuzuTruthy( await taskRuntime.awaitValue( fn( item ) ) ) ) {
2577
+ out.push( item );
2578
+ }
2579
+ }
2580
+ return out;
2581
+ },
2582
+ async __zuzu_collection_reduce_async( collection, fn ) {
2583
+ const items = Array.from( collection || [] );
2584
+ if ( items.length === 0 ) {
2585
+ return null;
2586
+ }
2587
+ let acc = items[0];
2588
+ for ( let i = 1; i < items.length; i++ ) {
2589
+ acc = await taskRuntime.awaitValue( fn( acc, items[i] ) );
2590
+ }
2591
+ return acc;
2592
+ },
2593
+ __zuzu_prepare_eval( source, namedArgs = null ) {
2594
+ if ( typeof source !== 'string' ) {
2595
+ throw new ZuzuTypeException(
2596
+ `TypeException: eval expects String, got ${zuzuTypeof( source )}`
2597
+ );
2598
+ }
2599
+ if ( namedArgs != null && !isPairListLike( namedArgs ) ) {
2600
+ throw new ZuzuTypeException(
2601
+ `TypeException: eval named arguments must be PairList, got ${zuzuTypeof( namedArgs )}`
2602
+ );
2603
+ }
2604
+ let compiled;
2605
+ try {
2606
+ compiled = runtime.transpile( source, { syncEval: true } );
2607
+ }
2608
+ catch ( err ) {
2609
+ const line = err && err.token && err.token.line != null
2610
+ ? err.token.line
2611
+ : 1;
2612
+ throw new ZuzuException( {
2613
+ message: err && err.message
2614
+ ? String( err.message )
2615
+ : String( err ),
2616
+ file: '<std/eval>',
2617
+ line,
2618
+ code: 'E_COMPILE_SYNTAX',
2619
+ } );
2620
+ }
2621
+ if ( namedArgs == null ) {
2622
+ return compiled;
2623
+ }
2624
+ const overrides = Object.create( null );
2625
+ const accepted = new Set( [
2626
+ 'deny_fs',
2627
+ 'deny_net',
2628
+ 'deny_perl',
2629
+ 'deny_js',
2630
+ 'deny_proc',
2631
+ 'deny_db',
2632
+ 'deny_clib',
2633
+ 'deny_gui',
2634
+ 'deny_worker',
2635
+ ] );
2636
+ for ( const optName of namedArgs.keys() ) {
2637
+ if ( !accepted.has( optName ) ) {
2638
+ throw new ZuzuException(
2639
+ `Unknown named argument '${optName}' for eval`
2640
+ );
2641
+ }
2642
+ }
2643
+ for ( const [ optName, flagName ] of [
2644
+ [ 'deny_fs', 'deny_fs' ],
2645
+ [ 'deny_net', 'deny_net' ],
2646
+ [ 'deny_perl', 'deny_perl' ],
2647
+ [ 'deny_js', 'deny_js' ],
2648
+ [ 'deny_proc', 'deny_proc' ],
2649
+ [ 'deny_db', 'deny_db' ],
2650
+ [ 'deny_clib', 'deny_clib' ],
2651
+ [ 'deny_gui', 'deny_gui' ],
2652
+ [ 'deny_worker', 'deny_worker' ],
2653
+ ] ) {
2654
+ if ( namedArgs.has( optName ) && zuzuTruthy( namedArgs.get( optName ) ) ) {
2655
+ overrides[flagName] = true;
2656
+ }
2657
+ }
2658
+ if ( Object.keys( overrides ).length === 0 ) {
2659
+ return compiled;
2660
+ }
2661
+ return [
2662
+ '( () => {',
2663
+ `const __zuzu_eval_prev_caps = __zuzu_push_eval_capability_overrides( ${JSON.stringify( overrides )} );`,
2664
+ 'try {',
2665
+ 'return ( () => {',
2666
+ 'const __system__ = __zuzu_current_system();',
2667
+ `return ${compiled};`,
2668
+ '} )();',
2669
+ '} finally {',
2670
+ '__zuzu_pop_eval_capability_overrides( __zuzu_eval_prev_caps );',
2671
+ '}',
2672
+ '} )()',
2673
+ ].join( '\n' );
2674
+ },
2675
+ __zuzu_prepare_eval_call_args( args ) {
2676
+ let source = '';
2677
+ let namedArgs = null;
2678
+ if ( args.length > 0 ) {
2679
+ if ( isPairListLike( args[args.length - 1] ) ) {
2680
+ namedArgs = args[args.length - 1];
2681
+ if ( args.length > 1 ) {
2682
+ source = args[0];
2683
+ }
2684
+ }
2685
+ else {
2686
+ source = args[0];
2687
+ }
2688
+ }
2689
+ return context.__zuzu_prepare_eval( source, namedArgs );
2690
+ },
2691
+ __zuzu_await_block_sync( value ) {
2692
+ return taskRuntime.awaitBlockSync( value );
2693
+ },
2694
+ __zuzu_iter( value ) {
2695
+ const asIterable = (input) => {
2696
+ const hasMethodHere = ( candidate, name ) => {
2697
+ if ( candidate == null ) {
2698
+ return false;
2699
+ }
2700
+ if ( Object.prototype.hasOwnProperty.call( candidate, name ) ) {
2701
+ return true;
2702
+ }
2703
+ const proto = Object.getPrototypeOf( candidate );
2704
+ if ( !proto ) {
2705
+ return false;
2706
+ }
2707
+ return Object.prototype.hasOwnProperty.call( proto, name );
2708
+ };
2709
+ if ( input == null ) {
2710
+ return [];
2711
+ }
2712
+ if ( typeof input[Symbol.iterator] === 'function' ) {
2713
+ return input;
2714
+ }
2715
+ if ( typeof input === 'function' ) {
2716
+ return {
2717
+ *[Symbol.iterator]() {
2718
+ while ( true ) {
2719
+ try {
2720
+ yield input();
2721
+ }
2722
+ catch ( err ) {
2723
+ if ( isExhaustedIteratorError( err ) ) {
2724
+ return;
2725
+ }
2726
+ throw err;
2727
+ }
2728
+ }
2729
+ },
2730
+ };
2731
+ }
2732
+ if ( input && typeof input.to_Iterator === 'function' && hasMethodHere( input, 'to_Iterator' ) ) {
2733
+ const iterator = input.to_Iterator();
2734
+ if ( typeof iterator === 'function' && input && typeof input === 'object' ) {
2735
+ return asIterable( iterator.bind( input ) );
2736
+ }
2737
+ return asIterable( iterator );
2738
+ }
2739
+ if ( input && typeof input.to_Array === 'function' && hasMethodHere( input, 'to_Array' ) ) {
2740
+ return asIterable( input.to_Array() );
2741
+ }
2742
+ if ( isPlainObjectLike( input ) && typeof input.to_Iterator === 'function' ) {
2743
+ return asIterable( input.to_Iterator() );
2744
+ }
2745
+ if ( isPlainObjectLike( input ) && typeof input.to_Array === 'function' ) {
2746
+ return asIterable( input.to_Array() );
2747
+ }
2748
+ if ( input && typeof input === 'object' ) {
2749
+ return Object.keys( input ).sort();
2750
+ }
2751
+ return [];
2752
+ };
2753
+ return asIterable( value );
2754
+ },
2755
+ __zuzu_length: operatorLength,
2756
+ __zuzu_num( value ) { return zuzuToNumber( value ); },
2757
+ __zuzu_truthy( value ) { return zuzuTruthy( value ); },
2758
+ __zuzu_not( value ) { return zuzuTruthy( value ) ? 0 : 1; },
2759
+ __zuzu_and( left, right ) { return zuzuTruthy( left ) && zuzuTruthy( right ) ? 1 : 0; },
2760
+ __zuzu_or( left, right ) { return zuzuTruthy( left ) || zuzuTruthy( right ) ? 1 : 0; },
2761
+ __zuzu_typeof( value ) { return zuzuTypeof( value ); },
2762
+ __zuzu_instanceof( value, klass ) { return zuzuInstanceof( value, klass ); },
2763
+ __zuzu_trait( name, methods, source = null, captures = {} ) {
2764
+ return zuzuTrait( name, methods, source, captures );
2765
+ },
2766
+ __zuzu_apply_traits( klass, traits ) { return zuzuApplyTraits( klass, traits ); },
2767
+ __zuzu_class_with_traits( klass, traits ) { return zuzuClassWithTraits( klass, traits ); },
2768
+ __zuzu_does( value, trait ) { return zuzuDoes( value, trait ); },
2769
+ __zuzu_can( value, methodName ) { return zuzuCan( value, methodName ); },
2770
+ __zuzu_super_call( self, klass, methodName, args ) { return zuzuSuperCall( self, klass, methodName, args ); },
2771
+ __zuzu_super_static_call( klass, methodName, args ) { return zuzuSuperStaticCall( klass, methodName, args ); },
2772
+ __zuzu_super_dispatch( isStatic, self, klass, methodName, args ) { return zuzuSuperDispatch( isStatic, self, klass, methodName, args ); },
2773
+ __zuzu_type_matches( value, typeName ) { return zuzuTypeMatches( value, typeName ); },
2774
+ __zuzu_require_type( argName, typeName, value ) {
2775
+ if ( !zuzuTypeMatches( value, typeName ) ) {
2776
+ throw new Error( `TypeException: argument '${argName}' must be ${typeName}, got ${zuzuTypeof( value )}` );
2777
+ }
2778
+ return value;
2779
+ },
2780
+ __zuzu_checked_declaration( name, typeName, value ) {
2781
+ if ( typeName !== 'Any' && !zuzuTypeMatches( value, typeName ) ) {
2782
+ throw new Error( `TypeException: '${name}' must be ${typeName}, got ${zuzuTypeof( value )}` );
2783
+ }
2784
+ return value;
2785
+ },
2786
+ __zuzu_checked_return( fnName, typeName, value ) {
2787
+ if ( typeName !== 'Any' && !zuzuTypeMatches( value, typeName ) ) {
2788
+ throw new Error( `TypeException: 'return value of '${fnName}'' must be ${typeName}, got ${zuzuTypeof( value )}` );
2789
+ }
2790
+ return value;
2791
+ },
2792
+ __zuzu_die( value ) {
2793
+ if ( typeof value === 'string' ) {
2794
+ throw new ZuzuException( value );
2795
+ }
2796
+ throw value;
2797
+ },
2798
+ __zuzu_throw( value, line ) {
2799
+ const err = (
2800
+ value instanceof Error
2801
+ || ( value && typeof value === 'object' )
2802
+ )
2803
+ ? value
2804
+ : new ZuzuException( value );
2805
+ if ( err.file == null ) {
2806
+ err.file = filename;
2807
+ }
2808
+ if ( err.line == null ) {
2809
+ err.line = Number( line || 0 );
2810
+ }
2811
+ throw err;
2812
+ },
2813
+ __zuzu_add( left, right ) { return zuzuToNumber( left ) + zuzuToNumber( right ); },
2814
+ __zuzu_concat( left, right ) { return concatValue( left, right ); },
2815
+ __zuzu_binary_literal( value ) { return binaryFromLiteral( value ); },
2816
+ to_binary( value ) { return toBinaryValue( value ); },
2817
+ to_string( value ) { return toStringValue( value ); },
2818
+ is_ascii( value ) {
2819
+ if ( !( value instanceof ZuzuBinary ) ) {
2820
+ throw new Error( `TypeException: expected BinaryString for is_ascii, got ${zuzuTypeof( value )}` );
2821
+ }
2822
+ return value.isAscii();
2823
+ },
2824
+ __zuzu_bit_and( left, right ) { return bitwiseAnd( left, right ); },
2825
+ __zuzu_bit_or( left, right ) { return bitwiseOr( left, right ); },
2826
+ __zuzu_bit_xor( left, right ) { return bitwiseXor( left, right ); },
2827
+ __zuzu_bit_not( value ) { return bitwiseNot( value ); },
2828
+ __zuzu_sub( left, right ) { return zuzuToNumber( left ) - zuzuToNumber( right ); },
2829
+ __zuzu_mul( left, right ) { return zuzuToNumber( left ) * zuzuToNumber( right ); },
2830
+ __zuzu_div( left, right ) { return zuzuToNumber( left ) / zuzuToNumber( right ); },
2831
+ __zuzu_mod( left, right ) { return zuzuToNumber( left ) % zuzuToNumber( right ); },
2832
+ __zuzu_pow( left, right ) { return zuzuToNumber( left ) ** zuzuToNumber( right ); },
2833
+ __zuzu_cmp( left, right ) {
2834
+ const l = zuzuToNumber( left );
2835
+ const r = zuzuToNumber( right );
2836
+ return l < r ? -1 : ( l > r ? 1 : 0 );
2837
+ },
2838
+ __zuzu_eq( left, right ) {
2839
+ if ( arguments.length < 2 ) {
2840
+ return 0;
2841
+ }
2842
+ return zuzuEqual( left, right );
2843
+ },
2844
+ __zuzu_ne( left, right ) {
2845
+ if ( arguments.length < 2 ) {
2846
+ return 0;
2847
+ }
2848
+ return zuzuEqual( left, right ) ? 0 : 1;
2849
+ },
2850
+ __zuzu_str_eq( left, right ) { return stringCompare( left, right ) === 0 ? 1 : 0; },
2851
+ __zuzu_str_ne( left, right ) { return stringCompare( left, right ) !== 0 ? 1 : 0; },
2852
+ __zuzu_str_gt( left, right ) { return stringCompare( left, right ) > 0 ? 1 : 0; },
2853
+ __zuzu_str_ge( left, right ) { return stringCompare( left, right ) >= 0 ? 1 : 0; },
2854
+ __zuzu_str_lt( left, right ) { return stringCompare( left, right ) < 0 ? 1 : 0; },
2855
+ __zuzu_str_le( left, right ) { return stringCompare( left, right ) <= 0 ? 1 : 0; },
2856
+ __zuzu_str_cmp( left, right ) { return stringCompare( left, right ); },
2857
+ __zuzu_str_eqi( left, right ) { return stringCompare( left, right, { insensitive: true } ) === 0 ? 1 : 0; },
2858
+ __zuzu_str_nei( left, right ) { return stringCompare( left, right, { insensitive: true } ) !== 0 ? 1 : 0; },
2859
+ __zuzu_str_gti( left, right ) { return stringCompare( left, right, { insensitive: true } ) > 0 ? 1 : 0; },
2860
+ __zuzu_str_gei( left, right ) { return stringCompare( left, right, { insensitive: true } ) >= 0 ? 1 : 0; },
2861
+ __zuzu_str_lti( left, right ) { return stringCompare( left, right, { insensitive: true } ) < 0 ? 1 : 0; },
2862
+ __zuzu_str_lei( left, right ) { return stringCompare( left, right, { insensitive: true } ) <= 0 ? 1 : 0; },
2863
+ __zuzu_str_cmpi( left, right ) { return stringCompare( left, right, { insensitive: true } ); },
2864
+ __zuzu_warn( ...parts ) {
2865
+ emitStderr( parts.map( (part) => zuzuStringify( part ) ).join( '' ) );
2866
+ },
2867
+ __zuzu_debug( levelThunk, messageThunk ) {
2868
+ const level = typeof levelThunk === 'function' ? levelThunk() : levelThunk;
2869
+ if ( Number( level || 0 ) > runtime.debugLevel ) {
2870
+ return null;
2871
+ }
2872
+ const message = typeof messageThunk === 'function' ? messageThunk() : messageThunk;
2873
+ emitStderr( zuzuStringify( message ?? '' ) );
2874
+ return null;
2875
+ },
2876
+ __zuzu_assert( conditionThunk ) {
2877
+ if ( runtime.debugLevel <= 0 ) {
2878
+ return null;
2879
+ }
2880
+ const condition = typeof conditionThunk === 'function' ? conditionThunk() : conditionThunk;
2881
+ if ( !condition ) {
2882
+ throw new Error( 'Assertion failed' );
2883
+ }
2884
+ return condition;
2885
+ },
2886
+ __zuzu_make_class( name, base ) {
2887
+ const parent = typeof base === 'function' ? base : Object;
2888
+ return {
2889
+ [name]: class extends parent {
2890
+ constructor( ...args ) {
2891
+ if (
2892
+ args.length === 1
2893
+ && args[0]
2894
+ && typeof args[0] === 'object'
2895
+ && !Array.isArray( args[0] )
2896
+ && Object.prototype.hasOwnProperty.call( args[0], 'message' )
2897
+ ) {
2898
+ super( args[0].message );
2899
+ if ( this instanceof Error ) {
2900
+ this.name = name;
2901
+ }
2902
+ return;
2903
+ }
2904
+ super( ...args );
2905
+ if ( this instanceof Error ) {
2906
+ this.name = name;
2907
+ }
2908
+ }
2909
+ },
2910
+ }[name];
2911
+ },
2912
+ __zuzu_define_class( name, base, spec ) {
2913
+ return defineZuzuClass( name, base, spec );
2914
+ },
2915
+ __zuzu_get_member( object, property ) {
2916
+ return zuzuGetMember( object, property );
2917
+ },
2918
+ __zuzu_get_index( object, index ) {
2919
+ return zuzuGetIndex( object, index );
2920
+ },
2921
+ __zuzu_get_brace_member( object, literalProperty, getDynamicProperty ) {
2922
+ return zuzuGetBraceMember( object, literalProperty, getDynamicProperty );
2923
+ },
2924
+ __zuzu_resolve_brace_key( object, literalProperty, getDynamicProperty ) {
2925
+ return zuzuResolveBraceKey( object, literalProperty, getDynamicProperty );
2926
+ },
2927
+ __zuzu_maybe_demolish( value ) {
2928
+ return zuzuMaybeDemolish( value );
2929
+ },
2930
+ __zuzu_xor( left, right ) { return ( zuzuTruthy( left ) !== zuzuTruthy( right ) ) ? 1 : 0; },
2931
+ __zuzu_nand( left, right ) { return ( zuzuTruthy( left ) && zuzuTruthy( right ) ) ? 0 : 1; },
2932
+ __zuzu_num_eq( left, right ) {
2933
+ if ( !isNumericComparable( left ) || !isNumericComparable( right ) ) {
2934
+ return zuzuEqual( left, right );
2935
+ }
2936
+ return numericEqual( left, right ) ? 1 : 0;
2937
+ },
2938
+ __zuzu_num_ne( left, right ) {
2939
+ if ( !isNumericComparable( left ) || !isNumericComparable( right ) ) {
2940
+ return zuzuEqual( left, right ) ? 0 : 1;
2941
+ }
2942
+ return numericEqual( left, right ) ? 0 : 1;
2943
+ },
2944
+ __zuzu_num_lt( left, right ) { return zuzuToNumber( left ) < zuzuToNumber( right ) ? 1 : 0; },
2945
+ __zuzu_num_lte( left, right ) { return zuzuToNumber( left ) <= zuzuToNumber( right ) ? 1 : 0; },
2946
+ __zuzu_num_gt( left, right ) { return zuzuToNumber( left ) > zuzuToNumber( right ) ? 1 : 0; },
2947
+ __zuzu_num_gte( left, right ) { return zuzuToNumber( left ) >= zuzuToNumber( right ) ? 1 : 0; },
2948
+ __zuzu_abs( value ) { return Math.abs( zuzuToNumber( value ) ); },
2949
+ __zuzu_sqrt( value ) { return Math.sqrt( zuzuToNumber( value ) ); },
2950
+ __zuzu_floor( value ) { return Math.floor( zuzuToNumber( value ) ); },
2951
+ __zuzu_ceil( value ) { return Math.ceil( zuzuToNumber( value ) ); },
2952
+ __zuzu_round( value ) {
2953
+ const n = zuzuToNumber( value );
2954
+ return n >= 0 ? Math.floor( n + 0.5 ) : Math.ceil( n - 0.5 );
2955
+ },
2956
+ __zuzu_int( value ) {
2957
+ const n = zuzuToNumber( value );
2958
+ return n < 0 ? Math.ceil( n ) : Math.floor( n );
2959
+ },
2960
+ __zuzu_uc( value ) {
2961
+ if ( value instanceof ZuzuBinary ) {
2962
+ throw new Error( 'TypeException: uc expects String, got BinaryString' );
2963
+ }
2964
+ return zuzuOperatorString( value ).toUpperCase();
2965
+ },
2966
+ __zuzu_lc( value ) {
2967
+ if ( value instanceof ZuzuBinary ) {
2968
+ throw new Error( 'TypeException: lc expects String, got BinaryString' );
2969
+ }
2970
+ return zuzuOperatorString( value ).toLowerCase();
2971
+ },
2972
+ __zuzu_range( start, end ) {
2973
+ const from = zuzuToNumber( start );
2974
+ const to = zuzuToNumber( end );
2975
+ const out = [];
2976
+ const step = from <= to ? 1 : -1;
2977
+ for ( let n = from; step > 0 ? n <= to : n >= to; n += step ) {
2978
+ out.push( n );
2979
+ }
2980
+ return out;
2981
+ },
2982
+ __zuzu_ref_index( target, index ) { return refIndex( target, index ); },
2983
+ __zuzu_ref_key( target, key ) { return refKey( target, key ); },
2984
+ __zuzu_ref_slice( target, from, length ) { return refSlice( target, from, length ); },
2985
+ __zuzu_assign_slice( target, from, length, value ) { return zuzuAssignSlice( target, from, length, value ); },
2986
+ Pair,
2987
+ };
2988
+ if ( this.host.name === 'browser' ) {
2989
+ context.Object = createObjectFacade();
2990
+ }
2991
+ context.__zuzu_push_eval_capability_overrides = (overrides = {}) => {
2992
+ const previous = this.evalCapabilityOverrides;
2993
+ const next = { ...( previous || {} ) };
2994
+ for ( const [ key, value ] of Object.entries( overrides || {} ) ) {
2995
+ if ( value ) {
2996
+ next[key] = true;
2997
+ }
2998
+ }
2999
+ this.evalCapabilityOverrides = Object.keys( next ).length > 0 ? next : null;
3000
+ return previous;
3001
+ };
3002
+ context.__zuzu_pop_eval_capability_overrides = (previous) => {
3003
+ this.evalCapabilityOverrides = previous || null;
3004
+ };
3005
+ context.__zuzu_import = (name) => {
3006
+ if ( name === 'std/eval' ) {
3007
+ return { eval: context.__zuzu_native_eval };
3008
+ }
3009
+ return this.loadModule( name, filename, context );
3010
+ };
3011
+ return context;
3012
+ }
3013
+
3014
+ installCollectionMethods( context ) {
3015
+ const bootstrap = `
3016
+ (function () {
3017
+ globalThis.__zuzu_native_eval = eval;
3018
+ globalThis.__zuzu_builtin_Array = Array;
3019
+ globalThis.__zuzu_builtin_Function = Function;
3020
+ globalThis.__zuzu_builtin_Object = Object;
3021
+ globalThis.__zuzu_builtin_RegExp = RegExp;
3022
+ globalThis.__zuzu_builtin_Set = Set;
3023
+ globalThis.Dict = function Dict( value ) {
3024
+ if ( value && typeof value === 'object' && !Array.isArray( value ) ) {
3025
+ return Object.assign( {}, value );
3026
+ }
3027
+ return {};
3028
+ };
3029
+ if ( !globalThis.__zuzu_define_property_patched ) {
3030
+ const __zuzu_native_define_property = Object.defineProperty;
3031
+ const __zuzu_native_define_properties = Object.defineProperties;
3032
+ const __zuzu_safe_descriptor = function ( descriptor ) {
3033
+ if ( !descriptor || typeof descriptor !== 'object' ) {
3034
+ return descriptor;
3035
+ }
3036
+ const safe = Object.create( null );
3037
+ for ( const key of [ 'value', 'get', 'set', 'writable', 'enumerable', 'configurable' ] ) {
3038
+ if ( Object.prototype.hasOwnProperty.call( descriptor, key ) ) {
3039
+ safe[key] = descriptor[key];
3040
+ }
3041
+ }
3042
+ return safe;
3043
+ };
3044
+ Object.defineProperty = function __zuzu_define_property( obj, prop, descriptor ) {
3045
+ return __zuzu_native_define_property(
3046
+ obj,
3047
+ prop,
3048
+ __zuzu_safe_descriptor( descriptor )
3049
+ );
3050
+ };
3051
+ Object.defineProperties = function __zuzu_define_properties( obj, descriptors ) {
3052
+ const safeDescriptors = Object.create( null );
3053
+ for ( const key of Object.keys( descriptors || {} ) ) {
3054
+ safeDescriptors[key] = __zuzu_safe_descriptor( descriptors[key] );
3055
+ }
3056
+ return __zuzu_native_define_properties( obj, safeDescriptors );
3057
+ };
3058
+ globalThis.__zuzu_define_property_patched = true;
3059
+ }
3060
+ const __zuzu_seed = globalThis.__zuzu_system_seed || Object.create( null );
3061
+ const __zuzu_system_desc = Object.create( null );
3062
+ __zuzu_system_desc.get = function __zuzu_get_system() {
3063
+ if ( typeof globalThis.__zuzu_current_system === 'function' ) {
3064
+ return globalThis.__zuzu_current_system();
3065
+ }
3066
+ return Object.freeze( Object.assign( {}, __zuzu_seed ) );
3067
+ };
3068
+ __zuzu_system_desc.enumerable = true;
3069
+ __zuzu_system_desc.configurable = true;
3070
+ Object.defineProperty(
3071
+ globalThis,
3072
+ '__system__',
3073
+ __zuzu_system_desc
3074
+ );
3075
+ delete globalThis.__zuzu_system_seed;
3076
+ const define = ( proto, name, fn ) => {
3077
+ if ( !Object.prototype.hasOwnProperty.call( proto, name ) ) {
3078
+ const desc = Object.create( null );
3079
+ desc.value = fn;
3080
+ desc.enumerable = false;
3081
+ desc.configurable = true;
3082
+ desc.writable = true;
3083
+ Object.defineProperty( proto, name, desc );
3084
+ }
3085
+ };
3086
+ define( Array.prototype, 'length', function _length() { return this.length; } );
3087
+ define( Array.prototype, 'count', function _count() { return this.length; } );
3088
+ define( Array.prototype, 'empty', function _empty() { return this.length === 0 ? 1 : 0; } );
3089
+ define( Array.prototype, 'is_empty', function _is_empty() { return this.empty(); } );
3090
+ define( Array.prototype, 'append', function _append( ...values ) { this.push( ...values.map( ( value ) => __zuzu_retain_collection_value( this, value ) ) ); return this; } );
3091
+ define( Array.prototype, 'add', function _add( ...values ) { this.push( ...values.map( ( value ) => __zuzu_retain_collection_value( this, value ) ) ); return this; } );
3092
+ define( Array.prototype, 'prepend', function _prepend( ...values ) { this.unshift( ...values.map( ( value ) => __zuzu_retain_collection_value( this, value ) ) ); return this; } );
3093
+ define( Array.prototype, 'push_weak', function _push_weak( ...values ) { this.push( ...values.map( __zuzu_make_weak_value ) ); return this; } );
3094
+ define( Array.prototype, 'unshift_weak', function _unshift_weak( ...values ) { this.unshift( ...values.map( __zuzu_make_weak_value ) ); return this; } );
3095
+ define( Array.prototype, 'get', function _get( idx, fallback = null ) { return idx >= 0 && idx < this.length ? this[idx] : fallback; } );
3096
+ define( Array.prototype, 'set', function _set( idx, value ) { __zuzu_release_collection_value( this, this[idx] ); this[idx] = __zuzu_retain_collection_value( this, value ); return this; } );
3097
+ define( Array.prototype, 'set_weak', function _set_weak( idx, value ) { __zuzu_release_collection_value( this, this[idx] ); this[idx] = __zuzu_make_weak_value( value ); return this; } );
3098
+ define( Array.prototype, 'grep', function _grep( fn ) { return this.filter( fn ); } );
3099
+ define( Array.prototype, 'any', function _any( fn ) { return this.some( fn ) ? 1 : 0; } );
3100
+ define( Array.prototype, 'all', function _all( fn ) { return this.every( fn ) ? 1 : 0; } );
3101
+ define( Array.prototype, 'first', function _first( fn ) { return this.find( fn ) ?? null; } );
3102
+ define( Array.prototype, 'remove', function _remove( fn ) { for ( let i = this.length - 1; i >= 0; i-- ) { if ( fn( this[i] ) ) { __zuzu_release_collection_value( this, this[i] ); this.splice( i, 1 ); } } return this; } );
3103
+ define( Array.prototype, 'contains', function _contains( value ) { return this.includes( value ) ? 1 : 0; } );
3104
+ define( Array.prototype, 'first_index', function _first_index( fn ) { return this.findIndex( fn ); } );
3105
+ define( Array.prototype, 'reductions', function _reductions( fn ) { const out = []; for ( const item of this ) { out.push( out.length === 0 ? item : fn( out[out.length - 1], item ) ); } return out; } );
3106
+ define( Array.prototype, 'head', function _head( n ) { return this.slice( 0, n ); } );
3107
+ define( Array.prototype, 'tail', function _tail( n ) { return this.slice( n - 1 ); } );
3108
+ define( Array.prototype, 'sum', function _sum() { return this.reduce( (a, b) => Number( a ) + Number( b ), 0 ); } );
3109
+ define( Array.prototype, 'product', function _product() { return this.reduce( (a, b) => Number( a ) * Number( b ), 1 ); } );
3110
+ define( Array.prototype, 'shuffle', function _shuffle() { return this.slice(); } );
3111
+ define( Array.prototype, 'sample', function _sample( n ) { return this.slice( 0, n ); } );
3112
+ define( Array.prototype, 'for_each_value', function _for_each_value( fn ) { this.forEach( fn ); return this; } );
3113
+ define( Array.prototype, 'sortstr', function _sortstr() { return this.slice().sort( (a, b) => String( a ).localeCompare( String( b ) ) ); } );
3114
+ define( Array.prototype, 'sortnum', function _sortnum() { return this.map( (item) => Number( item ) ).sort( (a, b) => a - b ); } );
3115
+ define( Array.prototype, 'to_Array', function _to_array() { return __zuzu_array( this ); } );
3116
+ define( Array.prototype, 'to_Set', function _to_set() { return __zuzu_set( this ); } );
3117
+ define( Array.prototype, 'to_Bag', function _to_bag() { return new Bag( this ); } );
3118
+ define( Array.prototype, 'to_Iterator', function _to_iterator() { return this[Symbol.iterator](); } );
3119
+ define( Array.prototype, 'copy', function _copy() { return __zuzu_array( this ); } );
3120
+ define( Array.prototype, 'clear', function _clear() { __zuzu_release_collection_values( this ); this.splice( 0, this.length ); return this; } );
3121
+
3122
+ define( Set.prototype, 'length', function _length() { return this.size; } );
3123
+ define( Set.prototype, 'count', function _count() { return this.size; } );
3124
+ define( Set.prototype, 'empty', function _empty() { return this.size === 0 ? 1 : 0; } );
3125
+ define( Set.prototype, 'is_empty', function _is_empty() { return this.empty(); } );
3126
+ define( Set.prototype, 'push', function _push( ...values ) { for ( const v of values ) { __zuzu_add_set_value( this, v ); } return this; } );
3127
+ define( Set.prototype, 'add_weak', function _add_weak( value ) { this.add( __zuzu_make_weak_value( value ) ); return this; } );
3128
+ define( Set.prototype, 'contains', function _contains( value ) { return __zuzu_contains( this, value ); } );
3129
+ define( Set.prototype, 'remove', function _remove( value ) { const resolved = __zuzu_resolve_weak_value( value ); if ( this.delete( resolved ) ) { __zuzu_release_collection_value( this, resolved ); } return this; } );
3130
+ define( Set.prototype, 'to_Array', function _to_array() { return __zuzu_array( this ); } );
3131
+ define( Set.prototype, 'to_Bag', function _to_bag() { return __zuzu_bag( [ ...this ] ); } );
3132
+ define( Set.prototype, 'to_Iterator', function _to_iterator() { return this.values(); } );
3133
+ define( Set.prototype, 'copy', function _copy() { return __zuzu_set( this ); } );
3134
+ define( Set.prototype, 'union', function _union( other ) { return __zuzu_union( this, other ); } );
3135
+ define( Set.prototype, 'intersection', function _intersection( other ) { return __zuzu_intersection( this, other ); } );
3136
+ define( Set.prototype, 'difference', function _difference( other ) { return __zuzu_difference( this, other ); } );
3137
+ define( Set.prototype, 'symmetric_difference', function _symmetric_difference( other ) { return __zuzu_difference( this.union( other ), this.intersection( other ) ); } );
3138
+ define( Set.prototype, 'is_subset', function _is_subset( other ) { return __zuzu_subsetof( this, other ); } );
3139
+ define( Set.prototype, 'is_superset', function _is_superset( other ) { return __zuzu_supersetof( this, other ); } );
3140
+ define( Set.prototype, 'is_disjoint', function _is_disjoint( other ) { return this.intersection( other ).size === 0 ? 1 : 0; } );
3141
+ define( Set.prototype, 'equals', function _equals( other ) { return __zuzu_equivalentof( this, other ); } );
3142
+ define( Set.prototype, 'sort', function _sort( fn ) { return [ ...this ].sort( fn ); } );
3143
+ define( Set.prototype, 'sortstr', function _sortstr() { return [ ...this ].sort( (a, b) => String( a ).localeCompare( String( b ) ) ); } );
3144
+ define( Set.prototype, 'sortnum', function _sortnum() { return [ ...this ].map( (item) => Number( item ) ).sort( (a, b) => a - b ); } );
3145
+ define( Set.prototype, 'map', function _map( fn ) { return new Set( [ ...this ].map( fn ) ); } );
3146
+ define( Set.prototype, 'grep', function _grep( fn ) { return new Set( [ ...this ].filter( fn ) ); } );
3147
+ define( Set.prototype, 'any', function _any( fn ) { return [ ...this ].some( fn ) ? 1 : 0; } );
3148
+ define( Set.prototype, 'all', function _all( fn ) { return [ ...this ].every( fn ) ? 1 : 0; } );
3149
+ define( Set.prototype, 'first', function _first( fn ) { for ( const v of this ) { if ( fn( v ) ) { return v; } } return null; } );
3150
+ define( Set.prototype, 'remove_if', function _remove_if( fn ) { for ( const v of [ ...this ] ) { if ( fn( v ) ) { __zuzu_release_collection_value( this, v ); this.delete( v ); } } return this; } );
3151
+ define( Set.prototype, 'for_each_value', function _for_each_value( fn ) { for ( const v of this ) { fn( v ); } return this; } );
3152
+ const clearSet = Set.prototype.clear;
3153
+ define( Set.prototype, 'clear', function _clear() { __zuzu_release_collection_values( this ); clearSet.call( this ); return this; } );
3154
+ define( RegExp.prototype, 'to_String', function _to_string() { return this.source; } );
3155
+ if ( !Object.prototype.hasOwnProperty.call( RegExp.prototype, Symbol.toPrimitive ) ) {
3156
+ const regDesc = Object.create( null );
3157
+ regDesc.value = function _regexp_to_primitive( hint ) {
3158
+ if ( hint === 'string' || hint === 'default' ) {
3159
+ return this.to_String();
3160
+ }
3161
+ return NaN;
3162
+ };
3163
+ regDesc.enumerable = false;
3164
+ regDesc.configurable = true;
3165
+ regDesc.writable = true;
3166
+ Object.defineProperty( RegExp.prototype, Symbol.toPrimitive, regDesc );
3167
+ }
3168
+ if ( !Object.prototype.hasOwnProperty.call( Object.prototype, Symbol.toPrimitive ) ) {
3169
+ const objectDesc = Object.create( null );
3170
+ objectDesc.value = function _object_to_primitive( hint ) {
3171
+ if ( ( hint === 'string' || hint === 'default' ) && typeof this.to_String === 'function' ) {
3172
+ return this.to_String();
3173
+ }
3174
+ const methods = hint === 'number'
3175
+ ? [ 'valueOf', 'toString' ]
3176
+ : [ 'toString', 'valueOf' ];
3177
+ for ( const methodName of methods ) {
3178
+ const method = this[methodName];
3179
+ if ( typeof method !== 'function' ) {
3180
+ continue;
3181
+ }
3182
+ if ( methodName === 'toString' && method === Object.prototype.toString ) {
3183
+ continue;
3184
+ }
3185
+ if ( methodName === 'valueOf' && method === Object.prototype.valueOf ) {
3186
+ continue;
3187
+ }
3188
+ const value = method.call( this );
3189
+ if ( value == null || typeof value !== 'object' ) {
3190
+ return value;
3191
+ }
3192
+ }
3193
+ return Object.prototype.toString.call( this );
3194
+ };
3195
+ objectDesc.enumerable = false;
3196
+ objectDesc.configurable = true;
3197
+ objectDesc.writable = true;
3198
+ Object.defineProperty( Object.prototype, Symbol.toPrimitive, objectDesc );
3199
+ }
3200
+
3201
+ })();
3202
+ `;
3203
+ const bootstrapRunOptions = {};
3204
+ if ( this.executionTimeoutMs != null ) {
3205
+ bootstrapRunOptions.timeout = this.executionTimeoutMs;
3206
+ }
3207
+ this.host.runInContext( bootstrap, context, bootstrapRunOptions );
3208
+ }
3209
+
3210
+ loadModule( moduleName, fromFile, contextForPolicy = null ) {
3211
+ if ( /(^|\/)\.\.(\/|$)/.test( moduleName ) ) {
3212
+ throw new Error( "Import module path cannot contain '..' segments" );
3213
+ }
3214
+ this.enforceModulePolicy( moduleName );
3215
+ const resolved = this.resolveModulePath( moduleName, fromFile );
3216
+ const cacheable = moduleName !== 'test/more'
3217
+ && this.evalCapabilityOverrides == null;
3218
+ if ( cacheable && this.moduleCache.has( resolved ) ) {
3219
+ return this.moduleCache.get( resolved );
3220
+ }
3221
+ if ( this.moduleLoading.has( resolved ) ) {
3222
+ throw new Error( 'Circular module loading detected' );
3223
+ }
3224
+ if ( resolved.endsWith( '.js' ) ) {
3225
+ const hiddenObjectPrototypeMethods = [];
3226
+ for ( const name of [ 'get', 'set' ] ) {
3227
+ const desc = Object.prototype.hasOwnProperty.call( Object.prototype, name )
3228
+ ? Object.getOwnPropertyDescriptor( Object.prototype, name )
3229
+ : null;
3230
+ if ( desc && desc.configurable ) {
3231
+ hiddenObjectPrototypeMethods.push( [ name, desc ] );
3232
+ delete Object.prototype[name];
3233
+ }
3234
+ }
3235
+ let loaded;
3236
+ try {
3237
+ loaded = this.host.loadJsModule( resolved, moduleName, fromFile );
3238
+ }
3239
+ finally {
3240
+ for ( const [ name, desc ] of hiddenObjectPrototypeMethods ) {
3241
+ Object.defineProperty( Object.prototype, name, desc );
3242
+ }
3243
+ }
3244
+ if (
3245
+ loaded
3246
+ && typeof loaded.__zuzu_set_runtime_policy === 'function'
3247
+ ) {
3248
+ const policy = {
3249
+ gui: this.host.gui || null,
3250
+ host_name: this.host.name,
3251
+ repo_root: this.repoRoot,
3252
+ include_paths: this.includePaths.slice(),
3253
+ deny_modules: [ ...this.denyModules ],
3254
+ debug_level: this.debugLevel,
3255
+ transpiler: this.transpiler,
3256
+ load_module: ( name, requestFromFile = fromFile ) => this.loadModule(
3257
+ name,
3258
+ requestFromFile || fromFile,
3259
+ contextForPolicy
3260
+ ),
3261
+ builtin_class: ( name ) => {
3262
+ if ( !contextForPolicy ) {
3263
+ return null;
3264
+ }
3265
+ const builtins = {
3266
+ Array: contextForPolicy.__zuzu_builtin_Array,
3267
+ Bag: contextForPolicy.Bag,
3268
+ Class: contextForPolicy.Class,
3269
+ Dict: contextForPolicy.Dict || contextForPolicy.__zuzu_builtin_Object,
3270
+ Function: contextForPolicy.__zuzu_builtin_Function,
3271
+ Object: contextForPolicy.__zuzu_builtin_Object,
3272
+ Pair: contextForPolicy.Pair,
3273
+ PairList: contextForPolicy.PairList,
3274
+ Regexp: contextForPolicy.__zuzu_builtin_RegExp,
3275
+ Set: contextForPolicy.__zuzu_builtin_Set,
3276
+ };
3277
+ return builtins[name] || null;
3278
+ },
3279
+ to_String: ( value ) => zuzuOperatorString( value ),
3280
+ to_Number: ( value ) => zuzuToNumber( value ),
3281
+ to_Boolean: ( value ) => zuzuTruthy( value ),
3282
+ to_Regexp: ( value ) => operatorRegexp( value ),
3283
+ to_Regexp_with_flags: ( value, flags ) => {
3284
+ const pattern = value instanceof RegExp
3285
+ ? value.source
3286
+ : zuzuOperatorString( value );
3287
+ return new RegExp( pattern, zuzuOperatorString( flags ) );
3288
+ },
3289
+ stdout_write: ( text ) => {
3290
+ if ( typeof this.stdoutHandler === 'function' ) {
3291
+ this.stdoutHandler( String( text ) );
3292
+ }
3293
+ else if ( typeof process !== 'undefined' && process.stdout ) {
3294
+ process.stdout.write( String( text ) );
3295
+ }
3296
+ else {
3297
+ this.host.consoleLog( String( text ) );
3298
+ }
3299
+ },
3300
+ stderr_write: ( text ) => {
3301
+ if ( typeof this.stderrHandler === 'function' ) {
3302
+ this.stderrHandler( String( text ) );
3303
+ }
3304
+ else if ( typeof process !== 'undefined' && process.stderr ) {
3305
+ process.stderr.write( String( text ) );
3306
+ }
3307
+ else if ( typeof console !== 'undefined' && typeof console.warn === 'function' ) {
3308
+ console.warn( String( text ) );
3309
+ }
3310
+ },
3311
+ browser_worker_source: this.host.workerSource || null,
3312
+ browser_worker_url: this.host.workerUrl || null,
3313
+ browser_worker_factory: this.host.workerFactory || null,
3314
+ };
3315
+ for ( const capability of [
3316
+ 'fs',
3317
+ 'net',
3318
+ 'perl',
3319
+ 'js',
3320
+ 'proc',
3321
+ 'db',
3322
+ 'clib',
3323
+ 'gui',
3324
+ 'worker',
3325
+ ] ) {
3326
+ policy[`deny_${capability}`] =
3327
+ this.isCapabilityDenied( capability )
3328
+ || !this.host.capabilities.has( capability );
3329
+ }
3330
+ loaded.__zuzu_set_runtime_policy( policy );
3331
+ }
3332
+ if ( cacheable ) {
3333
+ this.moduleCache.set( resolved, loaded );
3334
+ }
3335
+ return loaded;
3336
+ }
3337
+ const source = this.host.readFileText( resolved );
3338
+ let js = this.transpile( source );
3339
+ setCompiledSource( resolved, js );
3340
+ const exportNames = resolved.endsWith( '.zzm' )
3341
+ ? collectTopLevelDeclarations( source, stripPod )
3342
+ : [];
3343
+ if ( exportNames.length > 0 ) {
3344
+ const exportBridge = exportNames
3345
+ .map( (name) => {
3346
+ if ( name.startsWith( '_' ) ) {
3347
+ return `if ( typeof ${name} !== "undefined" ) { const __zuzu_desc = Object.create( null ); __zuzu_desc.get = function() { return ${name}; }; __zuzu_desc.set = function( value ) { ${name} = value; }; __zuzu_desc.enumerable = false; __zuzu_desc.configurable = true; Object.defineProperty( module.exports, ${JSON.stringify( name )}, __zuzu_desc ); }`;
3348
+ }
3349
+ return `if ( typeof ${name} !== "undefined" ) { const __zuzu_desc = Object.create( null ); __zuzu_desc.get = function() { return ${name}; }; __zuzu_desc.set = function( value ) { ${name} = value; }; __zuzu_desc.enumerable = true; __zuzu_desc.configurable = true; Object.defineProperty( module.exports, ${JSON.stringify( name )}, __zuzu_desc ); }`;
3350
+ } )
3351
+ .join( '\n' );
3352
+ js += `\n${exportBridge}\n`;
3353
+ }
3354
+ const moduleObj = { exports: {} };
3355
+ const context = this.buildContext( {
3356
+ exports: moduleObj.exports,
3357
+ module: moduleObj,
3358
+ filename: resolved,
3359
+ } );
3360
+ context.__global__ = Object.create( null );
3361
+ this.installCollectionMethods( context );
3362
+ const moduleRunOptions = { filename: resolved };
3363
+ if ( this.executionTimeoutMs != null ) {
3364
+ moduleRunOptions.timeout = this.executionTimeoutMs;
3365
+ }
3366
+ this.moduleLoading.add( resolved );
3367
+ try {
3368
+ this.host.runInContext( js, context, moduleRunOptions );
3369
+ if ( cacheable ) {
3370
+ this.moduleCache.set( resolved, moduleObj.exports );
3371
+ }
3372
+ }
3373
+ finally {
3374
+ this.moduleLoading.delete( resolved );
3375
+ }
3376
+ return moduleObj.exports;
3377
+ }
3378
+
3379
+ runSource( source, options = {} ) {
3380
+ const filename = options.filename || this.host.join( this.repoRoot, '<inline>.zzs' );
3381
+ let js;
3382
+ try {
3383
+ js = this.transpile( source );
3384
+ }
3385
+ catch ( err ) {
3386
+ const stderr = formatRuntimeError( err );
3387
+ if ( typeof options.onStderr === 'function' ) {
3388
+ options.onStderr( stderr );
3389
+ }
3390
+ return {
3391
+ status: 3,
3392
+ stdout: '',
3393
+ stderr,
3394
+ };
3395
+ }
3396
+ return this.runCompiled( js, options );
3397
+ }
3398
+
3399
+ runCompiled( js, options = {} ) {
3400
+ const filename = options.filename || this.host.join( this.repoRoot, '<inline>.zzs' );
3401
+ taskRuntime.resetForRun( this.debugLevel );
3402
+ setCompiledSource( filename, js );
3403
+ const preloadGlobals = Object.create( null );
3404
+ if ( Array.isArray( options.preloadModules ) ) {
3405
+ for ( const moduleName of options.preloadModules ) {
3406
+ Object.assign( preloadGlobals, this.loadModule( moduleName, filename ) );
3407
+ }
3408
+ }
3409
+ this.outputLines = [];
3410
+ const previousStdoutHandler = this.stdoutHandler;
3411
+ const previousStderrHandler = this.stderrHandler;
3412
+ this.stdoutHandler = typeof options.onStdout === 'function'
3413
+ ? options.onStdout
3414
+ : null;
3415
+ this.stderrHandler = typeof options.onStderr === 'function'
3416
+ ? options.onStderr
3417
+ : null;
3418
+ const context = this.buildContext( {
3419
+ filename,
3420
+ globals: preloadGlobals,
3421
+ } );
3422
+ context.__global__ = Object.create( null );
3423
+ this.installCollectionMethods( context );
3424
+ const finishRun = () => {
3425
+ let topLevelTests = 0;
3426
+ let hasTopLevelPlan = false;
3427
+ for ( const line of this.outputLines ) {
3428
+ if ( /^\d+\.\.\d+\s*$/.test( line ) ) {
3429
+ hasTopLevelPlan = true;
3430
+ }
3431
+ if ( /^ok\b/.test( line ) || /^not ok\b/.test( line ) ) {
3432
+ topLevelTests++;
3433
+ }
3434
+ }
3435
+ if ( topLevelTests > 0 && !hasTopLevelPlan ) {
3436
+ const stdout = this.outputLines.length > 0 ? `${this.outputLines.join( '\n' )}\n` : '';
3437
+ const stderr = 'Error: TAP plan missing (expected 1..N)\n';
3438
+ if ( typeof this.stderrHandler === 'function' ) {
3439
+ this.stderrHandler( stderr );
3440
+ }
3441
+ return {
3442
+ status: 1,
3443
+ stdout,
3444
+ stderr,
3445
+ };
3446
+ }
3447
+ const stdout = this.outputLines.length > 0 ? `${this.outputLines.join( '\n' )}\n` : '';
3448
+ return {
3449
+ status: 0,
3450
+ stdout,
3451
+ stderr: '',
3452
+ };
3453
+ };
3454
+ const failRun = (err) => {
3455
+ const stdout = this.outputLines.length > 0 ? `${this.outputLines.join( '\n' )}\n` : '';
3456
+ const isParse = err && err.name === 'SyntaxError';
3457
+ const stderr = formatRuntimeError( err );
3458
+ if ( typeof this.stderrHandler === 'function' ) {
3459
+ this.stderrHandler( stderr );
3460
+ }
3461
+ return {
3462
+ status: isParse ? 3 : 1,
3463
+ stdout,
3464
+ stderr,
3465
+ };
3466
+ };
3467
+ const cleanupRun = (result) => {
3468
+ taskRuntime.shutdown( 'Task cancelled' );
3469
+ this.outputLines = null;
3470
+ this.stdoutHandler = previousStdoutHandler;
3471
+ this.stderrHandler = previousStderrHandler;
3472
+ return result;
3473
+ };
3474
+ const invokeMain = () => {
3475
+ if ( typeof context.__main__ !== 'function' ) {
3476
+ return null;
3477
+ }
3478
+ const argv = Array.isArray( options.scriptArgs )
3479
+ ? options.scriptArgs.map( (value) => String( value ) )
3480
+ : [];
3481
+ const mainResult = context.__main__( argv );
3482
+ if (
3483
+ mainResult instanceof taskRuntime.Task
3484
+ || ( mainResult && typeof mainResult.then === 'function' )
3485
+ ) {
3486
+ return taskRuntime.awaitValue( mainResult );
3487
+ }
3488
+ return null;
3489
+ };
3490
+ try {
3491
+ const scriptRunOptions = { filename };
3492
+ if ( this.executionTimeoutMs != null ) {
3493
+ scriptRunOptions.timeout = this.executionTimeoutMs;
3494
+ }
3495
+ const topLevelResult = this.host.runInContext( js, context, scriptRunOptions );
3496
+ if ( topLevelResult && typeof topLevelResult.then === 'function' ) {
3497
+ return Promise.resolve( topLevelResult )
3498
+ .then( invokeMain )
3499
+ .then( finishRun, failRun )
3500
+ .then( cleanupRun );
3501
+ }
3502
+ const mainResult = invokeMain();
3503
+ if ( mainResult && typeof mainResult.then === 'function' ) {
3504
+ return Promise.resolve( mainResult )
3505
+ .then( finishRun, failRun )
3506
+ .then( cleanupRun );
3507
+ }
3508
+ return cleanupRun( finishRun() );
3509
+ }
3510
+ catch ( err ) {
3511
+ return cleanupRun( failRun( err ) );
3512
+ }
3513
+ }
3514
+
3515
+ runFile( scriptPath ) {
3516
+ const source = this.host.readFileText( scriptPath );
3517
+ return this.runSource( source, {
3518
+ filename: scriptPath,
3519
+ scriptArgs: [],
3520
+ } );
3521
+ }
3522
+ }
3523
+
3524
+ module.exports = {
3525
+ ZuzuScript,
3526
+ isWeakableValue,
3527
+ makeWeakValue,
3528
+ resolveWeakValue,
3529
+ };