@ball-lang/cli 1.23.0 → 1.25.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.
@@ -0,0 +1,1938 @@
1
+ // @ts-nocheck — auto-generated
2
+ // ── Ball runtime preamble (generated by @ball-lang/compiler) ────────
3
+ // Base class for all Ball runtime values.
4
+ export class BallValue {
5
+ }
6
+ // A cast pattern (value as T) ASSERTS the runtime type — it throws on a type
7
+ // mismatch (Dart semantics), it does NOT refute / fall through. Conjoined into a
8
+ // switch-case condition by the compiler; returns true when the type check passed,
9
+ // else throws a catchable error. (conformance 302_cast_patterns)
10
+ export function ball_cast_assert(ok, t) {
11
+ if (!ok)
12
+ throw new Error('TypeError: type cast failed: not a ' + t);
13
+ return true;
14
+ }
15
+ // ── Ball container runtime types ────────────────────────────────────
16
+ //
17
+ // The self-hosted engine IR models class instances as 'BallObject extends
18
+ // BallMap'. The compiler treats maps/lists transparently (a Ball map is a
19
+ // plain JS object, a Ball list a plain JS array) and _asMap() returns an
20
+ // instance verbatim, reading its data through bracket access (obj of f)
21
+ // and the Object.prototype .entries / .keys / .length getters. To stay
22
+ // compatible we make BallObject a plain-object-like instance: the field data
23
+ // lives as OWN ENUMERABLE properties (so bracket access and .entries see it),
24
+ // while the class bookkeeping (typeName/fields/methods/superObject) is stored
25
+ // non-enumerably so it never leaks into .entries / .keys / .length.
26
+ //
27
+ // BallMap / BallList exist only so 'extends BallMap' resolves and any stray
28
+ // new BallMap(...) / new BallList(...) behaves like the transparent value.
29
+ export class BallMap extends BallValue {
30
+ constructor(entries) {
31
+ super();
32
+ if (entries && typeof entries === 'object') {
33
+ if (entries instanceof Map) {
34
+ for (const [k, v] of entries)
35
+ this[k] = v;
36
+ }
37
+ else {
38
+ for (const k of Object.keys(entries))
39
+ this[k] = entries[k];
40
+ }
41
+ }
42
+ }
43
+ }
44
+ export class BallList extends Array {
45
+ constructor(items) {
46
+ super();
47
+ if (Array.isArray(items))
48
+ for (const it of items)
49
+ this.push(it);
50
+ }
51
+ }
52
+ export class BallObject extends BallMap {
53
+ constructor(arg0, superObject, fields, methods) {
54
+ super();
55
+ // Accept either the named-args object the encoder emits
56
+ // (new BallObject({typeName, superObject, fields, methods})) or the
57
+ // positional form, so the class works regardless of how it is invoked.
58
+ let typeName = arg0;
59
+ if (arg0 && typeof arg0 === 'object' && !Array.isArray(arg0) &&
60
+ ('typeName' in arg0 || 'fields' in arg0 || 'methods' in arg0 ||
61
+ 'superObject' in arg0)) {
62
+ typeName = arg0.typeName;
63
+ superObject = arg0.superObject;
64
+ fields = arg0.fields;
65
+ methods = arg0.methods;
66
+ }
67
+ const fieldMap = (fields && typeof fields === 'object') ? fields : {};
68
+ const methodMap = (methods && typeof methods === 'object') ? methods : {};
69
+ // Field data → own enumerable properties (visible to bracket access and
70
+ // the Object.prototype map getters).
71
+ for (const k of Object.keys(fieldMap))
72
+ this[k] = fieldMap[k];
73
+ // Class bookkeeping → own props the engine reads/writes by bracket name.
74
+ this['__type__'] = typeName ?? '';
75
+ this['__super__'] = superObject ?? null;
76
+ this['__fields__'] = fieldMap;
77
+ this['__methods__'] = methodMap;
78
+ // Mirror the Dart class fields too, but non-enumerably so they never show
79
+ // up as Ball fields in .entries / .keys / .length.
80
+ for (const [name, value] of [
81
+ ['typeName', typeName ?? ''], ['superObject', superObject ?? null],
82
+ ['fields', fieldMap], ['methods', methodMap],
83
+ ]) {
84
+ Object.defineProperty(this, name, {
85
+ value, writable: true, configurable: true, enumerable: false,
86
+ });
87
+ }
88
+ }
89
+ setField(name, value) {
90
+ this.fields[name] = value;
91
+ this[name] = value;
92
+ }
93
+ }
94
+ globalThis.BallMap = BallMap;
95
+ globalThis.BallList = BallList;
96
+ globalThis.BallObject = BallObject;
97
+ // BallDouble wrapper — tracks that a number should print as a double
98
+ // (e.g. 42.0 not 42). Used by the compiled Dart engine's _toDouble.
99
+ export class BallDouble {
100
+ value;
101
+ // Collapse nested wrapping down to the innermost raw number instead of
102
+ // storing a BallDouble that holds another BallDouble. The concrete source of
103
+ // nested wrapping was string_to_double's engine handler wrapping the result
104
+ // of the already-wrapping compiled parse path from issue 222; that redundant
105
+ // wrap was removed at its root in issue 237, so this guard is now purely
106
+ // defensive (verified: the full TS engine suite stays green without it). It is
107
+ // kept as a cheap, idempotent belt-and-suspenders against any other caller
108
+ // that might wrap an already-wrapped value: a doubly-wrapped BallDouble makes
109
+ // Number/valueOf coercion throw "Cannot convert object to primitive value".
110
+ // For a plain-number caller the instanceof check is a no-op.
111
+ constructor(v) { this.value = v instanceof BallDouble ? v.value : v; }
112
+ valueOf() { return this.value; }
113
+ get isNaN() { return Number.isNaN(this.value); }
114
+ get isFinite() { return Number.isFinite(this.value); }
115
+ get isInfinite() { return !Number.isFinite(this.value) && !Number.isNaN(this.value); }
116
+ get isNegative() { return this.value < 0 || (this.value === 0 && 1 / this.value === -Infinity); }
117
+ // Mirrors the Number.prototype.remainder polyfill below (truncating
118
+ // remainder, matching JS % and Dart's num.remainder) — BallDouble wraps
119
+ // a JS number so it never inherits Number.prototype and needs its own.
120
+ remainder(other) { return this.value % Number(other); }
121
+ toString() {
122
+ const v = this.value;
123
+ if (!isFinite(v))
124
+ return v.toString();
125
+ if (v === 0 && 1 / v === -Infinity)
126
+ return '-0.0';
127
+ if (Number.isInteger(v))
128
+ return v.toFixed(1);
129
+ return v.toString();
130
+ }
131
+ // Arithmetic: unwrap for operations
132
+ [Symbol.toPrimitive](hint) {
133
+ if (hint === 'string')
134
+ return this.toString();
135
+ return this.value;
136
+ }
137
+ }
138
+ globalThis.BallDouble = BallDouble;
139
+ // Arithmetic helpers that propagate BallDouble through operations.
140
+ // If either operand is BallDouble, the result is BallDouble (preserving .0).
141
+ //
142
+ // Operator-overload dispatch checks for __op_X__ methods (TRAILING double
143
+ // underscore) — this MUST match the Dart encoder's canonical operator naming
144
+ // (_canonicalOperatorName in dart/encoder/lib/encoder.dart), which always
145
+ // emits a trailing __. A single-underscore lookup (__op_mul) never matches,
146
+ // so overloaded operators silently fall through to raw JS arithmetic (#205).
147
+ export function __ball_mul(a, b) {
148
+ if (a != null && typeof a === 'object' && typeof a.__op_mul__ === 'function')
149
+ return a.__op_mul__(b);
150
+ if (typeof a === 'bigint' || typeof b === 'bigint')
151
+ return __i64_wrap(__to_bigint(a) * __to_bigint(b));
152
+ const av = a instanceof BallDouble ? a.value : a;
153
+ const bv = b instanceof BallDouble ? b.value : b;
154
+ const r = av * bv;
155
+ return (a instanceof BallDouble || b instanceof BallDouble) ? new BallDouble(r) : r;
156
+ }
157
+ export function __ball_add(a, b) {
158
+ if (a != null && typeof a === 'object' && typeof a.__op_add__ === 'function')
159
+ return a.__op_add__(b);
160
+ if (typeof a === 'bigint' || typeof b === 'bigint')
161
+ return __i64_wrap(__to_bigint(a) + __to_bigint(b));
162
+ const av = a instanceof BallDouble ? a.value : a;
163
+ const bv = b instanceof BallDouble ? b.value : b;
164
+ const r = av + bv;
165
+ return (a instanceof BallDouble || b instanceof BallDouble) ? new BallDouble(r) : r;
166
+ }
167
+ export function __ball_sub(a, b) {
168
+ if (a != null && typeof a === 'object' && typeof a.__op_sub__ === 'function')
169
+ return a.__op_sub__(b);
170
+ if (typeof a === 'bigint' || typeof b === 'bigint')
171
+ return __i64_wrap(__to_bigint(a) - __to_bigint(b));
172
+ const av = a instanceof BallDouble ? a.value : a;
173
+ const bv = b instanceof BallDouble ? b.value : b;
174
+ const r = av - bv;
175
+ return (a instanceof BallDouble || b instanceof BallDouble) ? new BallDouble(r) : r;
176
+ }
177
+ // Dart equality: NaN != NaN, BallDouble value comparison, null == undefined.
178
+ export function __ball_eq(a, b) {
179
+ if (a != null && typeof a === 'object' && typeof a.__op_eq__ === 'function')
180
+ return a.__op_eq__(b);
181
+ if (typeof a === 'bigint' || typeof b === 'bigint') {
182
+ if (typeof a === 'bigint' && typeof b === 'bigint')
183
+ return a === b;
184
+ if (typeof a === 'bigint' && typeof b === 'number')
185
+ return a === BigInt(b);
186
+ if (typeof a === 'number' && typeof b === 'bigint')
187
+ return BigInt(a) === b;
188
+ return false;
189
+ }
190
+ if (a instanceof BallDouble || b instanceof BallDouble) {
191
+ const av = a instanceof BallDouble ? a.value : a;
192
+ const bv = b instanceof BallDouble ? b.value : b;
193
+ if (Number.isNaN(av) || Number.isNaN(bv))
194
+ return false;
195
+ return av === bv;
196
+ }
197
+ if (a == null && b == null)
198
+ return true;
199
+ if (a == null || b == null)
200
+ return a == b;
201
+ return a === b;
202
+ }
203
+ // Relational operator-overload dispatch (less-than/greater-than/etc.),
204
+ // matching the __op_add__-style convention above. Unlike arithmetic,
205
+ // relational comparisons had NO overload attempt at all before #205 — every
206
+ // overloaded Vec2 < x etc. compiled straight to raw JS comparison.
207
+ export function __ball_lt(a, b) {
208
+ if (a != null && typeof a === 'object' && typeof a.__op_lt__ === 'function')
209
+ return a.__op_lt__(b);
210
+ if (typeof a === 'bigint' || typeof b === 'bigint')
211
+ return __to_bigint(a) < __to_bigint(b);
212
+ const av = a instanceof BallDouble ? a.value : a;
213
+ const bv = b instanceof BallDouble ? b.value : b;
214
+ return av < bv;
215
+ }
216
+ export function __ball_gt(a, b) {
217
+ if (a != null && typeof a === 'object' && typeof a.__op_gt__ === 'function')
218
+ return a.__op_gt__(b);
219
+ if (typeof a === 'bigint' || typeof b === 'bigint')
220
+ return __to_bigint(a) > __to_bigint(b);
221
+ const av = a instanceof BallDouble ? a.value : a;
222
+ const bv = b instanceof BallDouble ? b.value : b;
223
+ return av > bv;
224
+ }
225
+ export function __ball_le(a, b) {
226
+ if (a != null && typeof a === 'object' && typeof a.__op_le__ === 'function')
227
+ return a.__op_le__(b);
228
+ if (typeof a === 'bigint' || typeof b === 'bigint')
229
+ return __to_bigint(a) <= __to_bigint(b);
230
+ const av = a instanceof BallDouble ? a.value : a;
231
+ const bv = b instanceof BallDouble ? b.value : b;
232
+ return av <= bv;
233
+ }
234
+ export function __ball_ge(a, b) {
235
+ if (a != null && typeof a === 'object' && typeof a.__op_ge__ === 'function')
236
+ return a.__op_ge__(b);
237
+ if (typeof a === 'bigint' || typeof b === 'bigint')
238
+ return __to_bigint(a) >= __to_bigint(b);
239
+ const av = a instanceof BallDouble ? a.value : a;
240
+ const bv = b instanceof BallDouble ? b.value : b;
241
+ return av >= bv;
242
+ }
243
+ export function __ball_to_string(v) {
244
+ if (v === null || v === undefined)
245
+ return 'null';
246
+ if (typeof v === 'bigint')
247
+ return v.toString();
248
+ if (typeof v === 'boolean')
249
+ return v ? 'true' : 'false';
250
+ if (v instanceof BallDouble)
251
+ return v.toString();
252
+ if (typeof v === 'number') {
253
+ if (!isFinite(v) || Number.isNaN(v))
254
+ return v.toString();
255
+ if (v === 0 && 1 / v === -Infinity)
256
+ return '-0.0';
257
+ if (Number.isInteger(v))
258
+ return v.toString();
259
+ const s = v.toString();
260
+ return s.includes('.') || s.includes('e') ? s : s + '.0';
261
+ }
262
+ if (typeof v === 'string')
263
+ return v;
264
+ if (Array.isArray(v)) {
265
+ return '[' + v.map(__ball_to_string).join(', ') + ']';
266
+ }
267
+ if (v instanceof Map) {
268
+ const parts = [];
269
+ // v.entries() as a method call would hit the Dart-property-style
270
+ // getter of the same name (installed further down in this file) and
271
+ // try to invoke its return value -- an array -- as a function.
272
+ // _nativeMapEntries is the real, un-shadowed method (issue #259).
273
+ for (const [k, val] of _nativeMapEntries.call(v)) {
274
+ parts.push(__ball_to_string(k) + ': ' + __ball_to_string(val));
275
+ }
276
+ return '{' + parts.join(', ') + '}';
277
+ }
278
+ if (v instanceof Set) {
279
+ // A Set is a plain object from typeof's perspective (falls through to
280
+ // the generic branch below, which reads Object.keys — always [] for a
281
+ // Set's internal slots), so every Set printed as the empty "{}" no
282
+ // matter its contents until this dedicated case was added (#219).
283
+ return '{' + [...v].map(__ball_to_string).join(', ') + '}';
284
+ }
285
+ if (typeof v === 'object' && !Array.isArray(v)) {
286
+ // StringBuffer-like objects
287
+ if (v['__buffer__'] && Array.isArray(v['__buffer__'])) {
288
+ return v['__buffer__'].join('');
289
+ }
290
+ // Check for custom toString method on the instance (not Object.prototype).
291
+ if (v.toString !== Object.prototype.toString && typeof v.toString === 'function') {
292
+ return v.toString();
293
+ }
294
+ // Dart Map-like object: format as {key: value, ...}
295
+ const keys = Object.keys(v).filter((k) => !k.startsWith('__'));
296
+ if (keys.length > 0) {
297
+ return '{' + keys.map((k) => __ball_to_string(k) + ': ' + __ball_to_string(v[k])).join(', ') + '}';
298
+ }
299
+ return '{}';
300
+ }
301
+ return String(v);
302
+ }
303
+ export function __ball_parse_int(s) {
304
+ const trimmed = s.trim();
305
+ if (!/^-?\d+$/.test(trimmed)) {
306
+ throw new Error('FormatException: ' + s);
307
+ }
308
+ return parseInt(trimmed, 10);
309
+ }
310
+ // Dart-style int conversion that preserves int64 precision. JS numbers lose
311
+ // precision above 2^53, so integer literals encoded as decimal strings (the
312
+ // JSON proto3 representation of int64) would round. When the string magnitude
313
+ // exceeds Number.MAX_SAFE_INTEGER we return a BigInt to keep the exact value;
314
+ // otherwise we keep a plain number so the common arithmetic path is unchanged.
315
+ export function __ball_to_int(v) {
316
+ if (typeof v === 'bigint')
317
+ return v;
318
+ if (typeof v === 'string') {
319
+ if (/^-?\d+$/.test(v)) {
320
+ const b = BigInt(v);
321
+ if (b > 9007199254740991n || b < -9007199254740991n)
322
+ return b;
323
+ return Number(b);
324
+ }
325
+ return Math.trunc(Number(v)) || 0;
326
+ }
327
+ const n = (v instanceof BallDouble) ? v.value : v;
328
+ const t = Math.trunc(n) || 0;
329
+ if (t >= 9223372036854775808)
330
+ return __I64_MAX;
331
+ if (t <= -9223372036854775808)
332
+ return __I64_MIN;
333
+ if (t > 9007199254740991 || t < -9007199254740991) {
334
+ try {
335
+ return __i64_wrap(BigInt(Math.round(t)));
336
+ }
337
+ catch { }
338
+ }
339
+ return t;
340
+ }
341
+ // Returns a BallDouble (not a bare number) so a whole-valued result (e.g.
342
+ // double.parse('7.0')) still prints "7.0", not "7" — JS numbers erase the
343
+ // int/double distinction that the wrapper exists to preserve (#67/#222).
344
+ export function __ball_parse_double(s) {
345
+ const n = parseFloat(s);
346
+ if (Number.isNaN(n))
347
+ throw new Error('FormatException: ' + s);
348
+ return new BallDouble(n);
349
+ }
350
+ export function __ball_double_to_string(n) {
351
+ if (Number.isInteger(n))
352
+ return n.toFixed(1);
353
+ return n.toString();
354
+ }
355
+ // num.toStringAsFixed(digits). JS Number.prototype.toFixed drops the sign of
356
+ // -0 (returns "0.00" not "-0.00"); Dart's toStringAsFixed keeps it, matching
357
+ // the -0 handling __ball_to_string/BallDouble.toString already do.
358
+ export function __ball_to_fixed(v, digits) {
359
+ const n = Number(v);
360
+ const s = n.toFixed(digits);
361
+ if (n === 0 && 1 / n === -Infinity && !s.startsWith('-'))
362
+ return '-' + s;
363
+ return s;
364
+ }
365
+ // Polymorphic concat / merge used for std.list_concat. The encoder emits
366
+ // list_concat both for Dart list concat AND for Map.addAll(...) (encoded as
367
+ // m = list_concat(m, other)). Arrays concat positionally; plain objects
368
+ // (Ball maps) merge by key with the right side winning (so child class
369
+ // methods override parent methods).
370
+ export function __ball_concat(a, b) {
371
+ const aIsArr = Array.isArray(a);
372
+ const bIsArr = Array.isArray(b);
373
+ if (aIsArr || bIsArr) {
374
+ const al = aIsArr ? a : (a == null ? [] : [a]);
375
+ const bl = bIsArr ? b : (b == null ? [] : [b]);
376
+ return [...al, ...bl];
377
+ }
378
+ if ((a && typeof a === 'object') || (b && typeof b === 'object')) {
379
+ return Object.assign({}, a ?? {}, b ?? {});
380
+ }
381
+ return [a, b];
382
+ }
383
+ // In-place collection append: mutates target by appending all elements.
384
+ // For arrays: pushes elements (Dart List.addAll semantics).
385
+ // For objects: merges keys (Dart Map.addAll semantics).
386
+ // Preserves reference identity so callers sharing the same collection see changes.
387
+ export function __ball_push_all(target, items) {
388
+ if (Array.isArray(target)) {
389
+ if (Array.isArray(items)) {
390
+ for (let i = 0; i < items.length; i++)
391
+ target.push(items[i]);
392
+ }
393
+ else if (items != null) {
394
+ target.push(items);
395
+ }
396
+ }
397
+ else if (target && typeof target === 'object') {
398
+ if (items && typeof items === 'object' && !Array.isArray(items)) {
399
+ for (const k of Object.keys(items))
400
+ target[k] = items[k];
401
+ }
402
+ }
403
+ }
404
+ // ── BigInt / signed-64-bit integer support ──────────────────────
405
+ // Dart int is signed 64-bit; JS Number loses precision above 2^53.
406
+ // Arithmetic on BigInt values wraps to the signed 64-bit range and
407
+ // demotes back to Number when the result fits in MAX_SAFE_INTEGER.
408
+ export const __I64_MAX = 9223372036854775807n;
409
+ export const __I64_MIN = -9223372036854775808n;
410
+ export function __i64_wrap(v) {
411
+ // Two's-complement wrap to the signed 64-bit range — BigInt.asIntN(64, v)
412
+ // is the idiomatic builtin for exactly this (equivalent to the old manual
413
+ // modulo-then-resign, verified against it across boundary/overflow cases).
414
+ v = BigInt.asIntN(64, v);
415
+ if (v >= -9007199254740991n && v <= 9007199254740991n)
416
+ return Number(v);
417
+ return v;
418
+ }
419
+ export function __to_bigint(v) {
420
+ if (typeof v === 'bigint')
421
+ return v;
422
+ // Matches the reference Dart engine's _toInt (engine_std.dart), which
423
+ // falls through to 0 for anything that isn't an int/BallInt/double/
424
+ // BallDouble/String/bool -- including null. NaN is deliberately NOT
425
+ // special-cased here: Dart's double.toInt() throws on NaN (via
426
+ // _ballDoubleToInt64), and BigInt(NaN) already throws for the same
427
+ // reason (RangeError: not an integer), so that path already fails loud
428
+ // consistently with the reference engine without any extra handling.
429
+ if (v === null || v === undefined)
430
+ return 0n;
431
+ if (v instanceof BallDouble)
432
+ return BigInt(Math.trunc(v.value));
433
+ return BigInt(v);
434
+ }
435
+ // Fast-path guard: true when v is a plain (non-bigint, non-BallDouble)
436
+ // integer within the signed 32-bit range. AND/OR/XOR/NOT never grow a
437
+ // result past its operands' bit width, so when both operands fit in 32
438
+ // bits, JS's native 32-bit bitwise operators give a result numerically
439
+ // IDENTICAL to the full 64-bit BigInt path (sign-extending a 32-bit value
440
+ // to 64 bits before AND/OR/XOR/NOT never changes the low 32 result bits,
441
+ // and — verified across the full boundary range — never changes whether
442
+ // the high bits are the correct sign-extension of them either). Left/right
443
+ // shift are NOT given this fast path: shifting can grow a result past 32
444
+ // bits even when the input operand fits (e.g. large_int << 40), so their
445
+ // overflow behavior isn't safely 32-bit-local the way AND/OR/XOR/NOT is.
446
+ export function __fits32(v) {
447
+ return typeof v === 'number' && Number.isInteger(v) && v >= -2147483648 && v <= 2147483647;
448
+ }
449
+ export function __ball_bitand(a, b) {
450
+ if (__fits32(a) && __fits32(b))
451
+ return a & b;
452
+ return __i64_wrap(__to_bigint(a) & __to_bigint(b));
453
+ }
454
+ export function __ball_bitor(a, b) {
455
+ if (__fits32(a) && __fits32(b))
456
+ return a | b;
457
+ return __i64_wrap(__to_bigint(a) | __to_bigint(b));
458
+ }
459
+ export function __ball_bitxor(a, b) {
460
+ if (__fits32(a) && __fits32(b))
461
+ return a ^ b;
462
+ return __i64_wrap(__to_bigint(a) ^ __to_bigint(b));
463
+ }
464
+ export function __ball_bitnot(a) {
465
+ if (__fits32(a))
466
+ return ~a;
467
+ return __i64_wrap(~__to_bigint(a));
468
+ }
469
+ export function __ball_shl(a, b) { return __i64_wrap(__to_bigint(a) << __to_bigint(b)); }
470
+ export function __ball_shr(a, b) { return __i64_wrap(__to_bigint(a) >> __to_bigint(b)); }
471
+ // Unsigned/logical shift: reinterpret a as an unsigned 64-bit value (add
472
+ // 2^64 if negative) before shifting, so zeros fill from the left instead of
473
+ // the sign bit — unlike >>> on raw JS numbers, which is only 32-bit.
474
+ export function __ball_ushr(a, b) {
475
+ const unsigned = BigInt.asUintN(64, __to_bigint(a));
476
+ return __i64_wrap(unsigned >> __to_bigint(b));
477
+ }
478
+ // json_encode (dart:convert's jsonEncode) on a bigint-range int64 must not
479
+ // crash -- JSON.stringify throws "Do not know how to serialize a BigInt"
480
+ // without a toJSON. This is NOT proto3-JSON (which quotes int64 as a
481
+ // string) -- Ball's dart:convert-style jsonEncode matches Dart's own
482
+ // dart:convert (a bare, unquoted JSON number) and the C++ self-host's
483
+ // _ball_json_encode (std::to_string(int64_t), also unquoted). JSON.rawJSON
484
+ // embeds the exact decimal digits as a raw number token, avoiding the
485
+ // precision loss Number(this) would introduce for values past 2^53.
486
+ BigInt.prototype.toJSON = function () {
487
+ return JSON.rawJSON(this.toString());
488
+ };
489
+ export function __ball_negate(a) {
490
+ if (typeof a === 'bigint')
491
+ return __i64_wrap(-a);
492
+ if (a instanceof BallDouble)
493
+ return new BallDouble(-a.value);
494
+ return -a;
495
+ }
496
+ export function __ball_divide(a, b) {
497
+ if (typeof a === 'bigint' || typeof b === 'bigint') {
498
+ const ba = __to_bigint(a), bb = __to_bigint(b);
499
+ const r = ba / bb;
500
+ return __i64_wrap(r);
501
+ }
502
+ return Math.trunc(a / b);
503
+ }
504
+ export function __ball_math_abs(a) {
505
+ if (typeof a === 'bigint') {
506
+ const neg = -a;
507
+ return __i64_wrap(neg < 0n ? a : neg);
508
+ }
509
+ return Math.abs(a);
510
+ }
511
+ // Greatest common divisor (Dart's int.gcd). Preserves BigInt (i64) inputs so
512
+ // integer identities round-trip; falls back to Number arithmetic otherwise.
513
+ export function __ball_math_gcd(a, b) {
514
+ if (typeof a === 'bigint' || typeof b === 'bigint') {
515
+ let x = __to_bigint(a);
516
+ x = x < 0n ? -x : x;
517
+ let y = __to_bigint(b);
518
+ y = y < 0n ? -y : y;
519
+ while (y) {
520
+ const t = y;
521
+ y = x % y;
522
+ x = t;
523
+ }
524
+ return __i64_wrap(x);
525
+ }
526
+ let x = Math.abs(Number(a)), y = Math.abs(Number(b));
527
+ while (y) {
528
+ const t = y;
529
+ y = x % y;
530
+ x = t;
531
+ }
532
+ return x;
533
+ }
534
+ // Least common multiple, derived from gcd. lcm(0, n) == lcm(n, 0) == 0.
535
+ export function __ball_math_lcm(a, b) {
536
+ if (typeof a === 'bigint' || typeof b === 'bigint') {
537
+ const x = __to_bigint(a), y = __to_bigint(b);
538
+ if (x === 0n || y === 0n)
539
+ return __i64_wrap(0n);
540
+ const g = __to_bigint(__ball_math_gcd(x, y));
541
+ const r = (x / g) * y;
542
+ return __i64_wrap(r < 0n ? -r : r);
543
+ }
544
+ const x = Number(a), y = Number(b);
545
+ if (x === 0 || y === 0)
546
+ return 0;
547
+ const g = Number(__ball_math_gcd(x, y));
548
+ return Math.abs((x / g) * y);
549
+ }
550
+ // Dart-style Euclidean modulo: result is always non-negative.
551
+ // JS % is remainder (can be negative), Dart % is Euclidean modulo.
552
+ export function __dart_mod(a, b) {
553
+ if (typeof a === 'bigint' || typeof b === 'bigint') {
554
+ const ba = __to_bigint(a), bb = __to_bigint(b);
555
+ const r = ba % bb;
556
+ return __i64_wrap(r < 0n ? r + (bb < 0n ? -bb : bb) : r);
557
+ }
558
+ const r = a % b;
559
+ return r < 0 ? r + (b < 0 ? -b : b) : r;
560
+ }
561
+ // Active exception for rethrow. Catch bodies shadow with a local.
562
+ export let __ball_active_error = undefined;
563
+ // Dart-style index access. Dart's List '[]' operator throws RangeError on
564
+ // out-of-bounds access, whereas JS array indexing silently returns undefined.
565
+ // To make 'on RangeError' catch clauses behave like Dart we bounds-check list
566
+ // (array) access here and throw a RangeError-shaped exception. Maps, strings
567
+ // and objects keep their JS semantics (no throw) — Dart Map '[]' returns null
568
+ // for absent keys, and String '[]' is handled by callers.
569
+ export function __ball_index(target, idx) {
570
+ if (Array.isArray(target) && typeof idx === 'number' && Number.isInteger(idx)) {
571
+ if (idx < 0 || idx >= target.length) {
572
+ throw {
573
+ __type__: 'RangeError',
574
+ message: 'RangeError (index): Invalid value: ' +
575
+ (target.length === 0
576
+ ? 'Valid value range is empty: ' + idx
577
+ : 'Not in inclusive range 0..' + (target.length - 1) + ': ' + idx),
578
+ index: idx,
579
+ };
580
+ }
581
+ return target[idx];
582
+ }
583
+ return target[idx];
584
+ }
585
+ // Dart type shims — provide static methods for Dart built-in types
586
+ // that don't exist in JS (int, double, num, bool).
587
+ export const int = {
588
+ parse: (s) => { const n = parseInt(String(s), 10); if (isNaN(n))
589
+ throw new Error('FormatException: ' + s); return n; },
590
+ tryParse: (s) => { const n = parseInt(String(s), 10); return isNaN(n) ? null : n; },
591
+ };
592
+ export const double = {
593
+ parse: (s) => { const n = parseFloat(String(s)); if (isNaN(n))
594
+ throw new Error('FormatException: ' + s); return n; },
595
+ tryParse: (s) => { const n = parseFloat(String(s)); return isNaN(n) ? null : n; },
596
+ infinity: Infinity,
597
+ nan: NaN,
598
+ negativeInfinity: -Infinity,
599
+ };
600
+ export const num = {
601
+ parse: (s) => { const n = Number(s); if (isNaN(n))
602
+ throw new Error('FormatException: ' + s); return n; },
603
+ tryParse: (s) => { const n = Number(s); return isNaN(n) ? null : n; },
604
+ };
605
+ export const bool = {
606
+ parse: (s) => { if (s === 'true')
607
+ return true; if (s === 'false')
608
+ return false; throw new Error('FormatException: ' + s); },
609
+ tryParse: (s) => { if (s === 'true')
610
+ return true; if (s === 'false')
611
+ return false; return null; },
612
+ };
613
+ // Sentinel for "not yet initialized" — used by the Dart engine for
614
+ // late-initialized variables and block-scoped flow tracking.
615
+ export const __no_init__ = Symbol('__no_init__');
616
+ // Null-aware spread source normalizer (the ...? operator). Returns an
617
+ // iterable for the spread loop, mapping null / undefined / the __no_init__
618
+ // sentinel (an uninitialized nullable, e.g. List<int>? n;) to an empty list
619
+ // — matching Dart's ...?n which contributes nothing when the operand is null.
620
+ export function __ball_spread_iter(v) {
621
+ if (v == null || v === __no_init__)
622
+ return [];
623
+ return v;
624
+ }
625
+ // Dart type constructor shims — List, Map, etc.
626
+ export const List = {
627
+ filled: (count, value) => Array(count).fill(value),
628
+ generate: (count, generator) => {
629
+ const r = [];
630
+ for (let i = 0; i < count; i++)
631
+ r.push(generator(i));
632
+ return r;
633
+ },
634
+ from: (iter) => Array.isArray(iter) ? [...iter] : [...iter],
635
+ of: (iter) => Array.isArray(iter) ? [...iter] : [...iter],
636
+ unmodifiable: (iter) => Object.freeze(Array.isArray(iter) ? [...iter] : [...iter]),
637
+ empty: (opts) => [],
638
+ castFrom: (source) => Array.isArray(source) ? [...source] : [],
639
+ };
640
+ // Set.unmodifiable
641
+ export const _nativeSet = Set;
642
+ Set.unmodifiable = (iter) => {
643
+ const s = new _nativeSet(iter);
644
+ return Object.freeze(s);
645
+ };
646
+ Set.from = (iter) => new _nativeSet(iter);
647
+ Set.of = (iter) => new _nativeSet(iter);
648
+ // Ball encoder sometimes uses set_create for lists, then list_push on them.
649
+ // Bridge the gap with push/indexOf/length on Set.
650
+ if (!Set.prototype.push)
651
+ Set.prototype.push = function (v) { this.add(v); return this.size; };
652
+ Object.defineProperty(Set.prototype, 'length', { configurable: true, get() { return this.size; } });
653
+ Object.defineProperty(Set.prototype, 'isEmpty', { configurable: true, get() { return this.size === 0; } });
654
+ Object.defineProperty(Set.prototype, 'isNotEmpty', { configurable: true, get() { return this.size !== 0; } });
655
+ // Patch: scope _bindings must use null-prototype objects to avoid
656
+ // Object.prototype getters (entries, keys, values, length) polluting
657
+ // the "in" operator used by scope.lookup/has/set.
658
+ export const _origScopeInit = { patched: false };
659
+ export function _patchScopeBindings(scope) {
660
+ if (!scope || _origScopeInit.patched)
661
+ return;
662
+ const ScopeClass = scope.constructor;
663
+ if (!ScopeClass)
664
+ return;
665
+ const origCtor = ScopeClass;
666
+ const origBind = ScopeClass.prototype.bind;
667
+ // Override bind to lazily convert _bindings to null-proto object
668
+ ScopeClass.prototype.bind = function (name, value) {
669
+ if (Object.getPrototypeOf(this._bindings) !== null) {
670
+ const entries = Object.entries(this._bindings);
671
+ this._bindings = Object.create(null);
672
+ for (const [k, v] of entries)
673
+ this._bindings[k] = v;
674
+ }
675
+ return (this._bindings[name] = value);
676
+ };
677
+ // Also patch child() to create null-proto bindings
678
+ const origChild = ScopeClass.prototype.child;
679
+ if (origChild) {
680
+ ScopeClass.prototype.child = function () {
681
+ const c = origChild.call(this);
682
+ if (Object.getPrototypeOf(c._bindings) !== null) {
683
+ c._bindings = Object.create(null);
684
+ }
685
+ return c;
686
+ };
687
+ }
688
+ _origScopeInit.patched = true;
689
+ }
690
+ // Proto has* functions as global helpers (encoder routes method calls through ball_proto)
691
+ // Generic has* helper — returns true if obj[field] is present and non-null
692
+ export function _has(obj, field) { return obj?.[field] !== undefined && obj?.[field] !== null; }
693
+ export function hasMetadata(obj) { return _has(obj, 'metadata'); }
694
+ export function hasBody(obj) { return _has(obj, 'body'); }
695
+ export function hasInput(obj) { return _has(obj, 'input'); }
696
+ export function hasDescriptor(obj) { return _has(obj, 'descriptor'); }
697
+ // ModuleImport.source oneof (issue #364 — cli_core.dart's _importSource
698
+ // reads these via hasHttp()/hasFile()/hasGit()/hasRegistry()/hasInline()
699
+ // instead of whichSource(), since the self-hosted engine represents proto
700
+ // oneof-case enums as maps and can't self-host a whichSource() ==
701
+ // ModuleImport_Source.x comparison — see cli_core.dart's _importSource doc).
702
+ export function hasHttp(obj) { return _has(obj, 'http'); }
703
+ export function hasFile(obj) { return _has(obj, 'file'); }
704
+ export function hasGit(obj) { return _has(obj, 'git'); }
705
+ export function hasRegistry(obj) { return _has(obj, 'registry'); }
706
+ export function hasInline(obj) { return _has(obj, 'inline'); }
707
+ export function hasStringValue(obj) { return _has(obj, 'stringValue'); }
708
+ export function hasBoolValue(obj) { return _has(obj, 'boolValue'); }
709
+ export function hasNumberValue(obj) { return _has(obj, 'numberValue'); }
710
+ export function hasResult(obj) { return _has(obj, 'result'); }
711
+ export function hasCall(obj) { return _has(obj, 'call'); }
712
+ export function hasListValue(obj) { return _has(obj, 'listValue'); }
713
+ export function hasNullValue(obj) { return _has(obj, 'nullValue'); }
714
+ export function hasStructValue(obj) { return _has(obj, 'structValue'); }
715
+ export function hasMatch(obj) { return _has(obj, 'match'); }
716
+ export function hasXxx(obj) { return false; }
717
+ export function whichXxx(obj) { return 'notSet'; }
718
+ // whichExpr/whichValue/whichStmt/whichKind sit on the hottest path of the
719
+ // compiled engine (whichExpr alone runs up to 8x per _evalExpression). The
720
+ // previous 'typeof obj.whichXxx === "function"' probe always walked the
721
+ // prototype chain to the Object.prototype shim installed by installProtoShims
722
+ // (true for EVERY plain object) and then *invoked* it — a prototype walk + a
723
+ // megamorphic keyed-load loop per call, even though the compiled engine's AST
724
+ // nodes never carry an own whichXxx. We gate the method probe behind an
725
+ // own-property check (so plain nodes skip the prototype walk entirely and use
726
+ // the inline discriminator) while still honoring hand-rolled wrapper objects —
727
+ // notably the metadata wrapValue Value wrappers, whose own getters
728
+ // (.stringValue etc.) are always-defined, so their own whichXxx() must win
729
+ // over the inline field probes. Hence the own-method check stays FIRST.
730
+ export function whichExpr(obj) {
731
+ if (!obj)
732
+ return 'notSet';
733
+ if (Object.prototype.hasOwnProperty.call(obj, 'whichExpr') && typeof obj.whichExpr === 'function')
734
+ return obj.whichExpr();
735
+ if (obj.call)
736
+ return 'call';
737
+ if (obj.literal)
738
+ return 'literal';
739
+ if (obj.reference)
740
+ return 'reference';
741
+ if (obj.fieldAccess)
742
+ return 'fieldAccess';
743
+ if (obj.messageCreation)
744
+ return 'messageCreation';
745
+ if (obj.block)
746
+ return 'block';
747
+ if (obj.lambda)
748
+ return 'lambda';
749
+ return 'notSet';
750
+ }
751
+ export function whichValue(obj) {
752
+ if (!obj)
753
+ return 'notSet';
754
+ if (Object.prototype.hasOwnProperty.call(obj, 'whichValue') && typeof obj.whichValue === 'function')
755
+ return obj.whichValue();
756
+ if (obj.intValue !== undefined)
757
+ return 'intValue';
758
+ if (obj.doubleValue !== undefined)
759
+ return 'doubleValue';
760
+ if (obj.stringValue !== undefined)
761
+ return 'stringValue';
762
+ if (obj.boolValue !== undefined)
763
+ return 'boolValue';
764
+ if (obj.listValue)
765
+ return 'listValue';
766
+ if (obj.bytesValue !== undefined)
767
+ return 'bytesValue';
768
+ return 'notSet';
769
+ }
770
+ export function whichStmt(obj) {
771
+ if (!obj)
772
+ return 'notSet';
773
+ if (Object.prototype.hasOwnProperty.call(obj, 'whichStmt') && typeof obj.whichStmt === 'function')
774
+ return obj.whichStmt();
775
+ if (obj.let)
776
+ return 'let';
777
+ if (obj.expression)
778
+ return 'expression';
779
+ return 'notSet';
780
+ }
781
+ export function whichKind(obj) {
782
+ if (!obj)
783
+ return 'notSet';
784
+ if (Object.prototype.hasOwnProperty.call(obj, 'whichKind') && typeof obj.whichKind === 'function')
785
+ return obj.whichKind();
786
+ if (obj.nullValue !== undefined)
787
+ return 'nullValue';
788
+ if (obj.numberValue !== undefined)
789
+ return 'numberValue';
790
+ if (obj.stringValue !== undefined)
791
+ return 'stringValue';
792
+ if (obj.boolValue !== undefined)
793
+ return 'boolValue';
794
+ if (obj.structValue)
795
+ return 'structValue';
796
+ if (obj.listValue)
797
+ return 'listValue';
798
+ return 'notSet';
799
+ }
800
+ export function whichSource(obj) {
801
+ if (!obj)
802
+ return 'notSet';
803
+ if (obj.path)
804
+ return 'path';
805
+ if (obj.url)
806
+ return 'url';
807
+ if (obj.inline)
808
+ return 'inline';
809
+ return 'notSet';
810
+ }
811
+ // Identical function (Dart identical())
812
+ export function identical(a, b) { return a === b; }
813
+ // Function.apply shim (Dart Function.apply)
814
+ Function.apply = function (fn, positionalArgs, namedArgs) {
815
+ if (typeof fn !== 'function')
816
+ return undefined;
817
+ const args = positionalArgs == null ? [] : (Array.isArray(positionalArgs) ? positionalArgs : [positionalArgs]);
818
+ return fn(...args);
819
+ };
820
+ // Dart cascade helper — evaluates target, applies ops, returns target.
821
+ export function __ball_cascade(target, ops) {
822
+ for (const op of ops) {
823
+ if (typeof op === 'function')
824
+ op(target);
825
+ }
826
+ return target;
827
+ }
828
+ // ── Dart \u2192 JS method-name polyfills ────────────────────────────────
829
+ //
830
+ // Idempotent: guarded so multiple preamble inclusions don't double-install.
831
+ // Native Map.prototype.entries/keys/values, captured BEFORE the
832
+ // installBallPolyfills IIFE below shadows them with Dart-property-style
833
+ // getters of the same name. Top-level (not IIFE-scoped) so every internal
834
+ // call site that needs the REAL iterator method -- not the property-style
835
+ // getter -- can reach it: the getters themselves (which must call the
836
+ // original to avoid recursing into themselves), __ball_to_string's Map
837
+ // printer, the Map-like constructor copy sites, and the map_keys/values/
838
+ // entries base-function helpers (issue #259 -- calling .entries()/etc.
839
+ // as a METHOD on a real Map after the shadow is installed throws, since
840
+ // the getter's return value -- an array -- isn't itself callable).
841
+ export const _nativeMapEntries = Map.prototype.entries;
842
+ export const _nativeMapKeys = Map.prototype.keys;
843
+ export const _nativeMapValues = Map.prototype.values;
844
+ (function installBallPolyfills() {
845
+ const mp = Map.prototype;
846
+ if (!mp.containsKey)
847
+ mp.containsKey = function (k) { return this.has(k); };
848
+ if (!mp.putIfAbsent) {
849
+ mp.putIfAbsent = function (k, supplier) {
850
+ if (!this.has(k))
851
+ this.set(k, supplier());
852
+ return this.get(k);
853
+ };
854
+ }
855
+ if (!mp.addAll) {
856
+ mp.addAll = function (other) {
857
+ if (other instanceof Map) {
858
+ // _nativeMapEntries, not other.entries() -- see __ball_to_string's
859
+ // Map printer above for why (issue #259).
860
+ for (const [k, v] of _nativeMapEntries.call(other))
861
+ this.set(k, v);
862
+ }
863
+ else if (other && typeof other === 'object') {
864
+ for (const k of Object.keys(other))
865
+ this.set(k, other[k]);
866
+ }
867
+ };
868
+ }
869
+ Object.defineProperty(mp, 'isEmpty', {
870
+ configurable: true, get() { return this.size === 0; },
871
+ });
872
+ Object.defineProperty(mp, 'isNotEmpty', {
873
+ configurable: true, get() { return this.size !== 0; },
874
+ });
875
+ const ap = Array.prototype;
876
+ if (!ap.add)
877
+ ap.add = function (v) { this.push(v); };
878
+ if (!ap.addAll)
879
+ ap.addAll = function (iter) {
880
+ for (const v of iter)
881
+ this.push(v);
882
+ };
883
+ if (!ap.removeLast)
884
+ ap.removeLast = function () { return this.pop(); };
885
+ if (!ap.removeAt)
886
+ ap.removeAt = function (i) { return this.splice(i, 1)[0]; };
887
+ if (!ap.insert)
888
+ ap.insert = function (i, v) { this.splice(i, 0, v); };
889
+ if (!ap.setAll)
890
+ ap.setAll = function (idx, values) { for (let i = 0; i < values.length; i++)
891
+ this[idx + i] = values[i]; };
892
+ if (!ap.where)
893
+ ap.where = Array.prototype.filter;
894
+ if (!ap.toList)
895
+ ap.toList = function () { return this.slice(); };
896
+ if (!ap.toSet)
897
+ ap.toSet = function () { return new Set(this); };
898
+ if (!ap.contains)
899
+ ap.contains = function (v) { return this.indexOf(v) >= 0; };
900
+ if (!ap.sublist)
901
+ ap.sublist = function (start, end) { return this.slice(start, end); };
902
+ if (!ap.asMap)
903
+ ap.asMap = function () {
904
+ const m = {};
905
+ for (let i = 0; i < this.length; i++)
906
+ m[i] = this[i];
907
+ return m;
908
+ };
909
+ if (!ap.expand)
910
+ ap.expand = function (fn) { return this.flatMap(fn); };
911
+ if (!ap.take)
912
+ ap.take = function (n) { return this.slice(0, n); };
913
+ if (!ap.skip)
914
+ ap.skip = function (n) { return this.slice(n); };
915
+ if (!ap.any)
916
+ ap.any = function (fn) { return this.some(fn); };
917
+ if (!ap.fold)
918
+ ap.fold = function (init, fn) { return this.reduce(fn, init); };
919
+ if (!ap.followedBy)
920
+ ap.followedBy = function (other) { return [...this, ...other]; };
921
+ if (!ap.getRange)
922
+ ap.getRange = function (start, end) { return this.slice(start, end); };
923
+ if (!ap.fillRange)
924
+ ap.fillRange = function (start, end, fill) {
925
+ for (let i = start; i < end; i++)
926
+ this[i] = fill;
927
+ };
928
+ if (!ap.setRange)
929
+ ap.setRange = function (start, end, iterable, skipCount) {
930
+ const src = Array.isArray(iterable) ? iterable : [...iterable];
931
+ const skip = skipCount ?? 0;
932
+ for (let i = start; i < end; i++)
933
+ this[i] = src[i - start + skip];
934
+ };
935
+ // Dart Set polyfills — Set.contains → Set.has, etc.
936
+ const setp = Set.prototype;
937
+ if (!setp.contains)
938
+ setp.contains = function (v) { return this.has(v); };
939
+ if (!setp.includes)
940
+ setp.includes = function (v) { return this.has(v); };
941
+ if (!setp.toList)
942
+ setp.toList = function () { return [...this]; };
943
+ if (!setp.add) { /* Set already has .add */ }
944
+ if (!setp.remove)
945
+ setp.remove = function (v) { return this.delete(v); };
946
+ Object.defineProperty(ap, 'isEmpty', {
947
+ configurable: true, get() { return this.length === 0; },
948
+ });
949
+ Object.defineProperty(ap, 'isNotEmpty', {
950
+ configurable: true, get() { return this.length !== 0; },
951
+ });
952
+ Object.defineProperty(ap, 'first', {
953
+ configurable: true, get() { return this[0]; },
954
+ });
955
+ Object.defineProperty(ap, 'last', {
956
+ configurable: true, get() { return this[this.length - 1]; },
957
+ });
958
+ const sp = String.prototype;
959
+ Object.defineProperty(sp, 'isEmpty', {
960
+ configurable: true, get() { return this.length === 0; },
961
+ });
962
+ Object.defineProperty(sp, 'isNotEmpty', {
963
+ configurable: true, get() { return this.length !== 0; },
964
+ });
965
+ // Note: undefined/null safety for .isEmpty/.isNotEmpty is handled in the
966
+ // generated code via optional-chaining (?.isEmpty) patterns and protoWrap;
967
+ // properties cannot be installed on undefined/null directly.
968
+ // Dart String methods not on JS String.
969
+ if (!sp.contains)
970
+ sp.contains = function (s) { return this.includes(s); };
971
+ if (!sp.replaceFirst)
972
+ sp.replaceFirst = function (from, to) {
973
+ return this.replace(from instanceof RegExp ? from : String(from), to);
974
+ };
975
+ if (!sp.codeUnitAt)
976
+ sp.codeUnitAt = function (i) { return this.charCodeAt(i); };
977
+ if (!sp.compareTo)
978
+ sp.compareTo = function (other) {
979
+ return this < other ? -1 : this > other ? 1 : 0;
980
+ };
981
+ if (!sp.allMatches)
982
+ sp.allMatches = function (pattern, start) {
983
+ const s = typeof start === 'number' ? this.substring(start) : this;
984
+ if (typeof pattern === 'string') {
985
+ return Array.from(s.matchAll(new RegExp(pattern, 'g')));
986
+ }
987
+ const flags = pattern.flags.includes('g') ? pattern.flags : pattern.flags + 'g';
988
+ return Array.from(s.matchAll(new RegExp(pattern.source, flags)));
989
+ };
990
+ // Dart RegExp polyfills.
991
+ const rp = RegExp.prototype;
992
+ if (!rp.firstMatch)
993
+ rp.firstMatch = function (s) {
994
+ const m = this.exec(s);
995
+ if (m)
996
+ m.group = (i) => m[i];
997
+ return m;
998
+ };
999
+ if (!rp.allMatches)
1000
+ rp.allMatches = function (s) {
1001
+ const flags = this.flags.includes('g') ? this.flags : this.flags + 'g';
1002
+ return [...s.matchAll(new RegExp(this.source, flags))];
1003
+ };
1004
+ if (!rp.hasMatch)
1005
+ rp.hasMatch = function (s) { return this.test(s); };
1006
+ // Dart Number polyfills — Dart num/int methods not on JS Number.prototype.
1007
+ const _ballNp = Number.prototype;
1008
+ if (!_ballNp.gcd)
1009
+ _ballNp.gcd = function (other) {
1010
+ let a = Math.abs(this), b = Math.abs(Number(other));
1011
+ while (b) {
1012
+ const t = b;
1013
+ b = a % b;
1014
+ a = t;
1015
+ }
1016
+ return a;
1017
+ };
1018
+ Object.defineProperty(_ballNp, 'sign', {
1019
+ configurable: true, get() { const n = Number(this); return n > 0 ? 1 : n < 0 ? -1 : 0; },
1020
+ });
1021
+ Object.defineProperty(_ballNp, 'isNaN', {
1022
+ configurable: true, get() { return Number.isNaN(Number(this)); },
1023
+ });
1024
+ Object.defineProperty(_ballNp, 'isFinite', {
1025
+ configurable: true, get() { return Number.isFinite(Number(this)); },
1026
+ });
1027
+ Object.defineProperty(_ballNp, 'isInfinite', {
1028
+ configurable: true, get() { const n = Number(this); return n === Infinity || n === -Infinity; },
1029
+ });
1030
+ Object.defineProperty(_ballNp, 'isNegative', {
1031
+ configurable: true, get() { const n = Number(this); return n < 0 || (n === 0 && 1 / n === -Infinity); },
1032
+ });
1033
+ if (!_ballNp.abs)
1034
+ _ballNp.abs = function () { return Math.abs(Number(this)); };
1035
+ if (!_ballNp.ceil)
1036
+ _ballNp.ceil = function () { return Math.ceil(Number(this)); };
1037
+ if (!_ballNp.floor)
1038
+ _ballNp.floor = function () { return Math.floor(Number(this)); };
1039
+ if (!_ballNp.round)
1040
+ _ballNp.round = function () { return Math.round(Number(this)); };
1041
+ if (!_ballNp.truncate)
1042
+ _ballNp.truncate = function () { return Math.trunc(Number(this)); };
1043
+ if (!_ballNp.toInt)
1044
+ _ballNp.toInt = function () { return Math.trunc(Number(this)); };
1045
+ if (!_ballNp.toDouble)
1046
+ _ballNp.toDouble = function () { return Number(this); };
1047
+ if (!_ballNp.clamp)
1048
+ _ballNp.clamp = function (lo, hi) { const n = Number(this); return n < lo ? lo : n > hi ? hi : n; };
1049
+ if (!_ballNp.compareTo)
1050
+ _ballNp.compareTo = function (other) { const a = Number(this), b = Number(other); return a < b ? -1 : a > b ? 1 : 0; };
1051
+ if (!_ballNp.toStringAsFixed)
1052
+ _ballNp.toStringAsFixed = function (digits) { return __ball_to_fixed(this, digits); };
1053
+ if (!_ballNp.remainder)
1054
+ _ballNp.remainder = function (other) { return Number(this) % Number(other); };
1055
+ // Object.prototype polyfills — used by the compiled engine when
1056
+ // checking Ball program inputs (plain objects, not Maps).
1057
+ const op2 = Object.prototype;
1058
+ if (!op2.containsKey) {
1059
+ Object.defineProperty(op2, 'containsKey', {
1060
+ configurable: true, writable: true, enumerable: false,
1061
+ value: function (k) {
1062
+ if (this instanceof Map)
1063
+ return this.has(k);
1064
+ if (this == null || typeof this !== 'object')
1065
+ return false;
1066
+ return Object.prototype.hasOwnProperty.call(this, k);
1067
+ },
1068
+ });
1069
+ }
1070
+ // putIfAbsent — Dart Map.putIfAbsent. Works on plain objects too.
1071
+ if (!op2.putIfAbsent) {
1072
+ Object.defineProperty(op2, 'putIfAbsent', {
1073
+ configurable: true, writable: true, enumerable: false,
1074
+ value: function (k, supplier) {
1075
+ if (this instanceof Map) {
1076
+ if (!this.has(k))
1077
+ this.set(k, supplier());
1078
+ return this.get(k);
1079
+ }
1080
+ if (!(k in this))
1081
+ this[k] = supplier();
1082
+ return this[k];
1083
+ },
1084
+ });
1085
+ }
1086
+ // addAll — Dart Map.addAll. Works on plain objects too.
1087
+ if (!op2.addAll) {
1088
+ Object.defineProperty(op2, 'addAll', {
1089
+ configurable: true, writable: true, enumerable: false,
1090
+ value: function (other) {
1091
+ if (this instanceof Map) {
1092
+ if (other instanceof Map) {
1093
+ // _nativeMapEntries, not other.entries() (issue #259).
1094
+ for (const [k, v] of _nativeMapEntries.call(other))
1095
+ this.set(k, v);
1096
+ }
1097
+ else if (other && typeof other === 'object') {
1098
+ for (const k of Object.keys(other))
1099
+ this.set(k, other[k]);
1100
+ }
1101
+ }
1102
+ else {
1103
+ if (other instanceof Map) {
1104
+ for (const [k, v] of other)
1105
+ this[k] = v;
1106
+ }
1107
+ else if (other && typeof other === 'object') {
1108
+ Object.assign(this, other);
1109
+ }
1110
+ }
1111
+ },
1112
+ });
1113
+ }
1114
+ // forEach — Dart Map.forEach. Works on plain objects.
1115
+ // Don't overwrite native Map.prototype.forEach.
1116
+ Object.defineProperty(op2, 'forEach', {
1117
+ configurable: true, writable: true, enumerable: false,
1118
+ value: function (fn) {
1119
+ if (this instanceof Map) {
1120
+ return Map.prototype.forEach.call(this, fn);
1121
+ }
1122
+ if (Array.isArray(this)) {
1123
+ return Array.prototype.forEach.call(this, fn);
1124
+ }
1125
+ // Plain object: Dart Map.forEach(void f(K key, V value))
1126
+ if (typeof fn === 'function') {
1127
+ for (const k of Object.keys(this))
1128
+ fn(k, this[k]);
1129
+ }
1130
+ },
1131
+ });
1132
+ // remove — Dart Map.remove.
1133
+ if (!op2.remove) {
1134
+ Object.defineProperty(op2, 'remove', {
1135
+ configurable: true, writable: true, enumerable: false,
1136
+ value: function (k) {
1137
+ if (this instanceof Map) {
1138
+ const v = this.get(k);
1139
+ this.delete(k);
1140
+ return v;
1141
+ }
1142
+ const v = this[k];
1143
+ delete this[k];
1144
+ return v;
1145
+ },
1146
+ });
1147
+ }
1148
+ // cast — Dart Map.cast<K2,V2>() / List.cast<E2>(). The cast is a static
1149
+ // re-typing only; at runtime it returns the same collection unchanged.
1150
+ if (!op2.cast) {
1151
+ Object.defineProperty(op2, 'cast', {
1152
+ configurable: true, writable: true, enumerable: false,
1153
+ value: function () { return this; },
1154
+ });
1155
+ }
1156
+ // Dart Map has .entries / .keys / .values as GETTERS (no parens).
1157
+ // JS Map has them as METHODS (need parens). The compiled engine
1158
+ // accesses map.entries as a getter. Shadow BOTH Map.prototype AND
1159
+ // Object.prototype so Map and plain-object dispatch tables work.
1160
+ // (_nativeMapEntries/_nativeMapKeys/_nativeMapValues are captured at
1161
+ // top level above, not here, so other call sites outside this IIFE
1162
+ // can reach them too -- issue #259.)
1163
+ // Shadow Map.prototype.entries with a getter (Dart uses it as a getter).
1164
+ Object.defineProperty(Map.prototype, 'entries', {
1165
+ configurable: true, enumerable: false,
1166
+ get() {
1167
+ return [..._nativeMapEntries.call(this)].map(([k, v]) => ({ key: k, value: v }));
1168
+ },
1169
+ });
1170
+ Object.defineProperty(Map.prototype, 'keys', {
1171
+ configurable: true, enumerable: false,
1172
+ get() { return [..._nativeMapKeys.call(this)]; },
1173
+ });
1174
+ Object.defineProperty(Map.prototype, 'values', {
1175
+ configurable: true, enumerable: false,
1176
+ get() { return [..._nativeMapValues.call(this)]; },
1177
+ });
1178
+ // For plain objects — same getters on Object.prototype.
1179
+ // Helper: define a getter on Object.prototype that also allows
1180
+ // own-property assignment (setter stores as a data property on the
1181
+ // instance, shadowing the prototype getter for future accesses).
1182
+ function defDartGetter(name, getter) {
1183
+ Object.defineProperty(op2, name, {
1184
+ configurable: true, enumerable: false,
1185
+ get: getter,
1186
+ set(v) {
1187
+ Object.defineProperty(this, name, {
1188
+ value: v, writable: true, configurable: true, enumerable: true,
1189
+ });
1190
+ },
1191
+ });
1192
+ }
1193
+ // .entries/.keys/.values on a non-Map must FAIL LOUD (throw a catchable
1194
+ // error), not silently return [] — the silent-degradation class of bug
1195
+ // that hid issue #55 (mirrors the fix already applied to the Dart/C++
1196
+ // compilers). .entries used to be the odd one out here, silently
1197
+ // returning [] instead of throwing — same bug family as #218.
1198
+ //
1199
+ // A getter installed on Object.prototype is invoked in "sloppy" (non-strict)
1200
+ // script contexts with this auto-boxed to a Number/String/Boolean WRAPPER
1201
+ // object for a primitive receiver (e.g. (42).keys boxes this to a Number
1202
+ // instance) — typeof this is then 'object', not 'number', so a bare
1203
+ // __ball_is_type(this, 'Map') (which only excludes Array/BallDouble/Set)
1204
+ // would wrongly treat a boxed int/string as Map-like. Exclude the wrapper
1205
+ // types explicitly instead of widening the shared type-check.
1206
+ const __isGenuineMap = (v) => typeof v === 'object' && v !== null && !Array.isArray(v) &&
1207
+ !(v instanceof BallDouble) && !(v instanceof Set) &&
1208
+ !(v instanceof Number) && !(v instanceof String) && !(v instanceof Boolean);
1209
+ defDartGetter('entries', function () {
1210
+ if (this instanceof Map)
1211
+ return [..._nativeMapEntries.call(this)].map(([k, v]) => ({ key: k, value: v }));
1212
+ if (!__isGenuineMap(this)) {
1213
+ throw new Error('type \'' + __ball_to_string(this) + '\' has no .entries getter (not a Map)');
1214
+ }
1215
+ return Object.entries(this).map(([k, v]) => ({ key: k, value: v }));
1216
+ });
1217
+ defDartGetter('keys', function () {
1218
+ if (this instanceof Map)
1219
+ return [..._nativeMapKeys.call(this)];
1220
+ if (!__isGenuineMap(this)) {
1221
+ throw new Error('type \'' + __ball_to_string(this) + '\' has no .keys getter (not a Map)');
1222
+ }
1223
+ return Object.keys(this);
1224
+ });
1225
+ defDartGetter('values', function () {
1226
+ if (this instanceof Map)
1227
+ return [..._nativeMapValues.call(this)];
1228
+ if (!__isGenuineMap(this)) {
1229
+ throw new Error('type \'' + __ball_to_string(this) + '\' has no .values getter (not a Map)');
1230
+ }
1231
+ return Object.values(this);
1232
+ });
1233
+ defDartGetter('length', function () {
1234
+ if (this instanceof Map)
1235
+ return this.size;
1236
+ if (this instanceof Set)
1237
+ return this.size;
1238
+ if (typeof this === 'string' || Array.isArray(this))
1239
+ return this.length;
1240
+ if (this == null || typeof this !== 'object')
1241
+ return 0;
1242
+ return Object.keys(this).filter((k) => !k.startsWith('__')).length;
1243
+ });
1244
+ // runtimeType — Dart's Object.runtimeType. Returns the Dart-style
1245
+ // type name for any JS value. Used by the compiled engine for type
1246
+ // checking and error messages.
1247
+ Object.defineProperty(op2, 'runtimeType', {
1248
+ configurable: true, enumerable: false,
1249
+ get() {
1250
+ if (this === null || this === undefined)
1251
+ return 'Null';
1252
+ if (this instanceof BallDouble)
1253
+ return 'double';
1254
+ if (typeof this === 'number' || this instanceof Number)
1255
+ return Number.isInteger(+this) ? 'int' : 'double';
1256
+ if (typeof this === 'string' || this instanceof String)
1257
+ return 'String';
1258
+ if (typeof this === 'boolean' || this instanceof Boolean)
1259
+ return 'bool';
1260
+ if (typeof this === 'function')
1261
+ return 'Function';
1262
+ if (Array.isArray(this))
1263
+ return 'List';
1264
+ if (this instanceof Set)
1265
+ return 'Set';
1266
+ if (this instanceof Map)
1267
+ return 'Map';
1268
+ if (this instanceof RegExp)
1269
+ return 'RegExp';
1270
+ const t = this['__type__'];
1271
+ if (typeof t === 'string' && t.length > 0) {
1272
+ const ci = t.indexOf(':');
1273
+ return ci >= 0 ? t.substring(ci + 1) : t;
1274
+ }
1275
+ return 'Map';
1276
+ },
1277
+ });
1278
+ // Also add to Number.prototype, String.prototype, Boolean.prototype
1279
+ // (they don't inherit from Object.prototype getters reliably for primitives).
1280
+ Object.defineProperty(Number.prototype, 'runtimeType', {
1281
+ configurable: true, enumerable: false,
1282
+ get() { return Number.isInteger(+this) ? 'int' : 'double'; },
1283
+ });
1284
+ Object.defineProperty(String.prototype, 'runtimeType', {
1285
+ configurable: true, enumerable: false,
1286
+ get() { return 'String'; },
1287
+ });
1288
+ Object.defineProperty(Boolean.prototype, 'runtimeType', {
1289
+ configurable: true, enumerable: false,
1290
+ get() { return 'bool'; },
1291
+ });
1292
+ })();
1293
+ // std.map_keys/std.map_values/std.map_entries (the base-function-call form,
1294
+ // as opposed to the .keys/.values/.entries DART-GETTER-STYLE property
1295
+ // access the defDartGetter block above already guards) must ALSO fail loud
1296
+ // on a non-Map receiver instead of silently returning [] — same "genuine
1297
+ // Map" check, exposed as top-level helpers so compileStdCall's emitted code
1298
+ // can call them (#218).
1299
+ export function __ball_map_keys(m) {
1300
+ // _nativeMapKeys, not m.keys() -- m.keys() would hit the Dart-property-
1301
+ // style getter shadowing Map.prototype.keys and try to invoke its
1302
+ // return value (an array) as a function (issue #259).
1303
+ if (m instanceof Map)
1304
+ return [..._nativeMapKeys.call(m)];
1305
+ if (typeof m !== 'object' || m === null || Array.isArray(m) ||
1306
+ m instanceof BallDouble || m instanceof Set ||
1307
+ m instanceof Number || m instanceof String || m instanceof Boolean) {
1308
+ throw new Error('type \'' + __ball_to_string(m) + '\' has no .keys getter (not a Map)');
1309
+ }
1310
+ return Object.keys(m);
1311
+ }
1312
+ export function __ball_map_values(m) {
1313
+ // _nativeMapValues, not m.values() (issue #259 -- see __ball_map_keys).
1314
+ if (m instanceof Map)
1315
+ return [..._nativeMapValues.call(m)];
1316
+ if (typeof m !== 'object' || m === null || Array.isArray(m) ||
1317
+ m instanceof BallDouble || m instanceof Set ||
1318
+ m instanceof Number || m instanceof String || m instanceof Boolean) {
1319
+ throw new Error('type \'' + __ball_to_string(m) + '\' has no .values getter (not a Map)');
1320
+ }
1321
+ return Object.values(m);
1322
+ }
1323
+ export function __ball_map_entries(m) {
1324
+ // _nativeMapEntries, not m.entries() (issue #259 -- see __ball_map_keys).
1325
+ if (m instanceof Map)
1326
+ return [..._nativeMapEntries.call(m)].map(([k, v]) => ({ key: k, value: v }));
1327
+ if (typeof m !== 'object' || m === null || Array.isArray(m) ||
1328
+ m instanceof BallDouble || m instanceof Set ||
1329
+ m instanceof Number || m instanceof String || m instanceof Boolean) {
1330
+ throw new Error('type \'' + __ball_to_string(m) + '\' has no .entries getter (not a Map)');
1331
+ }
1332
+ return Object.entries(m).map(([k, v]) => ({ key: k, value: v }));
1333
+ }
1334
+ // Shared guard for the REMAINING map_* base-function-call cases
1335
+ // (map_get/map_set/map_delete/map_merge/map_length/map_is_empty/
1336
+ // map_contains_key/map_contains_value/map_foreach) that used to route a
1337
+ // bare map[key], Object.keys/values(map), or key in map straight to the
1338
+ // receiver with no type check at all -- silently returning undefined,
1339
+ // no-opping, or checking array-index membership instead of throwing on a
1340
+ // non-Map (issue #55's silent-degradation class, same family as #218's
1341
+ // map_keys/map_values/map_entries). Returns the validated Map/plain-object
1342
+ // itself (not a boolean) so a call site can keep using it directly, e.g.
1343
+ // __ball_require_map(x, 'map_get')[key].
1344
+ export function __ball_require_map(v, opName) {
1345
+ if (v instanceof Map)
1346
+ return v;
1347
+ if (typeof v !== 'object' || v === null || Array.isArray(v) ||
1348
+ v instanceof BallDouble || v instanceof Set ||
1349
+ v instanceof Number || v instanceof String || v instanceof Boolean) {
1350
+ throw new Error('type \'' + __ball_to_string(v) + '\' is not a Map (' + opName + ')');
1351
+ }
1352
+ return v;
1353
+ }
1354
+ // ── Protobuf Struct/Value compatibility ─────────────────────────
1355
+ //
1356
+ // Dart's protobuf runtime wraps google.protobuf.Struct as a class
1357
+ // with .fields (Map<String, Value>) and Value as .whichKind() +
1358
+ // .stringValue / .boolValue / .numberValue / .listValue / .structValue.
1359
+ // In proto3 JSON, these serialize as plain objects and values.
1360
+ //
1361
+ // This shim makes plain JSON objects behave like Struct/Value so the
1362
+ // compiled engine.dart can call .fields['key'].whichKind() etc.
1363
+ //
1364
+ // Strategy: Object.prototype gets a .fields getter that returns a
1365
+ // Proxy wrapping the object as a Map-like. Accessing [key] on the
1366
+ // proxy returns a Value-like wrapper with .whichKind() / typed
1367
+ // accessors (.stringValue, .boolValue, .numberValue, .listValue,
1368
+ // .structValue).
1369
+ export const structpb_Value_Kind = {
1370
+ nullValue: 'nullValue',
1371
+ numberValue: 'numberValue',
1372
+ stringValue: 'stringValue',
1373
+ boolValue: 'boolValue',
1374
+ structValue: 'structValue',
1375
+ listValue: 'listValue',
1376
+ };
1377
+ export class __BallValueWrapper {
1378
+ _raw;
1379
+ constructor(raw) { this._raw = raw; }
1380
+ whichKind() {
1381
+ const v = this._raw;
1382
+ if (v === null || v === undefined)
1383
+ return 'nullValue';
1384
+ if (typeof v === 'string')
1385
+ return 'stringValue';
1386
+ if (typeof v === 'boolean')
1387
+ return 'boolValue';
1388
+ if (typeof v === 'number')
1389
+ return 'numberValue';
1390
+ if (Array.isArray(v))
1391
+ return 'listValue';
1392
+ if (typeof v === 'object')
1393
+ return 'structValue';
1394
+ return 'nullValue';
1395
+ }
1396
+ get stringValue() { return typeof this._raw === 'string' ? this._raw : String(this._raw ?? ''); }
1397
+ get boolValue() { return !!this._raw; }
1398
+ get numberValue() { return Number(this._raw); }
1399
+ get nullValue() { return null; }
1400
+ get listValue() {
1401
+ const arr = Array.isArray(this._raw) ? this._raw : [];
1402
+ return { values: arr.map((v) => new __BallValueWrapper(v)) };
1403
+ }
1404
+ get structValue() {
1405
+ const obj = (typeof this._raw === 'object' && this._raw !== null) ? this._raw : {};
1406
+ const fields = {};
1407
+ for (const [k, v] of Object.entries(obj))
1408
+ fields[k] = new __BallValueWrapper(v);
1409
+ return { fields };
1410
+ }
1411
+ // Also proxy hasXxx for sub-values.
1412
+ hasNullValue() { return this._raw == null; }
1413
+ hasStringValue() { return typeof this._raw === 'string'; }
1414
+ hasBoolValue() { return typeof this._raw === 'boolean'; }
1415
+ hasNumberValue() { return typeof this._raw === 'number'; }
1416
+ hasListValue() { return Array.isArray(this._raw); }
1417
+ hasStructValue() { return typeof this._raw === 'object' && this._raw !== null && !Array.isArray(this._raw); }
1418
+ // Pass-through for when the wrapper is used in expressions.
1419
+ toString() { return String(this._raw); }
1420
+ valueOf() { return this._raw; }
1421
+ }
1422
+ // Struct.fields shimming is done via a metadata-specific wrapper.
1423
+ // We do NOT add .fields to Object.prototype because it conflicts
1424
+ // with data properties named "fields" on MessageCreation / TypeDef.
1425
+ // Instead, the compiled engine accesses metadata.fields['key'] —
1426
+ // in proto3 JSON, metadata IS the fields directly, so we add a
1427
+ // .fields getter only when the object is a metadata Struct (i.e.,
1428
+ // it has string/bool/number/array/object values and no proto-shape
1429
+ // keys like "call"/"literal"/"block").
1430
+ //
1431
+ // The protoWrap normalizer in the test harness is responsible for
1432
+ // converting metadata objects to have the right shape.
1433
+ // ── Protobuf compatibility shims ────────────────────────────────
1434
+ //
1435
+ // The Dart encoder produces code that uses Dart's protobuf runtime
1436
+ // API (.whichExpr(), Expression_Expr.call, .hasInput(), .toInt(), etc.)
1437
+ // on what are really plain JSON objects at runtime. These shims make
1438
+ // the proto-style method calls work on plain objects so the compiled
1439
+ // engine.dart can execute on Node.
1440
+ // Oneof discriminator enums — string-valued constants that match the
1441
+ // field names the Dart protobuf codegen uses.
1442
+ export const Expression_Expr = {
1443
+ call: 'call', literal: 'literal', reference: 'reference',
1444
+ fieldAccess: 'fieldAccess', messageCreation: 'messageCreation',
1445
+ block: 'block', lambda: 'lambda', notSet: 'notSet',
1446
+ };
1447
+ export const Literal_Value = {
1448
+ intValue: 'intValue', doubleValue: 'doubleValue',
1449
+ stringValue: 'stringValue', boolValue: 'boolValue',
1450
+ listValue: 'listValue', bytesValue: 'bytesValue', notSet: 'notSet',
1451
+ };
1452
+ export const Statement_Stmt = {
1453
+ let: 'let', expression: 'expression', notSet: 'notSet',
1454
+ };
1455
+ export const ModuleImport_Source = {
1456
+ http: 'http', file: 'file', inline: 'inline',
1457
+ git: 'git', registry: 'registry', notSet: 'notSet',
1458
+ };
1459
+ // Object.prototype shims for .whichXxx() / .hasXxx() / .toInt() —
1460
+ // these match the Dart protobuf generated API. Each is configurable
1461
+ // and non-enumerable so it doesn't pollute for-in loops.
1462
+ (function installProtoShims() {
1463
+ const op = Object.prototype;
1464
+ function defMethod(name, fn) {
1465
+ if (op[name])
1466
+ return;
1467
+ Object.defineProperty(op, name, {
1468
+ configurable: true, writable: true, enumerable: false, value: fn,
1469
+ });
1470
+ }
1471
+ // whichExpr / whichValue / whichStmt / whichSource — return which
1472
+ // oneof field is set on this object.
1473
+ defMethod('whichExpr', function () {
1474
+ for (const k of ['call', 'literal', 'reference', 'fieldAccess', 'messageCreation', 'block', 'lambda']) {
1475
+ if (this[k] !== undefined && this[k] !== null)
1476
+ return k;
1477
+ }
1478
+ return 'notSet';
1479
+ });
1480
+ defMethod('whichValue', function () {
1481
+ for (const k of ['intValue', 'doubleValue', 'stringValue', 'boolValue', 'listValue', 'bytesValue']) {
1482
+ if (this[k] !== undefined && this[k] !== null)
1483
+ return k;
1484
+ }
1485
+ return 'notSet';
1486
+ });
1487
+ defMethod('whichStmt', function () {
1488
+ if (this['let'] !== undefined && this['let'] !== null)
1489
+ return 'let';
1490
+ if (this['expression'] !== undefined && this['expression'] !== null)
1491
+ return 'expression';
1492
+ return 'notSet';
1493
+ });
1494
+ defMethod('whichSource', function () {
1495
+ for (const k of ['http', 'file', 'inline', 'git', 'registry']) {
1496
+ if (this[k] !== undefined && this[k] !== null)
1497
+ return k;
1498
+ }
1499
+ return 'notSet';
1500
+ });
1501
+ // Presence checks — .hasXxx() returns true if the field is set.
1502
+ for (const field of [
1503
+ 'input', 'body', 'result', 'metadata', 'value', 'name', 'module',
1504
+ 'left', 'right', 'condition', 'then', 'else', 'finally',
1505
+ 'subject', 'cases', 'catches', 'init', 'update', 'iterable',
1506
+ 'target', 'index', 'field', 'object', 'key', 'message',
1507
+ 'stringValue', 'boolValue', 'intValue', 'doubleValue', 'listValue',
1508
+ 'call', 'literal', 'reference', 'fieldAccess', 'messageCreation',
1509
+ 'block', 'lambda', 'let', 'expression', 'descriptor',
1510
+ ]) {
1511
+ const methodName = 'has' + field[0].toUpperCase() + field.slice(1);
1512
+ defMethod(methodName, function () {
1513
+ return this[field] !== undefined && this[field] !== null;
1514
+ });
1515
+ }
1516
+ // Proto field-name aliases — Dart's protobuf codegen renames some
1517
+ // fields to avoid keyword collisions (field → field_2, etc.) but
1518
+ // proto3 JSON uses the original names. Add getters so both work.
1519
+ Object.defineProperty(op, 'field_2', {
1520
+ configurable: true, enumerable: false,
1521
+ get() { return this.field; },
1522
+ set(v) { this.field = v; },
1523
+ });
1524
+ // descriptor_ → descriptor (same issue)
1525
+ Object.defineProperty(op, 'descriptor_', {
1526
+ configurable: true, enumerable: false,
1527
+ get() { return this.descriptor; },
1528
+ set(v) { this.descriptor = v; },
1529
+ });
1530
+ // .toInt() — Dart's Int64/fixnum returns int from string. In proto3
1531
+ // JSON, int64 fields are serialized as strings ("42" not 42).
1532
+ defMethod('toInt', function () {
1533
+ if (typeof this === 'number')
1534
+ return this;
1535
+ if (typeof this === 'string')
1536
+ return parseInt(this, 10);
1537
+ if (typeof this.valueOf === 'function')
1538
+ return parseInt(String(this.valueOf()), 10);
1539
+ return 0;
1540
+ });
1541
+ // .toList() on Uint8Array (bytesValue)
1542
+ defMethod('toList', function () {
1543
+ if (this instanceof Uint8Array)
1544
+ return Array.from(this);
1545
+ if (Array.isArray(this))
1546
+ return this.slice();
1547
+ return [];
1548
+ });
1549
+ })();
1550
+ // ── Reified generics helpers ────────────────────────────────────────
1551
+ export function __ball_with_type_args(obj, args) {
1552
+ obj.__type_args__ = args;
1553
+ return obj;
1554
+ }
1555
+ // ── Generic type checking helper ────────────────────────────────────
1556
+ export function __ball_split_type_args(s) {
1557
+ const result = [];
1558
+ let depth = 0, start = 0;
1559
+ for (let i = 0; i < s.length; i++) {
1560
+ if (s[i] === '<')
1561
+ depth++;
1562
+ else if (s[i] === '>')
1563
+ depth--;
1564
+ else if (s[i] === ',' && depth === 0) {
1565
+ result.push(s.slice(start, i).trim());
1566
+ start = i + 1;
1567
+ }
1568
+ }
1569
+ const last = s.slice(start).trim();
1570
+ if (last)
1571
+ result.push(last);
1572
+ return result;
1573
+ }
1574
+ export function __ball_is_type(value, typeStr) {
1575
+ const t = typeStr.trim();
1576
+ if (t.endsWith('?')) {
1577
+ if (value == null)
1578
+ return true;
1579
+ return __ball_is_type(value, t.slice(0, -1));
1580
+ }
1581
+ const ltIdx = t.indexOf('<');
1582
+ if (ltIdx === -1) {
1583
+ switch (t) {
1584
+ case 'int': return typeof value === 'number' && Number.isInteger(value);
1585
+ case 'double': return value instanceof BallDouble || (typeof value === 'number' && !Number.isInteger(value));
1586
+ case 'num':
1587
+ case 'number': return typeof value === 'number' || value instanceof BallDouble;
1588
+ case 'String':
1589
+ case 'string': return typeof value === 'string';
1590
+ case 'bool':
1591
+ case 'boolean': return typeof value === 'boolean';
1592
+ case 'List':
1593
+ case 'Iterable': return Array.isArray(value);
1594
+ case 'Map': return typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof BallDouble) && !(value instanceof Set);
1595
+ case 'Set': return value instanceof Set;
1596
+ case 'Null': return value == null;
1597
+ case 'Function': return typeof value === 'function';
1598
+ case 'Object':
1599
+ case 'dynamic': return value != null;
1600
+ default: {
1601
+ const objType = value?.__type__ ?? value?.constructor?.name;
1602
+ if (objType === t)
1603
+ return true;
1604
+ return value != null;
1605
+ }
1606
+ }
1607
+ }
1608
+ const baseType = t.slice(0, ltIdx).trim();
1609
+ const typeArgs = __ball_split_type_args(t.slice(ltIdx + 1, t.lastIndexOf('>')));
1610
+ switch (baseType) {
1611
+ case 'List':
1612
+ case 'Iterable':
1613
+ if (!Array.isArray(value))
1614
+ return false;
1615
+ if (typeArgs.length === 0)
1616
+ return true;
1617
+ return value.every((e) => __ball_is_type(e, typeArgs[0]));
1618
+ case 'Map':
1619
+ if (typeof value !== 'object' || value === null || Array.isArray(value) || value instanceof BallDouble || value instanceof Set)
1620
+ return false;
1621
+ if (typeArgs.length < 2)
1622
+ return true;
1623
+ return Object.keys(value).filter((k) => !k.startsWith('__')).every((k) => __ball_is_type(k, typeArgs[0]) && __ball_is_type(value[k], typeArgs[1]));
1624
+ case 'Set':
1625
+ if (!(value instanceof Set))
1626
+ return false;
1627
+ if (typeArgs.length === 0)
1628
+ return true;
1629
+ for (const e of value) {
1630
+ if (!__ball_is_type(e, typeArgs[0]))
1631
+ return false;
1632
+ }
1633
+ return true;
1634
+ default: {
1635
+ const objType = value?.__type__ ?? value?.constructor?.name;
1636
+ if (objType === baseType) {
1637
+ const objArgs = value.__type_args__;
1638
+ if (Array.isArray(objArgs)) {
1639
+ if (objArgs.length !== typeArgs.length)
1640
+ return false;
1641
+ return objArgs.every((a, i) => String(a).trim() === typeArgs[i].trim());
1642
+ }
1643
+ return false;
1644
+ }
1645
+ return __ball_is_type(value, baseType);
1646
+ }
1647
+ }
1648
+ }
1649
+ // Minimal DateTime / Duration / Future polyfills used by std_time and
1650
+ // the round-tripped engine's sleep_ms helper. Wide enough for the
1651
+ // conformance suite, narrow enough to stay out of users' way.
1652
+ export class DateTime {
1653
+ _epochMs;
1654
+ isUtc;
1655
+ constructor(epochMs, isUtc = false) {
1656
+ this._epochMs = typeof epochMs === 'number' ? epochMs : Date.now();
1657
+ this.isUtc = isUtc;
1658
+ }
1659
+ static now() { return new DateTime(Date.now(), false); }
1660
+ static fromMillisecondsSinceEpoch(ms, isUtc = false) {
1661
+ return new DateTime(ms, isUtc === true || (isUtc && isUtc.isUtc === true));
1662
+ }
1663
+ static parse(s) { return new DateTime(Date.parse(s), true); }
1664
+ get millisecondsSinceEpoch() { return this._epochMs; }
1665
+ get microsecondsSinceEpoch() { return this._epochMs * 1000; }
1666
+ toUtc() { return new DateTime(this._epochMs, true); }
1667
+ toIso8601String() { return new Date(this._epochMs).toISOString(); }
1668
+ get year() { return new Date(this._epochMs).getUTCFullYear(); }
1669
+ get month() { return new Date(this._epochMs).getUTCMonth() + 1; }
1670
+ get day() { return new Date(this._epochMs).getUTCDate(); }
1671
+ get hour() { return new Date(this._epochMs).getUTCHours(); }
1672
+ get minute() { return new Date(this._epochMs).getUTCMinutes(); }
1673
+ get second() { return new Date(this._epochMs).getUTCSeconds(); }
1674
+ }
1675
+ export class Duration {
1676
+ _us;
1677
+ constructor(opts) {
1678
+ const o = opts ?? {};
1679
+ const ms = o.milliseconds ?? 0;
1680
+ const s = o.seconds ?? 0;
1681
+ const m = o.minutes ?? 0;
1682
+ const us = o.microseconds ?? 0;
1683
+ this._us = us + ms * 1000 + s * 1_000_000 + m * 60_000_000;
1684
+ }
1685
+ get inMilliseconds() { return Math.floor(this._us / 1000); }
1686
+ get inMicroseconds() { return this._us; }
1687
+ }
1688
+ export const Future = {
1689
+ delayed(d) {
1690
+ const ms = (d && typeof d.inMilliseconds === 'number') ? d.inMilliseconds : Number(d ?? 0);
1691
+ return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
1692
+ },
1693
+ value(v) { return Promise.resolve(v); },
1694
+ };
1695
+ // ── dart:typed_data shims (ByteData, Endian) ───────────────────────
1696
+ // ball_protobuf uses ByteData for IEEE 754 float/double bit conversion.
1697
+ // Dart's ByteData wraps a fixed-size byte buffer with typed get/set methods.
1698
+ export const Endian = { little: true, big: false, host: true };
1699
+ export class ByteData {
1700
+ _view;
1701
+ _length;
1702
+ constructor(size) {
1703
+ this._view = new DataView(new ArrayBuffer(size));
1704
+ this._length = size;
1705
+ }
1706
+ get lengthInBytes() { return this._length; }
1707
+ getUint8(i) { return this._view.getUint8(i); }
1708
+ setUint8(i, v) { this._view.setUint8(i, v); }
1709
+ getInt8(i) { return this._view.getInt8(i); }
1710
+ setInt8(i, v) { this._view.setInt8(i, v); }
1711
+ getUint16(i, endian) { return this._view.getUint16(i, endian === Endian.little); }
1712
+ setUint16(i, v, endian) { this._view.setUint16(i, v, endian === Endian.little); }
1713
+ getInt16(i, endian) { return this._view.getInt16(i, endian === Endian.little); }
1714
+ setInt16(i, v, endian) { this._view.setInt16(i, v, endian === Endian.little); }
1715
+ getUint32(i, endian) { return this._view.getUint32(i, endian === Endian.little); }
1716
+ setUint32(i, v, endian) { this._view.setUint32(i, v, endian === Endian.little); }
1717
+ getInt32(i, endian) { return this._view.getInt32(i, endian === Endian.little); }
1718
+ setInt32(i, v, endian) { this._view.setInt32(i, v, endian === Endian.little); }
1719
+ getFloat32(i, endian) { return this._view.getFloat32(i, endian === Endian.little); }
1720
+ setFloat32(i, v, endian) { this._view.setFloat32(i, v, endian === Endian.little); }
1721
+ getFloat64(i, endian) { return this._view.getFloat64(i, endian === Endian.little); }
1722
+ setFloat64(i, v, endian) { this._view.setFloat64(i, v, endian === Endian.little); }
1723
+ getUint64(i, endian) {
1724
+ const lo = this._view.getUint32(i, endian === Endian.little);
1725
+ const hi = this._view.getUint32(i + 4, endian === Endian.little);
1726
+ return endian === Endian.little
1727
+ ? BigInt(lo) | (BigInt(hi) << 32n)
1728
+ : (BigInt(lo) << 32n) | BigInt(hi);
1729
+ }
1730
+ setUint64(i, v, endian) {
1731
+ const lo = Number(v & 0xffffffffn);
1732
+ const hi = Number((v >> 32n) & 0xffffffffn);
1733
+ if (endian === Endian.little) {
1734
+ this._view.setUint32(i, lo, true);
1735
+ this._view.setUint32(i + 4, hi, true);
1736
+ }
1737
+ else {
1738
+ this._view.setUint32(i, hi, false);
1739
+ this._view.setUint32(i + 4, lo, false);
1740
+ }
1741
+ }
1742
+ getInt64(i, endian) {
1743
+ const unsigned = this.getUint64(i, endian);
1744
+ return unsigned >= 0x8000000000000000n ? unsigned - 0x10000000000000000n : unsigned;
1745
+ }
1746
+ setInt64(i, v, endian) {
1747
+ this.setUint64(i, v < 0n ? v + 0x10000000000000000n : v, endian);
1748
+ }
1749
+ get buffer() {
1750
+ const view = this._view;
1751
+ return {
1752
+ asUint8List: (start, length) => {
1753
+ const s = start ?? 0;
1754
+ const l = length ?? view.byteLength - s;
1755
+ return [...new Uint8Array(view.buffer, s, l)];
1756
+ },
1757
+ };
1758
+ }
1759
+ }
1760
+ // ── dart:convert shims (utf8, jsonEncode, jsonDecode) ───────────────
1761
+ // ball_protobuf uses utf8.encode/decode for string↔bytes and
1762
+ // jsonEncode/jsonDecode for JSON serialization.
1763
+ export const utf8 = {
1764
+ encode(s) { return [...new TextEncoder().encode(s)]; },
1765
+ decode(bytes) { return new TextDecoder().decode(new Uint8Array(bytes)); },
1766
+ };
1767
+ export function jsonEncode(obj) { return JSON.stringify(obj); }
1768
+ export function jsonDecode(s) { return JSON.parse(s); }
1769
+ export function __isUnknownFnError(e) {
1770
+ const m = e && typeof e.message === 'string' ? e.message : (typeof e === 'string' ? e : '');
1771
+ return m.startsWith('Unknown std function:') || m.startsWith('Unknown base module:');
1772
+ }
1773
+ export function versionLine(version) {
1774
+ const input = version;
1775
+ return ('ball ' + __ball_to_string(version));
1776
+ }
1777
+ export function infoReport(program) {
1778
+ const input = program;
1779
+ let lines = [];
1780
+ lines = (lines.push(((('Program: ' + __ball_to_string(program.name)) + ' v') + __ball_to_string(program.version))), lines);
1781
+ lines = (lines.push(((('Entry: ' + __ball_to_string(program.entryModule)) + '.') + __ball_to_string(program.entryFunction))), lines);
1782
+ lines = (lines.push(('Modules: ' + __ball_to_string(program.modules.length))), lines);
1783
+ lines = (lines.push(''), lines);
1784
+ for (const module of program.modules) {
1785
+ let isBase = _allBase(module.functions);
1786
+ lines = (lines.push(((' ' + __ball_to_string(module.name)) + __ball_to_string((isBase ? ' (base)' : '')))), lines);
1787
+ if (!(module.typeDefs.length === 0)) {
1788
+ lines = (lines.push((' typeDefs: ' + __ball_to_string(module.typeDefs.length))), lines);
1789
+ }
1790
+ if (!(module.typeAliases.length === 0)) {
1791
+ lines = (lines.push((' aliases: ' + __ball_to_string(module.typeAliases.length))), lines);
1792
+ }
1793
+ if (!(module.enums.length === 0)) {
1794
+ lines = (lines.push((' enums: ' + __ball_to_string(module.enums.length))), lines);
1795
+ }
1796
+ lines = (lines.push((' functions: ' + __ball_to_string(module.functions.length))), lines);
1797
+ if (!(module.description.length === 0)) {
1798
+ lines = (lines.push((' desc: ' + __ball_to_string(module.description))), lines);
1799
+ }
1800
+ }
1801
+ return lines.join('\n');
1802
+ }
1803
+ export function validationErrors(program) {
1804
+ const input = program;
1805
+ let errors = [];
1806
+ if ((program.entryModule.length === 0)) {
1807
+ errors = (errors.push('Missing entry_module'), errors);
1808
+ }
1809
+ if ((program.entryFunction.length === 0)) {
1810
+ errors = (errors.push('Missing entry_function'), errors);
1811
+ }
1812
+ if ((!(program.entryModule.length === 0) && !(program.entryFunction.length === 0))) {
1813
+ let entryMod;
1814
+ for (const m of program.modules) {
1815
+ if (__ball_eq(m.name, program.entryModule)) {
1816
+ entryMod = m;
1817
+ break;
1818
+ }
1819
+ }
1820
+ if (__ball_eq(entryMod, null)) {
1821
+ errors = (errors.push((('Entry module "' + __ball_to_string(program.entryModule)) + '" not found in modules')), errors);
1822
+ }
1823
+ else {
1824
+ let entryFunc;
1825
+ for (const f of entryMod.functions) {
1826
+ if (__ball_eq(f.name, program.entryFunction)) {
1827
+ entryFunc = f;
1828
+ break;
1829
+ }
1830
+ }
1831
+ if (__ball_eq(entryFunc, null)) {
1832
+ errors = (errors.push(((('Entry function "' + __ball_to_string(program.entryFunction)) + '" not found ') + (('in module "' + __ball_to_string(program.entryModule)) + '"'))), errors);
1833
+ }
1834
+ }
1835
+ }
1836
+ for (let i = 0; __ball_lt(i, program.modules.length); (i++)) {
1837
+ let m = __ball_index(program.modules, i);
1838
+ if ((m.name.length === 0)) {
1839
+ errors = (errors.push((('Module at index ' + __ball_to_string(i)) + ' has no name')), errors);
1840
+ }
1841
+ }
1842
+ let seen = [];
1843
+ for (const m of program.modules) {
1844
+ if (!(m.name.length === 0)) {
1845
+ if (seen.includes(m.name)) {
1846
+ errors = (errors.push((('Duplicate module name: "' + __ball_to_string(m.name)) + '"')), errors);
1847
+ }
1848
+ else {
1849
+ seen = (seen.push(m.name), seen);
1850
+ }
1851
+ }
1852
+ }
1853
+ for (const m of program.modules) {
1854
+ for (const f of m.functions) {
1855
+ if (((!f.isBase && !hasBody(f)) && !hasMetadata(f))) {
1856
+ errors = (errors.push((((__ball_to_string(m.name) + '.') + __ball_to_string(f.name)) + ': non-base function with no body or metadata')), errors);
1857
+ }
1858
+ }
1859
+ }
1860
+ return errors;
1861
+ }
1862
+ export function validateOk(program) {
1863
+ const input = program;
1864
+ return (validationErrors(program).length === 0);
1865
+ }
1866
+ export function validateReport(program) {
1867
+ const input = program;
1868
+ let errors = validationErrors(program);
1869
+ if ((errors.length === 0)) {
1870
+ let totalFns = 0;
1871
+ for (const m of program.modules) {
1872
+ totalFns += m.functions.length;
1873
+ }
1874
+ return ((((('Valid: "' + __ball_to_string(program.name)) + '" v') + __ball_to_string(program.version)) + '\n') + ((((' ' + __ball_to_string(program.modules.length)) + ' modules, ') + __ball_to_string(totalFns)) + ' functions'));
1875
+ }
1876
+ let lines = [];
1877
+ lines = (lines.push((('Invalid: ' + __ball_to_string(errors.length)) + ' error(s) found')), lines);
1878
+ for (const e of errors) {
1879
+ lines = (lines.push((' - ' + __ball_to_string(e))), lines);
1880
+ }
1881
+ return lines.join('\n');
1882
+ }
1883
+ export function treeReport(program) {
1884
+ const input = program;
1885
+ let lines = [];
1886
+ lines = (lines.push(((__ball_to_string(program.name) + ' v') + __ball_to_string(program.version))), lines);
1887
+ for (const m of program.modules) {
1888
+ let isBase = (_allBase(m.functions) && !(m.functions.length === 0));
1889
+ let tag = (isBase ? ' (base)' : '');
1890
+ let fnCount = m.functions.length;
1891
+ lines = (lines.push((((((' ' + __ball_to_string(m.name)) + __ball_to_string(tag)) + ' \u2014 ') + __ball_to_string(fnCount)) + ' functions')), lines);
1892
+ for (const imp of m.moduleImports) {
1893
+ lines = (lines.push(((((' \u2192 ' + __ball_to_string(imp.name)) + ' (') + __ball_to_string(_importSource(imp))) + ')')), lines);
1894
+ }
1895
+ }
1896
+ return lines.join('\n');
1897
+ }
1898
+ export function _importSource(imp) {
1899
+ const input = imp;
1900
+ if (hasHttp(imp)) {
1901
+ return ('http: ' + __ball_to_string(imp.http.url));
1902
+ }
1903
+ if (hasFile(imp)) {
1904
+ return ('file: ' + __ball_to_string(imp.file.path));
1905
+ }
1906
+ if (hasGit(imp)) {
1907
+ return ((('git: ' + __ball_to_string(imp.git.url)) + '@') + __ball_to_string(imp.git.ref));
1908
+ }
1909
+ if (hasRegistry(imp)) {
1910
+ return ((__ball_to_string(imp.registry.registry.name) + ': ') + ((__ball_to_string(imp.registry.package) + '@') + __ball_to_string(imp.registry.version)));
1911
+ }
1912
+ if (hasInline(imp)) {
1913
+ return 'inline';
1914
+ }
1915
+ return 'ref only';
1916
+ }
1917
+ export function auditReport(program) {
1918
+ const input = program;
1919
+ let report = analyzeCapabilities(program);
1920
+ let buf = "";
1921
+ buf.writeln(formatCapabilityReport(report));
1922
+ let termReport = analyzeTermination(program);
1923
+ if (!(termReport.warnings.length === 0)) {
1924
+ buf.writeln('');
1925
+ buf.writeln(formatTerminationReport(termReport));
1926
+ }
1927
+ return __ball_to_string(buf);
1928
+ }
1929
+ export function _allBase(functions) {
1930
+ const input = functions;
1931
+ for (const f of functions) {
1932
+ if (!f.isBase) {
1933
+ return false;
1934
+ }
1935
+ }
1936
+ return true;
1937
+ }
1938
+ //# sourceMappingURL=compiled_cli.js.map