// @ts-nocheck — auto-generated // ── Ball runtime preamble (generated by @ball-lang/compiler) ──────── // Base class for all Ball runtime values. class BallValue {} // A cast pattern (value as T) ASSERTS the runtime type — it throws on a type // mismatch (Dart semantics), it does NOT refute / fall through. Conjoined into a // switch-case condition by the compiler; returns true when the type check passed, // else throws a catchable error. (conformance 302_cast_patterns) function ball_cast_assert(ok: boolean, t: string): boolean { if (!ok) throw new Error('TypeError: type cast failed: not a ' + t); return true; } // ── Ball container runtime types ──────────────────────────────────── // // The self-hosted engine IR models class instances as 'BallObject extends // BallMap'. The compiler treats maps/lists transparently (a Ball map is a // plain JS object, a Ball list a plain JS array) and _asMap() returns an // instance verbatim, reading its data through bracket access (obj of f) // and the Object.prototype .entries / .keys / .length getters. To stay // compatible we make BallObject a plain-object-like instance: the field data // lives as OWN ENUMERABLE properties (so bracket access and .entries see it), // while the class bookkeeping (typeName/fields/methods/superObject) is stored // non-enumerably so it never leaks into .entries / .keys / .length. // // BallMap / BallList exist only so 'extends BallMap' resolves and any stray // new BallMap(...) / new BallList(...) behaves like the transparent value. class BallMap extends BallValue { constructor(entries?: any) { super(); if (entries && typeof entries === 'object') { if (entries instanceof Map) { for (const [k, v] of entries) (this as any)[k] = v; } else { for (const k of Object.keys(entries)) (this as any)[k] = entries[k]; } } } } class BallList extends Array { constructor(items?: any) { super(); if (Array.isArray(items)) for (const it of items) this.push(it); } } class BallObject extends BallMap { constructor(arg0?: any, superObject?: any, fields?: any, methods?: any) { super(); // Accept either the named-args object the encoder emits // (new BallObject({typeName, superObject, fields, methods})) or the // positional form, so the class works regardless of how it is invoked. let typeName: any = arg0; if (arg0 && typeof arg0 === 'object' && !Array.isArray(arg0) && ('typeName' in arg0 || 'fields' in arg0 || 'methods' in arg0 || 'superObject' in arg0)) { typeName = arg0.typeName; superObject = arg0.superObject; fields = arg0.fields; methods = arg0.methods; } const fieldMap = (fields && typeof fields === 'object') ? fields : {}; const methodMap = (methods && typeof methods === 'object') ? methods : {}; // Field data → own enumerable properties (visible to bracket access and // the Object.prototype map getters). for (const k of Object.keys(fieldMap)) (this as any)[k] = fieldMap[k]; // Class bookkeeping → own props the engine reads/writes by bracket name. (this as any)['__type__'] = typeName ?? ''; (this as any)['__super__'] = superObject ?? null; (this as any)['__fields__'] = fieldMap; (this as any)['__methods__'] = methodMap; // Mirror the Dart class fields too, but non-enumerably so they never show // up as Ball fields in .entries / .keys / .length. for (const [name, value] of [ ['typeName', typeName ?? ''], ['superObject', superObject ?? null], ['fields', fieldMap], ['methods', methodMap], ] as Array<[string, any]>) { Object.defineProperty(this, name, { value, writable: true, configurable: true, enumerable: false, }); } } setField(name: any, value: any): void { (this as any).fields[name] = value; (this as any)[name] = value; } } (globalThis as any).BallMap = BallMap; (globalThis as any).BallList = BallList; (globalThis as any).BallObject = BallObject; // BallDouble wrapper — tracks that a number should print as a double // (e.g. 42.0 not 42). Used by the compiled Dart engine's _toDouble. class BallDouble { readonly value: number; // Collapse nested wrapping down to the innermost raw number instead of // storing a BallDouble that holds another BallDouble. The concrete source of // nested wrapping was string_to_double's engine handler wrapping the result // of the already-wrapping compiled parse path from issue 222; that redundant // wrap was removed at its root in issue 237, so this guard is now purely // defensive (verified: the full TS engine suite stays green without it). It is // kept as a cheap, idempotent belt-and-suspenders against any other caller // that might wrap an already-wrapped value: a doubly-wrapped BallDouble makes // Number/valueOf coercion throw "Cannot convert object to primitive value". // For a plain-number caller the instanceof check is a no-op. constructor(v: number) { this.value = v instanceof BallDouble ? v.value : v; } valueOf(): number { return this.value; } get isNaN(): boolean { return Number.isNaN(this.value); } get isFinite(): boolean { return Number.isFinite(this.value); } get isInfinite(): boolean { return !Number.isFinite(this.value) && !Number.isNaN(this.value); } get isNegative(): boolean { return this.value < 0 || (this.value === 0 && 1/this.value === -Infinity); } // Mirrors the Number.prototype.remainder polyfill below (truncating // remainder, matching JS % and Dart's num.remainder) — BallDouble wraps // a JS number so it never inherits Number.prototype and needs its own. remainder(other: any): number { return this.value % Number(other); } toString(): string { const v = this.value; if (!isFinite(v)) return v.toString(); if (v === 0 && 1/v === -Infinity) return '-0.0'; if (Number.isInteger(v)) return v.toFixed(1); return v.toString(); } // Arithmetic: unwrap for operations [Symbol.toPrimitive](hint: string): any { if (hint === 'string') return this.toString(); return this.value; } } (globalThis as any).BallDouble = BallDouble; // Arithmetic helpers that propagate BallDouble through operations. // If either operand is BallDouble, the result is BallDouble (preserving .0). // // Operator-overload dispatch checks for __op_X__ methods (TRAILING double // underscore) — this MUST match the Dart encoder's canonical operator naming // (_canonicalOperatorName in dart/encoder/lib/encoder.dart), which always // emits a trailing __. A single-underscore lookup (__op_mul) never matches, // so overloaded operators silently fall through to raw JS arithmetic (#205). function __ball_mul(a: any, b: any): any { if (a != null && typeof a === 'object' && typeof a.__op_mul__ === 'function') return a.__op_mul__(b); if (typeof a === 'bigint' || typeof b === 'bigint') return __i64_wrap(__to_bigint(a) * __to_bigint(b)); const av = a instanceof BallDouble ? a.value : a; const bv = b instanceof BallDouble ? b.value : b; const r = av * bv; return (a instanceof BallDouble || b instanceof BallDouble) ? new BallDouble(r) : r; } function __ball_add(a: any, b: any): any { if (a != null && typeof a === 'object' && typeof a.__op_add__ === 'function') return a.__op_add__(b); if (typeof a === 'bigint' || typeof b === 'bigint') return __i64_wrap(__to_bigint(a) + __to_bigint(b)); const av = a instanceof BallDouble ? a.value : a; const bv = b instanceof BallDouble ? b.value : b; const r = av + bv; return (a instanceof BallDouble || b instanceof BallDouble) ? new BallDouble(r) : r; } function __ball_sub(a: any, b: any): any { if (a != null && typeof a === 'object' && typeof a.__op_sub__ === 'function') return a.__op_sub__(b); if (typeof a === 'bigint' || typeof b === 'bigint') return __i64_wrap(__to_bigint(a) - __to_bigint(b)); const av = a instanceof BallDouble ? a.value : a; const bv = b instanceof BallDouble ? b.value : b; const r = av - bv; return (a instanceof BallDouble || b instanceof BallDouble) ? new BallDouble(r) : r; } // Dart equality: NaN != NaN, BallDouble value comparison, null == undefined. function __ball_eq(a: any, b: any): boolean { if (a != null && typeof a === 'object' && typeof a.__op_eq__ === 'function') return a.__op_eq__(b); if (typeof a === 'bigint' || typeof b === 'bigint') { if (typeof a === 'bigint' && typeof b === 'bigint') return a === b; if (typeof a === 'bigint' && typeof b === 'number') return a === BigInt(b); if (typeof a === 'number' && typeof b === 'bigint') return BigInt(a) === b; return false; } if (a instanceof BallDouble || b instanceof BallDouble) { const av = a instanceof BallDouble ? a.value : a; const bv = b instanceof BallDouble ? b.value : b; if (Number.isNaN(av) || Number.isNaN(bv)) return false; return av === bv; } if (a == null && b == null) return true; if (a == null || b == null) return a == b; return a === b; } // Relational operator-overload dispatch (less-than/greater-than/etc.), // matching the __op_add__-style convention above. Unlike arithmetic, // relational comparisons had NO overload attempt at all before #205 — every // overloaded Vec2 < x etc. compiled straight to raw JS comparison. function __ball_lt(a: any, b: any): any { if (a != null && typeof a === 'object' && typeof a.__op_lt__ === 'function') return a.__op_lt__(b); if (typeof a === 'bigint' || typeof b === 'bigint') return __to_bigint(a) < __to_bigint(b); const av = a instanceof BallDouble ? a.value : a; const bv = b instanceof BallDouble ? b.value : b; return av < bv; } function __ball_gt(a: any, b: any): any { if (a != null && typeof a === 'object' && typeof a.__op_gt__ === 'function') return a.__op_gt__(b); if (typeof a === 'bigint' || typeof b === 'bigint') return __to_bigint(a) > __to_bigint(b); const av = a instanceof BallDouble ? a.value : a; const bv = b instanceof BallDouble ? b.value : b; return av > bv; } function __ball_le(a: any, b: any): any { if (a != null && typeof a === 'object' && typeof a.__op_le__ === 'function') return a.__op_le__(b); if (typeof a === 'bigint' || typeof b === 'bigint') return __to_bigint(a) <= __to_bigint(b); const av = a instanceof BallDouble ? a.value : a; const bv = b instanceof BallDouble ? b.value : b; return av <= bv; } function __ball_ge(a: any, b: any): any { if (a != null && typeof a === 'object' && typeof a.__op_ge__ === 'function') return a.__op_ge__(b); if (typeof a === 'bigint' || typeof b === 'bigint') return __to_bigint(a) >= __to_bigint(b); const av = a instanceof BallDouble ? a.value : a; const bv = b instanceof BallDouble ? b.value : b; return av >= bv; } function __ball_to_string(v: any): string { if (v === null || v === undefined) return 'null'; if (typeof v === 'bigint') return v.toString(); if (typeof v === 'boolean') return v ? 'true' : 'false'; if (v instanceof BallDouble) return v.toString(); if (typeof v === 'number') { if (!isFinite(v) || Number.isNaN(v)) return v.toString(); if (v === 0 && 1/v === -Infinity) return '-0.0'; if (Number.isInteger(v)) return v.toString(); const s = v.toString(); return s.includes('.') || s.includes('e') ? s : s + '.0'; } if (typeof v === 'string') return v; if (Array.isArray(v)) { return '[' + v.map(__ball_to_string).join(', ') + ']'; } if (v instanceof Map) { const parts: string[] = []; // v.entries() as a method call would hit the Dart-property-style // getter of the same name (installed further down in this file) and // try to invoke its return value -- an array -- as a function. // _nativeMapEntries is the real, un-shadowed method (issue #259). for (const [k, val] of _nativeMapEntries.call(v)) { parts.push(__ball_to_string(k) + ': ' + __ball_to_string(val)); } return '{' + parts.join(', ') + '}'; } if (v instanceof Set) { // A Set is a plain object from typeof's perspective (falls through to // the generic branch below, which reads Object.keys — always [] for a // Set's internal slots), so every Set printed as the empty "{}" no // matter its contents until this dedicated case was added (#219). return '{' + [...v].map(__ball_to_string).join(', ') + '}'; } if (typeof v === 'object' && !Array.isArray(v)) { // StringBuffer-like objects if (v['__buffer__'] && Array.isArray(v['__buffer__'])) { return v['__buffer__'].join(''); } // Check for custom toString method on the instance (not Object.prototype). if (v.toString !== Object.prototype.toString && typeof v.toString === 'function') { return v.toString(); } // Dart Map-like object: format as {key: value, ...} const keys = Object.keys(v).filter((k: string) => !k.startsWith('__')); if (keys.length > 0) { return '{' + keys.map((k: string) => __ball_to_string(k) + ': ' + __ball_to_string(v[k])).join(', ') + '}'; } return '{}'; } return String(v); } function __ball_parse_int(s: string): number { const trimmed = s.trim(); if (!/^-?\d+$/.test(trimmed)) { throw new Error('FormatException: ' + s); } return parseInt(trimmed, 10); } // Dart-style int conversion that preserves int64 precision. JS numbers lose // precision above 2^53, so integer literals encoded as decimal strings (the // JSON proto3 representation of int64) would round. When the string magnitude // exceeds Number.MAX_SAFE_INTEGER we return a BigInt to keep the exact value; // otherwise we keep a plain number so the common arithmetic path is unchanged. function __ball_to_int(v: any): any { if (typeof v === 'bigint') return v; if (typeof v === 'string') { if (/^-?\d+$/.test(v)) { const b = BigInt(v); if (b > 9007199254740991n || b < -9007199254740991n) return b; return Number(b); } return Math.trunc(Number(v)) || 0; } const n = (v instanceof BallDouble) ? v.value : v; const t = Math.trunc(n) || 0; if (t >= 9223372036854775808) return __I64_MAX; if (t <= -9223372036854775808) return __I64_MIN; if (t > 9007199254740991 || t < -9007199254740991) { try { return __i64_wrap(BigInt(Math.round(t))); } catch {} } return t; } // Returns a BallDouble (not a bare number) so a whole-valued result (e.g. // double.parse('7.0')) still prints "7.0", not "7" — JS numbers erase the // int/double distinction that the wrapper exists to preserve (#67/#222). function __ball_parse_double(s: string): BallDouble { const n = parseFloat(s); if (Number.isNaN(n)) throw new Error('FormatException: ' + s); return new BallDouble(n); } function __ball_double_to_string(n: number): string { if (Number.isInteger(n)) return n.toFixed(1); return n.toString(); } // num.toStringAsFixed(digits). JS Number.prototype.toFixed drops the sign of // -0 (returns "0.00" not "-0.00"); Dart's toStringAsFixed keeps it, matching // the -0 handling __ball_to_string/BallDouble.toString already do. function __ball_to_fixed(v: any, digits: any): string { const n = Number(v); const s = n.toFixed(digits); if (n === 0 && 1 / n === -Infinity && !s.startsWith('-')) return '-' + s; return s; } // Polymorphic concat / merge used for std.list_concat. The encoder emits // list_concat both for Dart list concat AND for Map.addAll(...) (encoded as // m = list_concat(m, other)). Arrays concat positionally; plain objects // (Ball maps) merge by key with the right side winning (so child class // methods override parent methods). function __ball_concat(a: any, b: any): any { const aIsArr = Array.isArray(a); const bIsArr = Array.isArray(b); if (aIsArr || bIsArr) { const al = aIsArr ? a : (a == null ? [] : [a]); const bl = bIsArr ? b : (b == null ? [] : [b]); return [...al, ...bl]; } if ((a && typeof a === 'object') || (b && typeof b === 'object')) { return Object.assign({}, a ?? {}, b ?? {}); } return [a, b]; } // In-place collection append: mutates target by appending all elements. // For arrays: pushes elements (Dart List.addAll semantics). // For objects: merges keys (Dart Map.addAll semantics). // Preserves reference identity so callers sharing the same collection see changes. function __ball_push_all(target: any, items: any): void { if (Array.isArray(target)) { if (Array.isArray(items)) { for (let i = 0; i < items.length; i++) target.push(items[i]); } else if (items != null) { target.push(items); } } else if (target && typeof target === 'object') { if (items && typeof items === 'object' && !Array.isArray(items)) { for (const k of Object.keys(items)) target[k] = items[k]; } } } // ── BigInt / signed-64-bit integer support ────────────────────── // Dart int is signed 64-bit; JS Number loses precision above 2^53. // Arithmetic on BigInt values wraps to the signed 64-bit range and // demotes back to Number when the result fits in MAX_SAFE_INTEGER. const __I64_MAX = 9223372036854775807n; const __I64_MIN = -9223372036854775808n; function __i64_wrap(v: bigint): any { // Two's-complement wrap to the signed 64-bit range — BigInt.asIntN(64, v) // is the idiomatic builtin for exactly this (equivalent to the old manual // modulo-then-resign, verified against it across boundary/overflow cases). v = BigInt.asIntN(64, v); if (v >= -9007199254740991n && v <= 9007199254740991n) return Number(v); return v; } function __to_bigint(v: any): bigint { if (typeof v === 'bigint') return v; // Matches the reference Dart engine's _toInt (engine_std.dart), which // falls through to 0 for anything that isn't an int/BallInt/double/ // BallDouble/String/bool -- including null. NaN is deliberately NOT // special-cased here: Dart's double.toInt() throws on NaN (via // _ballDoubleToInt64), and BigInt(NaN) already throws for the same // reason (RangeError: not an integer), so that path already fails loud // consistently with the reference engine without any extra handling. if (v === null || v === undefined) return 0n; if (v instanceof BallDouble) return BigInt(Math.trunc(v.value)); return BigInt(v); } // Fast-path guard: true when v is a plain (non-bigint, non-BallDouble) // integer within the signed 32-bit range. AND/OR/XOR/NOT never grow a // result past its operands' bit width, so when both operands fit in 32 // bits, JS's native 32-bit bitwise operators give a result numerically // IDENTICAL to the full 64-bit BigInt path (sign-extending a 32-bit value // to 64 bits before AND/OR/XOR/NOT never changes the low 32 result bits, // and — verified across the full boundary range — never changes whether // the high bits are the correct sign-extension of them either). Left/right // shift are NOT given this fast path: shifting can grow a result past 32 // bits even when the input operand fits (e.g. large_int << 40), so their // overflow behavior isn't safely 32-bit-local the way AND/OR/XOR/NOT is. function __fits32(v: any): boolean { return typeof v === 'number' && Number.isInteger(v) && v >= -2147483648 && v <= 2147483647; } function __ball_bitand(a: any, b: any): any { if (__fits32(a) && __fits32(b)) return a & b; return __i64_wrap(__to_bigint(a) & __to_bigint(b)); } function __ball_bitor(a: any, b: any): any { if (__fits32(a) && __fits32(b)) return a | b; return __i64_wrap(__to_bigint(a) | __to_bigint(b)); } function __ball_bitxor(a: any, b: any): any { if (__fits32(a) && __fits32(b)) return a ^ b; return __i64_wrap(__to_bigint(a) ^ __to_bigint(b)); } function __ball_bitnot(a: any): any { if (__fits32(a)) return ~a; return __i64_wrap(~__to_bigint(a)); } function __ball_shl(a: any, b: any): any { return __i64_wrap(__to_bigint(a) << __to_bigint(b)); } function __ball_shr(a: any, b: any): any { return __i64_wrap(__to_bigint(a) >> __to_bigint(b)); } // Unsigned/logical shift: reinterpret a as an unsigned 64-bit value (add // 2^64 if negative) before shifting, so zeros fill from the left instead of // the sign bit — unlike >>> on raw JS numbers, which is only 32-bit. function __ball_ushr(a: any, b: any): any { const unsigned = BigInt.asUintN(64, __to_bigint(a)); return __i64_wrap(unsigned >> __to_bigint(b)); } // json_encode (dart:convert's jsonEncode) on a bigint-range int64 must not // crash -- JSON.stringify throws "Do not know how to serialize a BigInt" // without a toJSON. This is NOT proto3-JSON (which quotes int64 as a // string) -- Ball's dart:convert-style jsonEncode matches Dart's own // dart:convert (a bare, unquoted JSON number) and the C++ self-host's // _ball_json_encode (std::to_string(int64_t), also unquoted). JSON.rawJSON // embeds the exact decimal digits as a raw number token, avoiding the // precision loss Number(this) would introduce for values past 2^53. (BigInt.prototype as any).toJSON = function (this: bigint) { return (JSON as any).rawJSON(this.toString()); }; function __ball_negate(a: any): any { if (typeof a === 'bigint') return __i64_wrap(-a); if (a instanceof BallDouble) return new BallDouble(-a.value); return -a; } function __ball_divide(a: any, b: any): any { if (typeof a === 'bigint' || typeof b === 'bigint') { const ba = __to_bigint(a), bb = __to_bigint(b); const r = ba / bb; return __i64_wrap(r); } return Math.trunc(a / b); } function __ball_math_abs(a: any): any { if (typeof a === 'bigint') { const neg = -a; return __i64_wrap(neg < 0n ? a : neg); } return Math.abs(a); } // Greatest common divisor (Dart's int.gcd). Preserves BigInt (i64) inputs so // integer identities round-trip; falls back to Number arithmetic otherwise. function __ball_math_gcd(a: any, b: any): any { if (typeof a === 'bigint' || typeof b === 'bigint') { let x = __to_bigint(a); x = x < 0n ? -x : x; let y = __to_bigint(b); y = y < 0n ? -y : y; while (y) { const t = y; y = x % y; x = t; } return __i64_wrap(x); } let x = Math.abs(Number(a)), y = Math.abs(Number(b)); while (y) { const t = y; y = x % y; x = t; } return x; } // Least common multiple, derived from gcd. lcm(0, n) == lcm(n, 0) == 0. function __ball_math_lcm(a: any, b: any): any { if (typeof a === 'bigint' || typeof b === 'bigint') { const x = __to_bigint(a), y = __to_bigint(b); if (x === 0n || y === 0n) return __i64_wrap(0n); const g = __to_bigint(__ball_math_gcd(x, y)); const r = (x / g) * y; return __i64_wrap(r < 0n ? -r : r); } const x = Number(a), y = Number(b); if (x === 0 || y === 0) return 0; const g = Number(__ball_math_gcd(x, y)); return Math.abs((x / g) * y); } // Dart-style Euclidean modulo: result is always non-negative. // JS % is remainder (can be negative), Dart % is Euclidean modulo. function __dart_mod(a: any, b: any): any { if (typeof a === 'bigint' || typeof b === 'bigint') { const ba = __to_bigint(a), bb = __to_bigint(b); const r = ba % bb; return __i64_wrap(r < 0n ? r + (bb < 0n ? -bb : bb) : r); } const r = a % b; return r < 0 ? r + (b < 0 ? -b : b) : r; } // Active exception for rethrow. Catch bodies shadow with a local. let __ball_active_error: any = undefined; // Dart-style index access. Dart's List '[]' operator throws RangeError on // out-of-bounds access, whereas JS array indexing silently returns undefined. // To make 'on RangeError' catch clauses behave like Dart we bounds-check list // (array) access here and throw a RangeError-shaped exception. Maps, strings // and objects keep their JS semantics (no throw) — Dart Map '[]' returns null // for absent keys, and String '[]' is handled by callers. function __ball_index(target: any, idx: any): any { if (Array.isArray(target) && typeof idx === 'number' && Number.isInteger(idx)) { if (idx < 0 || idx >= target.length) { throw { __type__: 'RangeError', message: 'RangeError (index): Invalid value: ' + (target.length === 0 ? 'Valid value range is empty: ' + idx : 'Not in inclusive range 0..' + (target.length - 1) + ': ' + idx), index: idx, }; } return target[idx]; } return target[idx]; } // Dart type shims — provide static methods for Dart built-in types // that don't exist in JS (int, double, num, bool). const int = { parse: (s: any) => { const n = parseInt(String(s), 10); if (isNaN(n)) throw new Error('FormatException: ' + s); return n; }, tryParse: (s: any) => { const n = parseInt(String(s), 10); return isNaN(n) ? null : n; }, }; const double = { parse: (s: any) => { const n = parseFloat(String(s)); if (isNaN(n)) throw new Error('FormatException: ' + s); return n; }, tryParse: (s: any) => { const n = parseFloat(String(s)); return isNaN(n) ? null : n; }, infinity: Infinity, nan: NaN, negativeInfinity: -Infinity, }; const num = { parse: (s: any) => { const n = Number(s); if (isNaN(n)) throw new Error('FormatException: ' + s); return n; }, tryParse: (s: any) => { const n = Number(s); return isNaN(n) ? null : n; }, }; const bool = { parse: (s: any) => { if (s === 'true') return true; if (s === 'false') return false; throw new Error('FormatException: ' + s); }, tryParse: (s: any) => { if (s === 'true') return true; if (s === 'false') return false; return null; }, }; // Sentinel for "not yet initialized" — used by the Dart engine for // late-initialized variables and block-scoped flow tracking. const __no_init__: unique symbol = Symbol('__no_init__'); // Null-aware spread source normalizer (the ...? operator). Returns an // iterable for the spread loop, mapping null / undefined / the __no_init__ // sentinel (an uninitialized nullable, e.g. List? n;) to an empty list // — matching Dart's ...?n which contributes nothing when the operand is null. function __ball_spread_iter(v: any): any { if (v == null || v === __no_init__) return []; return v; } // Dart type constructor shims — List, Map, etc. const List = { filled: (count: any, value: any) => Array(count).fill(value), generate: (count: any, generator: any) => { const r: any[] = []; for (let i = 0; i < count; i++) r.push(generator(i)); return r; }, from: (iter: any) => Array.isArray(iter) ? [...iter] : [...iter], of: (iter: any) => Array.isArray(iter) ? [...iter] : [...iter], unmodifiable: (iter: any) => Object.freeze(Array.isArray(iter) ? [...iter] : [...iter]), empty: (opts?: any) => [], castFrom: (source: any) => Array.isArray(source) ? [...source] : [], }; // Set.unmodifiable const _nativeSet = Set; (Set as any).unmodifiable = (iter: any) => { const s = new _nativeSet(iter); return Object.freeze(s); }; (Set as any).from = (iter: any) => new _nativeSet(iter); (Set as any).of = (iter: any) => new _nativeSet(iter); // Ball encoder sometimes uses set_create for lists, then list_push on them. // Bridge the gap with push/indexOf/length on Set. if (!(Set.prototype as any).push) (Set.prototype as any).push = function(v: any) { this.add(v); return this.size; }; Object.defineProperty(Set.prototype, 'length', { configurable: true, get() { return this.size; } }); Object.defineProperty(Set.prototype, 'isEmpty', { configurable: true, get() { return this.size === 0; } }); Object.defineProperty(Set.prototype, 'isNotEmpty', { configurable: true, get() { return this.size !== 0; } }); // Patch: scope _bindings must use null-prototype objects to avoid // Object.prototype getters (entries, keys, values, length) polluting // the "in" operator used by scope.lookup/has/set. const _origScopeInit = { patched: false }; function _patchScopeBindings(scope: any) { if (!scope || _origScopeInit.patched) return; const ScopeClass = scope.constructor; if (!ScopeClass) return; const origCtor = ScopeClass; const origBind = ScopeClass.prototype.bind; // Override bind to lazily convert _bindings to null-proto object ScopeClass.prototype.bind = function(name: any, value: any) { if (Object.getPrototypeOf(this._bindings) !== null) { const entries = Object.entries(this._bindings); this._bindings = Object.create(null); for (const [k, v] of entries) this._bindings[k] = v; } return (this._bindings[name] = value); }; // Also patch child() to create null-proto bindings const origChild = ScopeClass.prototype.child; if (origChild) { ScopeClass.prototype.child = function() { const c = origChild.call(this); if (Object.getPrototypeOf(c._bindings) !== null) { c._bindings = Object.create(null); } return c; }; } _origScopeInit.patched = true; } // Proto has* functions as global helpers (encoder routes method calls through ball_proto) // Generic has* helper — returns true if obj[field] is present and non-null function _has(obj: any, field: string): boolean { return obj?.[field] !== undefined && obj?.[field] !== null; } function hasMetadata(obj: any): boolean { return _has(obj, 'metadata'); } function hasBody(obj: any): boolean { return _has(obj, 'body'); } function hasInput(obj: any): boolean { return _has(obj, 'input'); } function hasDescriptor(obj: any): boolean { return _has(obj, 'descriptor'); } // ModuleImport.source oneof (issue #364 — cli_core.dart's _importSource // reads these via hasHttp()/hasFile()/hasGit()/hasRegistry()/hasInline() // instead of whichSource(), since the self-hosted engine represents proto // oneof-case enums as maps and can't self-host a whichSource() == // ModuleImport_Source.x comparison — see cli_core.dart's _importSource doc). function hasHttp(obj: any): boolean { return _has(obj, 'http'); } function hasFile(obj: any): boolean { return _has(obj, 'file'); } function hasGit(obj: any): boolean { return _has(obj, 'git'); } function hasRegistry(obj: any): boolean { return _has(obj, 'registry'); } function hasInline(obj: any): boolean { return _has(obj, 'inline'); } function hasStringValue(obj: any): boolean { return _has(obj, 'stringValue'); } function hasBoolValue(obj: any): boolean { return _has(obj, 'boolValue'); } function hasNumberValue(obj: any): boolean { return _has(obj, 'numberValue'); } function hasResult(obj: any): boolean { return _has(obj, 'result'); } function hasCall(obj: any): boolean { return _has(obj, 'call'); } // Statement oneof presence (let, expression) + FieldAccess object presence, // issue 362. The self-hosted ball audit analyzers and engine.dart read these // via hasLet, hasExpression, hasObject; they route to ball_proto and compile to // free calls, so they need top-level definitions here (mirrors hasHttp etc.). function hasLet(obj: any): boolean { return _has(obj, 'let'); } function hasExpression(obj: any): boolean { return _has(obj, 'expression'); } function hasObject(obj: any): boolean { return _has(obj, 'object'); } // Expression oneof presence (issue 362): the self-hosted ball audit // capability/termination analyzers dispatch expression kinds via a hasX() // presence cascade (hasCall/hasLiteral/hasBlock/hasLambda/hasMessageCreation/ // hasFieldAccess/hasReference) instead of the whichExpr() enum, so these route // to ball_proto and compile to free calls needing top-level definitions here. function hasLiteral(obj: any): boolean { return _has(obj, 'literal'); } function hasBlock(obj: any): boolean { return _has(obj, 'block'); } function hasLambda(obj: any): boolean { return _has(obj, 'lambda'); } function hasMessageCreation(obj: any): boolean { return _has(obj, 'messageCreation'); } function hasFieldAccess(obj: any): boolean { return _has(obj, 'fieldAccess'); } function hasReference(obj: any): boolean { return _has(obj, 'reference'); } function hasListValue(obj: any): boolean { return _has(obj, 'listValue'); } function hasNullValue(obj: any): boolean { return _has(obj, 'nullValue'); } function hasStructValue(obj: any): boolean { return _has(obj, 'structValue'); } function hasMatch(obj: any): boolean { return _has(obj, 'match'); } function hasXxx(obj: any): boolean { return false; } function whichXxx(obj: any): string { return 'notSet'; } // whichExpr/whichValue/whichStmt/whichKind sit on the hottest path of the // compiled engine (whichExpr alone runs up to 8x per _evalExpression). The // previous 'typeof obj.whichXxx === "function"' probe always walked the // prototype chain to the Object.prototype shim installed by installProtoShims // (true for EVERY plain object) and then *invoked* it — a prototype walk + a // megamorphic keyed-load loop per call, even though the compiled engine's AST // nodes never carry an own whichXxx. We gate the method probe behind an // own-property check (so plain nodes skip the prototype walk entirely and use // the inline discriminator) while still honoring hand-rolled wrapper objects — // notably the metadata wrapValue Value wrappers, whose own getters // (.stringValue etc.) are always-defined, so their own whichXxx() must win // over the inline field probes. Hence the own-method check stays FIRST. function whichExpr(obj: any): string { if (!obj) return 'notSet'; if (Object.prototype.hasOwnProperty.call(obj, 'whichExpr') && typeof obj.whichExpr === 'function') return obj.whichExpr(); if (obj.call) return 'call'; if (obj.literal) return 'literal'; if (obj.reference) return 'reference'; if (obj.fieldAccess) return 'fieldAccess'; if (obj.messageCreation) return 'messageCreation'; if (obj.block) return 'block'; if (obj.lambda) return 'lambda'; return 'notSet'; } function whichValue(obj: any): string { if (!obj) return 'notSet'; if (Object.prototype.hasOwnProperty.call(obj, 'whichValue') && typeof obj.whichValue === 'function') return obj.whichValue(); if (obj.intValue !== undefined) return 'intValue'; if (obj.doubleValue !== undefined) return 'doubleValue'; if (obj.stringValue !== undefined) return 'stringValue'; if (obj.boolValue !== undefined) return 'boolValue'; if (obj.listValue) return 'listValue'; if (obj.bytesValue !== undefined) return 'bytesValue'; return 'notSet'; } function whichStmt(obj: any): string { if (!obj) return 'notSet'; if (Object.prototype.hasOwnProperty.call(obj, 'whichStmt') && typeof obj.whichStmt === 'function') return obj.whichStmt(); if (obj.let) return 'let'; if (obj.expression) return 'expression'; return 'notSet'; } function whichKind(obj: any): string { if (!obj) return 'notSet'; if (Object.prototype.hasOwnProperty.call(obj, 'whichKind') && typeof obj.whichKind === 'function') return obj.whichKind(); if (obj.nullValue !== undefined) return 'nullValue'; if (obj.numberValue !== undefined) return 'numberValue'; if (obj.stringValue !== undefined) return 'stringValue'; if (obj.boolValue !== undefined) return 'boolValue'; if (obj.structValue) return 'structValue'; if (obj.listValue) return 'listValue'; return 'notSet'; } function whichSource(obj: any): string { if (!obj) return 'notSet'; if (obj.path) return 'path'; if (obj.url) return 'url'; if (obj.inline) return 'inline'; return 'notSet'; } // Identical function (Dart identical()) function identical(a: any, b: any): boolean { return a === b; } // Function.apply shim (Dart Function.apply) (Function as any).apply = function(fn: any, positionalArgs: any, namedArgs?: any) { if (typeof fn !== 'function') return undefined; const args = positionalArgs == null ? [] : (Array.isArray(positionalArgs) ? positionalArgs : [positionalArgs]); return fn(...args); }; // Dart cascade helper — evaluates target, applies ops, returns target. function __ball_cascade(target: any, ops: any[]): any { for (const op of ops) { if (typeof op === 'function') op(target); } return target; } // ── Dart \u2192 JS method-name polyfills ──────────────────────────────── // // Idempotent: guarded so multiple preamble inclusions don't double-install. // Native Map.prototype.entries/keys/values, captured BEFORE the // installBallPolyfills IIFE below shadows them with Dart-property-style // getters of the same name. Top-level (not IIFE-scoped) so every internal // call site that needs the REAL iterator method -- not the property-style // getter -- can reach it: the getters themselves (which must call the // original to avoid recursing into themselves), __ball_to_string's Map // printer, the Map-like constructor copy sites, and the map_keys/values/ // entries base-function helpers (issue #259 -- calling .entries()/etc. // as a METHOD on a real Map after the shadow is installed throws, since // the getter's return value -- an array -- isn't itself callable). const _nativeMapEntries = Map.prototype.entries; const _nativeMapKeys = Map.prototype.keys; const _nativeMapValues = Map.prototype.values; (function installBallPolyfills() { const mp: any = Map.prototype; if (!mp.containsKey) mp.containsKey = function (k: any) { return this.has(k); }; if (!mp.putIfAbsent) { mp.putIfAbsent = function (k: any, supplier: any) { if (!this.has(k)) this.set(k, supplier()); return this.get(k); }; } if (!mp.addAll) { mp.addAll = function (other: any) { if (other instanceof Map) { // _nativeMapEntries, not other.entries() -- see __ball_to_string's // Map printer above for why (issue #259). for (const [k, v] of _nativeMapEntries.call(other)) this.set(k, v); } else if (other && typeof other === 'object') { for (const k of Object.keys(other)) this.set(k, other[k]); } }; } Object.defineProperty(mp, 'isEmpty', { configurable: true, get() { return this.size === 0; }, }); Object.defineProperty(mp, 'isNotEmpty', { configurable: true, get() { return this.size !== 0; }, }); const ap: any = Array.prototype; if (!ap.add) ap.add = function (v: any) { this.push(v); }; if (!ap.addAll) ap.addAll = function (iter: any) { for (const v of iter) this.push(v); }; if (!ap.removeLast) ap.removeLast = function () { return this.pop(); }; if (!ap.removeAt) ap.removeAt = function (i: any) { return this.splice(i, 1)[0]; }; if (!ap.insert) ap.insert = function (i: any, v: any) { this.splice(i, 0, v); }; if (!ap.setAll) ap.setAll = function (idx: number, values: any[]) { for (let i = 0; i < values.length; i++) this[idx + i] = values[i]; }; if (!ap.where) ap.where = Array.prototype.filter; if (!ap.toList) ap.toList = function () { return this.slice(); }; if (!ap.toSet) ap.toSet = function () { return new Set(this); }; if (!ap.contains) ap.contains = function (v: any) { return this.indexOf(v) >= 0; }; if (!ap.sublist) ap.sublist = function (start: any, end?: any) { return this.slice(start, end); }; if (!ap.asMap) ap.asMap = function () { const m: any = {}; for (let i = 0; i < this.length; i++) m[i] = this[i]; return m; }; if (!ap.expand) ap.expand = function (fn: any) { return this.flatMap(fn); }; if (!ap.take) ap.take = function (n: any) { return this.slice(0, n); }; if (!ap.skip) ap.skip = function (n: any) { return this.slice(n); }; if (!ap.any) ap.any = function (fn: any) { return this.some(fn); }; if (!ap.fold) ap.fold = function (init: any, fn: any) { return this.reduce(fn, init); }; if (!ap.followedBy) ap.followedBy = function (other: any) { return [...this, ...other]; }; if (!ap.getRange) ap.getRange = function (start: any, end: any) { return this.slice(start, end); }; if (!ap.fillRange) ap.fillRange = function (start: any, end: any, fill: any) { for (let i = start; i < end; i++) this[i] = fill; }; if (!ap.setRange) ap.setRange = function (start: any, end: any, iterable: any, skipCount?: any) { const src = Array.isArray(iterable) ? iterable : [...iterable]; const skip = skipCount ?? 0; for (let i = start; i < end; i++) this[i] = src[i - start + skip]; }; // Dart Set polyfills — Set.contains → Set.has, etc. const setp: any = Set.prototype; if (!setp.contains) setp.contains = function (v: any) { return this.has(v); }; if (!setp.includes) setp.includes = function (v: any) { return this.has(v); }; if (!setp.toList) setp.toList = function () { return [...this]; }; if (!setp.add) { /* Set already has .add */ } if (!setp.remove) setp.remove = function (v: any) { return this.delete(v); }; Object.defineProperty(ap, 'isEmpty', { configurable: true, get() { return this.length === 0; }, }); Object.defineProperty(ap, 'isNotEmpty', { configurable: true, get() { return this.length !== 0; }, }); Object.defineProperty(ap, 'first', { configurable: true, get() { return this[0]; }, }); Object.defineProperty(ap, 'last', { configurable: true, get() { return this[this.length - 1]; }, }); const sp: any = String.prototype; Object.defineProperty(sp, 'isEmpty', { configurable: true, get() { return this.length === 0; }, }); Object.defineProperty(sp, 'isNotEmpty', { configurable: true, get() { return this.length !== 0; }, }); // Note: undefined/null safety for .isEmpty/.isNotEmpty is handled in the // generated code via optional-chaining (?.isEmpty) patterns and protoWrap; // properties cannot be installed on undefined/null directly. // Dart String methods not on JS String. if (!sp.contains) sp.contains = function (s: any) { return this.includes(s); }; if (!sp.replaceFirst) sp.replaceFirst = function (from: any, to: any) { return this.replace(from instanceof RegExp ? from : String(from), to); }; if (!sp.codeUnitAt) sp.codeUnitAt = function (i: any) { return this.charCodeAt(i); }; if (!sp.compareTo) sp.compareTo = function (other: any) { return this < other ? -1 : this > other ? 1 : 0; }; if (!sp.allMatches) sp.allMatches = function (pattern: any, start: any) { const s = typeof start === 'number' ? this.substring(start) : this; if (typeof pattern === 'string') { return Array.from(s.matchAll(new RegExp(pattern, 'g'))); } const flags = pattern.flags.includes('g') ? pattern.flags : pattern.flags + 'g'; return Array.from(s.matchAll(new RegExp(pattern.source, flags))); }; // Dart RegExp polyfills. const rp: any = RegExp.prototype; if (!rp.firstMatch) rp.firstMatch = function (s: any) { const m = this.exec(s); if (m) m.group = (i: any) => m[i]; return m; }; if (!rp.allMatches) rp.allMatches = function (s: any) { const flags = this.flags.includes('g') ? this.flags : this.flags + 'g'; return [...s.matchAll(new RegExp(this.source, flags))]; }; if (!rp.hasMatch) rp.hasMatch = function (s: any) { return this.test(s); }; // Dart Number polyfills — Dart num/int methods not on JS Number.prototype. const _ballNp: any = Number.prototype; if (!_ballNp.gcd) _ballNp.gcd = function (other: any) { let a = Math.abs(this as number), b = Math.abs(Number(other)); while (b) { const t = b; b = a % b; a = t; } return a; }; Object.defineProperty(_ballNp, 'sign', { configurable: true, get() { const n = Number(this); return n > 0 ? 1 : n < 0 ? -1 : 0; }, }); Object.defineProperty(_ballNp, 'isNaN', { configurable: true, get() { return Number.isNaN(Number(this)); }, }); Object.defineProperty(_ballNp, 'isFinite', { configurable: true, get() { return Number.isFinite(Number(this)); }, }); Object.defineProperty(_ballNp, 'isInfinite', { configurable: true, get() { const n = Number(this); return n === Infinity || n === -Infinity; }, }); Object.defineProperty(_ballNp, 'isNegative', { configurable: true, get() { const n = Number(this); return n < 0 || (n === 0 && 1 / n === -Infinity); }, }); if (!_ballNp.abs) _ballNp.abs = function () { return Math.abs(Number(this)); }; if (!_ballNp.ceil) _ballNp.ceil = function () { return Math.ceil(Number(this)); }; if (!_ballNp.floor) _ballNp.floor = function () { return Math.floor(Number(this)); }; if (!_ballNp.round) _ballNp.round = function () { return Math.round(Number(this)); }; if (!_ballNp.truncate) _ballNp.truncate = function () { return Math.trunc(Number(this)); }; if (!_ballNp.toInt) _ballNp.toInt = function () { return Math.trunc(Number(this)); }; if (!_ballNp.toDouble) _ballNp.toDouble = function () { return Number(this); }; if (!_ballNp.clamp) _ballNp.clamp = function (lo: any, hi: any) { const n = Number(this); return n < lo ? lo : n > hi ? hi : n; }; if (!_ballNp.compareTo) _ballNp.compareTo = function (other: any) { const a = Number(this), b = Number(other); return a < b ? -1 : a > b ? 1 : 0; }; if (!_ballNp.toStringAsFixed) _ballNp.toStringAsFixed = function (digits: any) { return __ball_to_fixed(this, digits); }; if (!_ballNp.remainder) _ballNp.remainder = function (other: any) { return Number(this) % Number(other); }; // Object.prototype polyfills — used by the compiled engine when // checking Ball program inputs (plain objects, not Maps). const op2: any = Object.prototype; if (!op2.containsKey) { Object.defineProperty(op2, 'containsKey', { configurable: true, writable: true, enumerable: false, value: function (k: any) { if (this instanceof Map) return this.has(k); if (this == null || typeof this !== 'object') return false; return Object.prototype.hasOwnProperty.call(this, k); }, }); } // putIfAbsent — Dart Map.putIfAbsent. Works on plain objects too. if (!op2.putIfAbsent) { Object.defineProperty(op2, 'putIfAbsent', { configurable: true, writable: true, enumerable: false, value: function (k: any, supplier: any) { if (this instanceof Map) { if (!this.has(k)) this.set(k, supplier()); return this.get(k); } if (!(k in this)) this[k] = supplier(); return this[k]; }, }); } // addAll — Dart Map.addAll. Works on plain objects too. if (!op2.addAll) { Object.defineProperty(op2, 'addAll', { configurable: true, writable: true, enumerable: false, value: function (other: any) { if (this instanceof Map) { if (other instanceof Map) { // _nativeMapEntries, not other.entries() (issue #259). for (const [k, v] of _nativeMapEntries.call(other)) this.set(k, v); } else if (other && typeof other === 'object') { for (const k of Object.keys(other)) this.set(k, other[k]); } } else { if (other instanceof Map) { for (const [k, v] of other) this[k] = v; } else if (other && typeof other === 'object') { Object.assign(this, other); } } }, }); } // forEach — Dart Map.forEach. Works on plain objects. // Don't overwrite native Map.prototype.forEach. Object.defineProperty(op2, 'forEach', { configurable: true, writable: true, enumerable: false, value: function (fn: any) { if (this instanceof Map) { return Map.prototype.forEach.call(this, fn); } if (Array.isArray(this)) { return Array.prototype.forEach.call(this, fn); } // Plain object: Dart Map.forEach(void f(K key, V value)) if (typeof fn === 'function') { for (const k of Object.keys(this)) fn(k, this[k]); } }, }); // remove — Dart Map.remove. if (!op2.remove) { Object.defineProperty(op2, 'remove', { configurable: true, writable: true, enumerable: false, value: function (k: any) { if (this instanceof Map) { const v = this.get(k); this.delete(k); return v; } const v = this[k]; delete this[k]; return v; }, }); } // cast — Dart Map.cast() / List.cast(). The cast is a static // re-typing only; at runtime it returns the same collection unchanged. if (!op2.cast) { Object.defineProperty(op2, 'cast', { configurable: true, writable: true, enumerable: false, value: function () { return this; }, }); } // Dart Map has .entries / .keys / .values as GETTERS (no parens). // JS Map has them as METHODS (need parens). The compiled engine // accesses map.entries as a getter. Shadow BOTH Map.prototype AND // Object.prototype so Map and plain-object dispatch tables work. // (_nativeMapEntries/_nativeMapKeys/_nativeMapValues are captured at // top level above, not here, so other call sites outside this IIFE // can reach them too -- issue #259.) // Shadow Map.prototype.entries with a getter (Dart uses it as a getter). Object.defineProperty(Map.prototype, 'entries', { configurable: true, enumerable: false, get() { return [..._nativeMapEntries.call(this)].map(([k, v]: any) => ({ key: k, value: v })); }, }); Object.defineProperty(Map.prototype, 'keys', { configurable: true, enumerable: false, get() { return [..._nativeMapKeys.call(this)]; }, }); Object.defineProperty(Map.prototype, 'values', { configurable: true, enumerable: false, get() { return [..._nativeMapValues.call(this)]; }, }); // For plain objects — same getters on Object.prototype. // Helper: define a getter on Object.prototype that also allows // own-property assignment (setter stores as a data property on the // instance, shadowing the prototype getter for future accesses). function defDartGetter(name: string, getter: () => any) { Object.defineProperty(op2, name, { configurable: true, enumerable: false, get: getter, set(v: any) { Object.defineProperty(this, name, { value: v, writable: true, configurable: true, enumerable: true, }); }, }); } // .entries/.keys/.values on a non-Map must FAIL LOUD (throw a catchable // error), not silently return [] — the silent-degradation class of bug // that hid issue #55 (mirrors the fix already applied to the Dart/C++ // compilers). .entries used to be the odd one out here, silently // returning [] instead of throwing — same bug family as #218. // // A getter installed on Object.prototype is invoked in "sloppy" (non-strict) // script contexts with this auto-boxed to a Number/String/Boolean WRAPPER // object for a primitive receiver (e.g. (42).keys boxes this to a Number // instance) — typeof this is then 'object', not 'number', so a bare // __ball_is_type(this, 'Map') (which only excludes Array/BallDouble/Set) // would wrongly treat a boxed int/string as Map-like. Exclude the wrapper // types explicitly instead of widening the shared type-check. const __isGenuineMap = (v: any) => typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set) && !(v instanceof Number) && !(v instanceof String) && !(v instanceof Boolean); defDartGetter('entries', function (this: any) { if (this instanceof Map) return [..._nativeMapEntries.call(this)].map(([k, v]: any) => ({ key: k, value: v })); if (!__isGenuineMap(this)) { throw new Error('type \'' + __ball_to_string(this) + '\' has no .entries getter (not a Map)'); } return Object.entries(this).map(([k, v]: any) => ({ key: k, value: v })); }); defDartGetter('keys', function (this: any) { if (this instanceof Map) return [..._nativeMapKeys.call(this)]; if (!__isGenuineMap(this)) { throw new Error('type \'' + __ball_to_string(this) + '\' has no .keys getter (not a Map)'); } return Object.keys(this); }); defDartGetter('values', function (this: any) { if (this instanceof Map) return [..._nativeMapValues.call(this)]; if (!__isGenuineMap(this)) { throw new Error('type \'' + __ball_to_string(this) + '\' has no .values getter (not a Map)'); } return Object.values(this); }); defDartGetter('length', function (this: any) { if (this instanceof Map) return this.size; if (this instanceof Set) return this.size; if (typeof this === 'string' || Array.isArray(this)) return this.length; if (this == null || typeof this !== 'object') return 0; return Object.keys(this).filter((k: string) => !k.startsWith('__')).length; }); // runtimeType — Dart's Object.runtimeType. Returns the Dart-style // type name for any JS value. Used by the compiled engine for type // checking and error messages. Object.defineProperty(op2, 'runtimeType', { configurable: true, enumerable: false, get() { if (this === null || this === undefined) return 'Null'; if (this instanceof BallDouble) return 'double'; if (typeof this === 'number' || this instanceof Number) return Number.isInteger(+this) ? 'int' : 'double'; if (typeof this === 'string' || this instanceof String) return 'String'; if (typeof this === 'boolean' || this instanceof Boolean) return 'bool'; if (typeof this === 'function') return 'Function'; if (Array.isArray(this)) return 'List'; if (this instanceof Set) return 'Set'; if (this instanceof Map) return 'Map'; if (this instanceof RegExp) return 'RegExp'; const t = this['__type__']; if (typeof t === 'string' && t.length > 0) { const ci = t.indexOf(':'); return ci >= 0 ? t.substring(ci + 1) : t; } return 'Map'; }, }); // Also add to Number.prototype, String.prototype, Boolean.prototype // (they don't inherit from Object.prototype getters reliably for primitives). Object.defineProperty(Number.prototype, 'runtimeType', { configurable: true, enumerable: false, get() { return Number.isInteger(+this) ? 'int' : 'double'; }, }); Object.defineProperty(String.prototype, 'runtimeType', { configurable: true, enumerable: false, get() { return 'String'; }, }); Object.defineProperty(Boolean.prototype, 'runtimeType', { configurable: true, enumerable: false, get() { return 'bool'; }, }); })(); // std.map_keys/std.map_values/std.map_entries (the base-function-call form, // as opposed to the .keys/.values/.entries DART-GETTER-STYLE property // access the defDartGetter block above already guards) must ALSO fail loud // on a non-Map receiver instead of silently returning [] — same "genuine // Map" check, exposed as top-level helpers so compileStdCall's emitted code // can call them (#218). function __ball_map_keys(m: any): any { // _nativeMapKeys, not m.keys() -- m.keys() would hit the Dart-property- // style getter shadowing Map.prototype.keys and try to invoke its // return value (an array) as a function (issue #259). if (m instanceof Map) return [..._nativeMapKeys.call(m)]; if (typeof m !== 'object' || m === null || Array.isArray(m) || m instanceof BallDouble || m instanceof Set || m instanceof Number || m instanceof String || m instanceof Boolean) { throw new Error('type \'' + __ball_to_string(m) + '\' has no .keys getter (not a Map)'); } return Object.keys(m); } function __ball_map_values(m: any): any { // _nativeMapValues, not m.values() (issue #259 -- see __ball_map_keys). if (m instanceof Map) return [..._nativeMapValues.call(m)]; if (typeof m !== 'object' || m === null || Array.isArray(m) || m instanceof BallDouble || m instanceof Set || m instanceof Number || m instanceof String || m instanceof Boolean) { throw new Error('type \'' + __ball_to_string(m) + '\' has no .values getter (not a Map)'); } return Object.values(m); } function __ball_map_entries(m: any): any { // _nativeMapEntries, not m.entries() (issue #259 -- see __ball_map_keys). if (m instanceof Map) return [..._nativeMapEntries.call(m)].map(([k, v]) => ({ key: k, value: v })); if (typeof m !== 'object' || m === null || Array.isArray(m) || m instanceof BallDouble || m instanceof Set || m instanceof Number || m instanceof String || m instanceof Boolean) { throw new Error('type \'' + __ball_to_string(m) + '\' has no .entries getter (not a Map)'); } return Object.entries(m).map(([k, v]) => ({ key: k, value: v })); } // Shared guard for the REMAINING map_* base-function-call cases // (map_get/map_set/map_delete/map_merge/map_length/map_is_empty/ // map_contains_key/map_contains_value/map_foreach) that used to route a // bare map[key], Object.keys/values(map), or key in map straight to the // receiver with no type check at all -- silently returning undefined, // no-opping, or checking array-index membership instead of throwing on a // non-Map (issue #55's silent-degradation class, same family as #218's // map_keys/map_values/map_entries). Returns the validated Map/plain-object // itself (not a boolean) so a call site can keep using it directly, e.g. // __ball_require_map(x, 'map_get')[key]. function __ball_require_map(v: any, opName: string): any { if (v instanceof Map) return v; if (typeof v !== 'object' || v === null || Array.isArray(v) || v instanceof BallDouble || v instanceof Set || v instanceof Number || v instanceof String || v instanceof Boolean) { throw new Error('type \'' + __ball_to_string(v) + '\' is not a Map (' + opName + ')'); } return v; } // ── Protobuf Struct/Value compatibility ───────────────────────── // // Dart's protobuf runtime wraps google.protobuf.Struct as a class // with .fields (Map) and Value as .whichKind() + // .stringValue / .boolValue / .numberValue / .listValue / .structValue. // In proto3 JSON, these serialize as plain objects and values. // // This shim makes plain JSON objects behave like Struct/Value so the // compiled engine.dart can call .fields['key'].whichKind() etc. // // Strategy: Object.prototype gets a .fields getter that returns a // Proxy wrapping the object as a Map-like. Accessing [key] on the // proxy returns a Value-like wrapper with .whichKind() / typed // accessors (.stringValue, .boolValue, .numberValue, .listValue, // .structValue). const structpb_Value_Kind = { nullValue: 'nullValue', numberValue: 'numberValue', stringValue: 'stringValue', boolValue: 'boolValue', structValue: 'structValue', listValue: 'listValue', } as const; class __BallValueWrapper { private _raw: any; constructor(raw: any) { this._raw = raw; } whichKind(): string { const v = this._raw; if (v === null || v === undefined) return 'nullValue'; if (typeof v === 'string') return 'stringValue'; if (typeof v === 'boolean') return 'boolValue'; if (typeof v === 'number') return 'numberValue'; if (Array.isArray(v)) return 'listValue'; if (typeof v === 'object') return 'structValue'; return 'nullValue'; } get stringValue(): string { return typeof this._raw === 'string' ? this._raw : String(this._raw ?? ''); } get boolValue(): boolean { return !!this._raw; } get numberValue(): number { return Number(this._raw); } get nullValue(): null { return null; } get listValue(): { values: __BallValueWrapper[] } { const arr = Array.isArray(this._raw) ? this._raw : []; return { values: arr.map((v: any) => new __BallValueWrapper(v)) }; } get structValue(): { fields: Record } { const obj = (typeof this._raw === 'object' && this._raw !== null) ? this._raw : {}; const fields: Record = {}; for (const [k, v] of Object.entries(obj)) fields[k] = new __BallValueWrapper(v); return { fields }; } // Also proxy hasXxx for sub-values. hasNullValue(): boolean { return this._raw == null; } hasStringValue(): boolean { return typeof this._raw === 'string'; } hasBoolValue(): boolean { return typeof this._raw === 'boolean'; } hasNumberValue(): boolean { return typeof this._raw === 'number'; } hasListValue(): boolean { return Array.isArray(this._raw); } hasStructValue(): boolean { return typeof this._raw === 'object' && this._raw !== null && !Array.isArray(this._raw); } // Pass-through for when the wrapper is used in expressions. toString(): string { return String(this._raw); } valueOf(): any { return this._raw; } } // Struct.fields shimming is done via a metadata-specific wrapper. // We do NOT add .fields to Object.prototype because it conflicts // with data properties named "fields" on MessageCreation / TypeDef. // Instead, the compiled engine accesses metadata.fields['key'] — // in proto3 JSON, metadata IS the fields directly, so we add a // .fields getter only when the object is a metadata Struct (i.e., // it has string/bool/number/array/object values and no proto-shape // keys like "call"/"literal"/"block"). // // The protoWrap normalizer in the test harness is responsible for // converting metadata objects to have the right shape. // ── Protobuf compatibility shims ──────────────────────────────── // // The Dart encoder produces code that uses Dart's protobuf runtime // API (.whichExpr(), Expression_Expr.call, .hasInput(), .toInt(), etc.) // on what are really plain JSON objects at runtime. These shims make // the proto-style method calls work on plain objects so the compiled // engine.dart can execute on Node. // Oneof discriminator enums — string-valued constants that match the // field names the Dart protobuf codegen uses. const Expression_Expr = { call: 'call', literal: 'literal', reference: 'reference', fieldAccess: 'fieldAccess', messageCreation: 'messageCreation', block: 'block', lambda: 'lambda', notSet: 'notSet', } as const; const Literal_Value = { intValue: 'intValue', doubleValue: 'doubleValue', stringValue: 'stringValue', boolValue: 'boolValue', listValue: 'listValue', bytesValue: 'bytesValue', notSet: 'notSet', } as const; const Statement_Stmt = { let: 'let', expression: 'expression', notSet: 'notSet', } as const; const ModuleImport_Source = { http: 'http', file: 'file', inline: 'inline', git: 'git', registry: 'registry', notSet: 'notSet', } as const; // Object.prototype shims for .whichXxx() / .hasXxx() / .toInt() — // these match the Dart protobuf generated API. Each is configurable // and non-enumerable so it doesn't pollute for-in loops. (function installProtoShims() { const op: any = Object.prototype; function defMethod(name: string, fn: Function) { if (op[name]) return; Object.defineProperty(op, name, { configurable: true, writable: true, enumerable: false, value: fn, }); } // whichExpr / whichValue / whichStmt / whichSource — return which // oneof field is set on this object. defMethod('whichExpr', function (this: any) { for (const k of ['call','literal','reference','fieldAccess','messageCreation','block','lambda']) { if (this[k] !== undefined && this[k] !== null) return k; } return 'notSet'; }); defMethod('whichValue', function (this: any) { for (const k of ['intValue','doubleValue','stringValue','boolValue','listValue','bytesValue']) { if (this[k] !== undefined && this[k] !== null) return k; } return 'notSet'; }); defMethod('whichStmt', function (this: any) { if (this['let'] !== undefined && this['let'] !== null) return 'let'; if (this['expression'] !== undefined && this['expression'] !== null) return 'expression'; return 'notSet'; }); defMethod('whichSource', function (this: any) { for (const k of ['http','file','inline','git','registry']) { if (this[k] !== undefined && this[k] !== null) return k; } return 'notSet'; }); // Presence checks — .hasXxx() returns true if the field is set. for (const field of [ 'input','body','result','metadata','value','name','module', 'left','right','condition','then','else','finally', 'subject','cases','catches','init','update','iterable', 'target','index','field','object','key','message', 'stringValue','boolValue','intValue','doubleValue','listValue', 'call','literal','reference','fieldAccess','messageCreation', 'block','lambda','let','expression','descriptor', ]) { const methodName = 'has' + field[0].toUpperCase() + field.slice(1); defMethod(methodName, function (this: any) { return this[field] !== undefined && this[field] !== null; }); } // Proto field-name aliases — Dart's protobuf codegen renames some // fields to avoid keyword collisions (field → field_2, etc.) but // proto3 JSON uses the original names. Add getters so both work. Object.defineProperty(op, 'field_2', { configurable: true, enumerable: false, get() { return this.field; }, set(v: any) { this.field = v; }, }); // descriptor_ → descriptor (same issue) Object.defineProperty(op, 'descriptor_', { configurable: true, enumerable: false, get() { return this.descriptor; }, set(v: any) { this.descriptor = v; }, }); // .toInt() — Dart's Int64/fixnum returns int from string. In proto3 // JSON, int64 fields are serialized as strings ("42" not 42). defMethod('toInt', function (this: any) { if (typeof this === 'number') return this; if (typeof this === 'string') return parseInt(this, 10); if (typeof this.valueOf === 'function') return parseInt(String(this.valueOf()), 10); return 0; }); // .toList() on Uint8Array (bytesValue) defMethod('toList', function (this: any) { if (this instanceof Uint8Array) return Array.from(this); if (Array.isArray(this)) return this.slice(); return []; }); })(); // ── Reified generics helpers ──────────────────────────────────────── function __ball_with_type_args(obj: T, args: string[]): T { (obj as any).__type_args__ = args; return obj; } // ── Generic type checking helper ──────────────────────────────────── function __ball_split_type_args(s: string): string[] { const result: string[] = []; let depth = 0, start = 0; for (let i = 0; i < s.length; i++) { if (s[i] === '<') depth++; else if (s[i] === '>') depth--; else if (s[i] === ',' && depth === 0) { result.push(s.slice(start, i).trim()); start = i + 1; } } const last = s.slice(start).trim(); if (last) result.push(last); return result; } function __ball_is_type(value: any, typeStr: string): boolean { const t = typeStr.trim(); if (t.endsWith('?')) { if (value == null) return true; return __ball_is_type(value, t.slice(0, -1)); } const ltIdx = t.indexOf('<'); if (ltIdx === -1) { switch (t) { case 'int': return typeof value === 'number' && Number.isInteger(value); case 'double': return value instanceof BallDouble || (typeof value === 'number' && !Number.isInteger(value)); case 'num': case 'number': return typeof value === 'number' || value instanceof BallDouble; case 'String': case 'string': return typeof value === 'string'; case 'bool': case 'boolean': return typeof value === 'boolean'; case 'List': case 'Iterable': return Array.isArray(value); case 'Map': return typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof BallDouble) && !(value instanceof Set); case 'Set': return value instanceof Set; case 'Null': return value == null; case 'Function': return typeof value === 'function'; case 'Object': case 'dynamic': return value != null; default: { const objType = value?.__type__ ?? value?.constructor?.name; if (objType === t) return true; return value != null; } } } const baseType = t.slice(0, ltIdx).trim(); const typeArgs = __ball_split_type_args(t.slice(ltIdx + 1, t.lastIndexOf('>'))); switch (baseType) { case 'List': case 'Iterable': if (!Array.isArray(value)) return false; if (typeArgs.length === 0) return true; return value.every((e: any) => __ball_is_type(e, typeArgs[0])); case 'Map': if (typeof value !== 'object' || value === null || Array.isArray(value) || value instanceof BallDouble || value instanceof Set) return false; if (typeArgs.length < 2) return true; return Object.keys(value).filter((k: string) => !k.startsWith('__')).every((k: string) => __ball_is_type(k, typeArgs[0]) && __ball_is_type(value[k], typeArgs[1])); case 'Set': if (!(value instanceof Set)) return false; if (typeArgs.length === 0) return true; for (const e of value) { if (!__ball_is_type(e, typeArgs[0])) return false; } return true; default: { const objType = value?.__type__ ?? value?.constructor?.name; if (objType === baseType) { const objArgs = value.__type_args__; if (Array.isArray(objArgs)) { if (objArgs.length !== typeArgs.length) return false; return objArgs.every((a: any, i: number) => String(a).trim() === typeArgs[i].trim()); } return false; } return __ball_is_type(value, baseType); } } } // Minimal DateTime / Duration / Future polyfills used by std_time and // the round-tripped engine's sleep_ms helper. Wide enough for the // conformance suite, narrow enough to stay out of users' way. class DateTime { readonly _epochMs: number; readonly isUtc: boolean; constructor(epochMs?: number, isUtc: boolean = false) { this._epochMs = typeof epochMs === 'number' ? epochMs : Date.now(); this.isUtc = isUtc; } static now(): DateTime { return new DateTime(Date.now(), false); } static fromMillisecondsSinceEpoch(ms: number, isUtc: any = false): DateTime { return new DateTime(ms, isUtc === true || (isUtc && (isUtc as any).isUtc === true)); } static parse(s: string): DateTime { return new DateTime(Date.parse(s), true); } get millisecondsSinceEpoch(): number { return this._epochMs; } get microsecondsSinceEpoch(): number { return this._epochMs * 1000; } toUtc(): DateTime { return new DateTime(this._epochMs, true); } toIso8601String(): string { return new Date(this._epochMs).toISOString(); } get year(): number { return new Date(this._epochMs).getUTCFullYear(); } get month(): number { return new Date(this._epochMs).getUTCMonth() + 1; } get day(): number { return new Date(this._epochMs).getUTCDate(); } get hour(): number { return new Date(this._epochMs).getUTCHours(); } get minute(): number { return new Date(this._epochMs).getUTCMinutes(); } get second(): number { return new Date(this._epochMs).getUTCSeconds(); } } class Duration { readonly _us: number; constructor(opts?: any) { const o = opts ?? {}; const ms = o.milliseconds ?? 0; const s = o.seconds ?? 0; const m = o.minutes ?? 0; const us = o.microseconds ?? 0; this._us = us + ms * 1000 + s * 1_000_000 + m * 60_000_000; } get inMilliseconds(): number { return Math.floor(this._us / 1000); } get inMicroseconds(): number { return this._us; } } const Future = { delayed(d: any): Promise { const ms = (d && typeof d.inMilliseconds === 'number') ? d.inMilliseconds : Number(d ?? 0); return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms))); }, value(v: any): Promise { return Promise.resolve(v); }, }; // ── dart:typed_data shims (ByteData, Endian) ─────────────────────── // ball_protobuf uses ByteData for IEEE 754 float/double bit conversion. // Dart's ByteData wraps a fixed-size byte buffer with typed get/set methods. const Endian = { little: true, big: false, host: true }; class ByteData { _view: DataView; _length: number; constructor(size: number) { this._view = new DataView(new ArrayBuffer(size)); this._length = size; } get lengthInBytes(): number { return this._length; } getUint8(i: number): number { return this._view.getUint8(i); } setUint8(i: number, v: number): void { this._view.setUint8(i, v); } getInt8(i: number): number { return this._view.getInt8(i); } setInt8(i: number, v: number): void { this._view.setInt8(i, v); } getUint16(i: number, endian?: any): number { return this._view.getUint16(i, endian === Endian.little); } setUint16(i: number, v: number, endian?: any): void { this._view.setUint16(i, v, endian === Endian.little); } getInt16(i: number, endian?: any): number { return this._view.getInt16(i, endian === Endian.little); } setInt16(i: number, v: number, endian?: any): void { this._view.setInt16(i, v, endian === Endian.little); } getUint32(i: number, endian?: any): number { return this._view.getUint32(i, endian === Endian.little); } setUint32(i: number, v: number, endian?: any): void { this._view.setUint32(i, v, endian === Endian.little); } getInt32(i: number, endian?: any): number { return this._view.getInt32(i, endian === Endian.little); } setInt32(i: number, v: number, endian?: any): void { this._view.setInt32(i, v, endian === Endian.little); } getFloat32(i: number, endian?: any): number { return this._view.getFloat32(i, endian === Endian.little); } setFloat32(i: number, v: number, endian?: any): void { this._view.setFloat32(i, v, endian === Endian.little); } getFloat64(i: number, endian?: any): number { return this._view.getFloat64(i, endian === Endian.little); } setFloat64(i: number, v: number, endian?: any): void { this._view.setFloat64(i, v, endian === Endian.little); } getUint64(i: number, endian?: any): bigint { const lo = this._view.getUint32(i, endian === Endian.little); const hi = this._view.getUint32(i + 4, endian === Endian.little); return endian === Endian.little ? BigInt(lo) | (BigInt(hi) << 32n) : (BigInt(lo) << 32n) | BigInt(hi); } setUint64(i: number, v: bigint, endian?: any): void { const lo = Number(v & 0xFFFFFFFFn); const hi = Number((v >> 32n) & 0xFFFFFFFFn); if (endian === Endian.little) { this._view.setUint32(i, lo, true); this._view.setUint32(i + 4, hi, true); } else { this._view.setUint32(i, hi, false); this._view.setUint32(i + 4, lo, false); } } getInt64(i: number, endian?: any): bigint { const unsigned = this.getUint64(i, endian); return unsigned >= 0x8000000000000000n ? unsigned - 0x10000000000000000n : unsigned; } setInt64(i: number, v: bigint, endian?: any): void { this.setUint64(i, v < 0n ? v + 0x10000000000000000n : v, endian); } get buffer(): { asUint8List: (start?: number, length?: number) => number[] } { const view = this._view; return { asUint8List: (start?: number, length?: number) => { const s = start ?? 0; const l = length ?? view.byteLength - s; return [...new Uint8Array(view.buffer, s, l)]; }, }; } } // ── dart:convert shims (utf8, jsonEncode, jsonDecode) ─────────────── // ball_protobuf uses utf8.encode/decode for string↔bytes and // jsonEncode/jsonDecode for JSON serialization. const utf8 = { encode(s: string): number[] { return [...new TextEncoder().encode(s)]; }, decode(bytes: any): string { return new TextDecoder().decode(new Uint8Array(bytes)); }, }; function jsonEncode(obj: any): string { return JSON.stringify(obj); } function jsonDecode(s: string): any { return JSON.parse(s); } function __isUnknownFnError(e: any): boolean { const m = e && typeof e.message === 'string' ? e.message : (typeof e === 'string' ? e : ''); return m.startsWith('Unknown std function:') || m.startsWith('Unknown base module:'); } export type BallCallable = any; export class BallEngine { readonly program: Program; readonly _types: Map = {}; readonly _functions: Map = {}; readonly _getters: any = {}; readonly _setters: any = {}; readonly _getters: Map = {}; readonly _setters: Map = {}; readonly _globalScope: _Scope = new _Scope(); stdout: any; _currentModule: string = ''; _activeGeneratorScope: _Scope = null; readonly _paramCache: Map> = {}; readonly _callCache: Map = {}; readonly _typeMethodDispatch: Map = {}; readonly _instanceMethodCache: Map = {}; readonly _topLevelRefs: Map = {}; readonly _staticFieldRefs: Map = {}; readonly _enumValues: Map> = {}; readonly _constructors: Map = {}; _callCounts: Map = {}; readonly maxRecursionDepth: number = 0; readonly timeoutMs: number = null; readonly maxMemoryBytes: number = null; readonly maxModules: number = 0; readonly maxExpressionDepth: number = 0; readonly maxProgramSizeBytes: number = null; readonly sandbox: boolean = false; _memoryUsedBytes: number = 0; _expressionDepth: number = 0; _executionStartMs: number = null; _recursionDepth: number = 0; readonly moduleHandlers: Array = []; readonly _random: math.Random = ({ nextInt(max: number) { return Math.floor(Math.random() * max); }, nextDouble() { return Math.random(); } }); stderr: any; stdinReader: any = null; _envGet: any; _args: Array = []; _nextMutexId: number = 0; _activeException: any = null; readonly _resolver: ModuleResolver = null; readonly _initialized: Promise; constructor(program: any, stdout: any, stderr: any, stdinReader: any, envGet: any, args: any, enableProfiling: any, maxRecursionDepth: any, timeoutMs: any, maxMemoryBytes: any, maxModules: any, maxExpressionDepth: any, maxProgramSizeBytes: any, sandbox: any, moduleHandlers: any, resolver: any) { if (typeof stdout === 'object' && stdout !== null && !Array.isArray(stdout) && ('stdout' in stdout || 'stderr' in stdout || 'stdinReader' in stdout || 'envGet' in stdout || 'args' in stdout || 'enableProfiling' in stdout || 'maxRecursionDepth' in stdout || 'timeoutMs' in stdout || 'maxMemoryBytes' in stdout || 'maxModules' in stdout || 'maxExpressionDepth' in stdout || 'maxProgramSizeBytes' in stdout || 'sandbox' in stdout || 'moduleHandlers' in stdout || 'resolver' in stdout)) { let __n = stdout; stdout = __n.stdout; stderr = __n.stderr; stdinReader = __n.stdinReader; envGet = __n.envGet; args = __n.args; enableProfiling = __n.enableProfiling; maxRecursionDepth = __n.maxRecursionDepth; timeoutMs = __n.timeoutMs; maxMemoryBytes = __n.maxMemoryBytes; maxModules = __n.maxModules; maxExpressionDepth = __n.maxExpressionDepth; maxProgramSizeBytes = __n.maxProgramSizeBytes; sandbox = __n.sandbox; moduleHandlers = __n.moduleHandlers; resolver = __n.resolver; } this.program = program; this.stdout = stdout; this.stderr = stderr; this.stdinReader = stdinReader; this.maxRecursionDepth = maxRecursionDepth; this.timeoutMs = timeoutMs; this.maxMemoryBytes = maxMemoryBytes; this.maxModules = maxModules; this.maxExpressionDepth = maxExpressionDepth; this.maxProgramSizeBytes = maxProgramSizeBytes; this.sandbox = sandbox; this.moduleHandlers = moduleHandlers; this._validateProgramLimits(); if (enableProfiling) { this._callCounts = {}; } for (const handler of this.moduleHandlers) { handler.init(this); } this._buildLookupTables(); this._initialized = this._initTopLevelVariables(); } _consumeGeneratorFlow(result: any): any { const input = result; if (!((result instanceof _FlowSignal))) { return result; } let gs = this._activeGeneratorScope; if ((__ball_eq(gs, null) || !gs.has('__generator__'))) { return result; } let gen = gs.lookup('__generator__'); if (!((gen instanceof BallGenerator))) { return result; } if (__ball_eq(result.kind, 'yield')) { gen.yield_(result.value); return null; } if (__ball_eq(result.kind, 'yield_each')) { let val = result.value; if ((val instanceof BallGenerator)) { gen.yieldAll(val.values); } else { gen.yieldAll(this._toIterable(val)); } return null; } return result; } profilingReport(): any { return Map.unmodifiable((this._callCounts ?? {})); } callFunction(module: any, function_: any, input: any): any { return this._resolveAndCallFunction(module, function_, input); } _validateProgramLimits(): any { let moduleCount = this.program.modules.length; if (__ball_gt(moduleCount, this.maxModules)) { throw new BallRuntimeError((((('Too many modules: ' + __ball_to_string(moduleCount)) + ' (max ') + __ball_to_string(this.maxModules)) + ')')); } let maxProgramBytes = this.maxProgramSizeBytes; if (!__ball_eq(maxProgramBytes, null)) { let programSizeBytes = this.program.writeToBuffer().length; if (__ball_gt(programSizeBytes, maxProgramBytes)) { throw new BallRuntimeError((((('Program too large: ' + __ball_to_string(programSizeBytes)) + ' bytes (max ') + __ball_to_string(maxProgramBytes)) + ')')); } } this._validateStaticExpressionDepth(); } _validateStaticExpressionDepth(): any { for (const module of this.program.modules) { for (const func of module.functions) { if (hasBody(func)) { this._validateExpressionDepth(func.body); } } } } _validateExpressionDepth(root: any): any { const input = root; let stack = [{ expr: root, depth: 1 }]; while (!(stack.length === 0)) { let current = stack.pop(); let depth = current.depth; if (__ball_gt(depth, this.maxExpressionDepth)) { throw new BallRuntimeError((((('Expression too deep: ' + __ball_to_string(depth)) + ' levels (max ') + __ball_to_string(this.maxExpressionDepth)) + ')')); } do { const __sw = whichExpr(current.expr); if ((__sw === Expression_Expr.call)) { let call = current.expr.call; if (hasInput(call)) { stack = (stack.push({ expr: call.input, depth: __ball_add(depth, 1) }), stack); } } else if ((__sw === Expression_Expr.literal)) { let literal = current.expr.literal; if (hasListValue(literal)) { for (const element of literal.listValue.elements) { stack = (stack.push({ expr: element, depth: __ball_add(depth, 1) }), stack); } } } else if ((__sw === Expression_Expr.fieldAccess)) { let access = current.expr.fieldAccess; if (hasObject(access)) { stack = (stack.push({ expr: access.object, depth: __ball_add(depth, 1) }), stack); } } else if ((__sw === Expression_Expr.messageCreation)) { for (const field of current.expr.messageCreation.fields) { if (field.hasValue()) { stack = (stack.push({ expr: field.value, depth: __ball_add(depth, 1) }), stack); } } } else if ((__sw === Expression_Expr.block)) { let block = current.expr.block; for (const statement of block.statements) { do { const __sw = whichStmt(statement); if ((__sw === Statement_Stmt.let)) { let binding = statement.let; if (binding.hasValue()) { stack = (stack.push({ expr: binding.value, depth: __ball_add(depth, 1) }), stack); } } else if ((__sw === Statement_Stmt.expression)) { stack = (stack.push({ expr: statement.expression, depth: __ball_add(depth, 1) }), stack); } else if ((__sw === Statement_Stmt.notSet)) { break; } } while (false); } if (hasResult(block)) { stack = (stack.push({ expr: block.result, depth: __ball_add(depth, 1) }), stack); } } else if ((__sw === Expression_Expr.lambda)) { let lambda = current.expr.lambda; if (hasBody(lambda)) { stack = (stack.push({ expr: lambda.body, depth: __ball_add(depth, 1) }), stack); } } else if ((__sw === Expression_Expr.reference) || (__sw === Expression_Expr.notSet)) { break; } } while (false); } } _checkExpressionDepth(): any { this._expressionDepth += 1; if (__ball_gt(this._expressionDepth, this.maxExpressionDepth)) { throw new BallRuntimeError((((('Expression too deep: ' + __ball_to_string(this._expressionDepth)) + ' levels (max ') + __ball_to_string(this.maxExpressionDepth)) + ')')); } } _exitExpression(): any { return (this._expressionDepth -= 1); } _buildLookupTables(): any { for (const module of this.program.modules) { for (const td of module.typeDefs) { if (hasDescriptor(td)) { this._types[td.name] = td.descriptor; let tc = td.name.indexOf(':'); if (__ball_ge(tc, 0)) { this._types[td.name.substring(__ball_add(tc, 1))] = td.descriptor; } } } for (const enumDesc of module.enums) { let enumName = enumDesc.name; let enumMap = {}; let enumValueList = enumDesc.value; for (let vi = 0; __ball_lt(vi, enumValueList.length); (vi++)) { let v = __ball_index(enumValueList, vi); let entry = { ['__type__']: enumName, ['name']: v.name, ['index']: v.number }; enumMap[v.name] = entry; } this._enumValues[enumName] = enumMap; let ec = enumName.indexOf(':'); if (__ball_ge(ec, 0)) { this._enumValues[enumName.substring(__ball_add(ec, 1))] = enumMap; } } for (const func of module.functions) { let key = ((__ball_to_string(module.name) + '.') + __ball_to_string(func.name)); if (hasMetadata(func)) { let isGetterField = __ball_index(func.metadata.fields, 'is_getter'); let isSetterField = __ball_index(func.metadata.fields, 'is_setter'); if (_metadataBool(isGetterField)) { this._getters[key] = func; } else { if (_metadataBool(isSetterField)) { this._setters[key] = func; this._setters[(__ball_to_string(key) + '=')] = func; } } if (_metadataBool(isSetterField)) { (this._functions[key] ??= ((() => { return func; }))()); } else { this._functions[key] = func; } } else { this._functions[key] = func; } if (hasMetadata(func)) { let params = this._extractParams(func.metadata); if ((!(params.length === 0) && !(func.name.length === 0))) { this._paramCache[key] = params; } let kindField = __ball_index(func.metadata.fields, 'kind'); if (__ball_eq((__ball_eq(kindField, null) ? null : kindField.stringValue), 'constructor')) { let entry = { module: module.name, func: func }; let dotIdx = func.name.indexOf('.'); if (__ball_ge(dotIdx, 0)) { let className = func.name.substring(0, dotIdx); let ctorSuffix = func.name.substring(__ball_add(dotIdx, 1)); if (__ball_eq(ctorSuffix, 'new')) { this._constructors[className] = entry; this._constructors[((__ball_to_string(module.name) + ':') + __ball_to_string(className))] = entry; } this._constructors[func.name] = entry; } } } this._registerFunctionDispatchTables(module, func); } } } static _typeMethodKey(typePrefix: any, methodName: any): any { return ((__ball_to_string(typePrefix) + '\u0000') + __ball_to_string(methodName)); } _registerFunctionDispatchTables(module: any, func: any): any { if ((func.isBase || !hasBody(func))) { return; } if (hasMetadata(func)) { let kind = (() => { let __naa_0 = __ball_index(func.metadata.fields, 'kind'); return (__ball_eq(__naa_0, null) ? null : __naa_0.stringValue); })(); if ((__ball_eq(kind, 'top_level_variable') || __ball_eq(kind, 'function'))) { (this._topLevelRefs[func.name] ??= ((() => { return { module: module.name, func: func, kind: kind }; }))()); } if (__ball_eq(kind, 'static_field')) { let dotIdx = func.name.lastIndexOf('.'); if (__ball_ge(dotIdx, 0)) { let bareName = func.name.substring(__ball_add(dotIdx, 1)); (this._staticFieldRefs[bareName] ??= ((() => { return { module: module.name, func: func, fullName: func.name }; }))()); } } } let funcName = func.name; let dotIdx = funcName.lastIndexOf('.'); if (__ball_lt(dotIdx, 0)) { return; } let methodName = funcName.substring(__ball_add(dotIdx, 1)); if (__ball_eq(methodName, 'new')) { return; } if ((this._isGetter(func) || this._isSetter(func))) { return; } let kindField = (hasMetadata(func) ? __ball_index(func.metadata.fields, 'kind') : null); if (__ball_eq((__ball_eq(kindField, null) ? null : kindField.stringValue), 'constructor')) { return; } let entry = { module: module.name, func: func }; let typePrefix = funcName.substring(0, dotIdx); this._typeMethodDispatch[BallEngine._typeMethodKey(typePrefix, methodName)] = entry; if (hasMetadata(func)) { let className = __ball_index(func.metadata.fields, 'class'); if ((!__ball_eq(className, null) && hasStringValue(className))) { this._typeMethodDispatch[BallEngine._typeMethodKey(className.stringValue, methodName)] = entry; } } } _resolveInstanceMethodDispatch(typeName: any, methodName: any): any { let cacheKey = BallEngine._typeMethodKey(typeName, methodName); if ((cacheKey in __ball_require_map(this._instanceMethodCache, 'map_contains_key'))) { return __ball_index(this._instanceMethodCache, cacheKey); } let resolved = (this._resolveMethod(typeName, methodName) ?? this._lookupTypeMethodWithInheritance(typeName, methodName)); this._instanceMethodCache[cacheKey] = resolved; return resolved; } _lookupTypeMethodWithInheritance(typeName: any, methodName: any): any { let colonIdx = typeName.indexOf(':'); let modPart = (__ball_ge(colonIdx, 0) ? typeName.substring(0, colonIdx) : this._currentModule); let current = typeName; while (!(current.length === 0)) { let direct = __ball_index(this._typeMethodDispatch, BallEngine._typeMethodKey(current, methodName)); if (!__ball_eq(direct, null)) { return direct; } let currentColon = current.indexOf(':'); if (__ball_ge(currentColon, 0)) { let bare = current.substring(__ball_add(currentColon, 1)); let bareHit = __ball_index(this._typeMethodDispatch, BallEngine._typeMethodKey(bare, methodName)); if (!__ball_eq(bareHit, null)) { return bareHit; } } let typeDef = this._findTypeDef(current); if (((__ball_eq(typeDef, null) || __ball_eq(typeDef.superclass, null)) || (typeDef.superclass.length === 0))) { break; } let superclass = typeDef.superclass; current = (superclass.includes(':') ? superclass : ((__ball_to_string(modPart) + ':') + __ball_to_string(superclass))); } let mixins = this._getMixins(typeName); for (const mixin of mixins) { let qualMixin = (mixin.includes(':') ? mixin : ((__ball_to_string(modPart) + ':') + __ball_to_string(mixin))); let mixinHit = __ball_index(this._typeMethodDispatch, BallEngine._typeMethodKey(qualMixin, methodName)); if (!__ball_eq(mixinHit, null)) { return mixinHit; } let mixinColon = qualMixin.indexOf(':'); if (__ball_ge(mixinColon, 0)) { let bareMixin = qualMixin.substring(__ball_add(mixinColon, 1)); let bareMixinHit = __ball_index(this._typeMethodDispatch, BallEngine._typeMethodKey(bareMixin, methodName)); if (!__ball_eq(bareMixinHit, null)) { return bareMixinHit; } } } } async _initTopLevelVariables(): Promise { for (const module of this.program.modules) { if (__ball_eq(module.name, 'std')) { continue; } for (const func of module.functions) { if (!hasMetadata(func)) { continue; } let kindValue = __ball_index(func.metadata.fields, 'kind'); let kindStr = (__ball_eq(kindValue, null) ? null : kindValue.stringValue); if ((!__ball_eq(kindStr, 'top_level_variable') && !__ball_eq(kindStr, 'static_field'))) { continue; } this._currentModule = module.name; let value = (hasBody(func) ? await this._evalExpression(func.body, this._globalScope) : null); if (func.outputType.startsWith('Map')) { if ((this._isBallSet(value) && (this._ballSetItems(value).length === 0))) { value = _ballUserMap(); } if ((Array.isArray(value) && (value.length === 0))) { value = _ballUserMap(); } } // Convert empty Set to Map if outputType says Map if (func.outputType && typeof func.outputType === 'string' && func.outputType.startsWith('Map')) { if (value instanceof Set && value.size === 0) value = {}; if (Array.isArray(value) && value.length === 0) value = {}; } this._globalScope.bind(func.name, value); // Also bind short name for unqualified access const __dotIdx = func.name.lastIndexOf('.'); if (__dotIdx >= 0) { this._globalScope.bind(func.name.substring(__dotIdx + 1), value); } } } } async run(): Promise { this._executionStartMs = DateTime.now().millisecondsSinceEpoch; await this._initialized; let key = ((__ball_to_string(this.program.entryModule) + '.') + __ball_to_string(this.program.entryFunction)); let entryFunc = __ball_index(this._functions, key); if (__ball_eq(entryFunc, null)) { throw new BallRuntimeError(((('Entry point "' + __ball_to_string(this.program.entryFunction)) + '" not found ') + (('in module "' + __ball_to_string(this.program.entryModule)) + '"'))); } this._currentModule = this.program.entryModule; return this._callFunction(this.program.entryModule, entryFunc, null); } _checkExecutionTimeout(): any { let timeout = this.timeoutMs; let start = this._executionStartMs; if ((__ball_eq(timeout, null) || __ball_eq(start, null))) { return; } let elapsed = __ball_sub(DateTime.now().millisecondsSinceEpoch, start); if (__ball_gt(elapsed, timeout)) { throw new BallRuntimeError('Execution timeout exceeded'); } } _trackStringAllocation(value: any): any { const input = value; this._trackMemoryAllocation(__ball_mul(value.length, _ballStringCodeUnitBytes)); return value; } _trackByteListAllocation(value: any): any { const input = value; this._trackMemoryAllocation(__ball_mul(value.length, _ballPointerBytes)); return value; } _trackMemoryAllocation(bytes: any): any { const input = bytes; let limit = this.maxMemoryBytes; if ((__ball_eq(limit, null) || __ball_le(bytes, 0))) { return; } if (__ball_gt(__ball_add(this._memoryUsedBytes, bytes), limit)) { throw new BallRuntimeError('Memory limit exceeded'); } this._memoryUsedBytes += bytes; } _asMap(v: any): any { const input = v; if (((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) && !(false /* BallMap is Map in TS */))) { if (__ball_is_type(v, "Map")) { return v; } return v.cast(); } if (false /* BallMap is Map in TS */) { return v.entries; } } async _callFunction(moduleName: any, func: any, input: any): Promise { let kind = (hasMetadata(func) ? (() => { let __naa_1 = __ball_index(func.metadata.fields, 'kind'); return (__ball_eq(__naa_1, null) ? null : __naa_1.stringValue); })() : null); if (func.isBase) { return this._callBaseFunction(moduleName, func.name, input); } if (__ball_ge(this._recursionDepth, this.maxRecursionDepth)) { throw new BallRuntimeError(('Maximum recursion depth exceeded: ' + __ball_to_string(this.maxRecursionDepth))); } (this._recursionDepth++); let prevGeneratorScope = this._activeGeneratorScope; try { if (!hasBody(func)) { if (hasMetadata(func)) { if (__ball_eq(kind, 'constructor')) { return this._buildConstructorInstance(moduleName, func, input); } } return null; } if (__ball_eq(kind, 'constructor')) { let constructorInput = this._asMap(input); let dotIdx = func.name.indexOf('.'); let typeName = (__ball_ge(dotIdx, 0) ? func.name.substring(0, dotIdx) : func.name); let isFactory = (hasMetadata(func) && _metadataBool(__ball_index(func.metadata.fields, 'is_factory'))); if (((!isFactory && (__ball_eq(constructorInput, null) || !('self' in __ball_require_map(constructorInput, 'map_contains_key')))) && !__ball_eq(this._findTypeDef(typeName), null))) { return this._callObjectConstructor(moduleName, func, input); } } let prevModule = this._currentModule; this._currentModule = moduleName; let scope = new _Scope(this._globalScope); if ((!(func.inputType.length === 0) && !__ball_eq(input, null))) { scope.bind('input', input); } let params = (!(func.name.length === 0) ? (__ball_index(this._paramCache, ((__ball_to_string(moduleName) + '.') + __ball_to_string(func.name))) ?? ((hasMetadata(func) ? this._extractParams(func.metadata) : []))) : ((hasMetadata(func) ? this._extractParams(func.metadata) : []))); let inputMap = this._asMap(input); if (!(params.length === 0)) { if ((__ball_eq(params.length, 1) && !(!__ball_eq(inputMap, null) && ('self' in __ball_require_map(inputMap, 'map_contains_key'))))) { if ((!__ball_eq(inputMap, null) && (__ball_index(params, 0) in __ball_require_map(inputMap, 'map_contains_key')))) { scope.bind(__ball_index(params, 0), __ball_index(inputMap, __ball_index(params, 0))); } else { if (((!__ball_eq(inputMap, null) && ('arg0' in __ball_require_map(inputMap, 'map_contains_key'))) && !(__ball_index(params, 0) in __ball_require_map(inputMap, 'map_contains_key')))) { scope.bind(__ball_index(params, 0), __ball_index(inputMap, 'arg0')); } else { scope.bind(__ball_index(params, 0), input); } } } else { if (!__ball_eq(inputMap, null)) { for (let i = 0; __ball_lt(i, params.length); (i++)) { let p = __ball_index(params, i); if ((p in __ball_require_map(inputMap, 'map_contains_key'))) { scope.bind(p, __ball_index(inputMap, p)); } else { if ((('arg' + __ball_to_string(i)) in __ball_require_map(inputMap, 'map_contains_key'))) { scope.bind(p, __ball_index(inputMap, ('arg' + __ball_to_string(i)))); } else { if ((((__ball_eq(i, 0) && __ball_eq(params.length, 1)) && ('value' in __ball_require_map(inputMap, 'map_contains_key'))) && this._isSetter(func))) { scope.bind(p, __ball_index(inputMap, 'value')); } } } } } else { if (Array.isArray(input)) { for (let i = 0; (__ball_lt(i, params.length) && __ball_lt(i, input.length)); (i++)) { scope.bind(__ball_index(params, i), __ball_index(input, i)); } } } } } if ((!__ball_eq(inputMap, null) && ('self' in __ball_require_map(inputMap, 'map_contains_key')))) { let self = __ball_index(inputMap, 'self'); scope.bind('self', self); let selfMap = this._asMap(self); if (!__ball_eq(selfMap, null)) { for (const entry of selfMap.entries) { if (!entry.key.startsWith('__')) { scope.bind(entry.key, entry.value); } } let superObj = this._asMap(__ball_index(selfMap, '__super__')); while (!__ball_eq(superObj, null)) { for (const entry of superObj.entries) { if (((!entry.key.startsWith('__') && !scope.has(entry.key)) && !__ball_eq(entry.value, null))) { scope.bind(entry.key, entry.value); } } superObj = this._asMap(__ball_index(superObj, '__super__')); } let superValue = __ball_index(selfMap, '__super__'); if (!__ball_eq(superValue, null)) { scope.bind('super', superValue); } if (__ball_eq(kind, 'constructor')) { let typeName = __ball_index(selfMap, '__type__'); if ((typeof typeName === 'string')) { scope.bind('__constructor_type__', typeName); } } } } let isSyncStar = (hasMetadata(func) && _metadataBool(__ball_index(func.metadata.fields, 'is_sync_star'))); let isAsyncStar = (hasMetadata(func) && _metadataBool(__ball_index(func.metadata.fields, 'is_async_star'))); let isGenerator = (hasMetadata(func) && _metadataBool(__ball_index(func.metadata.fields, 'is_generator'))); let isGenFunc = ((isSyncStar || isAsyncStar) || isGenerator); let generator; if (isGenFunc) { generator = _ballNewGenerator(); scope.bind('__generator__', generator); } if (isGenFunc) { this._activeGeneratorScope = scope; } let isAsync = (hasMetadata(func) && _metadataBool(__ball_index(func.metadata.fields, 'is_async'))); let finalResult; if ((isAsync && !isGenFunc)) { try { let result = await this._evalExpression(func.body, scope); this._currentModule = prevModule; if (((result instanceof _FlowSignal) && __ball_eq(result.kind, 'return'))) { finalResult = result.value; } else { finalResult = result; } } catch (__ball_active_error) { const e = __ball_active_error; this._currentModule = prevModule; return _ballFutureError(e); } } else { let result = await this._evalExpression(func.body, scope); this._currentModule = prevModule; if (((__ball_eq(kind, 'constructor') && !__ball_eq(inputMap, null)) && ('self' in __ball_require_map(inputMap, 'map_contains_key')))) { let isFactory = (hasMetadata(func) && _metadataBool(__ball_index(func.metadata.fields, 'is_factory'))); if (((result instanceof _FlowSignal) && __ball_eq(result.kind, 'return'))) { finalResult = result.value; } else { if (!isFactory) { finalResult = __ball_index(inputMap, 'self'); } else { if ((result instanceof _FlowSignal)) { finalResult = result.value; } else { finalResult = result; } } } } else { if (((result instanceof _FlowSignal) && __ball_eq(result.kind, 'return'))) { if ((isGenFunc && !__ball_eq(generator, null))) { } else { finalResult = result.value; } } else { finalResult = result; } } } if ((isGenFunc && !__ball_eq(generator, null))) { generator.completed = true; let genFromScope = scope.lookup('__generator__'); let values = ((genFromScope instanceof BallGenerator) ? _ballGeneratorValues(genFromScope) : generator.values); if (isAsyncStar) { return _ballFuture(values); } return values; } if (isAsync) { if (!_isBallFuture(finalResult)) { return _ballFuture(finalResult); } } return finalResult; } catch (__ball_active_error) { throw __ball_active_error; } finally { this._activeGeneratorScope = prevGeneratorScope; (this._recursionDepth--); } } async _callObjectConstructor(moduleName: any, func: any, input: any): Promise { let dotIdx = func.name.indexOf('.'); let typeName = (__ball_ge(dotIdx, 0) ? func.name.substring(0, dotIdx) : func.name); let typeDef = this._findTypeDef(typeName); if (__ball_eq(typeDef, null)) { return null; } let inputMap = (this._asMap(input) ?? { ['arg0']: input }); let instanceFields = {}; for (const fieldName of typeDef.fieldNames) { instanceFields[fieldName] = null; } let allFieldNames = this._collectAllFieldNames(typeName); let params = (hasMetadata(func) ? this._extractParams(func.metadata) : []); let paramsMeta = (hasMetadata(func) ? this._extractParamsMeta(func.metadata) : []); let resolvedParams = {}; for (let i = 0; __ball_lt(i, params.length); (i++)) { let param = __ball_index(params, i); let value; if ((param in __ball_require_map(inputMap, 'map_contains_key'))) { value = __ball_index(inputMap, param); } else { if ((('arg' + __ball_to_string(i)) in __ball_require_map(inputMap, 'map_contains_key'))) { value = __ball_index(inputMap, ('arg' + __ball_to_string(i))); } } if (((__ball_eq(value, null) && __ball_lt(i, paramsMeta.length)) && ('default' in __ball_require_map(__ball_index(paramsMeta, i), 'map_contains_key')))) { value = __ball_index(__ball_index(paramsMeta, i), 'default'); } resolvedParams[param] = value; let isThis = (__ball_lt(i, paramsMeta.length) && __ball_eq(__ball_index(__ball_index(paramsMeta, i), 'is_this'), true)); if ((isThis || allFieldNames.includes(param))) { instanceFields[param] = value; } else { if ((__ball_eq(params.length, 1) && __ball_eq(allFieldNames.length, 1))) { instanceFields[allFieldNames.first] = value; } } } this._initFieldDefaults(typeName, instanceFields); let superclass = this._getMetaString(typeDef, 'superclass'); let superObject; if ((!__ball_eq(superclass, null) && !(superclass.length === 0))) { superObject = await this._invokeSuperConstructor(func, superclass, resolvedParams); superObject ??= this._buildSuperObject(superclass, instanceFields); } let methods = this._resolveTypeMethodsWithInheritance(typeName); let instance = new BallObject({ typeName: typeName, superObject: superObject, fields: instanceFields, methods: methods.cast() }); let ctorInput = (() => { let __cascade_self__ = {}; __cascade_self__.addAll(inputMap); __cascade_self__.addAll(resolvedParams); __cascade_self__['self'] = instance; return __cascade_self__; })(); let constructed = await this._callFunction(moduleName, func, ctorInput); let constructedMap = this._asMap(constructed); if ((!__ball_eq(constructedMap, null) && ('__type__' in __ball_require_map(constructedMap, 'map_contains_key')))) { return constructed; } return instance; } _applyConstructorInitializers(func: any, targetFields: any, resolvedParams: any, onlyIfAbsent: any): any { if (!hasMetadata(func)) { return; } let initsField = __ball_index(func.metadata.fields, 'initializers'); if ((__ball_eq(initsField, null) || !__ball_eq(whichKind(initsField), structpb_Value_Kind.listValue))) { return; } for (const init of initsField.listValue.values) { if (!__ball_eq(whichKind(init), structpb_Value_Kind.structValue)) { continue; } let kind = (() => { let __naa_2 = __ball_index(init.structValue.fields, 'kind'); return (__ball_eq(__naa_2, null) ? null : __naa_2.stringValue); })(); let name = (() => { let __naa_3 = __ball_index(init.structValue.fields, 'name'); return (__ball_eq(__naa_3, null) ? null : __naa_3.stringValue); })(); if ((!__ball_eq(kind, 'field') || __ball_eq(name, null))) { continue; } if ((onlyIfAbsent && !__ball_eq(__ball_index(targetFields, name), null))) { continue; } let valField = __ball_index(init.structValue.fields, 'value'); if ((!__ball_eq(valField, null) && hasStringValue(valField))) { let valStr = valField.stringValue; let indexMatch = new RegExp('^(\\w+)\\[(\\d+)\\]$').firstMatch(valStr); if (!__ball_eq(indexMatch, null)) { let arrName = indexMatch.group(1); let idx = __ball_parse_int(indexMatch.group(2)); let rawArr = __ball_index(resolvedParams, arrName); let arr = (false /* BallList is List in TS */ ? rawArr.items : rawArr); if ((Array.isArray(arr) && __ball_lt(idx, arr.length))) { targetFields[name] = __ball_index(arr, idx); } else { targetFields[name] = null; } } else { if (__ball_eq(valStr, 'true')) { targetFields[name] = true; } else { if (__ball_eq(valStr, 'false')) { targetFields[name] = false; } else { if (!__ball_eq(num.tryParse(valStr), null)) { let numVal = num.parse(valStr); targetFields[name] = (valStr.includes('.') ? new BallDouble(new BallDouble(Number(numVal))) : __ball_to_int(numVal)); } else { targetFields[name] = (__ball_index(resolvedParams, valStr) ?? valStr); } } } } } else { if ((!__ball_eq(valField, null) && hasNumberValue(valField))) { let n = valField.numberValue; targetFields[name] = (__ball_eq(n, __ball_to_int(n)) ? __ball_to_int(n) : n); } else { if ((!__ball_eq(valField, null) && hasBoolValue(valField))) { targetFields[name] = valField.boolValue; } else { targetFields[name] = null; } } } } } async _buildConstructorInstance(moduleName: any, func: any, input: any): Promise { let params = (hasMetadata(func) ? this._extractParams(func.metadata) : []); let paramsMeta = this._extractParamsMeta(func.metadata); let instance = {}; let dotIdx = func.name.indexOf('.'); let typeName = (__ball_ge(dotIdx, 0) ? func.name.substring(0, dotIdx) : func.name); instance['__type__'] = typeName; let resolvedParams = {}; let inputMap = this._asMap(input); if (!__ball_eq(inputMap, null)) { for (let i = 0; __ball_lt(i, params.length); (i++)) { let p = __ball_index(params, i); let isThis = (__ball_lt(i, paramsMeta.length) && __ball_eq(__ball_index(__ball_index(paramsMeta, i), 'is_this'), true)); let val; if ((p in __ball_require_map(inputMap, 'map_contains_key'))) { val = __ball_index(inputMap, p); } else { if ((('arg' + __ball_to_string(i)) in __ball_require_map(inputMap, 'map_contains_key'))) { val = __ball_index(inputMap, ('arg' + __ball_to_string(i))); } else { val = (__ball_lt(i, paramsMeta.length) ? __ball_index(__ball_index(paramsMeta, i), 'default') : null); } } resolvedParams[p] = val; if (isThis) { instance[p] = val; } } for (const entry of inputMap.entries) { if (entry.key.startsWith('arg')) { continue; } instance[entry.key] = entry.value; } } else { if (__ball_eq(params.length, 1)) { resolvedParams[__ball_index(params, 0)] = input; let isThis = (!(paramsMeta.length === 0) && __ball_eq(__ball_index(__ball_index(paramsMeta, 0), 'is_this'), true)); if (isThis) { instance[__ball_index(params, 0)] = input; } } } this._applyConstructorInitializers(func, instance, resolvedParams); let typeDef = this._findTypeDef(typeName); if (!__ball_eq(typeDef, null)) { let superclass = this._getMetaString(typeDef, 'superclass'); if ((!__ball_eq(superclass, null) && !(superclass.length === 0))) { let superInstance = await this._invokeSuperConstructor(func, superclass, resolvedParams); let superMap = this._asMap(superInstance); if (!__ball_eq(superMap, null)) { instance['__super__'] = superInstance; for (const e of superMap.entries) { if ((!e.key.startsWith('__') && !(e.key in __ball_require_map(instance, 'map_contains_key')))) { instance[e.key] = e.value; } } } else { instance['__super__'] = this._buildSuperObject(superclass, instance); } } let methods = this._resolveTypeMethodsWithInheritance(typeName); if (!(methods.length === 0)) { instance['__methods__'] = methods; } } let fields = {}; for (const entry of instance.entries) { if (!entry.key.startsWith('__')) { fields[entry.key] = entry.value; } } return new BallObject({ typeName: typeName, superObject: __ball_index(instance, '__super__'), fields: fields, methods: (__ball_index(instance, '__methods__') ?? {}) }); } async _invokeSuperConstructor(childCtor: any, superclass: any, resolvedParams: any): Promise { if (hasMetadata(childCtor)) { let initsField = __ball_index(childCtor.metadata.fields, 'initializers'); if ((!__ball_eq(initsField, null) && __ball_eq(whichKind(initsField), structpb_Value_Kind.listValue))) { for (const init of initsField.listValue.values) { if (!__ball_eq(whichKind(init), structpb_Value_Kind.structValue)) { continue; } let kind = (() => { let __naa_4 = __ball_index(init.structValue.fields, 'kind'); return (__ball_eq(__naa_4, null) ? null : __naa_4.stringValue); })(); if (__ball_eq(kind, 'super')) { let argsStr = ((() => { let __naa_5 = __ball_index(init.structValue.fields, 'args'); return (__ball_eq(__naa_5, null) ? null : __naa_5.stringValue); })() ?? ''); let argNames = this._parseSuperArgs(argsStr); let superInput = {}; for (let i = 0; __ball_lt(i, argNames.length); (i++)) { let token = __ball_index(argNames, i); if ((token in __ball_require_map(resolvedParams, 'map_contains_key'))) { superInput[('arg' + __ball_to_string(i))] = __ball_index(resolvedParams, token); } else { if (((token.startsWith('\'') && token.endsWith('\'')) || (token.startsWith('"') && token.endsWith('"')))) { superInput[('arg' + __ball_to_string(i))] = token.substring(1, __ball_sub(token.length, 1)); } else { if (!__ball_eq(num.tryParse(token), null)) { let n = num.parse(token); superInput[('arg' + __ball_to_string(i))] = (token.includes('.') ? new BallDouble(Number(n)) : __ball_to_int(n)); } else { if (__ball_eq(token, 'true')) { superInput[('arg' + __ball_to_string(i))] = true; } else { if (__ball_eq(token, 'false')) { superInput[('arg' + __ball_to_string(i))] = false; } } } } } } let superCtorEntry = this._lookupConstructor(superclass); if (!__ball_eq(superCtorEntry, null)) { return this._callFunction(superCtorEntry.module, superCtorEntry.func, superInput); } } } } } let superCtorEntry = this._lookupConstructor(superclass); if (!__ball_eq(superCtorEntry, null)) { let superInput = {}; for (let i = 0; __ball_lt(i, resolvedParams.length); (i++)) { superInput[('arg' + __ball_to_string(i))] = resolvedParams.values.elementAt(i); } return this._callFunction(superCtorEntry.module, superCtorEntry.func, superInput); } } _lookupConstructor(name: any): any { const input = name; let direct = __ball_index(this._constructors, name); if (!__ball_eq(direct, null)) { return direct; } let qualified = ((__ball_to_string(this._currentModule) + ':') + __ball_to_string(name)); let qual = __ball_index(this._constructors, qualified); if (!__ball_eq(qual, null)) { return qual; } for (const entry of this._constructors.entries) { let key = entry.key; let colonIdx = key.indexOf(':'); let bare = (__ball_ge(colonIdx, 0) ? key.substring(__ball_add(colonIdx, 1)) : key); if (__ball_eq(bare, name)) { return entry.value; } } } _parseSuperArgs(argsStr: any): any { const input = argsStr; let trimmed = argsStr.trim(); if ((trimmed.length === 0)) { return []; } let inner = ((trimmed.startsWith('(') && trimmed.endsWith(')')) ? trimmed.substring(1, __ball_sub(trimmed.length, 1)) : trimmed); if ((inner.length === 0)) { return []; } return [...inner.split(',').map(((s) => { const input = s; return s.trim(); })).filter(((s) => { const input = s; return !(s.length === 0); }))]; } _extractParamsMeta(metadata: any): any { const input = metadata; let paramsValue = __ball_index(metadata.fields, 'params'); if ((__ball_eq(paramsValue, null) || !__ball_eq(whichKind(paramsValue), structpb_Value_Kind.listValue))) { return []; } return [...paramsValue.listValue.values.filter(((v) => { const input = v; return __ball_eq(whichKind(v), structpb_Value_Kind.structValue); })).map(((v) => { const input = v; let fields = v.structValue.fields; let result = {}; let nameField = __ball_index(fields, 'name'); if (!__ball_eq(nameField, null)) { result['name'] = nameField.stringValue; } let isThisField = __ball_index(fields, 'is_this'); if (!__ball_eq(isThisField, null)) { result['is_this'] = isThisField.boolValue; } let defaultField = __ball_index(fields, 'default_value'); if (!__ball_eq(defaultField, null)) { if (hasStringValue(defaultField)) { result['default'] = defaultField.stringValue; } else { if (hasNumberValue(defaultField)) { let n = defaultField.numberValue; result['default'] = (__ball_eq(n, __ball_to_int(n)) ? __ball_to_int(n) : n); } else { if (hasBoolValue(defaultField)) { result['default'] = defaultField.boolValue; } } } } return result; }))]; } _extractParams(metadata: any): any { const input = metadata; let paramsValue = __ball_index(metadata.fields, 'params'); if ((__ball_eq(paramsValue, null) || !__ball_eq(whichKind(paramsValue), structpb_Value_Kind.listValue))) { return []; } return [...paramsValue.listValue.values.filter(((v) => { const input = v; return __ball_eq(whichKind(v), structpb_Value_Kind.structValue); })).map(((v) => { const input = v; let nameField = __ball_index(v.structValue.fields, 'name'); return ((__ball_eq(nameField, null) ? null : nameField.stringValue) ?? ''); })).filter(((n) => { const input = n; return !(n.length === 0); }))]; } _rawTypeDefCache: any = {}; _fieldDefaultsCache: any = {}; _findRawTypeDef(typeName: any): any { if (this._rawTypeDefCache[typeName] !== undefined) return this._rawTypeDefCache[typeName]; for (const module of this.program.modules) { for (const td of module.typeDefs) { if (td.name === typeName || td.name.endsWith(':' + String(typeName))) { this._rawTypeDefCache[typeName] = td; return td; } } } this._rawTypeDefCache[typeName] = null; return null; } _getFieldDefaults(typeName: any): any { if (this._fieldDefaultsCache[typeName]) return this._fieldDefaultsCache[typeName]; const defaults: any = {}; const rawTd = this._findRawTypeDef(typeName); if (!rawTd || !rawTd.metadata) { this._fieldDefaultsCache[typeName] = defaults; return defaults; } // Parse metadata fields array for initializers const metaFields = rawTd.metadata.fields ? rawTd.metadata.fields['fields'] : null; let fieldArr: any[] = []; if (metaFields && metaFields.whichKind && metaFields.whichKind() === 'listValue') { for (const v of metaFields.listValue.values) { if (v.whichKind && v.whichKind() === 'structValue') { const r: any = {}; const sf = v.structValue.fields; for (const k of Object.keys(sf)) { const fv = sf[k]; if (fv && fv.whichKind) { const kind = fv.whichKind(); if (kind === 'stringValue') r[k] = fv.stringValue; else if (kind === 'boolValue') r[k] = fv.boolValue; else r[k] = fv._raw ?? null; } else r[k] = fv; } fieldArr.push(r); } } } else if (Array.isArray(metaFields)) { fieldArr = metaFields; } for (const fm of fieldArr) { if (!fm.name) continue; if (fm.initializer && fm.initializer !== 'null') { const init = fm.initializer; if (init === '[]' || init.startsWith('<')) defaults[fm.name] = []; else if (init === '{}') defaults[fm.name] = {}; else if (init === '0' || init === '0.0') defaults[fm.name] = 0; else if (init === 'false') defaults[fm.name] = false; else if (init === 'true') defaults[fm.name] = true; else if (init === "''" || init === '""') defaults[fm.name] = ''; else defaults[fm.name] = null; } } this._fieldDefaultsCache[typeName] = defaults; return defaults; } async __buildCtorInstance(moduleName: any, func: any, input: any): Promise { const params = func.hasMetadata() ? this._extractParams(func.metadata) : []; const paramsMeta = this.__extractParamsMeta(func.metadata); const instance: any = {}; const dotIdx = func.name.indexOf('.'); const typeName = dotIdx >= 0 ? func.name.substring(0, dotIdx) : func.name; instance['__type__'] = typeName; // Resolve all param values. const resolvedParams: any = {}; if (typeof input === 'object' && input !== null && !Array.isArray(input)) { for (let i = 0; i < params.length; i++) { const p = params[i]; const isThis = i < paramsMeta.length && paramsMeta[i]['is_this'] === true; let val: any; if (p in input) { val = input[p]; } else if (('arg' + i) in input) { val = input['arg' + i]; } else { val = i < paramsMeta.length ? (paramsMeta[i]['default'] ?? null) : null; } resolvedParams[p] = val; if (isThis) { instance[p] = val; } } } else if (params.length === 1) { resolvedParams[params[0]] = input; const isThis = paramsMeta.length > 0 && paramsMeta[0]['is_this'] === true; if (isThis) { instance[params[0]] = input; } } // Process initializers (super calls, field initializations). if (func.hasMetadata()) { const initsField = func.metadata.fields ? func.metadata.fields['initializers'] : null; let inits: any[] = []; if (initsField && initsField.whichKind && initsField.whichKind() === 'listValue') { inits = initsField.listValue.values.map((v: any) => { if (v.whichKind && v.whichKind() === 'structValue') { const r: any = {}; const sf = v.structValue.fields; for (const k of Object.keys(sf)) { const fv = sf[k]; if (fv && fv.whichKind) { const kind = fv.whichKind(); if (kind === 'stringValue') r[k] = fv.stringValue; else if (kind === 'boolValue') r[k] = fv.boolValue; else r[k] = fv._raw ?? null; } else { r[k] = fv; } } return r; } return {}; }); } else if (initsField && Array.isArray(initsField)) { inits = initsField; } else if (initsField && initsField._raw && Array.isArray(initsField._raw)) { inits = initsField._raw; } for (const init of inits) { if (init.kind === 'super') { // Call super constructor. const typeDef = this._findTypeDef(typeName); const superclass = typeDef?.superclass; if (superclass && typeof superclass === 'string' && superclass.length > 0) { // Parse args from the initializer. const argsStr = typeof init.args === 'string' ? init.args : ''; const superInput: any = {}; // Simple arg parsing: "(name)" -> {arg0: resolvedParams[name]} // "(name, age)" -> {arg0: name, arg1: age} const argMatch = argsStr.match(/\(([^)]*)\)/); if (argMatch) { const argNames = argMatch[1].split(',').map((s: string) => s.trim()).filter((s: string) => s); for (let i = 0; i < argNames.length; i++) { const argName = argNames[i]; // Strip quotes from string literal args let __argVal = resolvedParams[argName]; if (__argVal === undefined) { if ((argName.startsWith("'") && argName.endsWith("'")) || (argName.startsWith('"') && argName.endsWith('"'))) { __argVal = argName.substring(1, argName.length - 1); } else if (!isNaN(Number(argName))) { __argVal = Number(argName); } else { __argVal = argName; } } superInput['arg' + i] = __argVal; } } // Try various constructor key patterns for the superclass. const __scKeys = [ superclass + '.new', superclass, moduleName + ':' + superclass + '.new', moduleName + ':' + superclass, ]; let superCtor: any = null; for (const __sk of __scKeys) { if (this._constructors[__sk]) { superCtor = this._constructors[__sk]; break; } } if (superCtor) { const superObj = await this._callFunction(superCtor.module, superCtor.func, superInput); if (typeof superObj === 'object' && superObj !== null) { // Copy super's non-__ fields into our instance. for (const k of Object.keys(superObj)) { if (!k.startsWith('__') && !(k in instance)) instance[k] = superObj[k]; } instance['__super__'] = superObj; } } } } else if (init.kind === 'field') { // Field initializer: assign a value to a field. const fieldName = init.name; const valStr = init.value; if (fieldName && valStr != null) { if (valStr in resolvedParams) { instance[fieldName] = resolvedParams[valStr]; } else { // Try evaluating simple expressions like "coords[0]" const __idxMatch = String(valStr).match(/^(\w+)\[(\d+)\]$/); if (__idxMatch && __idxMatch[1] in resolvedParams) { const __arr = resolvedParams[__idxMatch[1]]; const __idx = parseInt(__idxMatch[2], 10); instance[fieldName] = Array.isArray(__arr) ? __arr[__idx] : __arr; } else { instance[fieldName] = valStr; } } } } } } // Initialize field defaults from typeDef descriptor. const typeDef = this._findTypeDef(typeName); if (typeDef != null) { if (typeDef.fieldNames) { for (const fn of typeDef.fieldNames) { if (!(fn in instance)) instance[fn] = null; } } if (!instance['__super__'] && typeDef.superclass && typeof typeDef.superclass === 'string' && typeDef.superclass.length > 0) { instance['__super__'] = this._buildSuperObject(typeDef.superclass, instance); } const methods = this._resolveTypeMethodsWithInheritance(typeName); if (typeof methods === 'object' && methods !== null && Object.keys(methods).length > 0) { instance['__methods__'] = methods; } } return instance; } __extractParamsMeta(metadata: any): any[] { if (!metadata) return []; const paramsField = metadata.fields ? metadata.fields['params'] : (metadata['params'] ?? null); if (!paramsField) return []; let raw: any[]; if (paramsField.whichKind && paramsField.whichKind() === 'listValue') { raw = paramsField.listValue.values.map((v: any) => { if (v.whichKind && v.whichKind() === 'structValue') { const result: any = {}; const sf = v.structValue.fields; for (const k of Object.keys(sf)) { const fv = sf[k]; if (fv.whichKind) { const kind = fv.whichKind(); if (kind === 'stringValue') result[k] = fv.stringValue; else if (kind === 'boolValue') result[k] = fv.boolValue; else if (kind === 'numberValue') result[k] = fv.numberValue; else result[k] = fv._raw ?? null; } else { result[k] = fv; } } return result; } return {}; }); } else if (Array.isArray(paramsField)) { raw = paramsField; } else if (paramsField._raw && Array.isArray(paramsField._raw)) { raw = paramsField._raw; } else { return []; } return raw; } async _resolveAndCallFunction(module: any, function_: any, input: any): Promise { let moduleName = ((module.length === 0) ? this._currentModule : module); let key = ((__ball_to_string(moduleName) + '.') + __ball_to_string(function_)); let func = __ball_index(this._functions, key); if (!__ball_eq(func, null)) { return this._callFunction(moduleName, func, input); } let cached = __ball_index(this._callCache, function_); if (!__ball_eq(cached, null)) { return this._callFunction(cached.module, cached.func, input); } let sawBase = false; let sawUser = false; for (const m of this.program.modules) { for (const f of m.functions) { if (__ball_eq(f.name, function_)) { if (f.isBase) { sawBase = true; } else { sawUser = true; } } } } if ((sawBase && sawUser)) { throw new BallRuntimeError((((('Ambiguous unqualified call to "' + __ball_to_string(function_)) + '": a user-defined function ') + 'shadows a base function of the same name. Qualify the call with an ') + 'explicit module to disambiguate (issue #420).')); } for (const m of this.program.modules) { for (const f of m.functions) { if (__ball_eq(f.name, function_)) { this._callCache[function_] = { module: m.name, func: f }; return this._callFunction(m.name, f, input); } } } let ctorKey = (((__ball_to_string(moduleName) + '.') + __ball_to_string(function_)) + '.new'); let ctorFunc = __ball_index(this._functions, ctorKey); if (!__ball_eq(ctorFunc, null)) { return this._callFunction(moduleName, ctorFunc, input); } let ctorEntry = __ball_index(this._constructors, function_); if (!__ball_eq(ctorEntry, null)) { return this._callFunction(ctorEntry.module, ctorEntry.func, input); } if (!__ball_eq(this._resolver, null)) { let resolved = await this._tryLazyResolve(moduleName); if (!__ball_eq(resolved, null)) { this._indexModule(resolved); let resolvedFunc = __ball_index(this._functions, ((__ball_to_string(moduleName) + '.') + __ball_to_string(function_))); if (!__ball_eq(resolvedFunc, null)) { return this._callFunction(moduleName, resolvedFunc, input); } } } // Fallback: try OOP method dispatch via self.__type__ if (typeof input === 'object' && input !== null && !Array.isArray(input)) { const __self = input['self']; if (__self != null && typeof __self === 'object' && !Array.isArray(__self)) { let __tn = __self['__type__']; // Handle built-in class references (List, Map, Set, or user types) if (__tn === '__builtin_class__' && __self['__class_ref__']) { const __cr = __self['__class_ref__']; // Try as a named constructor (e.g., Point.origin) const __ctorKeys = [ __cr + '.' + function_, moduleName + ':' + __cr + '.' + function_, ]; for (const __ck of __ctorKeys) { const __ctorEntry = this._constructors[__ck]; if (__ctorEntry) { const __ctorInput = Object.assign({}, input); delete __ctorInput['self']; return this._callFunction(__ctorEntry.module, __ctorEntry.func, __ctorInput); } } // Try as a static method const __staticKeys = [ moduleName + '.' + moduleName + ':' + __cr + '.' + function_, moduleName + '.' + __cr + '.' + function_, ]; for (const __sk of __staticKeys) { const __sfn = this._functions[__sk]; if (__sfn) { const __sInput = Object.assign({}, input); delete __sInput['self']; return this._callFunction(moduleName, __sfn, __sInput); } } } if (__tn != null && __tn !== '__builtin_class__') { const __ci = String(__tn).indexOf(':'); const __mp = __ci >= 0 ? String(__tn).substring(0, __ci) : moduleName; // Try various key formats const __bareType = String(__tn).indexOf(':') >= 0 ? String(__tn).substring(String(__tn).indexOf(':') + 1) : String(__tn); const __keys = [ __mp + '.' + __tn + '.' + function_, __mp + '.' + __bareType + '.' + function_, __mp + '.' + __mp + ':' + __bareType + '.' + function_, __mp + '.' + __mp + ':' + __tn + '.' + function_, ]; // Also try via __methods__ dispatch entries const __methods = __self['__methods__']; if (__methods) { // Try dispatch entry (short name) const __dEntry = __methods['__dispatch_' + function_]; if (__dEntry && __dEntry.func) return this._callFunction(__dEntry.module, __dEntry.func, input); // Try full name match if (__methods[function_] && typeof __methods[function_] === 'function') return __methods[function_](input); } // Try via super chain let __sp = __self['__super__']; while (__sp != null && typeof __sp === 'object' && !Array.isArray(__sp)) { const __stn = __sp['__type__']; if (__stn) { const __sci = String(__stn).indexOf(':'); const __smp = __sci >= 0 ? String(__stn).substring(0, __sci) : __mp; __keys.push(__smp + '.' + __stn + '.' + function_); __keys.push(__smp + '.' + (String(__stn).indexOf(':') >= 0 ? String(__stn).substring(String(__stn).indexOf(':') + 1) : __stn) + '.' + function_); } const __sm = __sp['__methods__']; if (__sm && __sm[function_]) { const __smEntry = __sm[function_]; if (typeof __smEntry === 'object' && __smEntry.func) { return this._callFunction(__smEntry.module, __smEntry.func, input); } } __sp = __sp['__super__']; } for (const __k of __keys) { const __fn = this._functions[__k]; if (__fn != null) { return this._callFunction(__mp, __fn, input); } } // No more keys to try } } // Fallback: try dispatching as a std/std_collections base function // This handles method-style calls like sort(), where() on lists/maps for (const __stdMod of ['std', 'std_collections', 'std_io']) { try { return await this._callBaseFunction(__stdMod, function_, input); } catch(e) { if (!__isUnknownFnError(e)) throw e; } } // Try with list_ or map_ prefix const __self2 = input['self']; if (__self2 != null) { const __prefixes = Array.isArray(__self2) ? ['list_'] : (typeof __self2 === 'string' ? ['string_'] : ['map_']); for (const __px of __prefixes) { for (const __stdMod of ['std', 'std_collections']) { try { return await this._callBaseFunction(__stdMod, __px + function_, input); } catch(e) { if (!__isUnknownFnError(e)) throw e; } } } } } throw new BallRuntimeError((('Function "' + __ball_to_string(key)) + '" not found')); } async _tryLazyResolve(moduleName: any): Promise { const input = moduleName; for (const m of this.program.modules) { for (const import_ of m.moduleImports) { if ((__ball_eq(import_.name, moduleName) && !__ball_eq(whichSource(import_), ModuleImport_Source.notSet))) { try { return await this._resolver.resolve(import_); } catch (__ball_active_error) { const _ = __ball_active_error; } } } } } _indexModule(module: any): any { const input = module; (this.program.modules.push(module), this.program.modules); for (const td of module.typeDefs) { if (hasDescriptor(td)) { this._types[td.name] = td.descriptor; } } for (const func of module.functions) { let key = ((__ball_to_string(module.name) + '.') + __ball_to_string(func.name)); this._functions[key] = func; // Separate getter/setter storage if (func.hasMetadata()) { const __igf = func.metadata.fields ? func.metadata.fields['is_getter'] : null; const __isf = func.metadata.fields ? func.metadata.fields['is_setter'] : null; if (__igf && (__igf.boolValue === true || __igf === true)) { this._getters[key] = func; } if (__isf && (__isf.boolValue === true || __isf === true)) { this._setters[key] = func; } } if (hasMetadata(func)) { let params = this._extractParams(func.metadata); if ((!(params.length === 0) && !(func.name.length === 0))) { this._paramCache[key] = params; } let kindField = __ball_index(func.metadata.fields, 'kind'); if (__ball_eq((__ball_eq(kindField, null) ? null : kindField.stringValue), 'constructor')) { let entry = { module: module.name, func: func }; let dotIdx = func.name.indexOf('.'); if (__ball_ge(dotIdx, 0)) { let className = func.name.substring(0, dotIdx); let ctorSuffix = func.name.substring(__ball_add(dotIdx, 1)); if (__ball_eq(ctorSuffix, 'new')) { this._constructors[className] = entry; this._constructors[((__ball_to_string(module.name) + ':') + __ball_to_string(className))] = entry; } this._constructors[func.name] = entry; } } } this._registerFunctionDispatchTables(module, func); } } _asList(v: any): any { const input = v; if (false /* BallList is List in TS */) { return v.items; } if (__ball_is_type(v, "List")) { return v; } } static _extractMetadataTypeArgs(msg: any): any { const input = msg; if ((!hasMetadata(msg) || !('type_args' in __ball_require_map(msg.metadata.fields, 'map_contains_key')))) { return null; } return [...__ball_index(msg.metadata.fields, 'type_args').listValue.values.map(BallEngine._typeRefValueToString)]; } static _typeRefValueToString(v: any): any { const input = v; if (hasStringValue(v)) { return v.stringValue; } if (!hasStructValue(v)) { return ''; } let s = v.structValue; let name = ((() => { let __naa_6 = __ball_index(s.fields, 'name'); return (__ball_eq(__naa_6, null) ? null : __naa_6.stringValue); })() ?? ''); let typeArgsField = __ball_index(s.fields, 'type_args'); let args = ((!__ball_eq(typeArgsField, null) && hasListValue(typeArgsField)) ? typeArgsField.listValue.values : null); let nullable = ((() => { let __naa_7 = __ball_index(s.fields, 'nullable'); return (__ball_eq(__naa_7, null) ? null : __naa_7.boolValue); })() ?? false); let buf = ""; if ((!__ball_eq(args, null) && !(args.length === 0))) { (buf += (('<' + __ball_to_string(args.map(BallEngine._typeRefValueToString).join(', '))) + '>')); } if (nullable) { (buf += '?'); } return __ball_to_string(buf); } async _evalExpression(expr: any, scope: any): Promise { this._checkExecutionTimeout(); this._checkExpressionDepth(); try { let result = ((whichExpr(expr) === Expression_Expr.call) ? (await this._evalCall(expr.call, scope)) : ((whichExpr(expr) === Expression_Expr.literal) ? (await this._evalLiteral(expr.literal, scope)) : ((whichExpr(expr) === Expression_Expr.reference) ? (await this._evalReference(expr.reference, scope)) : ((whichExpr(expr) === Expression_Expr.fieldAccess) ? (await this._evalFieldAccess(expr.fieldAccess, scope)) : ((whichExpr(expr) === Expression_Expr.messageCreation) ? (await this._evalMessageCreation(expr.messageCreation, scope)) : ((whichExpr(expr) === Expression_Expr.block) ? (await this._evalBlock(expr.block, scope)) : ((whichExpr(expr) === Expression_Expr.lambda) ? (this._evalLambda(expr.lambda, scope)) : ((whichExpr(expr) === Expression_Expr.notSet) ? (null) : undefined)))))))); return this._consumeGeneratorFlow(result); } catch (__ball_active_error) { throw __ball_active_error; } finally { this._exitExpression(); } } _unwrapFuture(value: any): any { const input = value; return _unwrapBallFuture(value); } async _evalCall(call: any, scope: any): Promise { let moduleName = ((call.module.length === 0) ? this._currentModule : call.module); if (__ball_eq(moduleName, 'std')) { do { const __sw = call.function; if ((__sw === 'if')) { return this._evalLazyIf(call, scope); } else if ((__sw === 'for')) { return this._evalLazyFor(call, scope); } else if (__sw === 'for_in' || __sw === 'for_each') { return this._evalLazyForIn(call, scope); } else if ((__sw === 'while')) { return this._evalLazyWhile(call, scope); } else if ((__sw === 'do_while')) { return this._evalLazyDoWhile(call, scope); } else if ((__sw === 'switch')) { return this._evalLazySwitch(call, scope); } else if ((__sw === 'switch_expr')) { return this._evalLazySwitchExpr(call, scope); } else if ((__sw === 'try')) { return this._evalLazyTry(call, scope); } else if ((__sw === 'and')) { return this._evalShortCircuitAnd(call, scope); } else if ((__sw === 'or')) { return this._evalShortCircuitOr(call, scope); } else if ((__sw === 'return')) { return this._evalReturn(call, scope); } else if ((__sw === 'break')) { return this._evalBreak(call, scope); } else if ((__sw === 'continue')) { return this._evalContinue(call, scope); } else if ((__sw === 'assign')) { return this._evalAssign(call, scope); } else if ((__sw === 'labeled')) { return this._evalLabeled(call, scope); } else if ((__sw === 'goto')) { return this._evalGoto(call, scope); } else if ((__sw === 'label')) { return this._evalLabel(call, scope); } else if ((__sw === 'post_increment') || (__sw === 'pre_increment') || (__sw === 'post_decrement') || (__sw === 'pre_decrement')) { return this._evalIncDec(call, scope); } else if (__sw === 'cascade' || __sw === 'null_aware_cascade') { const __cf = this._lazyFields(call); const __targetExpr = __cf['target']; if (!__targetExpr) return null; const __target = await this._evalExpression(__targetExpr, scope); if (__sw === 'null_aware_cascade' && __target == null) return null; const __cScope = scope.child(); __cScope.bind('__cascade_self__', __target); const __sectionsExpr = __cf['sections']; if (__sectionsExpr) { if (__sectionsExpr.whichExpr && __sectionsExpr.whichExpr() === 'literal' && __sectionsExpr.literal && __sectionsExpr.literal.whichValue && __sectionsExpr.literal.whichValue() === 'listValue') { for (const __sec of __sectionsExpr.literal.listValue.elements) { await this._evalExpression(__sec, __cScope); } } else { await this._evalExpression(__sectionsExpr, __cScope); } } return __target; } else if (__sw === 'dart_await_for') { return this._evalAwaitFor(call, scope); } else if ((__sw === 'cascade') || (__sw === 'null_aware_cascade')) { return this._evalLazyCascade(call, scope); } else if ((__sw === 'yield')) { return this._evalYield(call, scope); } else if ((__sw === 'yield_each')) { return this._evalYieldEach(call, scope); } else if ((__sw === 'map_create')) { return this._evalLazyMapCreate(call, scope); } } while (false); } let input = (hasInput(call) ? await this._evalExpression(call.input, scope) : null); if ((call.module.length === 0)) { do { const __sw = call.function; if ((__sw === 'identical')) { let identicalMap = this._asMap(input); if (!__ball_eq(identicalMap, null)) { let a = (__ball_index(identicalMap, 'arg0') ?? __ball_index(identicalMap, 'left')); let b = (__ball_index(identicalMap, 'arg1') ?? __ball_index(identicalMap, 'right')); return identical(a, b); } return false; } } while (false); } if ((__ball_eq(call.module, 'std') || __ball_eq(call.module, 'std_collections'))) { return this._unwrapFuture(await this._callBaseFunction(call.module, call.function, input)); } let key = ((__ball_to_string(moduleName) + '.') + __ball_to_string(call.function)); let func = __ball_index(this._functions, key); if ((!__ball_eq(func, null) && func.isBase)) { return this._unwrapFuture(await this._callBaseFunction(moduleName, call.function, input)); } if (((call.module.length === 0) && scope.has(call.function))) { let bound = scope.lookup(call.function); if ((typeof bound === 'function')) { let result = bound(input); if ((result != null)) { return this._unwrapFuture(await result); } return this._unwrapFuture(result); } } let inputMap = this._asMap(input); if ((!__ball_eq(inputMap, null) && ('self' in __ball_require_map(inputMap, 'map_contains_key')))) { let self = __ball_index(inputMap, 'self'); let selfMap = this._asMap(self); if (!__ball_eq(selfMap, null)) { if (__ball_eq(__ball_index(selfMap, '__type__'), '__builtin_class__')) { let className = __ball_index(selfMap, '__class_ref__'); let argInput = (() => { let __cascade_self__ = ({ ...inputMap }); __cascade_self__.remove('self'); return __cascade_self__; })(); let builtinResult = await this._dispatchBuiltinClassMethod(className, call.function, argInput); if (!__ball_eq(builtinResult, _sentinel)) { return this._unwrapFuture(builtinResult); } } if (__ball_eq(__ball_index(selfMap, '__type__'), '__class__')) { let className = __ball_index(selfMap, '__class_ref__'); let qualifiedName = (className.includes(':') ? className : ((__ball_to_string(this._currentModule) + ':') + __ball_to_string(className))); let colonIdx2 = qualifiedName.indexOf(':'); let modPart2 = (__ball_ge(colonIdx2, 0) ? qualifiedName.substring(0, colonIdx2) : this._currentModule); let staticKey = ((((__ball_to_string(modPart2) + '.') + __ball_to_string(qualifiedName)) + '.') + __ball_to_string(call.function)); let staticFunc = __ball_index(this._functions, staticKey); if (!__ball_eq(staticFunc, null)) { let staticInput = (() => { let __cascade_self__ = ({ ...inputMap }); __cascade_self__.remove('self'); return __cascade_self__; })(); return this._unwrapFuture(await this._callFunction(modPart2, staticFunc, staticInput)); } } let typeName = __ball_index(selfMap, '__type__'); if (((!__ball_eq(typeName, null) && !__ball_eq(typeName, '__builtin_class__')) && !__ball_eq(typeName, '__class__'))) { let methodOwner = selfMap; while (!__ball_eq(methodOwner, null)) { let methods = __ball_index(methodOwner, '__methods__'); if (((typeof methods === 'object' && methods !== null && !Array.isArray(methods) && !(methods instanceof BallDouble) && !(methods instanceof Set)) && (call.function in __ball_require_map(methods, 'map_contains_key')))) { let method = __ball_index(methods, call.function); if ((typeof method === 'function')) { let result = method(input); if ((result != null)) { return this._unwrapFuture(await result); } return this._unwrapFuture(result); } } methodOwner = this._asMap(__ball_index(methodOwner, '__super__')); } let resolved = this._resolveMethod(typeName, call.function); if (!__ball_eq(resolved, null)) { return this._unwrapFuture(await this._callFunction(resolved.module, resolved.func, input)); } } } let builtinResult = await this._dispatchBuiltinInstanceMethod(self, call.function, input); if (!__ball_eq(builtinResult, _sentinel)) { return this._unwrapFuture(builtinResult); } } let fallbackMap = this._asMap(input); if ((!__ball_eq(fallbackMap, null) && ('self' in __ball_require_map(fallbackMap, 'map_contains_key')))) { let selfFallback = __ball_index(fallbackMap, 'self'); let selfFallbackMap = this._asMap(selfFallback); if (!__ball_eq(selfFallbackMap, null)) { let typeName = __ball_index(selfFallbackMap, '__type__'); if (!__ball_eq(typeName, null)) { let resolved = this._resolveInstanceMethodDispatch(typeName, call.function); if (!__ball_eq(resolved, null)) { return this._unwrapFuture(await this._callFunction(resolved.module, resolved.func, input)); } } } } return this._unwrapFuture(await this._resolveAndCallFunction(call.module, call.function, input)); } async _evalLiteral(lit: any, scope: any): Promise { return ((whichValue(lit) === Literal_Value.intValue) ? (__ball_to_int(lit.intValue)) : ((whichValue(lit) === Literal_Value.doubleValue) ? (new BallDouble(lit.doubleValue)) : ((whichValue(lit) === Literal_Value.stringValue) ? (this._trackStringAllocation(lit.stringValue)) : ((whichValue(lit) === Literal_Value.boolValue) ? (lit.boolValue) : ((whichValue(lit) === Literal_Value.bytesValue) ? (this._trackByteListAllocation([...lit.bytesValue])) : ((whichValue(lit) === Literal_Value.listValue) ? (await this._evalListLiteral(lit.listValue, scope)) : ((whichValue(lit) === Literal_Value.notSet) ? (null) : undefined))))))); } async _evalListLiteral(listVal: any, scope: any): Promise { let result = []; this._trackMemoryAllocation(__ball_mul(listVal.elements.length, _ballPointerBytes)); for (const element of listVal.elements) { await this._addCollectionElement(element, scope, result); } return result; } async _evalCollectionIf(call: any, scope: any, result: any): Promise { let fields = this._lazyFields(call); let condExpr = __ball_index(fields, 'condition'); if (__ball_eq(condExpr, null)) { return; } let cond = this._toBool(await this._evalExpression(condExpr, scope)); if (cond) { let thenExpr = __ball_index(fields, 'then'); if (!__ball_eq(thenExpr, null)) { this._trackMemoryAllocation(_ballPointerBytes); await this._addCollectionElement(thenExpr, scope, result); } } else { let elseExpr = __ball_index(fields, 'else'); if (!__ball_eq(elseExpr, null)) { this._trackMemoryAllocation(_ballPointerBytes); await this._addCollectionElement(elseExpr, scope, result); } } } async _evalCollectionFor(call: any, scope: any, result: any): Promise { let fields = this._lazyFields(call); let bodyExpr = __ball_index(fields, 'body'); if (__ball_eq(bodyExpr, null)) { throw new BallRuntimeError('collection_for: missing body'); } let iterableExpr = __ball_index(fields, 'iterable'); if (!__ball_eq(iterableExpr, null)) { let variable = this._stringFieldVal(fields, 'variable'); let varName = ((__ball_eq(variable, null) || (variable.length === 0)) ? 'item' : variable); let iterable = await this._evalExpression(iterableExpr, scope); for (const item of this._toIterable(iterable)) { this._trackMemoryAllocation(_ballPointerBytes); let loopScope = scope.child(); loopScope.bind(varName, item); await this._addCollectionElement(bodyExpr, loopScope, result); } return; } let condition = __ball_index(fields, 'condition'); let update = __ball_index(fields, 'update'); let initExpr = __ball_index(fields, 'init'); if (((__ball_eq(initExpr, null) && __ball_eq(condition, null)) && __ball_eq(update, null))) { throw new BallRuntimeError(('collection_for: unrecognized loop shape ' + '(no iterable and no init/condition/update)')); } let forScope = scope.child(); let loopVars = []; await this._evalForInit(initExpr, forScope, loopVars); while (true) { let iterScope = forScope.child(); for (const v of loopVars) { iterScope.bind(v, forScope.lookup(v)); } if (__ball_eq(condition, null)) { break; } if (!this._toBool(await this._evalExpression(condition, iterScope))) { break; } this._trackMemoryAllocation(_ballPointerBytes); await this._addCollectionElement(bodyExpr, iterScope, result); for (const v of loopVars) { forScope.bind(v, iterScope.lookup(v)); } if (!__ball_eq(update, null)) { await this._evalExpression(update, forScope); } } } async _addCollectionElement(expr: any, scope: any, result: any): Promise { if (hasCall(expr)) { let call = expr.call; let fn = call.function; if ((__ball_eq(call.module, 'std') && __ball_eq(fn, 'collection_if'))) { await this._evalCollectionIf(call, scope, result); return; } if ((__ball_eq(call.module, 'std') && __ball_eq(fn, 'collection_for'))) { await this._evalCollectionFor(call, scope, result); return; } if ((__ball_eq(call.module, 'std') && (__ball_eq(fn, 'spread') || __ball_eq(fn, 'null_spread')))) { await this._spliceSpread(call, scope, result, __ball_eq(fn, 'null_spread')); return; } } this._trackMemoryAllocation(_ballPointerBytes); result = (result.push(await this._evalExpression(expr, scope)), result); } async _spliceSpread(call: any, scope: any, result: any, nullAware: any): Promise { let fields = this._lazyFields(call); let valueExpr = __ball_index(fields, 'value'); if (__ball_eq(valueExpr, null)) { return; } let value = await this._evalExpression(valueExpr, scope); if ((nullAware && __ball_eq(value, null))) { return; } for (const it of this._toIterable(value)) { this._trackMemoryAllocation(_ballPointerBytes); result = (result.push(it), result); } } async _evalLazyMapCreate(call: any, scope: any): Promise { if ((!hasInput(call) || !__ball_eq(whichExpr(call.input), Expression_Expr.messageCreation))) { let input = (hasInput(call) ? await this._evalExpression(call.input, scope) : null); return this._stdMapCreate(input); } let result = _ballUserMap(); for (const pair of call.input.messageCreation.fields) { let name = pair.name; if ((__ball_eq(name, 'entry') || __ball_eq(name, 'entries'))) { await this._addMapEntryExpr(pair.value, scope, result); } else { if (__ball_eq(name, 'element')) { await this._addMapCollectionElement(pair.value, scope, result); } } } return result; } async _addMapEntryExpr(entryExpr: any, scope: any, result: any): Promise { return await this._putMapEntryValue(await this._evalExpression(entryExpr, scope), result); } async _putMapEntryValue(val: any, result: any): Promise { let list = this._asList(val); if (!__ball_eq(list, null)) { for (const e of list) { await this._putMapEntryValue(e, result); } return; } let em = this._asMap(val); if (__ball_eq(em, null)) { return; } this._trackMemoryAllocation(_ballMapEntryBytes); let key = await this._ballToStringAsync((__ball_index(em, 'key') ?? __ball_index(em, 'name'))); result[key] = __ball_index(em, 'value'); } async _addMapCollectionElement(expr: any, scope: any, result: any): Promise { if (hasCall(expr)) { let call = expr.call; let fn = call.function; if ((__ball_eq(call.module, 'std') && __ball_eq(fn, 'collection_if'))) { await this._evalMapCollectionIf(call, scope, result); return; } if ((__ball_eq(call.module, 'std') && __ball_eq(fn, 'collection_for'))) { await this._evalMapCollectionFor(call, scope, result); return; } if ((__ball_eq(call.module, 'std') && (__ball_eq(fn, 'spread') || __ball_eq(fn, 'null_spread')))) { await this._spliceMapSpread(call, scope, result, __ball_eq(fn, 'null_spread')); return; } } await this._addMapEntryExpr(expr, scope, result); } async _evalMapCollectionIf(call: any, scope: any, result: any): Promise { let fields = this._lazyFields(call); let condExpr = __ball_index(fields, 'condition'); if (__ball_eq(condExpr, null)) { return; } if (this._toBool(await this._evalExpression(condExpr, scope))) { let thenExpr = __ball_index(fields, 'then'); if (!__ball_eq(thenExpr, null)) { await this._addMapCollectionElement(thenExpr, scope, result); } } else { let elseExpr = __ball_index(fields, 'else'); if (!__ball_eq(elseExpr, null)) { await this._addMapCollectionElement(elseExpr, scope, result); } } } async _evalMapCollectionFor(call: any, scope: any, result: any): Promise { let fields = this._lazyFields(call); let bodyExpr = __ball_index(fields, 'body'); if (__ball_eq(bodyExpr, null)) { throw new BallRuntimeError('collection_for: missing body'); } let iterableExpr = __ball_index(fields, 'iterable'); if (!__ball_eq(iterableExpr, null)) { let variable = this._stringFieldVal(fields, 'variable'); let varName = ((__ball_eq(variable, null) || (variable.length === 0)) ? 'item' : variable); let iterable = await this._evalExpression(iterableExpr, scope); for (const item of this._toIterable(iterable)) { let loopScope = scope.child(); loopScope.bind(varName, item); await this._addMapCollectionElement(bodyExpr, loopScope, result); } return; } let condition = __ball_index(fields, 'condition'); let update = __ball_index(fields, 'update'); let initExpr = __ball_index(fields, 'init'); if (((__ball_eq(initExpr, null) && __ball_eq(condition, null)) && __ball_eq(update, null))) { throw new BallRuntimeError(('collection_for: unrecognized loop shape ' + '(no iterable and no init/condition/update)')); } let forScope = scope.child(); let loopVars = []; await this._evalForInit(initExpr, forScope, loopVars); while (true) { let iterScope = forScope.child(); for (const v of loopVars) { iterScope.bind(v, forScope.lookup(v)); } if (__ball_eq(condition, null)) { break; } if (!this._toBool(await this._evalExpression(condition, iterScope))) { break; } await this._addMapCollectionElement(bodyExpr, iterScope, result); for (const v of loopVars) { forScope.bind(v, iterScope.lookup(v)); } if (!__ball_eq(update, null)) { await this._evalExpression(update, forScope); } } } async _spliceMapSpread(call: any, scope: any, result: any, nullAware: any): Promise { let fields = this._lazyFields(call); let valueExpr = __ball_index(fields, 'value'); if (__ball_eq(valueExpr, null)) { return; } let value = await this._evalExpression(valueExpr, scope); if ((nullAware && __ball_eq(value, null))) { return; } let m = this._asMap(value); if (__ball_eq(m, null)) { return; } for (const e of m.entries) { this._trackMemoryAllocation(_ballMapEntryBytes); result[e.key] = e.value; } } async _evalReference(ref: any, scope: any): Promise { let name = ref.name; if (__ball_eq(name, 'super')) { let selfRef; try { selfRef = scope.lookup('self'); } catch (__ball_active_error) { const _ = __ball_active_error; selfRef = null; } if (!__ball_eq(selfRef, null)) { let selfMap = this._asMap(selfRef); if (!__ball_eq(selfMap, null)) { return (__ball_index(selfMap, '__super__') ?? selfRef); } } } if (scope.has(name)) { let bound = scope.lookup(name); if (!__ball_eq(bound, null)) { return bound; } } let ctorEntry = __ball_index(this._constructors, name); if (!__ball_eq(ctorEntry, null)) { return (async (input) => { return this._callFunction(ctorEntry.module, ctorEntry.func, input); }); } let colonIdx = name.indexOf(':'); if (__ball_ge(colonIdx, 0)) { let bare = name.substring(__ball_add(colonIdx, 1)); let bareEntry = __ball_index(this._constructors, bare); if (!__ball_eq(bareEntry, null)) { return (async (input) => { return this._callFunction(bareEntry.module, bareEntry.func, input); }); } } let enumVals = __ball_index(this._enumValues, name); if (!__ball_eq(enumVals, null)) { return enumVals; } if (!_builtinTypeNames.includes(name)) { let qualifiedName = ((__ball_to_string(this._currentModule) + ':') + __ball_to_string(name)); let hasCtor = ((name in __ball_require_map(this._constructors, 'map_contains_key')) || (qualifiedName in __ball_require_map(this._constructors, 'map_contains_key'))); let hasStaticMethods = this._functions.keys.some(((k) => { const input = k; return (k.startsWith((((__ball_to_string(this._currentModule) + '.') + __ball_to_string(qualifiedName)) + '.')) || k.startsWith((((__ball_to_string(this._currentModule) + '.') + __ball_to_string(name)) + '.'))); })); let typeExists = ((name in __ball_require_map(this._types, 'map_contains_key')) || (qualifiedName in __ball_require_map(this._types, 'map_contains_key'))); if ((typeExists && (hasCtor || hasStaticMethods))) { return { ['__class_ref__']: name, ['__type__']: '__class__' }; } } let getterKey = ((__ball_to_string(this._currentModule) + '.') + __ball_to_string(name)); let getterFunc = __ball_index(this._functions, getterKey); if ((!__ball_eq(getterFunc, null) && this._isGetter(getterFunc))) { return this._callFunction(this._currentModule, getterFunc, null); } let selfForGetter; try { selfForGetter = scope.lookup('self'); } catch (__ball_active_error) { const _ = __ball_active_error; selfForGetter = null; } if (!__ball_eq(selfForGetter, null)) { let selfMap = this._asMap(selfForGetter); if (!__ball_eq(selfMap, null)) { if ((name in __ball_require_map(selfMap, 'map_contains_key'))) { let direct = __ball_index(selfMap, name); if (!__ball_eq(direct, null)) { return direct; } } let superObj = __ball_index(selfMap, '__super__'); let superMap = this._asMap(superObj); while (!__ball_eq(superMap, null)) { if ((name in __ball_require_map(superMap, 'map_contains_key'))) { let inherited = __ball_index(superMap, name); if (!__ball_eq(inherited, null)) { return inherited; } } superObj = __ball_index(superMap, '__super__'); superMap = this._asMap(superObj); } let typeName = __ball_index(selfMap, '__type__'); if (!__ball_eq(typeName, null)) { let getterResult = await this._tryGetterDispatch(selfMap, name); if (!__ball_eq(getterResult, _sentinel)) { return getterResult; } } } } let topLevel = __ball_index(this._topLevelRefs, name); if (!__ball_eq(topLevel, null)) { if (__ball_eq(topLevel.kind, 'top_level_variable')) { if (this._globalScope.has(name)) { return this._globalScope.lookup(name); } return this._callFunction(topLevel.module, topLevel.func, null); } let modName = topLevel.module; return (async (input) => { return this._callFunction(modName, topLevel.func, input); }); } let staticField = __ball_index(this._staticFieldRefs, name); if (!__ball_eq(staticField, null)) { if (this._globalScope.has(staticField.fullName)) { return this._globalScope.lookup(staticField.fullName); } let func = staticField.func; let value = await this._callFunction(staticField.module, func, null); if (func.outputType.startsWith('Map')) { if ((this._isBallSet(value) && (this._ballSetItems(value).length === 0))) { value = _ballUserMap(); } if ((Array.isArray(value) && (value.length === 0))) { value = _ballUserMap(); } } this._globalScope.bind(staticField.fullName, value); return value; } if (((__ball_eq(name, 'List') || __ball_eq(name, 'Map')) || __ball_eq(name, 'Set'))) { return { ['__class_ref__']: name, ['__type__']: '__builtin_class__' }; } return scope.lookup(name); } async _evalFieldAccess(access: any, scope: any): Promise { let object = await this._evalExpression(access.object, scope); let fieldName = access.field_2; if (_isBallFuture(object)) { object = __ball_index(object, 'value'); } if (this._isBallSet(object)) { let items = this._ballSetItems(object); do { const __sw = fieldName; if ((__sw === 'length')) { return items.length; } else if ((__sw === 'isEmpty')) { return (items.length === 0); } else if ((__sw === 'isNotEmpty')) { return !(items.length === 0); } else if ((__sw === 'first')) { if (!(items.length === 0)) { return items.first; } throw new BallRuntimeError('First element of empty set'); } else if ((__sw === 'last')) { if (!(items.length === 0)) { return items.last; } throw new BallRuntimeError('Last element of empty set'); } else if ((__sw === 'single')) { if (__ball_eq(items.length, 1)) { return items.single; } throw new BallRuntimeError('Set does not have exactly one element'); } } while (false); } let objectMap = this._asMap(object); if ((!__ball_eq(objectMap, null) && __ball_eq(__ball_index(objectMap, '__type__'), '__builtin_class__'))) { let className = __ball_index(objectMap, '__class_ref__'); return (async (input) => { let argsMap = this._asMap(input); let args = (argsMap ?? { ['arg0']: input }); let result = await this._dispatchBuiltinClassMethod(className, fieldName, args); if (!__ball_eq(result, _sentinel)) { return result; } throw new BallRuntimeError(((('Unknown static method: ' + __ball_to_string(className)) + '.') + __ball_to_string(fieldName))); }); } if ((!__ball_eq(objectMap, null) && __ball_eq(__ball_index(objectMap, '__type__'), '__class__'))) { let className = __ball_index(objectMap, '__class_ref__'); let qualifiedName = (className.includes(':') ? className : ((__ball_to_string(this._currentModule) + ':') + __ball_to_string(className))); let namedCtor = (__ball_index(this._constructors, ((__ball_to_string(qualifiedName) + '.') + __ball_to_string(fieldName))) ?? __ball_index(this._constructors, ((__ball_to_string(className) + '.') + __ball_to_string(fieldName)))); if (!__ball_eq(namedCtor, null)) { return (async (input) => { return this._callFunction(namedCtor.module, namedCtor.func, input); }); } let colonIdx = qualifiedName.indexOf(':'); let modPart = (__ball_ge(colonIdx, 0) ? qualifiedName.substring(0, colonIdx) : this._currentModule); let staticKey = ((((__ball_to_string(modPart) + '.') + __ball_to_string(qualifiedName)) + '.') + __ball_to_string(fieldName)); let staticFunc = __ball_index(this._functions, staticKey); if (!__ball_eq(staticFunc, null)) { return (async (input) => { return this._callFunction(modPart, staticFunc, input); }); } let enumVals = (__ball_index(this._enumValues, className) ?? __ball_index(this._enumValues, qualifiedName)); if ((!__ball_eq(enumVals, null) && (fieldName in __ball_require_map(enumVals, 'map_contains_key')))) { return __ball_index(enumVals, fieldName); } } if (!__ball_eq(objectMap, null)) { if ((fieldName in __ball_require_map(objectMap, 'map_contains_key'))) { return __ball_index(objectMap, fieldName); } let superObj = __ball_index(objectMap, '__super__'); let superMap = this._asMap(superObj); while (!__ball_eq(superMap, null)) { if ((fieldName in __ball_require_map(superMap, 'map_contains_key'))) { return __ball_index(superMap, fieldName); } superObj = __ball_index(superMap, '__super__'); superMap = this._asMap(superObj); } let methods = __ball_index(objectMap, '__methods__'); if (((typeof methods === 'object' && methods !== null && !Array.isArray(methods) && !(methods instanceof BallDouble) && !(methods instanceof Set)) && (fieldName in __ball_require_map(methods, 'map_contains_key')))) { let method = __ball_index(methods, fieldName); if ((typeof method === 'function')) { return method; } } superObj = __ball_index(objectMap, '__super__'); superMap = this._asMap(superObj); while (!__ball_eq(superMap, null)) { let superMethods = __ball_index(superMap, '__methods__'); if (((typeof superMethods === 'object' && superMethods !== null && !Array.isArray(superMethods) && !(superMethods instanceof BallDouble) && !(superMethods instanceof Set)) && (fieldName in __ball_require_map(superMethods, 'map_contains_key')))) { let method = __ball_index(superMethods, fieldName); if ((typeof method === 'function')) { return method; } } superObj = __ball_index(superMap, '__super__'); superMap = this._asMap(superObj); } let getterResult = await this._tryGetterDispatch(objectMap, fieldName); if (!__ball_eq(getterResult, _sentinel)) { return getterResult; } do { const __sw = fieldName; if ((__sw === 'keys')) { return [...objectMap.entries.map(((e) => { const input = e; return e.key; }))]; } else if ((__sw === 'values')) { let vals = [...objectMap.entries.map(((e) => { const input = e; return e.value; }))]; if ((!(vals.length === 0) && vals.every(((v) => { const input = v; return (((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) && ('index' in __ball_require_map(v, 'map_contains_key'))) && ('__type__' in __ball_require_map(v, 'map_contains_key'))); })))) { vals = [...vals].sort(((a, b) => { return (__ball_index(a, 'index') < __ball_index(b, 'index') ? -1 : __ball_index(a, 'index') > __ball_index(b, 'index') ? 1 : 0); })); } return vals; } else if ((__sw === 'length')) { return objectMap.length; } else if ((__sw === 'isEmpty')) { return (objectMap.length === 0); } else if ((__sw === 'isNotEmpty')) { return !(objectMap.length === 0); } else if ((__sw === 'entries')) { return [...objectMap.entries.map(((e) => { const input = e; return { ['key']: e.key, ['value']: e.value }; }))]; } } while (false); throw new BallRuntimeError(((('Field "' + __ball_to_string(fieldName)) + '" not found. ') + ('Available: ' + __ball_to_string([...objectMap.keys])))); } let rawList = this._asList(object); do { const __sw = fieldName; if ((__sw === 'length')) { if ((typeof object === 'string')) { return object.length; } if (!__ball_eq(rawList, null)) { return rawList.length; } if ((typeof object === 'object' && object !== null && !Array.isArray(object) && !(object instanceof BallDouble) && !(object instanceof Set))) { return object.length; } if ((object instanceof Set)) { return object.length; } } else if ((__sw === 'isEmpty')) { if ((typeof object === 'string')) { return (object.length === 0); } if (!__ball_eq(rawList, null)) { return (rawList.length === 0); } if ((typeof object === 'object' && object !== null && !Array.isArray(object) && !(object instanceof BallDouble) && !(object instanceof Set))) { return (object.length === 0); } if ((object instanceof Set)) { return (object.length === 0); } } else if ((__sw === 'isNotEmpty')) { if ((typeof object === 'string')) { return !(object.length === 0); } if (!__ball_eq(rawList, null)) { return !(rawList.length === 0); } if ((typeof object === 'object' && object !== null && !Array.isArray(object) && !(object instanceof BallDouble) && !(object instanceof Set))) { return !(object.length === 0); } if ((object instanceof Set)) { return !(object.length === 0); } } else if ((__sw === 'first')) { if ((!__ball_eq(rawList, null) && !(rawList.length === 0))) { return rawList.first; } if (((object instanceof Set) && !(object.length === 0))) { return object.first; } } else if ((__sw === 'last')) { if ((!__ball_eq(rawList, null) && !(rawList.length === 0))) { return rawList.last; } if (((object instanceof Set) && !(object.length === 0))) { return object.last; } } else if ((__sw === 'single')) { if ((!__ball_eq(rawList, null) && __ball_eq(rawList.length, 1))) { return rawList.single; } if (((object instanceof Set) && __ball_eq(object.length, 1))) { return object.single; } } else if ((__sw === 'reversed')) { if (!__ball_eq(rawList, null)) { return this._manualReverse(rawList); } } else if ((__sw === 'keys')) { if ((typeof object === 'object' && object !== null && !Array.isArray(object) && !(object instanceof BallDouble) && !(object instanceof Set))) { return [...object.entries.map(((e) => { const input = e; return e.key; }))]; } throw new BallRuntimeError(('Cannot access field "keys" on ' + __ball_to_string(((__ball_eq(object, null) ? null : object.runtimeType) ?? 'null')))); } else if ((__sw === 'values')) { if ((typeof object === 'object' && object !== null && !Array.isArray(object) && !(object instanceof BallDouble) && !(object instanceof Set))) { let vals = [...object.entries.map(((e) => { const input = e; return e.value; }))]; if ((!(vals.length === 0) && vals.every(((v) => { const input = v; return (((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) && ('index' in __ball_require_map(v, 'map_contains_key'))) && ('__type__' in __ball_require_map(v, 'map_contains_key'))); })))) { vals = [...vals].sort(((a, b) => { return (__ball_index(a, 'index') < __ball_index(b, 'index') ? -1 : __ball_index(a, 'index') > __ball_index(b, 'index') ? 1 : 0); })); } return vals; } throw new BallRuntimeError(('Cannot access field "values" on ' + __ball_to_string(((__ball_eq(object, null) ? null : object.runtimeType) ?? 'null')))); } else if ((__sw === 'isNaN')) { return _ballNumIsNaN(object); } else if ((__sw === 'isFinite')) { return _ballNumIsFinite(object); } else if ((__sw === 'isInfinite')) { return _ballNumIsInfinite(object); } else if ((__sw === 'isNegative')) { if ((typeof object === 'number' || object instanceof BallDouble)) { return object.isNegative; } if ((typeof object === 'number' || object instanceof BallDouble)) { return object.value.isNegative; } if ((typeof object === 'number' && Number.isInteger(object))) { return object.value.isNegative; } } else if ((__sw === 'sign')) { if ((typeof object === 'number' || object instanceof BallDouble)) { return Math.sign(Number(object)); } if ((typeof object === 'number' || object instanceof BallDouble)) { return Math.sign(Number(object.value)); } if ((typeof object === 'number' && Number.isInteger(object))) { return Math.sign(Number(object.value)); } } else if ((__sw === 'abs')) { if ((typeof object === 'number' || object instanceof BallDouble)) { return __ball_math_abs(object); } if ((typeof object === 'number' || object instanceof BallDouble)) { return __ball_math_abs(object.value); } if ((typeof object === 'number' && Number.isInteger(object))) { return __ball_math_abs(object.value); } } else if ((__sw === 'toString')) { return await this._ballToStringAsync(object); } else if ((__sw === 'runtimeType')) { if ((__ball_eq(object, null) || (object == null))) { return 'Null'; } if (((typeof object === 'number' && Number.isInteger(object)) || (typeof object === 'number' && Number.isInteger(object)))) { return 'int'; } if (((object instanceof BallDouble || (typeof object === 'number' && !Number.isInteger(object))) || (typeof object === 'number' || object instanceof BallDouble))) { return 'double'; } if (((typeof object === 'string') || (typeof object === 'string'))) { return 'String'; } if (((typeof object === 'boolean') || (typeof object === 'boolean'))) { return 'bool'; } if ((Array.isArray(object) || false /* BallList is List in TS */)) { return 'List'; } if (((typeof object === 'object' && object !== null && !Array.isArray(object) && !(object instanceof BallDouble) && !(object instanceof Set)) || false /* BallMap is Map in TS */)) { return 'Map'; } return 'Object'; } } while (false); throw new BallRuntimeError(((('Cannot access field "' + __ball_to_string(fieldName)) + '" on ') + __ball_to_string(((__ball_eq(object, null) ? null : object.runtimeType) ?? 'null')))); } async _tryGetterDispatch(object: any, fieldName: any): Promise { let typeName = __ball_index(object, '__type__'); if (__ball_eq(typeName, null)) { return _sentinel; } let colonIdx = typeName.indexOf(':'); let modPart = (__ball_ge(colonIdx, 0) ? typeName.substring(0, colonIdx) : this._currentModule); let getterKey = ((((__ball_to_string(modPart) + '.') + __ball_to_string(typeName)) + '.') + __ball_to_string(fieldName)); let getterFunc = (__ball_index(this._getters, getterKey) ?? __ball_index(this._functions, getterKey)); if ((!__ball_eq(getterFunc, null) && this._isGetter(getterFunc))) { return this._callFunction(modPart, getterFunc, { ['self']: object }); } let superObj = __ball_index(object, '__super__'); let superMap = this._asMap(superObj); while (!__ball_eq(superMap, null)) { let superType = __ball_index(superMap, '__type__'); if (!__ball_eq(superType, null)) { let sColonIdx = superType.indexOf(':'); let sModPart = (__ball_ge(sColonIdx, 0) ? superType.substring(0, sColonIdx) : modPart); let sTypeName = (__ball_ge(sColonIdx, 0) ? superType : ((__ball_to_string(sModPart) + ':') + __ball_to_string(superType))); let superGetterKey = ((((__ball_to_string(sModPart) + '.') + __ball_to_string(sTypeName)) + '.') + __ball_to_string(fieldName)); let superGetterFunc = (__ball_index(this._getters, superGetterKey) ?? __ball_index(this._functions, superGetterKey)); if ((!__ball_eq(superGetterFunc, null) && this._isGetter(superGetterFunc))) { return this._callFunction(sModPart, superGetterFunc, { ['self']: object }); } } superObj = __ball_index(superMap, '__super__'); superMap = this._asMap(superObj); } return _sentinel; } _isGetter(func: any): any { const input = func; if (!hasMetadata(func)) { return false; } let field = __ball_index(func.metadata.fields, 'is_getter'); if (_metadataBool(field)) { return true; } let kind = __ball_index(func.metadata.fields, 'kind'); if ((!__ball_eq(kind, null) && __ball_eq(kind.stringValue, 'getter'))) { return true; } return false; } _isSetter(func: any): any { const input = func; if (!hasMetadata(func)) { return false; } let field = __ball_index(func.metadata.fields, 'is_setter'); if (_metadataBool(field)) { return true; } let kind = __ball_index(func.metadata.fields, 'kind'); return (!__ball_eq(kind, null) && __ball_eq(kind.stringValue, 'setter')); } async _trySetterDispatch(object: any, fieldName: any, value: any): Promise { let typeName = __ball_index(object, '__type__'); if (__ball_eq(typeName, null)) { return _sentinel; } let colonIdx = typeName.indexOf(':'); let modPart = (__ball_ge(colonIdx, 0) ? typeName.substring(0, colonIdx) : this._currentModule); let setterKey = (((((__ball_to_string(modPart) + '.') + __ball_to_string(typeName)) + '.') + __ball_to_string(fieldName)) + '='); let setterKeyNoEq = ((((__ball_to_string(modPart) + '.') + __ball_to_string(typeName)) + '.') + __ball_to_string(fieldName)); let setterFunc = ((__ball_index(this._setters, setterKey) ?? __ball_index(this._setters, setterKeyNoEq)) ?? __ball_index(this._functions, setterKey)); if ((!__ball_eq(setterFunc, null) && this._isSetter(setterFunc))) { let result = await this._callFunction(modPart, setterFunc, { ['self']: object, ['value']: value }); this._writeBackingField(object, fieldName, result); return result; } let superObj = __ball_index(object, '__super__'); let superMap = this._asMap(superObj); while (!__ball_eq(superMap, null)) { let superType = __ball_index(superMap, '__type__'); if (!__ball_eq(superType, null)) { let sColonIdx = superType.indexOf(':'); let sModPart = (__ball_ge(sColonIdx, 0) ? superType.substring(0, sColonIdx) : modPart); let sTypeName = (__ball_ge(sColonIdx, 0) ? superType : ((__ball_to_string(sModPart) + ':') + __ball_to_string(superType))); let superSetterKey = (((((__ball_to_string(sModPart) + '.') + __ball_to_string(sTypeName)) + '.') + __ball_to_string(fieldName)) + '='); let superSetterKeyNoEq = ((((__ball_to_string(sModPart) + '.') + __ball_to_string(sTypeName)) + '.') + __ball_to_string(fieldName)); let superSetterFunc = ((__ball_index(this._setters, superSetterKey) ?? __ball_index(this._setters, superSetterKeyNoEq)) ?? __ball_index(this._functions, superSetterKey)); if ((!__ball_eq(superSetterFunc, null) && this._isSetter(superSetterFunc))) { let result = await this._callFunction(sModPart, superSetterFunc, { ['self']: object, ['value']: value }); this._writeBackingField(object, fieldName, result); return result; } } superObj = __ball_index(superMap, '__super__'); superMap = this._asMap(superObj); } return _sentinel; } _writeBackingField(object: any, fieldName: any, assignedValue: any): any { if (__ball_eq(assignedValue, null)) { return; } let backing = ('_' + __ball_to_string(fieldName)); if ((backing in __ball_require_map(object, 'map_contains_key'))) { ballObjectSetField(object, backing, assignedValue); return; } if (('_celsius' in __ball_require_map(object, 'map_contains_key'))) { ballObjectSetField(object, '_celsius', assignedValue); } } _syncFieldToSelf(scope: any, fieldName: any, val: any): any { try { let self = scope.lookup('self'); ballObjectSetField(self, fieldName, val); let selfMap = this._asMap(self); if (__ball_eq(selfMap, null)) { return; } let superObj = __ball_index(selfMap, '__super__'); let superMap = this._asMap(superObj); while (!__ball_eq(superMap, null)) { if ((fieldName in __ball_require_map(superMap, 'map_contains_key'))) { ballObjectSetField(superObj, fieldName, val); } superObj = __ball_index(superMap, '__super__'); superMap = this._asMap(superObj); } } catch (__ball_active_error) { const _ = __ball_active_error; } } async _evalMessageCreation(msg: any, scope: any): Promise { let fields = {}; for (const pair of msg.fields) { let val = await this._evalExpression(pair.value, scope); if ((pair.name in __ball_require_map(fields, 'map_contains_key'))) { let existing = __ball_index(fields, pair.name); if (Array.isArray(existing)) { let merged = ([...existing]); merged = (merged.push(val), merged); fields[pair.name] = merged; } else { fields[pair.name] = [existing, val]; } } else { fields[pair.name] = val; } } if (!(msg.typeName.length === 0)) { let typeDef = this._findTypeDef(msg.typeName); if (!__ball_eq(typeDef, null)) { if ((scope.has('self') && scope.has('__constructor_type__'))) { let self = scope.lookup('self'); let constructorType = scope.lookup('__constructor_type__'); let selfMap = this._asMap(self); if ((!__ball_eq(selfMap, null) && __ball_eq(constructorType, msg.typeName))) { return self; } } let instanceFields = {}; let allFieldNames = this._collectAllFieldNames(msg.typeName); for (const entry of fields.entries) { if (!entry.key.startsWith('arg')) { instanceFields[entry.key] = entry.value; } } this._initFieldDefaults(msg.typeName, instanceFields); for (const fieldName of typeDef.fieldNames) { if (!(fieldName in __ball_require_map(instanceFields, 'map_contains_key'))) { instanceFields[fieldName] = null; } } let ctorEntry = this._lookupConstructor(msg.typeName); let resolvedParams = {}; if ((!__ball_eq(ctorEntry, null) && hasMetadata(ctorEntry.func))) { let params = this._extractParams(ctorEntry.func.metadata); let paramsMeta = this._extractParamsMeta(ctorEntry.func.metadata); for (let i = 0; __ball_lt(i, params.length); (i++)) { let param = __ball_index(params, i); let value; if ((param in __ball_require_map(fields, 'map_contains_key'))) { value = __ball_index(fields, param); } else { if ((('arg' + __ball_to_string(i)) in __ball_require_map(fields, 'map_contains_key'))) { value = __ball_index(fields, ('arg' + __ball_to_string(i))); } } if (((__ball_eq(value, null) && __ball_lt(i, paramsMeta.length)) && ('default' in __ball_require_map(__ball_index(paramsMeta, i), 'map_contains_key')))) { value = __ball_index(__ball_index(paramsMeta, i), 'default'); } resolvedParams[param] = value; let isThis = (__ball_lt(i, paramsMeta.length) && __ball_eq(__ball_index(__ball_index(paramsMeta, i), 'is_this'), true)); if ((isThis || allFieldNames.includes(param))) { instanceFields[param] = value; } else { if ((__ball_eq(params.length, 1) && __ball_eq(allFieldNames.length, 1))) { instanceFields[allFieldNames.first] = value; } } } } if (((!__ball_eq(ctorEntry, null) && hasMetadata(ctorEntry.func)) && !hasBody(ctorEntry.func))) { this._applyConstructorInitializers(ctorEntry.func, instanceFields, resolvedParams, true); } let superclass = this._getMetaString(typeDef, 'superclass'); let superObject; if ((!__ball_eq(superclass, null) && !(superclass.length === 0))) { superObject = (__ball_eq(ctorEntry, null) ? null : await this._invokeSuperConstructor(ctorEntry.func, superclass, resolvedParams)); superObject ??= this._buildSuperObject(superclass, instanceFields); } if (!('__type_args__' in __ball_require_map(instanceFields, 'map_contains_key'))) { let metaTypeArgs = BallEngine._extractMetadataTypeArgs(msg); if (!__ball_eq(metaTypeArgs, null)) { instanceFields['__type_args__'] = metaTypeArgs; } } // Initialize descriptor fields with defaults if (typeDef.fieldNames && typeDef.fieldNames.length > 0) { const __fDefaults = this._getFieldDefaults(msg.typeName); for (const __fn of typeDef.fieldNames) { if (!(__fn in fields)) { fields[__fn] = (__fn in __fDefaults) ? __fDefaults[__fn] : null; } } } let methods = this._resolveTypeMethodsWithInheritance(msg.typeName); // toString injection is handled by _stdPrint's __resolveToString let instance = new BallObject({ typeName: msg.typeName, superObject: superObject, fields: instanceFields, methods: methods.cast() }); if ((!__ball_eq(ctorEntry, null) && hasBody(ctorEntry.func))) { let isFactory = (hasMetadata(ctorEntry.func) && _metadataBool(__ball_index(ctorEntry.func.metadata.fields, 'is_factory'))); if (isFactory) { let ctorInput = (() => { let __cascade_self__ = {}; __cascade_self__.addAll(fields); __cascade_self__.addAll(resolvedParams); return __cascade_self__; })(); return this._callFunction(ctorEntry.module, ctorEntry.func, ctorInput); } let ctorInput = (() => { let __cascade_self__ = {}; __cascade_self__.addAll(fields); __cascade_self__.addAll(resolvedParams); __cascade_self__['self'] = instance; return __cascade_self__; })(); let constructed = await this._callFunction(ctorEntry.module, ctorEntry.func, ctorInput); let constructedMap = this._asMap(constructed); if ((!__ball_eq(constructedMap, null) && ('__type__' in __ball_require_map(constructedMap, 'map_contains_key')))) { return constructed; } return instance; } return instance; } else { if (((scope.has('self') && scope.has('__constructor_type__')) && __ball_eq(scope.lookup('__constructor_type__'), msg.typeName))) { let self = scope.lookup('self'); if (!__ball_eq(this._asMap(self), null)) { return self; } } let ctorEntry = __ball_index(this._constructors, msg.typeName); if (!__ball_eq(ctorEntry, null)) { let instanceFields = {}; for (const entry of fields.entries) { if (!entry.key.startsWith('arg')) { instanceFields[entry.key] = entry.value; } } if (!('__type_args__' in __ball_require_map(instanceFields, 'map_contains_key'))) { let metaTA = BallEngine._extractMetadataTypeArgs(msg); if (!__ball_eq(metaTA, null)) { instanceFields['__type_args__'] = metaTA; } } let methods = this._resolveTypeMethodsWithInheritance(msg.typeName); let instance = new BallObject({ typeName: msg.typeName, superObject: null, fields: instanceFields, methods: methods.cast() }); let ctorInput = (() => { let __cascade_self__ = {}; __cascade_self__.addAll(fields); __cascade_self__['self'] = instance; return __cascade_self__; })(); let constructed = await this._callFunction(ctorEntry.module, ctorEntry.func, ctorInput); let constructedMap = this._asMap(constructed); if ((!__ball_eq(constructedMap, null) && ('__type__' in __ball_require_map(constructedMap, 'map_contains_key')))) { return constructed; } return instance; } fields['__type__'] = msg.typeName; if (!('__type_args__' in __ball_require_map(fields, 'map_contains_key'))) { let metaTA2 = BallEngine._extractMetadataTypeArgs(msg); if (!__ball_eq(metaTA2, null)) { fields['__type_args__'] = metaTA2; } else { let genMatch = new RegExp('^(\\w+)<(.+)>$').firstMatch(msg.typeName); if (!__ball_eq(genMatch, null)) { fields['__type__'] = genMatch.group(1); fields['__type_args__'] = this._splitTypeArgs(genMatch.group(2)); } } } let fnKey = ((__ball_to_string(this._currentModule) + '.') + __ball_to_string(msg.typeName)); let fnMatch = __ball_index(this._functions, fnKey); if (((!__ball_eq(fnMatch, null) && !fnMatch.isBase) && hasBody(fnMatch))) { if (scope.has('self')) { let kindField = (hasMetadata(fnMatch) ? __ball_index(fnMatch.metadata.fields, 'kind') : null); if (__ball_eq((__ball_eq(kindField, null) ? null : kindField.stringValue), 'method')) { let selfObj = scope.lookup('self'); fields['self'] = selfObj; } } return this._callFunction(this._currentModule, fnMatch, fields); } if (scope.has('self')) { let selfObj = scope.lookup('self'); let selfObjMap = this._asMap(selfObj); if (!__ball_eq(selfObjMap, null)) { let selfType = __ball_index(selfObjMap, '__type__'); if (!__ball_eq(selfType, null)) { let colonIdx = msg.typeName.indexOf(':'); let methodName = (__ball_ge(colonIdx, 0) ? msg.typeName.substring(__ball_add(colonIdx, 1)) : msg.typeName); let resolved = this._resolveMethod(selfType, methodName); if (!__ball_eq(resolved, null)) { fields['self'] = selfObj; return this._callFunction(resolved.module, resolved.func, fields); } } } } for (const m of this.program.modules) { for (const f of m.functions) { if (((__ball_eq(f.name, msg.typeName) && !f.isBase) && hasBody(f))) { if (hasMetadata(f)) { let k = (() => { let __naa_8 = __ball_index(f.metadata.fields, 'kind'); return (__ball_eq(__naa_8, null) ? null : __naa_8.stringValue); })(); if (((__ball_eq(k, 'constructor') || __ball_eq(k, 'top_level_variable')) || __ball_eq(k, 'static_field'))) { continue; } } return this._callFunction(m.name, f, fields); } } } } } this._trackMemoryAllocation(__ball_mul(fields.length, _ballMapEntryBytes)); let instanceMap = (() => { let __cascade_self__ = _ballUserMap(); __cascade_self__.addAll(fields); return __cascade_self__; })(); return instanceMap.cast(); } _findTypeDef(typeName: any): any { const input = typeName; for (const module of this.program.modules) { for (const td of module.typeDefs) { if ((__ball_eq(td.name, typeName) || td.name.endsWith((':' + __ball_to_string(typeName))))) { let superclass; if (hasMetadata(td)) { let sc = __ball_index(td.metadata.fields, 'superclass'); if ((!__ball_eq(sc, null) && hasStringValue(sc))) { superclass = sc.stringValue; } } let fieldNames = []; if (hasDescriptor(td)) { for (const f of td.descriptor.field) { fieldNames = (fieldNames.push(f.name), fieldNames); } } if (hasMetadata(td)) { let fieldsMetaVal = __ball_index(td.metadata.fields, 'fields'); if ((!__ball_eq(fieldsMetaVal, null) && __ball_eq(whichKind(fieldsMetaVal), structpb_Value_Kind.listValue))) { for (const fv of fieldsMetaVal.listValue.values) { if (__ball_eq(whichKind(fv), structpb_Value_Kind.structValue)) { let fname = (() => { let __naa_9 = __ball_index(fv.structValue.fields, 'name'); return (__ball_eq(__naa_9, null) ? null : __naa_9.stringValue); })(); if ((!__ball_eq(fname, null) && !fieldNames.includes(fname))) { fieldNames = (fieldNames.push(fname), fieldNames); } } } } } return { superclass: superclass, fieldNames: fieldNames }; } } } } _initFieldDefaults(typeName: any, fields: any): any { for (const module of this.program.modules) { for (const td of module.typeDefs) { if ((__ball_eq(td.name, typeName) || td.name.endsWith((':' + __ball_to_string(typeName))))) { if (hasMetadata(td)) { let fieldsMetaVal = __ball_index(td.metadata.fields, 'fields'); if ((!__ball_eq(fieldsMetaVal, null) && __ball_eq(whichKind(fieldsMetaVal), structpb_Value_Kind.listValue))) { for (const fv of fieldsMetaVal.listValue.values) { if (!__ball_eq(whichKind(fv), structpb_Value_Kind.structValue)) { continue; } let fname = (() => { let __naa_10 = __ball_index(fv.structValue.fields, 'name'); return (__ball_eq(__naa_10, null) ? null : __naa_10.stringValue); })(); if ((__ball_eq(fname, null) || (fname in __ball_require_map(fields, 'map_contains_key')))) { continue; } let init = (() => { let __naa_11 = __ball_index(fv.structValue.fields, 'initializer'); return (__ball_eq(__naa_11, null) ? null : __naa_11.stringValue); })(); if (!__ball_eq(init, null)) { fields[fname] = this._parseInitializer(init); } } } } return; } } } } _parseInitializer(init: any): any { const input = init; let trimmed = init.trim(); if (__ball_eq(trimmed, '[]')) { return []; } if (__ball_eq(trimmed, '{}')) { return {}; } if (__ball_eq(trimmed, 'null')) { return null; } if (__ball_eq(trimmed, 'true')) { return true; } if (__ball_eq(trimmed, 'false')) { return false; } if ((__ball_eq(trimmed, '""') || __ball_eq(trimmed, '\'\''))) { return ''; } if (((__ball_ge(trimmed.length, 2) && trimmed.startsWith('[')) && trimmed.endsWith(']'))) { let inner = trimmed.substring(1, __ball_sub(trimmed.length, 1)).trim(); if ((inner.length === 0)) { return []; } if ((!inner.includes('[') && !inner.includes('{'))) { return [...inner.split(',').map(((s) => { const input = s; return s.trim(); })).filter(((s) => { const input = s; return !(s.length === 0); })).map(((s) => { const input = s; return this._parseInitializer(s); }))]; } } let intVal = int.tryParse(trimmed); if (!__ball_eq(intVal, null)) { return intVal; } let doubleVal = double.tryParse(trimmed); if (!__ball_eq(doubleVal, null)) { return doubleVal; } if ((__ball_ge(trimmed.length, 2) && ((trimmed.startsWith('\'') && trimmed.endsWith('\'')) || (trimmed.startsWith('"') && trimmed.endsWith('"'))))) { return trimmed.substring(1, __ball_sub(trimmed.length, 1)); } return trimmed; } _getMetaString(typeDef: any, key: any): any { if (__ball_eq(key, 'superclass')) { return typeDef.superclass; } } _collectAllFieldNames(typeName: any): any { const input = typeName; let names = []; let typeDef = this._findTypeDef(typeName); if (__ball_eq(typeDef, null)) { return names; } let colonIdx = typeName.indexOf(':'); let modPart = (__ball_ge(colonIdx, 0) ? typeName.substring(0, colonIdx) : this._currentModule); let superclass = typeDef.superclass; if ((!__ball_eq(superclass, null) && !(superclass.length === 0))) { let qualifiedSuper = (superclass.includes(':') ? superclass : ((__ball_to_string(modPart) + ':') + __ball_to_string(superclass))); __ball_push_all(names, this._collectAllFieldNames(qualifiedSuper)); } for (const fieldName of typeDef.fieldNames) { if (!names.includes(fieldName)) { names = (names.push(fieldName), names); } } return names; } _buildSuperObject(superclass: any, childFields: any): any { let qualifiedSuperclass = (superclass.includes(':') ? superclass : ((__ball_to_string(this._currentModule) + ':') + __ball_to_string(superclass))); let superFields = {}; let parentTypeDef = this._findTypeDef(superclass); if (!__ball_eq(parentTypeDef, null)) { for (const fname of parentTypeDef.fieldNames) { if ((fname in __ball_require_map(childFields, 'map_contains_key'))) { superFields[fname] = __ball_index(childFields, fname); } } this._initFieldDefaults(superclass, superFields); for (const fname of parentTypeDef.fieldNames) { if (!(fname in __ball_require_map(superFields, 'map_contains_key'))) { superFields[fname] = null; } } let parentMethods = this._resolveTypeMethods(qualifiedSuperclass); let parentMethodsMap = parentMethods.cast(); let grandparent = parentTypeDef.superclass; let grandparentObject; if ((!__ball_eq(grandparent, null) && !(grandparent.length === 0))) { grandparentObject = this._buildSuperObject(grandparent, childFields); } return new BallObject({ typeName: qualifiedSuperclass, superObject: grandparentObject, fields: superFields, methods: parentMethodsMap }); } return new BallObject({ typeName: qualifiedSuperclass, fields: superFields }); } _resolveTypeMethods(typeName: any): any { const input = typeName; let methods = {}; for (const module of this.program.modules) { for (const func of module.functions) { if (hasMetadata(func)) { let className = __ball_index(func.metadata.fields, 'class'); let bareTypeName = (typeName.includes(':') ? typeName.substring(__ball_add(typeName.indexOf(':'), 1)) : typeName); if ((((((!__ball_eq(className, null) && hasStringValue(className)) && (__ball_eq(className.stringValue, typeName) || __ball_eq(className.stringValue, bareTypeName))) && hasBody(func)) && !this._isGetter(func)) && !this._isSetter(func))) { let closure = (async (input) => { return this._callFunction(module.name, func, input); }); methods[func.name] = closure; let dotIdx = func.name.lastIndexOf('.'); if (__ball_ge(dotIdx, 0)) { methods[func.name.substring(__ball_add(dotIdx, 1))] = closure; } continue; } } let funcName = func.name; let dotIdx = funcName.lastIndexOf('.'); if (__ball_ge(dotIdx, 0)) { let prefix = funcName.substring(0, dotIdx); let suffix = funcName.substring(__ball_add(dotIdx, 1)); if (__ball_eq(suffix, 'new')) { continue; } let kindField2 = (hasMetadata(func) ? __ball_index(func.metadata.fields, 'kind') : null); if (__ball_eq((__ball_eq(kindField2, null) ? null : kindField2.stringValue), 'constructor')) { continue; } if ((this._isGetter(func) || this._isSetter(func))) { continue; } if (((__ball_eq(prefix, typeName) && hasBody(func)) && !func.isBase)) { let closure = (async (input) => { return this._callFunction(module.name, func, input); }); methods[func.name] = closure; methods[suffix] = closure; } } } } return methods; } _resolveTypeMethodsWithInheritance(typeName: any): any { const input = typeName; let methods = {}; let colonIdx = typeName.indexOf(':'); let modPart = (__ball_ge(colonIdx, 0) ? typeName.substring(0, colonIdx) : this._currentModule); let typeDef = this._findTypeDef(typeName); if (((!__ball_eq(typeDef, null) && !__ball_eq(typeDef.superclass, null)) && !(typeDef.superclass.length === 0))) { let qualSuper = (typeDef.superclass.includes(':') ? typeDef.superclass : ((__ball_to_string(modPart) + ':') + __ball_to_string(typeDef.superclass))); __ball_push_all(methods, this._resolveTypeMethodsWithInheritance(qualSuper)); } let mixins = this._getMixins(typeName); for (const mixin of mixins) { let qualMixin = (mixin.includes(':') ? mixin : ((__ball_to_string(modPart) + ':') + __ball_to_string(mixin))); __ball_push_all(methods, this._resolveTypeMethods(qualMixin)); } __ball_push_all(methods, this._resolveTypeMethods(typeName)); return methods; } async _evalBlock(block: any, scope: any): Promise { let blockScope = scope.child(); let flowResult; for (const stmt of block.statements) { let result = await this._evalStatement(stmt, blockScope); if ((result instanceof _FlowSignal)) { return result; } } if (hasResult(block)) { flowResult = await this._evalExpression(block.result, blockScope); } else { flowResult = null; } return flowResult; } async _evalStatement(stmt: any, scope: any): Promise { do { const __sw = whichStmt(stmt); if ((__sw === Statement_Stmt.let)) { let letValue = stmt.let.value; let value; if ((__ball_eq(whichExpr(letValue), Expression_Expr.reference) && __ball_eq(letValue.reference.name, '__no_init__'))) { value = null; } else { value = await this._evalExpression(letValue, scope); if ((value instanceof _FlowSignal)) { return value; } } if (hasMetadata(stmt.let)) { let letType = (() => { let __naa_12 = __ball_index(stmt.let.metadata.fields, 'type'); return (__ball_eq(__naa_12, null) ? null : __naa_12.stringValue); })(); if ((!__ball_eq(letType, null) && letType.startsWith('Map'))) { if ((this._isBallSet(value) && (this._ballSetItems(value).length === 0))) { value = _ballUserMap(); } if ((Array.isArray(value) && (value.length === 0))) { value = _ballUserMap(); } } } scope.bind(stmt.let.name, value); return null; } else if ((__sw === Statement_Stmt.expression)) { return await this._evalExpression(stmt.expression, scope); } else if ((__sw === Statement_Stmt.notSet)) { return null; } } while (false); } _evalLambda(func: any, scope: any): any { return (async (input) => { let lambdaScope = scope.child(); lambdaScope.bind('input', input); let paramNames = (hasMetadata(func) ? this._extractParams(func.metadata) : []); let inputMap = this._asMap(input); if ((__ball_eq(paramNames.length, 1) && __ball_eq(inputMap, null))) { lambdaScope.bind(paramNames.first, input); } if (!__ball_eq(inputMap, null)) { for (const entry of inputMap.entries) { if (!__ball_eq(entry.key, '__type__')) { lambdaScope.bind(entry.key, entry.value); } } if (!(paramNames.length === 0)) { for (let i = 0; __ball_lt(i, paramNames.length); (i++)) { let p = __ball_index(paramNames, i); if (!lambdaScope.has(p)) { if ((p in __ball_require_map(inputMap, 'map_contains_key'))) { lambdaScope.bind(p, __ball_index(inputMap, p)); } else { if ((('arg' + __ball_to_string(i)) in __ball_require_map(inputMap, 'map_contains_key'))) { lambdaScope.bind(p, __ball_index(inputMap, ('arg' + __ball_to_string(i)))); } } } } } } if (!hasBody(func)) { return null; } let result = await this._evalExpression(func.body, lambdaScope); if (((result instanceof _FlowSignal) && __ball_eq(result.kind, 'return'))) { return result.value; } return result; }); } _cfAsMap(v: any): any { const input = v; if (((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) && !(false /* BallMap is Map in TS */))) { if (__ball_is_type(v, "Map")) { return v; } return v.cast(); } if (false /* BallMap is Map in TS */) { return v.entries; } } _lazyFields(call: any): any { const input = call; if ((!hasInput(call) || !__ball_eq(whichExpr(call.input), Expression_Expr.messageCreation))) { return {}; } let result = {}; for (const f of call.input.messageCreation.fields) { result[f.name] = f.value; } return result; } async _evalLazyIf(call: any, scope: any): Promise { let fields = this._lazyFields(call); let condition = __ball_index(fields, 'condition'); let thenBranch = __ball_index(fields, 'then'); let elseBranch = __ball_index(fields, 'else'); if ((__ball_eq(condition, null) || __ball_eq(thenBranch, null))) { throw new BallRuntimeError('std.if missing condition or then'); } let condVal = await this._evalExpression(condition, scope); if (this._toBool(condVal)) { return await this._evalExpression(thenBranch, scope); } else { if (!__ball_eq(elseBranch, null)) { return await this._evalExpression(elseBranch, scope); } } } async _evalLazyFor(call: any, scope: any): Promise { let fields = this._lazyFields(call); let initExpr = __ball_index(fields, 'init'); let condition = __ball_index(fields, 'condition'); let update = __ball_index(fields, 'update'); let body = __ball_index(fields, 'body'); let forScope = scope.child(); let loopVars = []; await this._evalForInit(initExpr, forScope, loopVars); while (true) { let iterScope = forScope.child(); for (const v of loopVars) { iterScope.bind(v, forScope.lookup(v)); } if (!__ball_eq(condition, null)) { let condVal = await this._evalExpression(condition, iterScope); if (!this._toBool(condVal)) { break; } } if (!__ball_eq(body, null)) { let result = await this._evalExpression(body, iterScope); if ((result instanceof _FlowSignal)) { if (__ball_eq(result.kind, 'return')) { return result; } if ((!__ball_eq(result.label, null) && !(result.label.length === 0))) { return result; } if (__ball_eq(result.kind, 'break')) { break; } } } for (const v of loopVars) { forScope.bind(v, iterScope.lookup(v)); } if (!__ball_eq(update, null)) { await this._evalExpression(update, forScope); } } } async _evalForInit(initExpr: any, forScope: any, loopVars: any): Promise { if (__ball_eq(initExpr, null)) { return; } if (__ball_eq(whichExpr(initExpr), Expression_Expr.block)) { for (const stmt of initExpr.block.statements) { if (__ball_eq(whichStmt(stmt), Statement_Stmt.let)) { loopVars = (loopVars.push(stmt.let.name), loopVars); } await this._evalStatement(stmt, forScope); } } else { if ((__ball_eq(whichExpr(initExpr), Expression_Expr.literal) && hasStringValue(initExpr.literal))) { let s = initExpr.literal.stringValue; let match = new RegExp('(?:var|final|int|double|String)\\s+(\\w+)\\s*=\\s*(.+)').firstMatch(s); if (!__ball_eq(match, null)) { let varName = match.group(1); let rawVal = match.group(2).trim(); let intParsed = int.tryParse(rawVal); let doubleParsed = (__ball_eq(intParsed, null) ? double.tryParse(rawVal) : null); let parsed; if (!__ball_eq(intParsed, null)) { parsed = intParsed; } else { if (!__ball_eq(doubleParsed, null)) { parsed = doubleParsed; } else { if (__ball_eq(rawVal, 'true')) { parsed = true; } else { if (__ball_eq(rawVal, 'false')) { parsed = false; } else { parsed = this._evalSimpleInitExpr(rawVal, forScope); } } } } loopVars = (loopVars.push(varName), loopVars); forScope.bind(varName, parsed); } } else { await this._evalExpression(initExpr, forScope); } } } _evalSimpleInitExpr(rawVal: any, scope: any): any { let propOpNum = new RegExp('^(\\w+)\\.(\\w+)\\s*([+\\-*/])\\s*(\\d+)$').firstMatch(rawVal); if (!__ball_eq(propOpNum, null)) { let ref = propOpNum.group(1); let prop = propOpNum.group(2); let op = propOpNum.group(3); let operand = __ball_parse_int(propOpNum.group(4)); if (scope.has(ref)) { let obj = scope.lookup(ref); let propVal; if (((typeof obj === 'string') && __ball_eq(prop, 'length'))) { propVal = obj.value.length; } else { if (((typeof obj === 'string') && __ball_eq(prop, 'length'))) { propVal = obj.length; } else { if ((false /* BallList is List in TS */ && __ball_eq(prop, 'length'))) { propVal = obj.items.length; } else { if ((Array.isArray(obj) && __ball_eq(prop, 'length'))) { propVal = obj.length; } else { if ((false /* BallMap is Map in TS */ && __ball_eq(prop, 'length'))) { propVal = obj.entries.length; } else { if (((typeof obj === 'object' && obj !== null && !Array.isArray(obj) && !(obj instanceof BallDouble) && !(obj instanceof Set)) && __ball_eq(prop, 'length'))) { propVal = obj.length; } else { let map = this._cfAsMap(obj); if ((!__ball_eq(map, null) && (prop in __ball_require_map(map, 'map_contains_key')))) { let v = __ball_index(map, prop); if ((typeof v === 'number' || v instanceof BallDouble)) { propVal = v; } } } } } } } } if (!__ball_eq(propVal, null)) { return ((op === '+') ? (__ball_add(propVal, operand)) : ((op === '-') ? (__ball_sub(propVal, operand)) : ((op === '*') ? (__ball_mul(propVal, operand)) : ((op === '/') ? (__ball_divide(propVal, operand)) : rawVal)))); } } } let varOpVar = new RegExp('^(\\w+)\\s*([+\\-*/])\\s*(\\w+)$').firstMatch(rawVal); if (!__ball_eq(varOpVar, null)) { let left = varOpVar.group(1); let op = varOpVar.group(2); let right = varOpVar.group(3); let leftVal; let rightVal; if (scope.has(left)) { let v = scope.lookup(left); if ((typeof v === 'number' || v instanceof BallDouble)) { leftVal = v; } } let rightNum = int.tryParse(right); if (!__ball_eq(rightNum, null)) { rightVal = rightNum; } else { if (scope.has(right)) { let v = scope.lookup(right); if ((typeof v === 'number' || v instanceof BallDouble)) { rightVal = v; } } } if ((!__ball_eq(leftVal, null) && !__ball_eq(rightVal, null))) { return ((op === '+') ? (__ball_add(leftVal, rightVal)) : ((op === '-') ? (__ball_sub(leftVal, rightVal)) : ((op === '*') ? (__ball_mul(leftVal, rightVal)) : ((op === '/') ? (__ball_divide(leftVal, rightVal)) : rawVal)))); } } let propAccess = new RegExp('^(\\w+)\\.(\\w+)$').firstMatch(rawVal); if (!__ball_eq(propAccess, null)) { let ref = propAccess.group(1); let prop = propAccess.group(2); if (scope.has(ref)) { let obj = scope.lookup(ref); if (((typeof obj === 'string') && __ball_eq(prop, 'length'))) { return obj.value.length; } if (((typeof obj === 'string') && __ball_eq(prop, 'length'))) { return obj.length; } if ((false /* BallList is List in TS */ && __ball_eq(prop, 'length'))) { return obj.items.length; } if ((Array.isArray(obj) && __ball_eq(prop, 'length'))) { return obj.length; } if ((false /* BallMap is Map in TS */ && __ball_eq(prop, 'length'))) { return obj.entries.length; } if (((typeof obj === 'object' && obj !== null && !Array.isArray(obj) && !(obj instanceof BallDouble) && !(obj instanceof Set)) && __ball_eq(prop, 'length'))) { return obj.length; } let map = this._cfAsMap(obj); if ((!__ball_eq(map, null) && (prop in __ball_require_map(map, 'map_contains_key')))) { return __ball_index(map, prop); } } } if (scope.has(rawVal)) { return scope.lookup(rawVal); } return rawVal; } async _evalLazyForIn(call: any, scope: any): Promise { let fields = this._lazyFields(call); let variable = (this._stringFieldVal(fields, 'variable') ?? 'item'); let iterable = __ball_index(fields, 'iterable'); let body = __ball_index(fields, 'body'); if ((__ball_eq(iterable, null) || __ball_eq(body, null))) { return null; } let iterVal = await this._evalExpression(iterable, scope); let items = this._toIterable(iterVal); for (const item of items) { let loopScope = scope.child(); loopScope.bind(variable, item); let result = await this._evalExpression(body, loopScope); if ((result instanceof _FlowSignal)) { if (__ball_eq(result.kind, 'return')) { return result; } if ((!__ball_eq(result.label, null) && !(result.label.length === 0))) { return result; } if (__ball_eq(result.kind, 'break')) { break; } } } } async _evalLazyWhile(call: any, scope: any): Promise { let fields = this._lazyFields(call); let condition = __ball_index(fields, 'condition'); let body = __ball_index(fields, 'body'); while (true) { if (!__ball_eq(condition, null)) { let condVal = await this._evalExpression(condition, scope); if (!this._toBool(condVal)) { break; } } if (!__ball_eq(body, null)) { let result = await this._evalExpression(body, scope); if ((result instanceof _FlowSignal)) { if (__ball_eq(result.kind, 'return')) { return result; } if ((!__ball_eq(result.label, null) && !(result.label.length === 0))) { return result; } if (__ball_eq(result.kind, 'break')) { break; } } } } } async _evalLazyDoWhile(call: any, scope: any): Promise { let fields = this._lazyFields(call); let body = __ball_index(fields, 'body'); let condition = __ball_index(fields, 'condition'); do { if (!__ball_eq(body, null)) { let result = await this._evalExpression(body, scope); if ((result instanceof _FlowSignal)) { if (__ball_eq(result.kind, 'return')) { return result; } if ((!__ball_eq(result.label, null) && !(result.label.length === 0))) { return result; } if (__ball_eq(result.kind, 'break')) { break; } } } if (!__ball_eq(condition, null)) { let condVal = await this._evalExpression(condition, scope); if (!this._toBool(condVal)) { break; } } else { break; } } while (true); } async _evalLazySwitch(call: any, scope: any): Promise { let fields = this._lazyFields(call); let subject = __ball_index(fields, 'subject'); let cases = __ball_index(fields, 'cases'); if ((__ball_eq(subject, null) || __ball_eq(cases, null))) { return null; } let subjectVal = await this._evalExpression(subject, scope); if ((!__ball_eq(whichExpr(cases), Expression_Expr.literal) || !__ball_eq(whichValue(cases.literal), Literal_Value.listValue))) { return null; } let elements = cases.literal.listValue.elements; let caseFieldsList = []; let labelToIndex = {}; let defaultIndex = __ball_negate(1); for (let i = 0; __ball_lt(i, elements.length); (i++)) { let caseExpr = __ball_index(elements, i); let cf = {}; if (__ball_eq(whichExpr(caseExpr), Expression_Expr.messageCreation)) { for (const f of caseExpr.messageCreation.fields) { cf[f.name] = f.value; } } caseFieldsList = (caseFieldsList.push(cf), caseFieldsList); let label = this._stringFieldVal(cf, 'label'); if ((!__ball_eq(label, null) && !(label.length === 0))) { labelToIndex[label] = i; } if (this._caseIsDefault(cf)) { defaultIndex = i; } } let index = __ball_negate(1); let bodyScope = scope; for (let i = 0; __ball_lt(i, caseFieldsList.length); (i++)) { let cf = __ball_index(caseFieldsList, i); if (this._caseIsDefault(cf)) { continue; } let bindings = {}; let matched = await this._matchesSwitchCasePattern(subjectVal, cf, bindings, scope); if (!matched) { continue; } let matchScope = this._scopeWithPatternBindings(scope, bindings); let guard = __ball_index(cf, 'guard'); if ((!__ball_eq(guard, null) && !this._toBool(await this._evalExpression(guard, matchScope)))) { continue; } index = i; bodyScope = matchScope; break; } if (__ball_eq(index, __ball_negate(1))) { if (__ball_eq(defaultIndex, __ball_negate(1))) { return null; } index = defaultIndex; bodyScope = scope; } while ((__ball_ge(index, 0) && __ball_lt(index, caseFieldsList.length))) { let cf = __ball_index(caseFieldsList, index); let body = __ball_index(cf, 'body'); if ((__ball_eq(body, null) || ((__ball_eq(whichExpr(body), Expression_Expr.block) && (body.block.statements.length === 0)) && !hasResult(body.block)))) { (index++); continue; } let result = await this._evalExpression(body, bodyScope); if ((result instanceof _FlowSignal)) { if ((__ball_eq(result.kind, 'break') && __ball_eq(result.label, null))) { return null; } let label = result.label; if ((__ball_eq(result.kind, 'continue') && !__ball_eq(label, null))) { let targetIndex = __ball_index(labelToIndex, label); if (!__ball_eq(targetIndex, null)) { index = targetIndex; bodyScope = scope; continue; } } } return result; } } async _evalLazySwitchExpr(call: any, scope: any): Promise { let fields = this._lazyFields(call); let subject = __ball_index(fields, 'subject'); let cases = __ball_index(fields, 'cases'); if ((__ball_eq(subject, null) || __ball_eq(cases, null))) { return null; } let subjectVal = await this._evalExpression(subject, scope); if ((!__ball_eq(whichExpr(cases), Expression_Expr.literal) || !__ball_eq(whichValue(cases.literal), Literal_Value.listValue))) { return null; } let defaultBody; for (const caseExpr of cases.literal.listValue.elements) { if (!__ball_eq(whichExpr(caseExpr), Expression_Expr.messageCreation)) { continue; } let cf = {}; for (const f of caseExpr.messageCreation.fields) { cf[f.name] = f.value; } if (this._caseIsDefault(cf)) { defaultBody = __ball_index(cf, 'body'); continue; } let bindings = {}; if (!await this._matchesSwitchCasePattern(subjectVal, cf, bindings, scope)) { continue; } let guard = __ball_index(cf, 'guard'); let caseScope = this._scopeWithPatternBindings(scope, bindings); if ((!__ball_eq(guard, null) && !this._toBool(await this._evalExpression(guard, caseScope)))) { continue; } let body = __ball_index(cf, 'body'); if (__ball_eq(body, null)) { return null; } return this._evalExpression(body, caseScope); } if (!__ball_eq(defaultBody, null)) { return this._evalExpression(defaultBody, scope); } throw new BallRuntimeError('Non-exhaustive switch expression'); } _caseIsDefault(fields: any): any { const input = fields; let isDefault = __ball_index(fields, 'is_default'); if ((((!__ball_eq(isDefault, null) && __ball_eq(whichExpr(isDefault), Expression_Expr.literal)) && __ball_eq(whichValue(isDefault.literal), Literal_Value.boolValue)) && isDefault.literal.boolValue)) { return true; } let pattern = __ball_index(fields, 'pattern'); return (!__ball_eq(pattern, null) && __ball_eq(this._stringLiteral(pattern), '_')); } _scopeWithPatternBindings(parent: any, bindings: any): any { if ((bindings.length === 0)) { return parent; } let child = parent.child(); for (const entry of bindings.entries) { child.bind(entry.key, entry.value); } return child; } async _matchesSwitchCasePattern(subjectVal: any, fields: any, bindings: any, scope: any): Promise { let patternExpr = __ball_index(fields, 'pattern_expr'); if (!__ball_eq(patternExpr, null)) { let pattern = await this._evalExpression(patternExpr, scope); if (this._matchPattern(subjectVal, pattern, bindings)) { return true; } } let value = __ball_index(fields, 'value'); if (!__ball_eq(value, null)) { let caseVal = await this._evalExpression(value, scope); if (this._ballEquals(caseVal, subjectVal)) { return true; } } let patternField = __ball_index(fields, 'pattern'); let patternStr = (__ball_eq(patternField, null) ? null : this._stringLiteral(patternField)); if (!__ball_eq(patternStr, null)) { return (this._matchPattern(subjectVal, patternStr, bindings) || this._matchSwitchPattern(subjectVal, patternStr)); } if (!__ball_eq(patternField, null)) { let pattern = await this._evalExpression(patternField, scope); return this._matchPattern(subjectVal, pattern, bindings); } return false; } _stringLiteral(expr: any): any { const input = expr; if ((__ball_eq(whichExpr(expr), Expression_Expr.literal) && __ball_eq(whichValue(expr.literal), Literal_Value.stringValue))) { return expr.literal.stringValue; } } _ballEquals(a: any, b: any): any { if (__ball_eq(a, b)) { return true; } if (((typeof a === 'number' || a instanceof BallDouble) && (typeof b === 'number' || b instanceof BallDouble))) { return __ball_eq(a, b); } if ((!__ball_eq(a, null) && !__ball_eq(b, null))) { return __ball_eq(__ball_to_string(a), __ball_to_string(b)); } return false; } _matchSwitchPattern(subject: any, pattern: any): any { let dotIdx = pattern.indexOf('.'); if (__ball_ge(dotIdx, 0)) { let enumType = pattern.substring(0, dotIdx); let enumValue = pattern.substring(__ball_add(dotIdx, 1)); let subjectMap = this._cfAsMap(subject); if (!__ball_eq(subjectMap, null)) { let typeName = __ball_index(subjectMap, '__type__'); if (!__ball_eq(typeName, null)) { let colonIdx = typeName.indexOf(':'); let bareType = (__ball_ge(colonIdx, 0) ? typeName.substring(__ball_add(colonIdx, 1)) : typeName); if ((__ball_eq(bareType, enumType) && __ball_eq(__ball_index(subjectMap, 'name'), enumValue))) { return true; } if ((__ball_eq(typeName, enumType) && __ball_eq(__ball_index(subjectMap, 'name'), enumValue))) { return true; } } } let enumVals = __ball_index(this._enumValues, enumType); if ((!__ball_eq(enumVals, null) && (enumValue in __ball_require_map(enumVals, 'map_contains_key')))) { let resolved = __ball_index(enumVals, enumValue); let resolvedMap = this._cfAsMap(resolved); if ((!__ball_eq(subjectMap, null) && !__ball_eq(resolvedMap, null))) { return (__ball_eq(__ball_index(subjectMap, '__type__'), __ball_index(resolvedMap, '__type__')) && __ball_eq(__ball_index(subjectMap, 'name'), __ball_index(resolvedMap, 'name'))); } } let qualifiedEnumType = ((__ball_to_string(this._currentModule) + ':') + __ball_to_string(enumType)); let qualEnumVals = __ball_index(this._enumValues, qualifiedEnumType); if ((!__ball_eq(qualEnumVals, null) && (enumValue in __ball_require_map(qualEnumVals, 'map_contains_key')))) { let resolved = __ball_index(qualEnumVals, enumValue); let resolvedMap = this._cfAsMap(resolved); if ((!__ball_eq(subjectMap, null) && !__ball_eq(resolvedMap, null))) { return (__ball_eq(__ball_index(subjectMap, '__type__'), __ball_index(resolvedMap, '__type__')) && __ball_eq(__ball_index(subjectMap, 'name'), __ball_index(resolvedMap, 'name'))); } } } if (__ball_eq(pattern, 'null')) { return __ball_eq(subject, null); } if (__ball_eq(pattern, 'true')) { return __ball_eq(subject, true); } if (__ball_eq(pattern, 'false')) { return __ball_eq(subject, false); } let numVal = num.tryParse(pattern); if ((!__ball_eq(numVal, null) && (typeof subject === 'number' || subject instanceof BallDouble))) { return this._ballEquals(subject, numVal); } if (this._matchesTypePattern(subject, pattern)) { return true; } return __ball_eq(pattern, (__ball_eq(subject, null) ? null : subject.toString())); } async _evalLazyTry(call: any, scope: any): Promise { let fields = this._lazyFields(call); let body = __ball_index(fields, 'body'); let catches = __ball_index(fields, 'catches'); let finallyBlock = __ball_index(fields, 'finally'); let result; try { result = (!__ball_eq(body, null) ? await this._evalExpression(body, scope) : null); } catch (__ball_active_error) { const e = __ball_active_error; const stackTrace = (__ball_active_error instanceof Error && __ball_active_error.stack != null ? __ball_active_error.stack : (new Error().stack ?? '')); result = null; if (((!__ball_eq(catches, null) && __ball_eq(whichExpr(catches), Expression_Expr.literal)) && __ball_eq(whichValue(catches.literal), Literal_Value.listValue))) { let caught = false; for (const catchExpr of catches.literal.listValue.elements) { if (!__ball_eq(whichExpr(catchExpr), Expression_Expr.messageCreation)) { continue; } let cf = {}; for (const f of catchExpr.messageCreation.fields) { cf[f.name] = f.value; } let catchType = this._stringFieldVal(cf, 'type'); if ((!__ball_eq(catchType, null) && !(catchType.length === 0))) { let matches; if ((e instanceof BallException)) { let eType = e['typeName']; let eColonIdx = eType.indexOf(':'); let eBare = (__ball_ge(eColonIdx, 0) ? eType.substring(__ball_add(eColonIdx, 1)) : eType); matches = (__ball_eq(eType, catchType) || __ball_eq(eBare, catchType)); } else { if (((typeof e === 'object' && e !== null && !Array.isArray(e) && !(e instanceof BallDouble) && !(e instanceof Set)) && !__ball_eq(__ball_index(e, '__type__'), null))) { let eType = __ball_to_string(__ball_index(e, '__type__')); let eColonIdx = eType.indexOf(':'); let eBare = (__ball_ge(eColonIdx, 0) ? eType.substring(__ball_add(eColonIdx, 1)) : eType); matches = (__ball_eq(eType, catchType) || __ball_eq(eBare, catchType)); } else { matches = __ball_eq(__ball_to_string(e['runtimeType']), catchType); } } if (!matches) { continue; } } let variable = (this._stringFieldVal(cf, 'variable') ?? 'e'); let stackVariable = this._stringFieldVal(cf, 'stack_trace'); let catchBody = __ball_index(cf, 'body'); if (!__ball_eq(catchBody, null)) { let catchScope = scope.child(); { let __catchVal = e; if (e instanceof BallException) { __catchVal = e['value']; // Add 'message' field from arg0 if it's a typed exception object if (typeof __catchVal === 'object' && __catchVal !== null && !('message' in __catchVal) && 'arg0' in __catchVal) { __catchVal['message'] = __catchVal['arg0']; } } else if (e instanceof Error) { __catchVal = e.message; } catchScope.bind(variable, __catchVal); } if ((!__ball_eq(stackVariable, null) && !(stackVariable.length === 0))) { catchScope.bind(stackVariable, stackTrace); } let previousActive = this._activeException; this._activeException = e; try { result = await this._evalExpression(catchBody, catchScope); } catch (__ball_active_error) { throw __ball_active_error; } finally { this._activeException = previousActive; } caught = true; break; } } if (!caught) { throw __ball_active_error; } } else { throw __ball_active_error; } } finally { if (!__ball_eq(finallyBlock, null)) { await this._evalExpression(finallyBlock, scope); } } return result; } async _evalShortCircuitAnd(call: any, scope: any): Promise { let fields = this._lazyFields(call); let left = __ball_index(fields, 'left'); let right = __ball_index(fields, 'right'); if ((__ball_eq(left, null) || __ball_eq(right, null))) { return false; } let leftVal = await this._evalExpression(left, scope); if (!this._toBool(leftVal)) { return false; } return this._toBool(await this._evalExpression(right, scope)); } async _evalShortCircuitOr(call: any, scope: any): Promise { let fields = this._lazyFields(call); let left = __ball_index(fields, 'left'); let right = __ball_index(fields, 'right'); if ((__ball_eq(left, null) || __ball_eq(right, null))) { return false; } let leftVal = await this._evalExpression(left, scope); if (this._toBool(leftVal)) { return true; } return this._toBool(await this._evalExpression(right, scope)); } async _evalReturn(call: any, scope: any): Promise { let fields = this._lazyFields(call); let value = __ball_index(fields, 'value'); let val = (!__ball_eq(value, null) ? await this._evalExpression(value, scope) : null); return new _FlowSignal('return', { value: val }); } async _evalBreak(call: any, scope: any): Promise { let fields = this._lazyFields(call); let label = this._stringFieldVal(fields, 'label'); return new _FlowSignal('break', { label: label }); } async _evalContinue(call: any, scope: any): Promise { let fields = this._lazyFields(call); let label = this._stringFieldVal(fields, 'label'); return new _FlowSignal('continue', { label: label }); } _cfWritebackInstance(objExpr: any, obj: any, map: any, scope: any): any { if (!__ball_eq(whichExpr(objExpr), Expression_Expr.reference)) { return; } if ((!(__ball_is_type(obj, "Map")) || false /* BallMap is Map in TS */)) { return; } let name = objExpr.reference.name; if (scope.has(name)) { scope.set(name, map); } } _cfWritebackIndexed(targetExpr: any, container: any, scope: any): any { if (!__ball_eq(whichExpr(targetExpr), Expression_Expr.reference)) { return; } let name = targetExpr.reference.name; let staticField = __ball_index(this._staticFieldRefs, name); if (!__ball_eq(staticField, null)) { this._globalScope.set(staticField.fullName, container); return; } if (scope.has(name)) { scope.set(name, container); } } async _evalAssign(call: any, scope: any): Promise { let fields = this._lazyFields(call); let target = __ball_index(fields, 'target'); let value = __ball_index(fields, 'value'); if ((__ball_eq(target, null) || __ball_eq(value, null))) { return null; } let op = this._stringFieldVal(fields, 'op'); if (__ball_eq(op, '??=')) { return this._evalNullAwareAssign(target, value, scope); } if ((__ball_eq(whichExpr(target), Expression_Expr.reference) && __ball_eq(whichExpr(value), Expression_Expr.call))) { let valFn = value.call.function; let valMod = value.call.module; if ((((__ball_eq(valFn, 'list_remove_at') || __ball_eq(valFn, 'list_pop')) || __ball_eq(valFn, 'list_remove_last')) && ((__ball_eq(valMod, 'std') || __ball_eq(valMod, 'std_collections')) || (valMod.length === 0)))) { let valFields = this._lazyFields(value.call); let listExpr = __ball_index(valFields, 'list'); if (((!__ball_eq(listExpr, null) && __ball_eq(whichExpr(listExpr), Expression_Expr.reference)) && __ball_eq(listExpr.reference.name, target.reference.name))) { return await this._evalExpression(value, scope); } } } let val = await this._evalExpression(value, scope); if (__ball_eq(whichExpr(target), Expression_Expr.reference)) { let name = target.reference.name; if (((!__ball_eq(op, null) && !(op.length === 0)) && !__ball_eq(op, '='))) { let current = scope.lookup(name); let computed = this._applyCompoundOp(op, current, val); scope.set(name, computed); this._syncFieldToSelf(scope, name, computed); if ((this._globalScope.has(name) && !scope.has(name))) { this._globalScope.set(name, computed); } return computed; } scope.set(name, val); this._syncFieldToSelf(scope, name, val); if (this._globalScope.has(name)) { this._globalScope.set(name, val); } return val; } if (__ball_eq(whichExpr(target), Expression_Expr.fieldAccess)) { let obj = await this._evalExpression(target.fieldAccess.object, scope); let map = this._cfAsMap(obj); if (!__ball_eq(map, null)) { let fieldName = target.fieldAccess.field_2; if (((!__ball_eq(op, null) && !(op.length === 0)) && !__ball_eq(op, '='))) { let current = __ball_index(map, fieldName); let computed = this._applyCompoundOp(op, current, val); map[fieldName] = computed; this._cfWritebackInstance(target.fieldAccess.object, obj, map, scope); return computed; } let setterResult = await this._trySetterDispatch(map, fieldName, val); if (!__ball_eq(setterResult, _sentinel)) { return setterResult; } map[fieldName] = val; this._cfWritebackInstance(target.fieldAccess.object, obj, map, scope); return val; } } if (((__ball_eq(whichExpr(target), Expression_Expr.call) && __ball_eq(target.call.module, 'std')) && __ball_eq(target.call.function, 'index'))) { let indexFields = this._lazyFields(target.call); let indexTarget = __ball_index(indexFields, 'target'); let indexExpr = __ball_index(indexFields, 'index'); if ((!__ball_eq(indexTarget, null) && !__ball_eq(indexExpr, null))) { let list = await this._evalExpression(indexTarget, scope); let idx = await this._evalExpression(indexExpr, scope); if (this._isBallSet(list)) { list = _ballUserMap(); this._cfWritebackIndexed(indexTarget, list, scope); } if (((!__ball_eq(op, null) && !(op.length === 0)) && !__ball_eq(op, '='))) { let computed; let didSet = false; if ((false /* BallList is List in TS */ && (typeof idx === 'number' && Number.isInteger(idx)))) { computed = this._applyCompoundOp(op, __ball_index(list.items, idx), val); list.items[idx] = computed; didSet = true; } else { if ((Array.isArray(list) && (typeof idx === 'number' && Number.isInteger(idx)))) { computed = this._applyCompoundOp(op, __ball_index(list, idx), val); list[idx] = computed; didSet = true; } else { if ((false /* BallMap is Map in TS */ && (typeof idx === 'string'))) { computed = this._applyCompoundOp(op, __ball_index(list.entries, idx), val); list.entries[idx] = computed; didSet = true; } else { if ((typeof list === 'object' && list !== null && !Array.isArray(list) && !(list instanceof BallDouble) && !(list instanceof Set))) { computed = this._applyCompoundOp(op, __ball_index(list, idx), val); list[idx] = computed; didSet = true; } } } } if (didSet) { this._cfWritebackIndexed(indexTarget, list, scope); return computed; } } let didSet = false; if ((false /* BallList is List in TS */ && (typeof idx === 'number' && Number.isInteger(idx)))) { list.items[idx] = val; didSet = true; } else { if ((Array.isArray(list) && (typeof idx === 'number' && Number.isInteger(idx)))) { list[idx] = val; didSet = true; } else { if ((false /* BallMap is Map in TS */ && (typeof idx === 'string'))) { list.entries[idx] = val; didSet = true; } else { if ((typeof list === 'object' && list !== null && !Array.isArray(list) && !(list instanceof BallDouble) && !(list instanceof Set))) { list[idx] = val; didSet = true; } } } } if (didSet) { this._cfWritebackIndexed(indexTarget, list, scope); return val; } } } return val; } async _evalNullAwareAssign(target: any, value: any, scope: any): Promise { if (__ball_eq(whichExpr(target), Expression_Expr.reference)) { let name = target.reference.name; let current = scope.lookup(name); if (!__ball_eq(current, null)) { return current; } let val = await this._evalExpression(value, scope); scope.set(name, val); return val; } if (__ball_eq(whichExpr(target), Expression_Expr.fieldAccess)) { let obj = await this._evalExpression(target.fieldAccess.object, scope); let map = this._cfAsMap(obj); if (!__ball_eq(map, null)) { let fieldName = target.fieldAccess.field_2; let current = __ball_index(map, fieldName); if (!__ball_eq(current, null)) { return current; } let val = await this._evalExpression(value, scope); map[fieldName] = val; return val; } } if (((__ball_eq(whichExpr(target), Expression_Expr.call) && __ball_eq(target.call.module, 'std')) && __ball_eq(target.call.function, 'index'))) { let indexFields = this._lazyFields(target.call); let indexTarget = __ball_index(indexFields, 'target'); let indexExpr = __ball_index(indexFields, 'index'); if ((!__ball_eq(indexTarget, null) && !__ball_eq(indexExpr, null))) { let list = await this._evalExpression(indexTarget, scope); let idx = await this._evalExpression(indexExpr, scope); if ((false /* BallList is List in TS */ && (typeof idx === 'number' && Number.isInteger(idx)))) { let current = __ball_index(list.items, idx); if (!__ball_eq(current, null)) { return current; } let val = await this._evalExpression(value, scope); list.items[idx] = val; return val; } if ((Array.isArray(list) && (typeof idx === 'number' && Number.isInteger(idx)))) { let current = __ball_index(list, idx); if (!__ball_eq(current, null)) { return current; } let val = await this._evalExpression(value, scope); list[idx] = val; return val; } if ((false /* BallMap is Map in TS */ && (typeof idx === 'string'))) { let current = __ball_index(list.entries, idx); if (!__ball_eq(current, null)) { return current; } let val = await this._evalExpression(value, scope); list.entries[idx] = val; return val; } if ((typeof list === 'object' && list !== null && !Array.isArray(list) && !(list instanceof BallDouble) && !(list instanceof Set))) { let current = __ball_index(list, idx); if (!__ball_eq(current, null)) { return current; } let val = await this._evalExpression(value, scope); list[idx] = val; return val; } } } return this._evalExpression(value, scope); } async _evalIncDec(call: any, scope: any): Promise { let fields = this._lazyFields(call); let valueExpr = __ball_index(fields, 'value'); if (__ball_eq(valueExpr, null)) { return null; } if (__ball_eq(whichExpr(valueExpr), Expression_Expr.reference)) { let name = valueExpr.reference.name; let current = this._toNum(scope.lookup(name)); let isInc = call.function.includes('increment'); let isPre = call.function.startsWith('pre'); let updated = (isInc ? __ball_add(current, 1) : __ball_sub(current, 1)); scope.set(name, updated); this._syncFieldToSelf(scope, name, updated); if (this._globalScope.has(name)) { this._globalScope.set(name, updated); } return (isPre ? updated : current); } if (((__ball_eq(whichExpr(valueExpr), Expression_Expr.call) && __ball_eq(valueExpr.call.function, 'index')) && (__ball_eq(valueExpr.call.module, 'std') || (valueExpr.call.module.length === 0)))) { let indexFields = this._lazyFields(valueExpr.call); let targetExpr = __ball_index(indexFields, 'target'); let indexExpr = __ball_index(indexFields, 'index'); if ((!__ball_eq(targetExpr, null) && !__ball_eq(indexExpr, null))) { let container = await this._evalExpression(targetExpr, scope); let idx = await this._evalExpression(indexExpr, scope); let isInc = call.function.includes('increment'); let isPre = call.function.startsWith('pre'); if ((false /* BallList is List in TS */ && (typeof idx === 'number' && Number.isInteger(idx)))) { let current = this._toNum(__ball_index(container.items, idx)); let updated = (isInc ? __ball_add(current, 1) : __ball_sub(current, 1)); container.items[idx] = updated; return (isPre ? updated : current); } if ((Array.isArray(container) && (typeof idx === 'number' && Number.isInteger(idx)))) { let current = this._toNum(__ball_index(container, idx)); let updated = (isInc ? __ball_add(current, 1) : __ball_sub(current, 1)); container[idx] = updated; return (isPre ? updated : current); } if ((false /* BallMap is Map in TS */ && (typeof idx === 'string'))) { let current = this._toNum(__ball_index(container.entries, idx)); let updated = (isInc ? __ball_add(current, 1) : __ball_sub(current, 1)); container.entries[idx] = updated; return (isPre ? updated : current); } if ((typeof container === 'object' && container !== null && !Array.isArray(container) && !(container instanceof BallDouble) && !(container instanceof Set))) { let current = this._toNum(__ball_index(container, idx)); let updated = (isInc ? __ball_add(current, 1) : __ball_sub(current, 1)); container[idx] = updated; return (isPre ? updated : current); } } } if (__ball_eq(whichExpr(valueExpr), Expression_Expr.fieldAccess)) { let obj = await this._evalExpression(valueExpr.fieldAccess.object, scope); let fieldName = valueExpr.fieldAccess.field_2; let isInc = call.function.includes('increment'); let isPre = call.function.startsWith('pre'); let map = this._cfAsMap(obj); if (!__ball_eq(map, null)) { let current = this._toNum(__ball_index(map, fieldName)); let updated = (isInc ? __ball_add(current, 1) : __ball_sub(current, 1)); map[fieldName] = updated; return (isPre ? updated : current); } } let val = this._toNum(await this._evalExpression(valueExpr, scope)); let isInc = call.function.includes('increment'); return (isInc ? __ball_add(val, 1) : __ball_sub(val, 1)); } _applyCompoundOp(op: any, current: any, val: any): any { return ((op === '+=') ? ((((typeof current === 'string') || (typeof val === 'string')) ? (__ball_to_string((current ?? '')) + __ball_to_string((val ?? ''))) : this._numOp(current, val, ((a, b) => { return __ball_add(a, b); })))) : ((op === '-=') ? (this._numOp(current, val, ((a, b) => { return __ball_sub(a, b); }))) : ((op === '*=') ? (this._numOp(current, val, ((a, b) => { return __ball_mul(a, b); }))) : ((op === '/=') ? (new BallDouble(Number(this._toNum(current)) / Number(this._toNum(val)))) : ((op === '~/=') ? (this._intOp(current, val, ((a, b) => { return __ball_divide(a, b); }))) : ((op === '%=') ? (this._intOp(current, val, ((a, b) => { return __dart_mod(a, b); }))) : ((op === '&=') ? (this._intOp(current, val, ((a, b) => { return __ball_bitand(a, b); }))) : ((op === '|=') ? (this._intOp(current, val, ((a, b) => { return __ball_bitor(a, b); }))) : ((op === '^=') ? (this._intOp(current, val, ((a, b) => { return __ball_bitxor(a, b); }))) : ((op === '<<=') ? (this._intOp(current, val, ((a, b) => { return __ball_shl(a, b); }))) : ((op === '>>=') ? (this._intOp(current, val, ((a, b) => { return __ball_shr(a, b); }))) : ((op === '>>>=') ? (this._intOp(current, val, ((a, b) => { return __ball_ushr(a, b); }))) : ((op === '??=') ? ((current ?? val)) : val))))))))))))); } _numOp(a: any, b: any, op: any): any { return op(this._toNum(a), this._toNum(b)); } _intOp(a: any, b: any, op: any): any { return op(this._toInt(a), this._toInt(b)); } async _evalLabeled(call: any, scope: any): Promise { let fields = this._lazyFields(call); let label = this._stringFieldVal(fields, 'label'); let body = __ball_index(fields, 'body'); if (__ball_eq(body, null)) { return null; } if ((!__ball_eq(label, null) && !(label.length === 0))) { let loopCall = this._extractLoopFromBody(body); if (!__ball_eq(loopCall, null)) { let result = await this._evalLabeledLoop(loopCall, label, scope); if ((((result instanceof _FlowSignal) && (__ball_eq(result.kind, 'break') || __ball_eq(result.kind, 'continue'))) && __ball_eq(result.label, label))) { return null; } return result; } } let result = await this._evalExpression(body, scope); if ((((result instanceof _FlowSignal) && (__ball_eq(result.kind, 'break') || __ball_eq(result.kind, 'continue'))) && __ball_eq(result.label, label))) { return null; } return result; } _extractLoopFromBody(expr: any): any { const input = expr; if (__ball_eq(whichExpr(expr), Expression_Expr.call)) { let fn = expr.call.function; if ((((__ball_eq(fn, 'for') || __ball_eq(fn, 'while')) || __ball_eq(fn, 'for_in')) || __ball_eq(fn, 'do_while'))) { return expr.call; } } if ((__ball_eq(whichExpr(expr), Expression_Expr.block) && __ball_eq(expr.block.statements.length, 1))) { let stmt = __ball_index(expr.block.statements, 0); if ((__ball_eq(whichStmt(stmt), Statement_Stmt.expression) && __ball_eq(whichExpr(stmt.expression), Expression_Expr.call))) { let fn = stmt.expression.call.function; if ((((__ball_eq(fn, 'for') || __ball_eq(fn, 'while')) || __ball_eq(fn, 'for_in')) || __ball_eq(fn, 'do_while'))) { return stmt.expression.call; } } } } async _evalLabeledLoop(loopCall: any, label: any, scope: any): Promise { return ((loopCall.function === 'for') ? (this._evalLabeledFor(loopCall, label, scope)) : ((loopCall.function === 'for_in') ? (this._evalLabeledForIn(loopCall, label, scope)) : ((loopCall.function === 'while') ? (this._evalLabeledWhile(loopCall, label, scope)) : ((loopCall.function === 'do_while') ? (this._evalLabeledDoWhile(loopCall, label, scope)) : this._evalExpression((() => { let __cascade_self__ = { '__type': 'main:Expression' }; __cascade_self__.call = loopCall; return __cascade_self__; })(), scope))))); } async _evalLabeledFor(call: any, label: any, scope: any): Promise { let fields = this._lazyFields(call); let initExpr = __ball_index(fields, 'init'); let condition = __ball_index(fields, 'condition'); let update = __ball_index(fields, 'update'); let body = __ball_index(fields, 'body'); let forScope = scope.child(); let loopVars = []; if (!__ball_eq(initExpr, null)) { if (__ball_eq(whichExpr(initExpr), Expression_Expr.block)) { for (const stmt of initExpr.block.statements) { if (__ball_eq(whichStmt(stmt), Statement_Stmt.let)) { loopVars = (loopVars.push(stmt.let.name), loopVars); } await this._evalStatement(stmt, forScope); } } else { if ((__ball_eq(whichExpr(initExpr), Expression_Expr.literal) && hasStringValue(initExpr.literal))) { let s = initExpr.literal.stringValue; let match = new RegExp('(?:var|final|int|double|String)\\s+(\\w+)\\s*=\\s*(.+)').firstMatch(s); if (!__ball_eq(match, null)) { let varName = match.group(1); let rawVal = match.group(2).trim(); let parsed = ((int.tryParse(rawVal) ?? double.tryParse(rawVal)) ?? ((__ball_eq(rawVal, 'true') ? true : (__ball_eq(rawVal, 'false') ? false : rawVal)))); loopVars = (loopVars.push(varName), loopVars); forScope.bind(varName, parsed); } } else { await this._evalExpression(initExpr, forScope); } } } while (true) { let iterScope = forScope.child(); for (const v of loopVars) { iterScope.bind(v, forScope.lookup(v)); } if (!__ball_eq(condition, null)) { let condVal = await this._evalExpression(condition, iterScope); if (!this._toBool(condVal)) { break; } } if (!__ball_eq(body, null)) { let result = await this._evalExpression(body, iterScope); if ((result instanceof _FlowSignal)) { if (__ball_eq(result.kind, 'return')) { return result; } if (__ball_eq(result.label, label)) { if (__ball_eq(result.kind, 'break')) { break; } } else { if ((!__ball_eq(result.label, null) && !(result.label.length === 0))) { return result; } else { if (__ball_eq(result.kind, 'break')) { break; } } } } } for (const v of loopVars) { forScope.bind(v, iterScope.lookup(v)); } if (!__ball_eq(update, null)) { await this._evalExpression(update, forScope); } } } async _evalLabeledForIn(call: any, label: any, scope: any): Promise { let fields = this._lazyFields(call); let variable = (this._stringFieldVal(fields, 'variable') ?? 'item'); let iterable = __ball_index(fields, 'iterable'); let body = __ball_index(fields, 'body'); if ((__ball_eq(iterable, null) || __ball_eq(body, null))) { return null; } let iterVal = await this._evalExpression(iterable, scope); let items = this._toIterable(iterVal); for (const item of items) { let loopScope = scope.child(); loopScope.bind(variable, item); let result = await this._evalExpression(body, loopScope); if ((result instanceof _FlowSignal)) { if (__ball_eq(result.kind, 'return')) { return result; } if (__ball_eq(result.label, label)) { if (__ball_eq(result.kind, 'break')) { break; } if (__ball_eq(result.kind, 'continue')) { continue; } } if ((!__ball_eq(result.label, null) && !(result.label.length === 0))) { return result; } if (__ball_eq(result.kind, 'break')) { break; } } } } async _evalLabeledWhile(call: any, label: any, scope: any): Promise { let fields = this._lazyFields(call); let condition = __ball_index(fields, 'condition'); let body = __ball_index(fields, 'body'); while (true) { if (!__ball_eq(condition, null)) { let condVal = await this._evalExpression(condition, scope); if (!this._toBool(condVal)) { break; } } if (!__ball_eq(body, null)) { let result = await this._evalExpression(body, scope); if ((result instanceof _FlowSignal)) { if (__ball_eq(result.kind, 'return')) { return result; } if (__ball_eq(result.label, label)) { if (__ball_eq(result.kind, 'break')) { break; } if (__ball_eq(result.kind, 'continue')) { continue; } } if ((!__ball_eq(result.label, null) && !(result.label.length === 0))) { return result; } if (__ball_eq(result.kind, 'break')) { break; } } } } } async _evalLabeledDoWhile(call: any, label: any, scope: any): Promise { let fields = this._lazyFields(call); let body = __ball_index(fields, 'body'); let condition = __ball_index(fields, 'condition'); do { if (!__ball_eq(body, null)) { let result = await this._evalExpression(body, scope); if ((result instanceof _FlowSignal)) { if (__ball_eq(result.kind, 'return')) { return result; } if (__ball_eq(result.label, label)) { if (__ball_eq(result.kind, 'break')) { break; } if (__ball_eq(result.kind, 'continue')) { if (!__ball_eq(condition, null)) { let condVal = await this._evalExpression(condition, scope); if (!this._toBool(condVal)) { break; } } continue; } } if ((!__ball_eq(result.label, null) && !(result.label.length === 0))) { return result; } if (__ball_eq(result.kind, 'break')) { break; } } } if (!__ball_eq(condition, null)) { let condVal = await this._evalExpression(condition, scope); if (!this._toBool(condVal)) { break; } } else { break; } } while (true); } async _evalGoto(call: any, scope: any): Promise { let fields = this._lazyFields(call); let label = this._stringFieldVal(fields, 'label'); throw new _FlowSignal('goto', { label: label }); } _gotoSignalLabel(signal: any): any { const input = signal; if ((signal instanceof _FlowSignal)) { return (__ball_eq(signal.kind, 'goto') ? signal.label : null); } if ((typeof signal === 'string')) { return signal; } if (((typeof signal === 'object' && signal !== null && !Array.isArray(signal) && !(signal instanceof BallDouble) && !(signal instanceof Set)) && __ball_eq(__ball_index(signal, 'kind'), 'goto'))) { let l = __ball_index(signal, 'label'); return ((typeof l === 'string') ? l : null); } } async _evalLabel(call: any, scope: any): Promise { let fields = this._lazyFields(call); let label = this._stringFieldVal(fields, 'name'); let body = __ball_index(fields, 'body'); if (__ball_eq(body, null)) { return null; } let result; let repeat = true; while (repeat) { repeat = false; try { result = await this._evalExpression(body, scope); } catch (__ball_active_error) { const e = __ball_active_error; let signal = e; if (__ball_eq(this._gotoSignalLabel(signal), label)) { repeat = true; } else { throw __ball_active_error; } } if ((!repeat && __ball_eq(this._gotoSignalLabel(result), label))) { repeat = true; } } return result; } async _evalLazyCascade(call: any, scope: any): Promise { let fields = this._lazyFields(call); let targetExpr = __ball_index(fields, 'target'); if (__ball_eq(targetExpr, null)) { return null; } let target = await this._evalExpression(targetExpr, scope); if ((__ball_eq(call.function, 'null_aware_cascade') && __ball_eq(target, null))) { return null; } let cascadeScope = scope.child(); cascadeScope.bind('__cascade_self__', target); let sectionsExpr = __ball_index(fields, 'sections'); if (!__ball_eq(sectionsExpr, null)) { if ((__ball_eq(whichExpr(sectionsExpr), Expression_Expr.literal) && __ball_eq(whichValue(sectionsExpr.literal), Literal_Value.listValue))) { for (const section of sectionsExpr.literal.listValue.elements) { await this._evalExpression(section, cascadeScope); } } else { await this._evalExpression(sectionsExpr, cascadeScope); } } return target; } _evalAwaitFor(call: any, scope: any): any { return this._evalLazyForIn(call, scope); } async _evalYield(call: any, scope: any): Promise { let fields = this._lazyFields(call); let valueExpr = (__ball_index(fields, 'value') ?? __ball_index(fields, 'expression')); let val = (!__ball_eq(valueExpr, null) ? await this._evalExpression(valueExpr, scope) : (hasInput(call) ? await this._evalExpression(call.input, scope) : null)); if (scope.has('__generator__')) { let gen = scope.lookup('__generator__'); if ((gen instanceof BallGenerator)) { gen.yield_(val); return val; } } return val; } async _evalYieldEach(call: any, scope: any): Promise { let fields = this._lazyFields(call); let iterableExpr = ((__ball_index(fields, 'value') ?? __ball_index(fields, 'iterable')) ?? __ball_index(fields, 'expression')); let iterable = (!__ball_eq(iterableExpr, null) ? await this._evalExpression(iterableExpr, scope) : (hasInput(call) ? await this._evalExpression(call.input, scope) : null)); if (scope.has('__generator__')) { let gen = scope.lookup('__generator__'); if ((gen instanceof BallGenerator)) { if ((iterable instanceof BallGenerator)) { gen.yieldAll(iterable.values); } else { let items = this._toIterable(iterable); gen.yieldAll(items); } return iterable; } } return iterable; } async _dispatchBuiltinInstanceMethod(self: any, method: any, input: any): Promise { let inputMap = this._cfAsMap(input); let args = (inputMap ?? {}); let arg0 = (__ball_index(args, 'arg0') ?? __ball_index(args, 'value')); let wasBallList = false /* BallList is List in TS */; let unwrappedSelf; if (false /* BallList is List in TS */) { unwrappedSelf = self.items; } else { if ((typeof self === 'string')) { unwrappedSelf = self.value; } else { if (false /* BallMap is Map in TS */) { unwrappedSelf = self.entries; } else { if ((typeof self === 'number' || self instanceof BallDouble)) { unwrappedSelf = self; } else { if ((typeof self === 'number' && Number.isInteger(self))) { unwrappedSelf = self.value; } else { if ((typeof self === 'number' || self instanceof BallDouble)) { unwrappedSelf = self.value; } else { unwrappedSelf = self; } } } } } } if (_ballValueIsSet(unwrappedSelf)) { let items = this._ballSetItems(unwrappedSelf); do { const __sw = method; if ((__sw === 'add')) { if (items.includes(arg0)) { return false; } items = (items.push(arg0), items); return true; } else if ((__sw === 'remove')) { let had = items.includes(arg0); items.remove(arg0); return had; } else if ((__sw === 'addAll')) { for (const e of (this._stdAsList(arg0) ?? [])) { if (!items.includes(e)) { items = (items.push(e), items); } } return null; } else if ((__sw === 'contains')) { return items.includes(arg0); } else if ((__sw === 'union')) { let out = [items]; for (const e of (this._stdAsList(arg0) ?? [])) { if (!out.includes(e)) { out = (out.push(e), out); } } return this._ballSetOf(out); } else if ((__sw === 'intersection')) { let other = (this._stdAsList(arg0) ?? []); return this._ballSetOf(items.filter(((e) => { const input = e; return other.includes(e); }))); } else if ((__sw === 'difference')) { let other = (this._stdAsList(arg0) ?? []); return this._ballSetOf(items.filter(((e) => { const input = e; return !other.includes(e); }))); } else if ((__sw === 'toSet')) { return this._ballSetOf(items); } else if ((__sw === 'length')) { return items.length; } else if ((__sw === 'isEmpty')) { return (items.length === 0); } else if ((__sw === 'isNotEmpty')) { return !(items.length === 0); } else { return this._dispatchBuiltinInstanceMethod(items, method, input); } } while (false); } if (Array.isArray(unwrappedSelf)) { let self = unwrappedSelf; let _wrapList = ((result) => { const input = result; return (wasBallList ? result : result); }); do { const __sw = method; if ((__sw === 'length')) { return self.length; } else if ((__sw === 'isEmpty')) { return (self.length === 0); } else if ((__sw === 'isNotEmpty')) { return !(self.length === 0); } else if ((__sw === 'add')) { self = (self.push(arg0), self); return null; } else if ((__sw === 'removeLast')) { return self.pop(); } else if ((__sw === 'removeAt')) { return self.splice(this._toInt(arg0), 1)[0]; } else if ((__sw === 'insert')) { self = (self.splice(this._toInt(arg0), 0, __ball_index(args, 'arg1')), self); return null; } else if ((__sw === 'clear')) { self = (self.length = 0, self); return null; } else if ((__sw === 'contains')) { return self.includes(arg0); } else if ((__sw === 'indexOf')) { return self.indexOf(arg0); } else if ((__sw === 'join')) { let joinParts = []; for (const e of self) { joinParts = (joinParts.push(await this._ballToStringAsync(e)), joinParts); } return joinParts.join((!__ball_eq(arg0, null) ? __ball_to_string(arg0) : ', ')); } else if ((__sw === 'sublist')) { let end = __ball_index(args, 'arg1'); return _wrapList(self.slice(this._toInt(arg0), (!__ball_eq(end, null) ? this._toInt(end) : null))); } else if ((__sw === 'reversed')) { return _wrapList(this._manualReverse(self)); } else if ((__sw === 'sort')) { if ((typeof arg0 === 'function')) { let sorted = [...self]; for (let j = 1; __ball_lt(j, sorted.length); (j++)) { let key = __ball_index(sorted, j); let k = __ball_sub(j, 1); while (__ball_ge(k, 0)) { let r = arg0({ ['arg0']: __ball_index(sorted, k), ['arg1']: key, ['a']: __ball_index(sorted, k), ['b']: key, ['left']: __ball_index(sorted, k), ['right']: key }); if ((r != null)) { r = await r; } if (((typeof r === 'number' || r instanceof BallDouble) && __ball_gt(r, 0))) { sorted[__ball_add(k, 1)] = __ball_index(sorted, k); (k--); } else { break; } } sorted[__ball_add(k, 1)] = key; } self.setAll(0, sorted); return null; } let defaultSorted = [...self]; defaultSorted = [...defaultSorted].sort(((a, b) => { return (a < b ? -1 : a > b ? 1 : 0); })); self.setAll(0, defaultSorted); return null; } else if ((__sw === 'map')) { if ((typeof arg0 === 'function')) { let result = []; for (const item of self) { let r = arg0(item); if ((r != null)) { r = await r; } result = (result.push(r), result); } return _wrapList(result); } return (wasBallList ? self : self); } else if ((__sw === 'where') || (__sw === 'filter')) { if ((typeof arg0 === 'function')) { let result = []; for (const item of self) { let r = arg0(item); if ((r != null)) { r = await r; } if (__ball_eq(r, true)) { result = (result.push(item), result); } } return _wrapList(result); } return (wasBallList ? self : self); } else if ((__sw === 'forEach')) { if ((typeof arg0 === 'function')) { for (const item of self) { let r = arg0(item); if ((r != null)) { await r; } } } return null; } else if ((__sw === 'any')) { if ((typeof arg0 === 'function')) { for (const item of self) { let r = arg0(item); if ((r != null)) { r = await r; } if (__ball_eq(r, true)) { return true; } } return false; } return false; } else if ((__sw === 'every')) { if ((typeof arg0 === 'function')) { for (const item of self) { let r = arg0(item); if ((r != null)) { r = await r; } if (!__ball_eq(r, true)) { return false; } } return true; } return true; } else if ((__sw === 'reduce')) { if ((typeof arg0 === 'function')) { let seeded = false; let acc; for (const item of self) { if (!seeded) { acc = item; seeded = true; continue; } let r = arg0({ ['arg0']: acc, ['arg1']: item, ['a']: acc, ['b']: item, ['left']: acc, ['right']: item }); if ((r != null)) { r = await r; } acc = r; } if (!seeded) { throw { '__type__': 'StateError', 'message': 'No element' }; } return acc; } return null; } else if ((__sw === 'fold')) { if ((typeof __ball_index(args, 'arg1') === 'function')) { let fn = __ball_index(args, 'arg1'); let acc = arg0; for (const item of self) { let r = fn({ ['arg0']: acc, ['arg1']: item }); if ((r != null)) { r = await r; } acc = r; } return acc; } return arg0; } else if ((__sw === 'toList')) { return _wrapList([...self]); } else if ((__sw === 'toSet')) { return _wrapList([...self.toSet()]); } else if ((__sw === 'toString')) { let toStrParts = []; for (const e of self) { toStrParts = (toStrParts.push(await this._ballToStringAsync(e)), toStrParts); } return (('[' + __ball_to_string(toStrParts.join(', '))) + ']'); } else if ((__sw === 'filled')) { return _wrapList(List.filled(this._toInt(arg0), __ball_index(args, 'arg1'))); } else if ((__sw === 'union')) { let other = (false /* BallList is List in TS */ ? arg0.items : ((Array.isArray(arg0) ? arg0 : []))); let seen = {}; let result = []; for (const item of self) { if (!(item in __ball_require_map(seen, 'map_contains_key'))) { seen[item] = item; result = (result.push(item), result); } } for (const item of other) { if (!(item in __ball_require_map(seen, 'map_contains_key'))) { seen[item] = item; result = (result.push(item), result); } } return _wrapList(result); } else if ((__sw === 'intersection')) { let otherSet = ((false /* BallList is List in TS */ ? arg0.items : ((Array.isArray(arg0) ? arg0 : [])))).toSet(); return _wrapList([...self.filter(((x) => { const input = x; return otherSet.includes(x); }))]); } else if ((__sw === 'difference')) { let otherSet2 = ((false /* BallList is List in TS */ ? arg0.items : ((Array.isArray(arg0) ? arg0 : [])))).toSet(); return _wrapList([...self.filter(((x) => { const input = x; return !otherSet2.includes(x); }))]); } else if ((__sw === 'addAll')) { let other2 = (false /* BallList is List in TS */ ? arg0.items : ((Array.isArray(arg0) ? arg0 : []))); for (const item of other2) { if (!self.includes(item)) { self = (self.push(item), self); } } return null; } else if ((__sw === 'expand')) { if ((typeof arg0 === 'function')) { let result = []; for (const item of self) { let r = arg0(item); if ((r != null)) { r = await r; } if (false /* BallList is List in TS */) { __ball_push_all(result, r.items); } else { if (Array.isArray(r)) { __ball_push_all(result, r); } else { result = (result.push(r), result); } } } return _wrapList(result); } return (wasBallList ? self : self); } else if ((__sw === 'take')) { return _wrapList([...self.take(this._toInt(arg0))]); } else if ((__sw === 'skip')) { return _wrapList([...self.skip(this._toInt(arg0))]); } else if ((__sw === 'followedBy')) { let other3 = (false /* BallList is List in TS */ ? arg0.items : ((Array.isArray(arg0) ? arg0 : []))); return _wrapList((() => { const __r: any[] = []; for (const __e of self) { __r.push(__e); } for (const __e of other3) { __r.push(__e); } return __r; })()); } } while (false); } if ((unwrappedSelf instanceof Set)) { let self = unwrappedSelf; let selfList = [...self]; do { const __sw = method; if ((__sw === 'union')) { let otherU = ((arg0 instanceof Set) ? arg0 : ((Array.isArray(arg0) ? arg0.toSet() : new Set()))); return self.union(otherU); } else if ((__sw === 'intersection')) { let otherI = ((arg0 instanceof Set) ? arg0 : ((Array.isArray(arg0) ? arg0.toSet() : new Set()))); return self.intersection(otherI); } else if ((__sw === 'difference')) { let otherD = ((arg0 instanceof Set) ? arg0 : ((Array.isArray(arg0) ? arg0.toSet() : new Set()))); return self.difference(otherD); } else if ((__sw === 'add')) { self = (self.push(arg0), self); return null; } else if ((__sw === 'addAll')) { if (Array.isArray(arg0)) { __ball_push_all(self, arg0); } return null; } else if ((__sw === 'remove')) { self.remove(arg0); return null; } else if ((__sw === 'contains')) { return self.includes(arg0); } else if ((__sw === 'toList')) { return selfList; } else if ((__sw === 'toSet')) { return self; } else if ((__sw === 'length')) { return self.length; } else if ((__sw === 'isEmpty')) { return (self.length === 0); } else if ((__sw === 'isNotEmpty')) { return !(self.length === 0); } else if ((__sw === 'forEach')) { if ((typeof arg0 === 'function')) { for (const item of self) { let r = arg0(item); if ((r != null)) { await r; } } } return null; } else if ((__sw === 'map')) { if ((typeof arg0 === 'function')) { let result = []; for (const item of self) { let r = arg0(item); if ((r != null)) { r = await r; } result = (result.push(r), result); } return result; } return selfList; } else if ((__sw === 'where') || (__sw === 'filter')) { if ((typeof arg0 === 'function')) { let result = new Set(); for (const item of self) { let r = arg0(item); if ((r != null)) { r = await r; } if (__ball_eq(r, true)) { result = (result.push(item), result); } } return result; } return self; } } while (false); } if ((typeof unwrappedSelf === 'string')) { let self = unwrappedSelf; do { const __sw = method; if ((__sw === 'contains')) { return self.includes(__ball_to_string(arg0)); } else if ((__sw === 'substring')) { let end = __ball_index(args, 'arg1'); return self.substring(this._toInt(arg0), (!__ball_eq(end, null) ? this._toInt(end) : null)); } else if ((__sw === 'indexOf')) { return self.indexOf(__ball_to_string(arg0)); } else if ((__sw === 'split')) { return self.split(__ball_to_string(arg0)); } else if ((__sw === 'trim')) { return self.trim(); } else if ((__sw === 'toUpperCase')) { return self.toUpperCase(); } else if ((__sw === 'toLowerCase')) { return self.toLowerCase(); } else if ((__sw === 'replaceAll')) { return self.split(__ball_to_string(arg0)).join(__ball_to_string((__ball_index(args, 'arg1') ?? ''))); } else if ((__sw === 'startsWith')) { return self.startsWith(__ball_to_string(arg0)); } else if ((__sw === 'endsWith')) { return self.endsWith(__ball_to_string(arg0)); } else if ((__sw === 'padLeft')) { return self.padStart(this._toInt(arg0), ((() => { let __nac_13 = __ball_index(args, 'arg1'); return (__ball_eq(__nac_13, null) ? null : __nac_13.toString()); })() ?? ' ')); } else if ((__sw === 'padRight')) { return self.padEnd(this._toInt(arg0), ((() => { let __nac_14 = __ball_index(args, 'arg1'); return (__ball_eq(__nac_14, null) ? null : __nac_14.toString()); })() ?? ' ')); } else if ((__sw === 'toString')) { return self; } else if ((__sw === 'codeUnitAt')) { return _ballCodeUnitAt(self, this._toInt(arg0)); } else if ((__sw === 'compareTo')) { return (self < __ball_to_string(arg0) ? -1 : self > __ball_to_string(arg0) ? 1 : 0); } } while (false); } if ((typeof unwrappedSelf === 'number' || unwrappedSelf instanceof BallDouble)) { let self = unwrappedSelf; do { const __sw = method; if ((__sw === 'toDouble')) { return _ballToDouble(self); } else if ((__sw === 'toInt')) { return _ballDoubleToInt64(self); } else if ((__sw === 'toString')) { return await this._ballToStringAsync(self); } else if ((__sw === 'toStringAsFixed')) { return __ball_to_fixed(self, this._toInt(arg0)); } else if ((__sw === 'abs')) { return __ball_math_abs(self); } else if ((__sw === 'round')) { return Math.round(self); } else if ((__sw === 'floor')) { return Math.floor(self); } else if ((__sw === 'ceil')) { return Math.ceil(self); } else if ((__sw === 'compareTo')) { return (self < this._toNum(arg0) ? -1 : self > this._toNum(arg0) ? 1 : 0); } else if ((__sw === 'clamp')) { return Math.min(Math.max(self, this._toNum(arg0)), this._toNum((__ball_index(args, 'arg1') ?? self))); } else if ((__sw === 'truncate')) { return _ballDoubleToInt64(Math.trunc(self)); } else if ((__sw === 'remainder')) { return self.remainder(this._toNum(arg0)); } } while (false); } let selfMap = this._cfAsMap(self); if ((!__ball_eq(selfMap, null) && ('__type__' in __ball_require_map(selfMap, 'map_contains_key')))) { let typeName = __ball_index(selfMap, '__type__'); if ((!__ball_eq(typeName, null) && (typeName.endsWith(':StringBuffer') || __ball_eq(typeName, 'StringBuffer')))) { do { const __sw = method; if ((__sw === 'write')) { selfMap['__buffer__'] = __ball_add((__ball_index(selfMap, '__buffer__') ?? ''), await this._ballToStringAsync(arg0)); return null; } else if ((__sw === 'writeln')) { selfMap['__buffer__'] = __ball_add(__ball_add((__ball_index(selfMap, '__buffer__') ?? ''), await this._ballToStringAsync(arg0)), '\n'); return null; } else if ((__sw === 'writeCharCode')) { selfMap['__buffer__'] = __ball_add((__ball_index(selfMap, '__buffer__') ?? ''), String.fromCharCode(this._toInt(arg0))); return null; } else if ((__sw === 'toString')) { return (__ball_index(selfMap, '__buffer__') ?? ''); } else if ((__sw === 'clear')) { selfMap['__buffer__'] = ''; return null; } else if ((__sw === 'length')) { return (__ball_index(selfMap, '__buffer__') ?? '').length; } } while (false); } if (__ball_eq(method, 'toString')) { return await this._ballToStringAsync(self); } } return _sentinel; } _stdAsMap(v: any): any { const input = v; if (((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) && !(false /* BallMap is Map in TS */))) { if (__ball_is_type(v, "Map")) { return v; } return v.cast(); } if (false /* BallMap is Map in TS */) { return v.entries; } } _stdAsList(v: any): any { const input = v; if (false /* BallList is List in TS */) { return v.items; } if (this._isBallSet(v)) { return this._ballSetItems(v); } if (Array.isArray(v)) { return v; } } _isBallSet(v: any): any { const input = v; return ((v instanceof Set) || _ballValueIsSet(v)); } _ballSetItems(v: any): any { const input = v; if (_ballValueIsSet(v)) { let setMap = v; let raw = __ball_index(setMap, _kBallSetTag); if (false /* BallList is List in TS */) { return raw.items; } if (Array.isArray(raw)) { return raw; } return []; } if ((v instanceof Set)) { return [...v]; } return []; } _ballSetOf(items: any): any { const input = items; let result = []; for (const item of items) { if (!result.includes(item)) { result = (result.push(item), result); } } return { [_kBallSetTag]: result }; } async _tryOperatorOverride(function_: any, input: any): Promise { let op = __ball_index(_stdFunctionToOperator, function_); if (__ball_eq(op, null)) { return null; } let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return null; } let left; let right; if (__ball_eq(function_, 'index')) { left = __ball_index(m, 'target'); right = __ball_index(m, 'index'); } else { left = __ball_index(m, 'left'); right = __ball_index(m, 'right'); } let leftMap = this._stdAsMap(left); if ((__ball_eq(leftMap, null) || !('__type__' in __ball_require_map(leftMap, 'map_contains_key')))) { return null; } let typeName = __ball_index(leftMap, '__type__'); let colonIdx = typeName.indexOf(':'); let modPart = (__ball_ge(colonIdx, 0) ? typeName.substring(0, colonIdx) : this._currentModule); let current = leftMap; while (!__ball_eq(current, null)) { let curType = __ball_index(current, '__type__'); if (!__ball_eq(curType, null)) { let cColonIdx = curType.indexOf(':'); let cModPart = (__ball_ge(cColonIdx, 0) ? curType.substring(0, cColonIdx) : modPart); let cTypeName = (__ball_ge(cColonIdx, 0) ? curType : ((__ball_to_string(cModPart) + ':') + __ball_to_string(curType))); let opSymbol = __ball_index(_stdFunctionToOperatorSymbol, function_); let method = __ball_index(this._functions, ((((__ball_to_string(cModPart) + '.') + __ball_to_string(cTypeName)) + '.') + __ball_to_string(op))); method ??= (__ball_eq(opSymbol, null) ? null : __ball_index(this._functions, ((((__ball_to_string(cModPart) + '.') + __ball_to_string(cTypeName)) + '.') + __ball_to_string(opSymbol)))); if (!__ball_eq(method, null)) { let methodInput = { ['self']: left, ['other']: right, ['arg0']: right, ['right']: right }; return this._callFunction(cModPart, method, methodInput); } } current = this._stdAsMap(__ball_index(current, '__super__')); } } async _dispatchBuiltinClassMethod(className: any, method: any, args: any): Promise { do { const __sw = ((__ball_to_string(className) + '.') + __ball_to_string(method)); if ((__sw === 'List.generate')) { let count = (__ball_index(args, 'arg0') ?? __ball_index(args, 'count')); let generator = (__ball_index(args, 'arg1') ?? __ball_index(args, 'generator')); return this._callBaseFunction('std', 'dart_list_generate', { ['count']: count, ['generator']: generator }); } else if ((__sw === 'List.filled')) { let count = (__ball_index(args, 'arg0') ?? __ball_index(args, 'count')); let value = (__ball_index(args, 'arg1') ?? __ball_index(args, 'value')); return this._callBaseFunction('std', 'dart_list_filled', { ['count']: count, ['value']: value }); } else if ((__sw === 'List.of') || (__sw === 'List.from')) { let source = (__ball_index(args, 'arg0') ?? __ball_index(args, 'value')); let sourceList = this._stdAsList(source); if (!__ball_eq(sourceList, null)) { this._trackMemoryAllocation(__ball_mul(sourceList.length, _ballPointerBytes)); return [...sourceList]; } if ((source instanceof Set)) { this._trackMemoryAllocation(__ball_mul(source.length, _ballPointerBytes)); return [...source]; } if (Array.isArray(source)) { let result = [...source]; this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes)); return result; } return []; } else if ((__sw === 'Map.fromEntries')) { let list = (__ball_index(args, 'arg0') ?? __ball_index(args, 'list')); return this._callBaseFunction('std', 'map_from_entries', { ['list']: list }); } else { return _sentinel; } } while (false); } async _callBaseFunction(module: any, function_: any, input: any): Promise { if ((function_ in __ball_require_map(_stdFunctionToOperator, 'map_contains_key'))) { let override = await this._tryOperatorOverride(function_, input); if (!__ball_eq(override, null)) { return this._consumeGeneratorFlow(override); } } let handlerInput = (false /* BallMap is Map in TS */ ? input.entries : input); for (const handler of this.moduleHandlers) { if (handler.handles(module)) { let result = await handler.call(function_, handlerInput, this.callFunction.bind(this)); this._callCounts[function_] = __ball_add((__ball_index(this._callCounts, function_) ?? 0), 1); return this._consumeGeneratorFlow(result); } } throw new BallRuntimeError((('Unknown base module: "' + __ball_to_string(module)) + '"')); } _buildStdDispatch(): any { return { ['print']: this._stdPrint.bind(this), ['add']: this._stdAdd.bind(this), ['subtract']: ((i) => { const input = i; return this._stdBinary(i, ((a, b) => { return __ball_sub(a, b); })); }), ['multiply']: ((i) => { const input = i; let __ball_rec_0 = this._extractBinaryArgs(i); let l = __ball_rec_0[0]; let r = __ball_rec_0[1]; if ((typeof l === 'string')) { return this._repeatString(l, this._toInt(r)); } if ((typeof l === 'string')) { return this._repeatString(l.value, this._toInt(r)); } return this._stdBinary(i, ((a, b) => { return __ball_mul(a, b); })); }), ['divide']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_divide(a, b); })); }), ['divide_double']: ((i) => { const input = i; return this._stdBinaryDouble(i, ((a, b) => { return new BallDouble(Number(a) / Number(b)); })); }), ['modulo']: ((i) => { const input = i; return this._stdBinary(i, ((a, b) => { return __dart_mod(a, b); })); }), ['negate']: ((i) => { const input = i; return this._stdUnaryNum(i, ((v) => { const input = v; return __ball_negate(v); })); }), ['equals']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return __ball_eq(a, b); })); }), ['not_equals']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return !__ball_eq(a, b); })); }), ['less_than']: ((i) => { const input = i; return this._stdBinaryComp(i, ((a, b) => { return __ball_lt(a, b); })); }), ['greater_than']: ((i) => { const input = i; return this._stdBinaryComp(i, ((a, b) => { return __ball_gt(a, b); })); }), ['lte']: ((i) => { const input = i; return this._stdBinaryComp(i, ((a, b) => { return __ball_le(a, b); })); }), ['gte']: ((i) => { const input = i; return this._stdBinaryComp(i, ((a, b) => { return __ball_ge(a, b); })); }), ['and']: ((i) => { const input = i; return this._stdBinaryBool(i, ((a, b) => { return (a && b); })); }), ['or']: ((i) => { const input = i; return this._stdBinaryBool(i, ((a, b) => { return (a || b); })); }), ['not']: this._stdNot.bind(this), ['bitwise_and']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_bitand(a, b); })); }), ['bitwise_or']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_bitor(a, b); })); }), ['bitwise_xor']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_bitxor(a, b); })); }), ['bitwise_not']: ((i) => { const input = i; return this._stdUnaryNum(i, ((v) => { const input = v; return __ball_bitnot(v); })); }), ['left_shift']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_shl(a, b); })); }), ['right_shift']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_shr(a, b); })); }), ['unsigned_right_shift']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_ushr(a, b); })); }), ['pre_increment']: ((i) => { const input = i; return __ball_add(this._extractUnaryArg(i), 1); }), ['pre_decrement']: ((i) => { const input = i; return __ball_sub(this._extractUnaryArg(i), 1); }), ['post_increment']: ((i) => { const input = i; return __ball_add(this._extractUnaryArg(i), 1); }), ['post_decrement']: ((i) => { const input = i; return __ball_sub(this._extractUnaryArg(i), 1); }), ['concat']: this._stdConcat.bind(this), ['length']: this._stdLength.bind(this), ['to_string']: (async (i) => { const input = i; return await this._ballToStringAsync(this._extractUnaryArg(i)); }), ['int_to_string']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return __ball_to_string(v); })); }), ['double_to_string']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; if ((typeof v === 'number' || v instanceof BallDouble)) { return __ball_to_string(v); } return __ball_to_string(new BallDouble(v)); })); }), ['string_to_int']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return __ball_parse_int(v); })); }), ['string_to_double']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return __ball_parse_double(v); })); }), ['to_double']: ((i) => { const input = i; return _ballToDouble(this._extractUnaryArg(i)); }), ['to_int']: ((i) => { const input = i; return _ballDoubleToInt64(this._toNum(this._extractUnaryArg(i))); }), ['int_to_double']: ((i) => { const input = i; return _ballToDouble(this._extractUnaryArg(i)); }), ['double_to_int']: ((i) => { const input = i; return _ballDoubleToInt64(this._toNum(this._extractUnaryArg(i))); }), ['compare_to']: ((i) => { const input = i; let m = (this._stdAsMap(i) ?? { ['value']: i }); let v = (__ball_index(m, 'value') ?? __ball_index(m, 'left')); let other = (__ball_index(m, 'other') ?? __ball_index(m, 'right')); if (((typeof v === 'string') && (typeof other === 'string'))) { return (v < other ? -1 : v > other ? 1 : 0); } let a = this._toNum(v); let b = this._toNum(other); return (__ball_lt(a, b) ? __ball_negate(1) : ((__ball_gt(a, b) ? 1 : 0))); }), ['to_string_as_fixed']: ((i) => { const input = i; let m = (this._stdAsMap(i) ?? { ['value']: i }); let v = (__ball_index(m, 'value') ?? __ball_index(m, 'left')); let digits = (__ball_index(m, 'digits') ?? __ball_index(m, 'fractionDigits')); let n = this._toNum(v); let s = __ball_to_fixed(n, this._toInt(digits)); if (((__ball_eq(n, 0) && __ball_lt(new BallDouble(Number(new BallDouble(1)) / Number(n)), 0)) && !s.startsWith('-'))) { return ('-' + __ball_to_string(s)); } return s; }), ['to_string_as_exponential']: ((i) => { const input = i; let m = (this._stdAsMap(i) ?? { ['value']: i }); let v = (__ball_index(m, 'value') ?? __ball_index(m, 'left')); let digits = (__ball_index(m, 'digits') ?? __ball_index(m, 'fractionDigits')); let n = this._toNum(v); return (__ball_eq(digits, null) ? (+(n)).toExponential() : (+(n)).toExponential(this._toInt(digits))); }), ['to_string_as_precision']: ((i) => { const input = i; let m = (this._stdAsMap(i) ?? { ['value']: i }); let v = (__ball_index(m, 'value') ?? __ball_index(m, 'left')); let precision = (__ball_index(m, 'precision') ?? __ball_index(m, 'digits')); return (+(this._toNum(v))).toPrecision(this._toInt(precision)); }), ['string_interpolation']: (async (i) => { const input = i; let m = this._stdAsMap(i); if (!__ball_eq(m, null)) { let parts = this._stdAsList(__ball_index(m, 'parts')); if (!__ball_eq(parts, null)) { let strParts = []; for (const p of parts) { strParts = (strParts.push(await this._ballToStringAsync(p)), strParts); } let result = strParts.join(''); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; } let value = __ball_index(m, 'value'); if (!__ball_eq(value, null)) { let result = await this._ballToStringAsync(value); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; } } let result = await this._ballToStringAsync(i); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; }), ['null_coalesce']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return (a ?? b); })); }), ['null_check']: ((i) => { const input = i; let v = this._extractUnaryArg(i); if (__ball_eq(v, null)) { throw new BallRuntimeError('Null check operator used on a null value'); } return v; }), ['null_aware_access']: this._stdNullAwareAccess.bind(this), ['null_aware_call']: this._stdNullAwareCall.bind(this), ['if']: this._stdIf.bind(this), ['is']: this._stdTypeCheck.bind(this), ['is_not']: ((i) => { const input = i; return !this._stdTypeCheck(i); }), ['as']: this._extractUnaryArg.bind(this), ['index']: this._stdIndex.bind(this), ['cascade']: this._stdCascade.bind(this), ['null_aware_cascade']: this._stdNullAwareCascade.bind(this), ['spread']: this._extractUnaryArg.bind(this), ['null_spread']: this._extractUnaryArg.bind(this), ['invoke']: this._stdInvoke.bind(this), ['tear_off']: ((i) => { const input = i; let m = this._stdAsMap(i); if (!__ball_eq(m, null)) { return (__ball_index(m, 'callback') ?? __ball_index(m, 'method')); } return i; }), ['list_generate']: this._stdListGenerate.bind(this), ['dart_list_generate']: this._stdListGenerate.bind(this), ['list_filled']: this._stdListFilled.bind(this), ['typed_list']: ((i) => { const input = i; let m = this._stdAsMap(i); if (__ball_eq(m, null)) { return []; } let raw = __ball_index(m, 'elements'); return (this._stdAsList(raw) ?? []); }), ['dart_list_filled']: this._stdListFilled.bind(this), ['map_create']: this._stdMapCreate.bind(this), ['set_create']: this._stdSetCreate.bind(this), ['record']: this._stdRecord.bind(this), ['collection_if']: this._collectionMisuse.bind(this), ['collection_for']: this._collectionMisuse.bind(this), ['list_push']: ((i) => { const input = i; let m = this._stdAsMap(i); let raw = __ball_index(m, 'list'); if (this._isBallSet(raw)) { let items = this._ballSetItems(raw); let value = __ball_index(m, 'value'); if (!items.includes(value)) { this._trackMemoryAllocation(_ballPointerBytes); return this._ballSetOf([items, value]); } return this._ballSetOf(items); } let list = (this._stdAsList(raw) ?? []); this._trackMemoryAllocation(_ballPointerBytes); list = (list.push(__ball_index(m, 'value')), list); return list; }), ['list_pop']: ((i) => { const input = i; let list = this._stdAsList(__ball_index(this._stdAsMap(i), 'list')); if ((list.length === 0)) { throw new BallRuntimeError('pop on empty list'); } return list.pop(); }), ['list_insert']: ((i) => { const input = i; let m = this._stdAsMap(i); let list = [...this._stdAsList(__ball_index(m, 'list'))]; this._trackMemoryAllocation(__ball_mul(__ball_add(list.length, 1), _ballPointerBytes)); list = (list.splice(this._toInt(__ball_index(m, 'index')), 0, __ball_index(m, 'value')), list); return list; }), ['list_remove_at']: ((i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); return list.splice(this._toInt(__ball_index(m, 'index')), 1)[0]; }), ['list_get']: ((i) => { const input = i; let m = this._stdAsMap(i); return __ball_index(this._stdAsList(__ball_index(m, 'list')), this._toInt(__ball_index(m, 'index'))); }), ['list_set']: ((i) => { const input = i; let m = this._stdAsMap(i); let list = [...this._stdAsList(__ball_index(m, 'list'))]; this._trackMemoryAllocation(__ball_mul(list.length, _ballPointerBytes)); list[this._toInt(__ball_index(m, 'index'))] = __ball_index(m, 'value'); return list; }), ['list_length']: ((i) => { const input = i; return this._stdAsList(__ball_index(this._stdAsMap(i), 'list')).length; }), ['list_is_empty']: ((i) => { const input = i; return (this._stdAsList(__ball_index(this._stdAsMap(i), 'list')).length === 0); }), ['list_first']: ((i) => { const input = i; return this._stdAsList(__ball_index(this._stdAsMap(i), 'list')).first; }), ['list_last']: ((i) => { const input = i; return this._stdAsList(__ball_index(this._stdAsMap(i), 'list')).last; }), ['list_single']: ((i) => { const input = i; return this._stdAsList(__ball_index(this._stdAsMap(i), 'list')).single; }), ['list_contains']: ((i) => { const input = i; let m = this._stdAsMap(i); let collection = __ball_index(m, 'list'); if ((typeof collection === 'string')) { return collection.includes(__ball_to_string(__ball_index(m, 'value'))); } let collectionList = this._stdAsList(collection); if (!__ball_eq(collectionList, null)) { return collectionList.includes(__ball_index(m, 'value')); } if ((collection instanceof Set)) { return collection.includes(__ball_index(m, 'value')); } return false; }), ['list_index_of']: ((i) => { const input = i; let m = this._stdAsMap(i); let coll = __ball_index(m, 'list'); let needle = __ball_index(m, 'value'); if (((typeof coll === 'string') || (typeof coll === 'string'))) { let s = ((typeof coll === 'string') ? coll.value : coll); let n = ((typeof needle === 'string') ? needle.value : needle); return s.indexOf(n); } return this._stdAsList(coll).indexOf(needle); }), ['list_map']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let cb = ((__ball_index(m, 'callback') ?? __ball_index(m, 'function')) ?? __ball_index(m, 'value')); let result = []; this._trackMemoryAllocation(__ball_mul(list.length, _ballPointerBytes)); for (const e of list) { let v = cb(e); if ((v != null)) { v = await v; } result = (result.push(v), result); } return result; }), ['list_filter']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let cb = ((__ball_index(m, 'callback') ?? __ball_index(m, 'function')) ?? __ball_index(m, 'value')); let result = []; this._trackMemoryAllocation(__ball_mul(list.length, _ballPointerBytes)); for (const e of list) { let v = cb(e); if ((v != null)) { v = await v; } if (__ball_eq(v, true)) { result = (result.push(e), result); } } return result; }), ['list_reduce']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let cb = ((__ball_index(m, 'callback') ?? __ball_index(m, 'function')) ?? __ball_index(m, 'value')); let seeded = false; let acc; for (const e of list) { if (!seeded) { acc = e; seeded = true; continue; } let v = cb({ ['arg0']: acc, ['arg1']: e, ['a']: acc, ['b']: e, ['left']: acc, ['right']: e }); if ((v != null)) { v = await v; } acc = v; } if (!seeded) { throw { '__type__': 'StateError', 'message': 'No element' }; } return acc; }), ['list_find']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let cb = ((__ball_index(m, 'callback') ?? __ball_index(m, 'function')) ?? __ball_index(m, 'value')); for (const e of list) { let v = cb(e); if ((v != null)) { v = await v; } if (__ball_eq(v, true)) { return e; } } throw { '__type__': 'StateError', 'message': 'No element' }; }), ['list_any']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let cb = ((__ball_index(m, 'callback') ?? __ball_index(m, 'function')) ?? __ball_index(m, 'value')); for (const e of list) { let v = cb(e); if ((v != null)) { v = await v; } if (__ball_eq(v, true)) { return true; } } return false; }), ['list_all']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let cb = ((__ball_index(m, 'callback') ?? __ball_index(m, 'function')) ?? __ball_index(m, 'value')); for (const e of list) { let v = cb(e); if ((v != null)) { v = await v; } if (!__ball_eq(v, true)) { return false; } } return true; }), ['list_none']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let cb = ((__ball_index(m, 'callback') ?? __ball_index(m, 'function')) ?? __ball_index(m, 'value')); for (const e of list) { let v = cb(e); if ((v != null)) { v = await v; } if (__ball_eq(v, true)) { return false; } } return true; }), ['list_sort']: (async (i) => { const input = i; let m = this._stdAsMap(i); let sorted = [...this._stdAsList(__ball_index(m, 'list'))]; this._trackMemoryAllocation(__ball_mul(sorted.length, _ballPointerBytes)); let cb = (((__ball_index(m, 'callback') ?? __ball_index(m, 'comparator')) ?? __ball_index(m, 'compare')) ?? __ball_index(m, 'value')); if ((__ball_eq(cb, null) || !((typeof cb === 'function')))) { sorted = [...sorted].sort(((a, b) => { return (a < b ? -1 : a > b ? 1 : 0); })); return sorted; } for (let j = 1; __ball_lt(j, sorted.length); (j++)) { let key = __ball_index(sorted, j); let k = __ball_sub(j, 1); while (__ball_ge(k, 0)) { let r = cb({ ['left']: __ball_index(sorted, k), ['right']: key, ['arg0']: __ball_index(sorted, k), ['arg1']: key, ['a']: __ball_index(sorted, k), ['b']: key }); if ((r != null)) { r = await r; } let cmp = ((typeof r === 'number' && Number.isInteger(r)) ? r : __ball_to_int(r)); if (__ball_le(cmp, 0)) { break; } sorted[__ball_add(k, 1)] = __ball_index(sorted, k); (k--); } sorted[__ball_add(k, 1)] = key; } return sorted; }), ['list_sort_by']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = [...this._stdAsList(__ball_index(m, 'list'))]; this._trackMemoryAllocation(__ball_mul(list.length, _ballPointerBytes)); let cb = __ball_index(m, 'callback'); let keys = []; for (const e of list) { let k = cb(e); if ((k != null)) { k = await k; } keys = (keys.push(k), keys); } this._trackMemoryAllocation(__ball_mul(list.length, _ballPointerBytes)); let indices = List.generate(list.length, ((i) => { const input = i; return i; })); indices = [...indices].sort(((a, b) => { return (__ball_index(keys, a) < __ball_index(keys, b) ? -1 : __ball_index(keys, a) > __ball_index(keys, b) ? 1 : 0); })); this._trackMemoryAllocation(__ball_mul(indices.length, _ballPointerBytes)); return (() => { const __r: any[] = []; for (const idx of indices) { __r.push(__ball_index(list, idx)); } return __r; })(); }), ['list_reverse']: ((i) => { const input = i; return this._trackListCopy(this._manualReverse(this._stdAsList(__ball_index(this._stdAsMap(i), 'list')))); }), ['list_slice']: ((i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let s; let e; if (('start' in __ball_require_map(m, 'map_contains_key'))) { s = this._toInt(__ball_index(m, 'start')); e = (!__ball_eq(__ball_index(m, 'end'), null) ? this._toInt(__ball_index(m, 'end')) : null); } else { if ((('arg0' in __ball_require_map(m, 'map_contains_key')) && ('arg1' in __ball_require_map(m, 'map_contains_key')))) { s = this._toInt(__ball_index(m, 'arg0')); e = this._toInt(__ball_index(m, 'arg1')); } else { if (('value' in __ball_require_map(m, 'map_contains_key'))) { let v = __ball_index(m, 'value'); if ((Array.isArray(v) && __ball_ge(v.length, 2))) { s = this._toInt(__ball_index(v, 0)); e = this._toInt(__ball_index(v, 1)); } else { s = this._toInt(v); e = null; } } else { s = 0; e = null; } } } let result = list.slice(s, (e ?? list.length)); this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes)); return result; }), ['list_flat_map']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let cb = ((__ball_index(m, 'callback') ?? __ball_index(m, 'function')) ?? __ball_index(m, 'value')); let result = []; this._trackMemoryAllocation(__ball_mul(list.length, _ballPointerBytes)); for (const e of list) { let r = cb(e); if ((r != null)) { r = await r; } if (false /* BallList is List in TS */) { for (const item of r.items) { result = (result.push(item), result); } } else { if (Array.isArray(r)) { __ball_push_all(result, r); } else { result = (result.push(r), result); } } } return result; }), ['list_zip']: ((i) => { const input = i; let m = this._stdAsMap(i); let a = this._stdAsList(__ball_index(m, 'list')); let b = this._stdAsList(__ball_index(m, 'value')); let len = (__ball_lt(a.length, b.length) ? a.length : b.length); this._trackMemoryAllocation(__ball_mul(len, _ballPointerBytes)); return List.generate(len, ((j) => { const input = j; this._trackMemoryAllocation(__ball_mul(2, _ballPointerBytes)); return [__ball_index(a, j), __ball_index(b, j)]; })); }), ['list_take']: ((i) => { const input = i; let m = this._stdAsMap(i); let result = [...this._stdAsList(__ball_index(m, 'list')).take(this._toInt((__ball_index(m, 'value') ?? __ball_index(m, 'index'))))]; this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes)); return result; }), ['list_drop']: ((i) => { const input = i; let m = this._stdAsMap(i); let result = [...this._stdAsList(__ball_index(m, 'list')).skip(this._toInt((__ball_index(m, 'value') ?? __ball_index(m, 'index'))))]; this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes)); return result; }), ['list_concat']: ((i) => { const input = i; let m = this._stdAsMap(i); if (this._isBallSet(__ball_index(m, 'list'))) { return this._ballSetOf([this._ballSetItems(__ball_index(m, 'list')), (this._stdAsList(__ball_index(m, 'value')) ?? [])]); } let result = (() => { const __r: any[] = []; for (const __e of this._stdAsList(__ball_index(m, 'list'))) { __r.push(__e); } for (const __e of this._stdAsList(__ball_index(m, 'value'))) { __r.push(__e); } return __r; })(); this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes)); return result; }), ['list_clear']: ((i) => { const input = i; let m = this._stdAsMap(i); let raw = __ball_index(m, 'list'); if (this._isBallSet(raw)) { (this._ballSetItems(raw).length = 0, this._ballSetItems(raw)); return raw; } let list = this._stdAsList(raw); if (!__ball_eq(list, null)) { list = (list.length = 0, list); return list; } return []; }), ['list_to_list']: ((i) => { const input = i; let raw = __ball_index(this._stdAsMap(i), 'list'); let list = this._stdAsList(raw); if (!__ball_eq(list, null)) { this._trackMemoryAllocation(__ball_mul(list.length, _ballPointerBytes)); return [...list]; } if ((raw instanceof Set)) { this._trackMemoryAllocation(__ball_mul(raw.length, _ballPointerBytes)); return [...raw]; } return []; }), ['list_foreach']: (async (i) => { const input = i; let m = this._stdAsMap(i); let collection = __ball_index(m, 'list'); let fn = ((__ball_index(m, 'function') ?? __ball_index(m, 'value')) ?? __ball_index(m, 'callback')); if ((typeof fn === 'function')) { let listVal = this._stdAsList(collection); if (!__ball_eq(listVal, null)) { for (const item of listVal) { let r = fn(item); if ((r != null)) { await r; } } } else { if ((typeof collection === 'object' && collection !== null && !Array.isArray(collection) && !(collection instanceof BallDouble) && !(collection instanceof Set))) { for (const entry of collection.entries) { let r = fn({ ['key']: entry.key, ['value']: entry.value, ['arg0']: entry.key, ['arg1']: entry.value }); if ((r != null)) { await r; } } } else { if (false /* BallMap is Map in TS */) { for (const entry of collection.entries.entries) { let r = fn({ ['key']: entry.key, ['value']: entry.value, ['arg0']: entry.key, ['arg1']: entry.value }); if ((r != null)) { await r; } } } else { if ((collection instanceof Set)) { for (const item of collection) { let r = fn(item); if ((r != null)) { await r; } } } } } } } }), ['list_join']: (async (i) => { const input = i; let m = this._stdAsMap(i); let list = this._stdAsList(__ball_index(m, 'list')); let sep = ((() => { let __nac_15 = __ball_index(m, 'separator'); return (__ball_eq(__nac_15, null) ? null : __nac_15.toString()); })() ?? ','); let parts = []; for (const e of list) { parts = (parts.push(await this._ballToStringAsync(e)), parts); } return parts.join(sep); }), ['map_get']: ((i) => { const input = i; let m = this._stdAsMap(i); let raw = __ball_index(m, 'map'); let map = (false /* BallMap is Map in TS */ ? raw.entries : (((typeof raw === 'object' && raw !== null && !Array.isArray(raw) && !(raw instanceof BallDouble) && !(raw instanceof Set)) ? raw : {}))); return __ball_index(map, __ball_index(m, 'key')); }), ['map_set']: ((i) => { const input = i; let m = this._stdAsMap(i); let raw = __ball_index(m, 'map'); if (!_ballMapContainsKeyDyn(raw, __ball_index(m, 'key'))) { this._trackMemoryAllocation(_ballMapEntryBytes); } _ballMapSetDyn(raw, __ball_index(m, 'key'), __ball_index(m, 'value')); return raw; }), ['map_delete']: ((i) => { const input = i; let m = this._stdAsMap(i); let raw = __ball_index(m, 'map'); let map = (false /* BallMap is Map in TS */ ? raw.entries : (((typeof raw === 'object' && raw !== null && !Array.isArray(raw) && !(raw instanceof BallDouble) && !(raw instanceof Set)) ? raw : {}))); map.remove(__ball_index(m, 'key')); return map; }), ['map_contains_key']: ((i) => { const input = i; let m = this._stdAsMap(i); let target = __ball_index(m, 'map'); if (this._isBallSet(target)) { return this._ballSetItems(target).includes(__ball_index(m, 'key')); } if (((typeof target === 'object' && target !== null && !Array.isArray(target) && !(target instanceof BallDouble) && !(target instanceof Set)) || false /* BallMap is Map in TS */)) { return _ballMapContainsKeyDyn(target, __ball_index(m, 'key')); } throw new BallRuntimeError('map_contains_key: expected Map or Set'); }), ['map_contains_value']: ((i) => { const input = i; let m = this._stdAsMap(i); let raw = __ball_index(m, 'map'); let map = (false /* BallMap is Map in TS */ ? raw.entries : (((typeof raw === 'object' && raw !== null && !Array.isArray(raw) && !(raw instanceof BallDouble) && !(raw instanceof Set)) ? raw : {}))); return Object.values(__ball_require_map(map, 'map_contains_value')).includes(__ball_index(m, 'value')); }), ['map_put_if_absent']: ((i) => { const input = i; let m = this._stdAsMap(i); let map = (this._stdAsMap(__ball_index(m, 'map')) ?? __ball_index(m, 'map')); let key = __ball_index(m, 'key'); if (!(key in __ball_require_map(map, 'map_contains_key'))) { this._trackMemoryAllocation(_ballMapEntryBytes); let val = __ball_index(m, 'value'); map[key] = ((typeof val === 'function') ? val() : val); } return __ball_index(map, key); }), ['map_keys']: ((i) => { const input = i; let m = this._stdAsMap(i); let target = __ball_index(m, 'map'); if (this._isBallSet(target)) { return []; } if ((!((typeof target === 'object' && target !== null && !Array.isArray(target) && !(target instanceof BallDouble) && !(target instanceof Set))) && !(false /* BallMap is Map in TS */))) { throw new BallRuntimeError('map_keys: expected Map or Set'); } let result = _ballMapKeysDyn(target); this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes)); return result; }), ['map_values']: ((i) => { const input = i; let m = this._stdAsMap(i); let target = __ball_index(m, 'map'); if (this._isBallSet(target)) { return []; } if ((!((typeof target === 'object' && target !== null && !Array.isArray(target) && !(target instanceof BallDouble) && !(target instanceof Set))) && !(false /* BallMap is Map in TS */))) { throw new BallRuntimeError('map_values: expected Map or Set'); } let result = _ballMapValuesDyn(target); this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes)); return result; }), ['map_entries']: ((i) => { const input = i; let map = (this._stdAsMap(__ball_index(this._stdAsMap(i), 'map')) ?? __ball_index(this._stdAsMap(i), 'map')); this._trackMemoryAllocation(__ball_mul(map.length, __ball_add(_ballPointerBytes, _ballMapEntryBytes))); return [...map.entries.map(((e) => { const input = e; return { ['key']: e.key, ['value']: e.value }; }))]; }), ['map_from_entries']: ((i) => { const input = i; let list = this._stdAsList(__ball_index(this._stdAsMap(i), 'list')); this._trackMemoryAllocation(__ball_mul(list.length, _ballMapEntryBytes)); let result = {}; for (const e of list) { let eMap = this._stdAsMap(e); if (!__ball_eq(eMap, null)) { let k = (__ball_index(eMap, 'key') ?? __ball_index(eMap, 'arg0')); let v = (__ball_index(eMap, 'value') ?? __ball_index(eMap, 'arg1')); if (!__ball_eq(k, null)) { result[__ball_to_string(k)] = v; } } else { if ((typeof e === 'object' && e !== null && !Array.isArray(e) && !(e instanceof BallDouble) && !(e instanceof Set))) { let k = (__ball_index(e, 'key') ?? __ball_index(e, 'arg0')); let v = (__ball_index(e, 'value') ?? __ball_index(e, 'arg1')); if (!__ball_eq(k, null)) { result[__ball_to_string(k)] = v; } } } } return result; }), ['map_merge']: ((i) => { const input = i; let m = this._stdAsMap(i); let map1 = (this._stdAsMap(__ball_index(m, 'map')) ?? __ball_index(m, 'map')); let map2 = (this._stdAsMap(__ball_index(m, 'value')) ?? __ball_index(m, 'value')); let result = (() => { const __r: any = {}; { const __m = map1.cast(); for (const __k in __m) { __r[__k] = __m[__k]; } } { const __m = map2.cast(); for (const __k in __m) { __r[__k] = __m[__k]; } } return __r; })(); this._trackMemoryAllocation(__ball_mul(result.length, _ballMapEntryBytes)); return result; }), ['map_map']: (async (i) => { const input = i; let m = this._stdAsMap(i); let map = (this._stdAsMap(__ball_index(m, 'map')) ?? __ball_index(m, 'map')); let cb = __ball_index(m, 'callback'); let result = {}; this._trackMemoryAllocation(__ball_mul(map.length, _ballMapEntryBytes)); for (const entry of map.entries) { let r = cb({ ['key']: entry.key, ['value']: entry.value }); if ((r != null)) { r = await r; } let rMap = this._stdAsMap(r); if (!__ball_eq(rMap, null)) { result[__ball_index(rMap, 'key')] = __ball_index(rMap, 'value'); } else { result[entry.key] = r; } } return result; }), ['map_filter']: (async (i) => { const input = i; let m = this._stdAsMap(i); let map = (this._stdAsMap(__ball_index(m, 'map')) ?? __ball_index(m, 'map')); let cb = __ball_index(m, 'callback'); let result = {}; this._trackMemoryAllocation(__ball_mul(map.length, _ballMapEntryBytes)); for (const entry of map.entries) { let v = cb({ ['key']: entry.key, ['value']: entry.value }); if ((v != null)) { v = await v; } if (__ball_eq(v, true)) { result[entry.key] = entry.value; } } return result; }), ['map_is_empty']: ((i) => { const input = i; let map = (this._stdAsMap(__ball_index(this._stdAsMap(i), 'map')) ?? __ball_index(this._stdAsMap(i), 'map')); return (map.length === 0); }), ['map_length']: ((i) => { const input = i; let map = (this._stdAsMap(__ball_index(this._stdAsMap(i), 'map')) ?? __ball_index(this._stdAsMap(i), 'map')); return map.length; }), ['string_join']: ((i) => { const input = i; let m = this._stdAsMap(i); let result = this._stdAsList(__ball_index(m, 'list')).map(((e) => { const input = e; return __ball_to_string(e); })).join((__ball_index(m, 'separator') ?? '')); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; }), ['set_add']: ((i) => { const input = i; let m = this._stdAsMap(i); let items = this._ballSetItems(__ball_index(m, 'set')); let value = __ball_index(m, 'value'); if (!items.includes(value)) { this._trackMemoryAllocation(_ballPointerBytes); return this._ballSetOf([items, value]); } return this._ballSetOf(items); }), ['set_remove']: ((i) => { const input = i; let m = this._stdAsMap(i); let items = this._ballSetItems(__ball_index(m, 'set')); let value = __ball_index(m, 'value'); let kept = []; for (const e of items) { if (!__ball_eq(e, value)) { kept = (kept.push(e), kept); } } return this._ballSetOf(kept); }), ['set_contains']: ((i) => { const input = i; let m = this._stdAsMap(i); return this._ballSetItems(__ball_index(m, 'set')).includes(__ball_index(m, 'value')); }), ['set_union']: ((i) => { const input = i; let m = this._stdAsMap(i); return this._ballSetOf([this._ballSetItems(__ball_index(m, 'left')), this._ballSetItems(__ball_index(m, 'right'))]); }), ['set_intersection']: ((i) => { const input = i; let m = this._stdAsMap(i); let right = this._ballSetItems(__ball_index(m, 'right')); let result = []; for (const e of this._ballSetItems(__ball_index(m, 'left'))) { if (right.includes(e)) { result = (result.push(e), result); } } return this._ballSetOf(result); }), ['set_difference']: ((i) => { const input = i; let m = this._stdAsMap(i); let right = this._ballSetItems(__ball_index(m, 'right')); let result = []; for (const e of this._ballSetItems(__ball_index(m, 'left'))) { if (!right.includes(e)) { result = (result.push(e), result); } } return this._ballSetOf(result); }), ['set_length']: ((i) => { const input = i; return this._ballSetItems(__ball_index(this._stdAsMap(i), 'set')).length; }), ['set_is_empty']: ((i) => { const input = i; return (this._ballSetItems(__ball_index(this._stdAsMap(i), 'set')).length === 0); }), ['set_to_list']: ((i) => { const input = i; return [this._ballSetItems(__ball_index(this._stdAsMap(i), 'set'))]; }), ['switch_expr']: this._stdSwitchExpr.bind(this), ['throw']: ((i) => { const input = i; let val = this._extractUnaryArg(i); let typeName = 'Exception'; let valMap = this._stdAsMap(val); if (!__ball_eq(valMap, null)) { typeName = ((__ball_index(valMap, '__type__') ?? __ball_index(valMap, '__type')) ?? 'Exception'); if ((!('message' in __ball_require_map(valMap, 'map_contains_key')) && ('arg0' in __ball_require_map(valMap, 'map_contains_key')))) { valMap['message'] = __ball_index(valMap, 'arg0'); } } throw new BallException(typeName, val); }), ['rethrow']: ((_) => { const input = _; let ex = this._activeException; if (__ball_eq(ex, null)) { throw new BallRuntimeError('rethrow outside of catch'); } throw ex; }), ['paren']: ((i) => { const input = i; return this._extractUnaryArg(i); }), ['assert']: this._stdAssert.bind(this), ['await']: (async (i) => { const input = i; let val = this._extractUnaryArg(i); if ((val != null)) { val = await val; } if (_isBallFuture(val)) { return _unwrapBallFuture(val); } return val; }), ['yield']: (function*(i) { const input = i; return new _FlowSignal('yield', { value: this._extractUnaryArg(i) }); }), ['yield_each']: ((i) => { const input = i; return new _FlowSignal('yield_each', { value: this._extractUnaryArg(i) }); }), ['symbol']: ((i) => { const input = i; let name = this._extractField(i, 'value'); return (('Symbol("' + __ball_to_string(name)) + '")'); }), ['type_literal']: ((i) => { const input = i; return this._extractField(i, 'type'); }), ['labeled']: ((_) => { const input = _; return null; }), ['string_length']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return v.length; })); }), ['string_is_empty']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; if ((typeof v === 'string')) { return (v.length === 0); } if ((typeof v === 'string')) { return (v.value.length === 0); } let l = this._stdAsList(v); if (!__ball_eq(l, null)) { return (l.length === 0); } let m = this._stdAsMap(v); if (!__ball_eq(m, null)) { return (m.length === 0); } if ((v instanceof Set)) { return (v.length === 0); } if (Array.isArray(v)) { return (v.length === 0); } return (v.length === 0); })); }), ['string_concat']: this._stdConcat.bind(this), ['string_contains']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return a.includes(b); })); }), ['string_starts_with']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return a.startsWith(b); })); }), ['string_ends_with']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return a.endsWith(b); })); }), ['string_index_of']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return a.indexOf(b); })); }), ['string_last_index_of']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return a.lastIndexOf(b); })); }), ['string_substring']: this._stdStringSubstring.bind(this), ['string_char_at']: this._stdStringCharAt.bind(this), ['string_char_code_at']: this._stdStringCharCodeAt.bind(this), ['string_code_unit_at']: this._stdStringCharCodeAt.bind(this), ['string_from_char_code']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return String.fromCharCode(v); })); }), ['string_to_upper']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return v.toUpperCase(); })); }), ['string_to_lower']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return v.toLowerCase(); })); }), ['string_trim']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return v.trim(); })); }), ['string_trim_start']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return v.trimStart(); })); }), ['string_trim_end']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return v.trimEnd(); })); }), ['string_replace']: ((i) => { const input = i; return this._stdStringReplace(i, false); }), ['string_replace_all']: ((i) => { const input = i; return this._stdStringReplace(i, true); }), ['string_split']: ((i) => { const input = i; let m = this._stdAsMap(i); if (!__ball_eq(m, null)) { let str = (((__ball_index(m, 'string') ?? __ball_index(m, 'value')) ?? __ball_index(m, 'left')) ?? ''); let delim = (((__ball_index(m, 'delimiter') ?? __ball_index(m, 'separator')) ?? __ball_index(m, 'right')) ?? ''); let result = str.split(delim); this._trackMemoryAllocation(__ball_add(__ball_mul(result.length, _ballPointerBytes), __ball_mul(result.fold(0, ((sum, part) => { return __ball_add(sum, part.length); })), _ballStringCodeUnitBytes))); return result; } return []; }), ['string_runes']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return [...Array.from(v).map((c) => c.codePointAt(0))]; })); }), ['string_repeat']: this._stdStringRepeat.bind(this), ['string_pad_left']: ((i) => { const input = i; return this._stdStringPad(i, true); }), ['string_pad_right']: ((i) => { const input = i; return this._stdStringPad(i, false); }), ['regex_match']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return new RegExp(b).hasMatch(a); })); }), ['regex_find']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { let __nac_16 = new RegExp(b).firstMatch(a); return (__ball_eq(__nac_16, null) ? null : __nac_16.group(0)); })); }), ['regex_find_all']: ((i) => { const input = i; return this._stdBinaryAny(i, ((a, b) => { return [...new RegExp(b).allMatches(a).map(((m) => { const input = m; return m.group(0); }))]; })); }), ['regex_replace']: ((i) => { const input = i; return this._stdRegexReplace(i, false); }), ['regex_replace_all']: ((i) => { const input = i; return this._stdRegexReplace(i, true); }), ['math_abs']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return __ball_math_abs(this._toNum(v)); })); }), ['math_floor']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return Math.floor(this._toNum(v)); })); }), ['math_ceil']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return Math.ceil(this._toNum(v)); })); }), ['math_round']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return Math.round(this._toNum(v)); })); }), ['math_trunc']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return Math.trunc(this._toNum(v)); })); }), ['round_to_double']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return new BallDouble(Math.round(+(this._toNum(v)))); })); }), ['floor_to_double']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return new BallDouble(Math.floor(+(this._toNum(v)))); })); }), ['ceil_to_double']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return new BallDouble(Math.ceil(+(this._toNum(v)))); })); }), ['truncate_to_double']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return new BallDouble(Math.trunc(+(this._toNum(v)))); })); }), ['math_sqrt']: ((i) => { const input = i; return this._stdMathUnary(i, _mathSqrt); }), ['math_pow']: ((i) => { const input = i; return this._stdMathBinary(i, _mathPow); }), ['math_log']: ((i) => { const input = i; return this._stdMathUnary(i, _mathLog); }), ['math_log2']: ((i) => { const input = i; return this._stdMathUnary(i, ((v) => { const input = v; return new BallDouble(Number(_mathLog(v)) / Number(_mathLog(2))); })); }), ['math_log10']: ((i) => { const input = i; return this._stdMathUnary(i, ((v) => { const input = v; return new BallDouble(Number(_mathLog(v)) / Number(_mathLog(10))); })); }), ['math_exp']: ((i) => { const input = i; return this._stdMathUnary(i, _mathExp); }), ['math_sin']: ((i) => { const input = i; return this._stdMathUnary(i, _mathSin); }), ['math_cos']: ((i) => { const input = i; return this._stdMathUnary(i, _mathCos); }), ['math_tan']: ((i) => { const input = i; return this._stdMathUnary(i, _mathTan); }), ['math_asin']: ((i) => { const input = i; return this._stdMathUnary(i, _mathAsin); }), ['math_acos']: ((i) => { const input = i; return this._stdMathUnary(i, _mathAcos); }), ['math_atan']: ((i) => { const input = i; return this._stdMathUnary(i, _mathAtan); }), ['math_atan2']: ((i) => { const input = i; return this._stdMathBinary(i, _mathAtan2); }), ['math_min']: ((i) => { const input = i; return this._stdBinary(i, ((a, b) => { return (__ball_lt(a, b) ? a : b); })); }), ['math_max']: ((i) => { const input = i; return this._stdBinary(i, ((a, b) => { return (__ball_gt(a, b) ? a : b); })); }), ['math_clamp']: this._stdMathClamp.bind(this), ['math_pi']: ((_) => { const input = _; return new BallDouble(3.141592653589793); }), ['math_e']: ((_) => { const input = _; return new BallDouble(2.718281828459045); }), ['math_infinity']: ((_) => { const input = _; return double.infinity; }), ['math_nan']: ((_) => { const input = _; return double.nan; }), ['math_is_nan']: ((i) => { const input = i; return this._stdConvert(i, _ballNumIsNaN); }), ['math_is_finite']: ((i) => { const input = i; return this._stdConvert(i, _ballNumIsFinite); }), ['math_is_infinite']: ((i) => { const input = i; return this._stdConvert(i, _ballNumIsInfinite); }), ['math_sign']: ((i) => { const input = i; return this._stdConvert(i, ((v) => { const input = v; return Math.sign(Number(this._toNum(v))); })); }), ['math_gcd']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_math_gcd(a, b); })); }), ['math_lcm']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_divide(__ball_math_abs(__ball_mul(a, b)), __ball_math_gcd(a, b)); })); }), ['print_error']: ((i) => { const input = i; let im = this._stdAsMap(i); let msg = (!__ball_eq(im, null) ? ((() => { let __nac_17 = __ball_index(im, 'message'); return (__ball_eq(__nac_17, null) ? null : __nac_17.toString()); })() ?? '') : __ball_to_string(i)); this.stderr(msg); }), ['read_line']: ((_) => { const input = _; return ((__ball_eq(this.stdinReader, null) ? null : this.stdinReader.call()) ?? ''); }), ['exit']: ((i) => { const input = i; this._checkSandbox('exit'); let im = this._stdAsMap(i); let code = (!__ball_eq(im, null) ? (__ball_index(im, 'code') ?? 0) : 0); throw new _ExitSignal(code); }), ['panic']: ((i) => { const input = i; this._checkSandbox('panic'); let im = this._stdAsMap(i); let msg = (!__ball_eq(im, null) ? ((() => { let __nac_18 = __ball_index(im, 'message'); return (__ball_eq(__nac_18, null) ? null : __nac_18.toString()); })() ?? '') : __ball_to_string(i)); this.stderr(msg); throw new _ExitSignal(1); }), ['sleep_ms']: (async (i) => { const input = i; let ms = ((typeof i === 'number' || i instanceof BallDouble) ? __ball_to_int(i) : 0); if (__ball_gt(ms, 0)) { await Future.delayed(new Duration({ milliseconds: ms })); } }), ['timestamp_ms']: ((_) => { const input = _; return DateTime.now().millisecondsSinceEpoch; }), ['random_int']: ((i) => { const input = i; let m = this._stdAsMap(i); let min = ((() => { let __nac_19 = __ball_index(m, 'min'); return (__ball_eq(__nac_19, null) ? null : __nac_19.toInt()); })() ?? 0); let max = ((() => { let __nac_20 = __ball_index(m, 'max'); return (__ball_eq(__nac_20, null) ? null : __nac_20.toInt()); })() ?? 100); return __ball_add(min, this._random.nextInt(__ball_add(__ball_sub(max, min), 1))); }), ['random_double']: ((_) => { const input = _; return this._random.nextDouble(); }), ['env_get']: ((i) => { const input = i; this._checkSandbox('env_get'); let im = this._stdAsMap(i); let name = (!__ball_eq(im, null) ? (__ball_index(im, 'name') ?? '') : __ball_to_string(i)); return this._envGet(name); }), ['args_get']: ((_) => { const input = _; return this._args; }), ['json_encode']: ((i) => { const input = i; let im = this._stdAsMap(i); let val = (!__ball_eq(im, null) ? __ball_index(im, 'value') : i); return this._jsonEncode(val); }), ['json_decode']: ((i) => { const input = i; let im = this._stdAsMap(i); let str = (!__ball_eq(im, null) ? (__ball_index(im, 'value') ?? '') : __ball_to_string(i)); return this._jsonDecode(str); }), ['utf8_encode']: ((i) => { const input = i; let im = this._stdAsMap(i); let str = (!__ball_eq(im, null) ? (__ball_index(im, 'value') ?? '') : __ball_to_string(i)); return this._utf8Encode(str); }), ['utf8_decode']: ((i) => { const input = i; let im = this._stdAsMap(i); let bytes = (!__ball_eq(im, null) ? (__ball_index(im, 'value') ?? []) : []); return this._utf8Decode(bytes); }), ['base64_encode']: ((i) => { const input = i; let im = this._stdAsMap(i); let bytes = (!__ball_eq(im, null) ? (__ball_index(im, 'value') ?? []) : []); return this._base64Encode(bytes); }), ['base64_decode']: ((i) => { const input = i; let im = this._stdAsMap(i); let str = (!__ball_eq(im, null) ? (__ball_index(im, 'value') ?? '') : __ball_to_string(i)); return this._base64Decode(str); }), ['now']: ((_) => { const input = _; return DateTime.now().millisecondsSinceEpoch; }), ['now_micros']: ((_) => { const input = _; return DateTime.now().microsecondsSinceEpoch; }), ['format_timestamp']: ((i) => { const input = i; let m = this._stdAsMap(i); let ms = ((() => { let __nac_21 = __ball_index(m, 'timestamp_ms'); return (__ball_eq(__nac_21, null) ? null : __nac_21.toInt()); })() ?? 0); let dt = DateTime.fromMillisecondsSinceEpoch(ms, true); return dt.toIso8601String(); }), ['parse_timestamp']: ((i) => { const input = i; let m = this._stdAsMap(i); let str = (__ball_index(m, 'value') ?? ''); return DateTime.parse(str).millisecondsSinceEpoch; }), ['duration_add']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_add(a, b); })); }), ['duration_subtract']: ((i) => { const input = i; return this._stdBinaryInt(i, ((a, b) => { return __ball_sub(a, b); })); }), ['year']: ((_) => { const input = _; return DateTime.now().toUtc().year; }), ['month']: ((_) => { const input = _; return DateTime.now().toUtc().month; }), ['day']: ((_) => { const input = _; return DateTime.now().toUtc().day; }), ['hour']: ((_) => { const input = _; return DateTime.now().toUtc().hour; }), ['minute']: ((_) => { const input = _; return DateTime.now().toUtc().minute; }), ['second']: ((_) => { const input = _; return DateTime.now().toUtc().second; }), ['file_read']: this._stdFileRead.bind(this), ['file_read_bytes']: this._stdFileReadBytes.bind(this), ['file_write']: this._stdFileWrite.bind(this), ['file_write_bytes']: this._stdFileWriteBytes.bind(this), ['file_append']: this._stdFileAppend.bind(this), ['file_exists']: this._stdFileExists.bind(this), ['file_delete']: this._stdFileDelete.bind(this), ['dir_list']: this._stdDirList.bind(this), ['dir_create']: this._stdDirCreate.bind(this), ['dir_exists']: this._stdDirExists.bind(this), ['thread_spawn']: (async (i) => { const input = i; let m = this._stdAsMap(i); let body = __ball_index(m, 'body'); if ((typeof body === 'function')) { let v = body(null); if ((v != null)) { await v; } } return 0; }), ['thread_join']: ((_) => { const input = _; return null; }), ['mutex_create']: ((_) => { const input = _; return (this._nextMutexId++); }), ['mutex_lock']: ((_) => { const input = _; return null; }), ['mutex_unlock']: ((_) => { const input = _; return null; }), ['scoped_lock']: (async (i) => { const input = i; let m = this._stdAsMap(i); let body = __ball_index(m, 'body'); if ((typeof body === 'function')) { let v = body(null); if ((v != null)) { v = await v; } return v; } }), ['atomic_load']: ((i) => { const input = i; let m = this._stdAsMap(i); return __ball_index(m, 'value'); }), ['atomic_store']: ((i) => { const input = i; return null; }), ['atomic_compare_exchange']: ((i) => { const input = i; return true; }), ['goto']: ((i) => { const input = i; let im = this._stdAsMap(i); if (!__ball_eq(im, null)) { let label = (__ball_index(im, 'label') ?? ''); throw new _FlowSignal('goto', { label: label }); } }), ['label']: ((i) => { const input = i; let im = this._stdAsMap(i); if (!__ball_eq(im, null)) { return __ball_index(im, 'body'); } }) }; } _trackListCopy(list: any): any { const input = list; this._trackMemoryAllocation(__ball_mul(list.length, _ballPointerBytes)); return list; } _manualReverse(list: any): any { const input = list; let result = []; for (let i = __ball_sub(list.length, 1); __ball_ge(i, 0); (i--)) { result = (result.push(__ball_index(list, i)), result); } return result; } _resolveMethod(typeName: any, methodName: any): any { let colonIdx = typeName.indexOf(':'); let modPart = (__ball_ge(colonIdx, 0) ? typeName.substring(0, colonIdx) : this._currentModule); let methodKey = ((((__ball_to_string(modPart) + '.') + __ball_to_string(typeName)) + '.') + __ball_to_string(methodName)); let method = __ball_index(this._functions, methodKey); if ((!__ball_eq(method, null) && !method.isBase)) { return { module: modPart, func: method }; } let typeDef = this._findTypeDef(typeName); if (((!__ball_eq(typeDef, null) && !__ball_eq(typeDef.superclass, null)) && !(typeDef.superclass.length === 0))) { let superclass = typeDef.superclass; let qualSuper = (superclass.includes(':') ? superclass : ((__ball_to_string(modPart) + ':') + __ball_to_string(superclass))); let superResult = this._resolveMethod(qualSuper, methodName); if (!__ball_eq(superResult, null)) { return superResult; } } if (!__ball_eq(typeDef, null)) { let mixins = this._getMixins(typeName); for (const mixin of mixins) { let qualMixin = (mixin.includes(':') ? mixin : ((__ball_to_string(modPart) + ':') + __ball_to_string(mixin))); let mixinResult = this._resolveMethod(qualMixin, methodName); if (!__ball_eq(mixinResult, null)) { return mixinResult; } } } } _getMixins(typeName: any): any { const input = typeName; for (const module of this.program.modules) { for (const td of module.typeDefs) { if ((__ball_eq(td.name, typeName) || td.name.endsWith((':' + __ball_to_string(typeName))))) { if (hasMetadata(td)) { let mixinsField = __ball_index(td.metadata.fields, 'mixins'); if ((!__ball_eq(mixinsField, null) && __ball_eq(whichKind(mixinsField), structpb_Value_Kind.listValue))) { return [...mixinsField.listValue.values.filter(((v) => { const input = v; return hasStringValue(v); })).map(((v) => { const input = v; return v.stringValue; }))]; } } } } } return []; } async _stdPrint(input: any): Promise { let m = this._stdAsMap(input); if ((!__ball_eq(m, null) && ((('message' in __ball_require_map(m, 'map_contains_key')) || ('arg0' in __ball_require_map(m, 'map_contains_key'))) || ('value' in __ball_require_map(m, 'map_contains_key'))))) { let message = ((__ball_index(m, 'message') ?? __ball_index(m, 'arg0')) ?? __ball_index(m, 'value')); this.stdout(await this._ballToStringAsync(message)); return null; } this.stdout(await this._ballToStringAsync(input)); } async _ballToStringAsync(v: any): Promise { const input = v; if ((__ball_eq(v, null) || (v == null))) { return 'null'; } if ((typeof v === 'string')) { return v; } if ((typeof v === 'string')) { return v.value; } if ((typeof v === 'boolean')) { return __ball_to_string(v); } if ((typeof v === 'boolean')) { return __ball_to_string(v.value); } if ((typeof v === 'number' && Number.isInteger(v))) { return __ball_to_string(v); } if ((typeof v === 'number' && Number.isInteger(v))) { return __ball_to_string(v.value); } if ((v instanceof BallDouble || (typeof v === 'number' && !Number.isInteger(v)))) { return __ball_to_string(v); } if ((typeof v === 'number' || v instanceof BallDouble)) { return __ball_to_string(v); } if (this._isBallSet(v)) { let parts = []; for (const item of this._ballSetItems(v)) { parts = (parts.push(await this._ballToStringAsync(item)), parts); } return (('{' + __ball_to_string(parts.join(', '))) + '}'); } if (false /* BallList is List in TS */) { let parts = []; for (const item of v.items) { parts = (parts.push(await this._ballToStringAsync(item)), parts); } return (('[' + __ball_to_string(parts.join(', '))) + ']'); } if (Array.isArray(v)) { let parts = []; for (const item of v) { parts = (parts.push(await this._ballToStringAsync(item)), parts); } return (('[' + __ball_to_string(parts.join(', '))) + ']'); } if ((v instanceof Set)) { let parts = []; for (const item of v) { parts = (parts.push(await this._ballToStringAsync(item)), parts); } return (('{' + __ball_to_string(parts.join(', '))) + '}'); } if ((v instanceof BallException)) { let ev = v.value; let em = this._stdAsMap(ev); if (!__ball_eq(em, null)) { let msg = __ball_index(em, 'message'); if ((typeof msg === 'string')) { return msg; } } if ((typeof ev === 'string')) { return ev; } return v.typeName; } let map = this._stdAsMap(v); if (!__ball_eq(map, null)) { let typeName = __ball_index(map, '__type__'); if ((!__ball_eq(typeName, null) && (typeName.endsWith(':StringBuffer') || __ball_eq(typeName, 'StringBuffer')))) { return (__ball_index(map, '__buffer__') ?? ''); } if (!__ball_eq(typeName, null)) { if ((typeName.endsWith('Exception') || typeName.endsWith('Error'))) { let msg = __ball_index(map, 'message'); if ((typeof msg === 'string')) { return msg; } return (typeName.includes(':') ? typeName.substring(__ball_add(typeName.lastIndexOf(':'), 1)) : typeName); } if (('__tostring_guard__' in __ball_require_map(map, 'map_contains_key'))) { let shortType = (typeName.includes(':') ? typeName.substring(__ball_add(typeName.lastIndexOf(':'), 1)) : typeName); return (__ball_to_string(shortType) + '{...}'); } let resolved = this._resolveMethod(typeName, 'toString'); if (!__ball_eq(resolved, null)) { map['__tostring_guard__'] = true; try { let result = await this._callFunction(resolved.module, resolved.func, { ['self']: map }); return ((__ball_eq(result, null) ? null : result.toString()) ?? 'null'); } catch (__ball_active_error) { const _ = __ball_active_error; } finally { map.remove('__tostring_guard__'); } } } if (__ball_eq(typeName, null)) { let parts = []; let rawMap = (((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) && !(false /* BallMap is Map in TS */)) ? v : map); for (const e of rawMap.entries) { let k = await this._ballToStringAsync(e.key); let val = await this._ballToStringAsync(e.value); parts = (parts.push(((__ball_to_string(k) + ': ') + __ball_to_string(val))), parts); } return (('{' + __ball_to_string(parts.join(', '))) + '}'); } } return __ball_to_string(v); } _stdIf(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('std.if input must be a message'); } let condition = __ball_index(m, 'condition'); if (__ball_eq(condition, true)) { return __ball_index(m, 'then'); } return __ball_index(m, 'else'); } _stdIndex(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('std.index: expected message'); } let target = __ball_index(m, 'target'); let index = __ball_index(m, 'index'); let listTarget = this._stdAsList(target); if (!__ball_eq(listTarget, null)) { return __ball_index(listTarget, this._toInt(index)); } if (false /* BallMap is Map in TS */) { return __ball_index(target.entries, ((typeof index === 'number' && Number.isInteger(index)) ? __ball_to_string(index) : index)); } if ((typeof target === 'object' && target !== null && !Array.isArray(target) && !(target instanceof BallDouble) && !(target instanceof Set))) { return __ball_index(target, index); } if ((typeof target === 'string')) { return __ball_index(target, this._toInt(index)); } // Fallback: try flexible index access if (typeof target === 'object' && target !== null) { if (target instanceof Map) return target.get(index); if (!Array.isArray(target)) return target[String(index)]; return target[Number(index)]; } if (typeof target === 'string') return target.charAt(Number(index)); return null; } _stdCascade(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return input; } return __ball_index(m, 'target'); } _stdNullAwareCascade(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return input; } let target = __ball_index(m, 'target'); if (__ball_eq(target, null)) { return null; } return target; } async _stdListGenerate(input: any): Promise { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('std.list_generate: expected message'); } let length = this._toInt(((__ball_index(m, 'length') ?? __ball_index(m, 'count')) ?? __ball_index(m, 'arg0'))); let generator = (((__ball_index(m, 'generator') ?? __ball_index(m, 'callback')) ?? __ball_index(m, 'function')) ?? __ball_index(m, 'arg1')); if (!((typeof generator === 'function'))) { throw new BallRuntimeError('std.list_generate: generator is not callable'); } this._trackMemoryAllocation(__ball_mul(length, _ballPointerBytes)); let result = []; for (let index = 0; __ball_lt(index, length); (index++)) { let value = generator(index); if ((value != null)) { value = await value; } result = (result.push(value), result); } return result; } _stdListFilled(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('std.list_filled: expected message'); } let length = this._toInt(((__ball_index(m, 'length') ?? __ball_index(m, 'count')) ?? __ball_index(m, 'arg0'))); this._trackMemoryAllocation(__ball_mul(length, _ballPointerBytes)); return { '__type': 'main:List.filled', '__type_args__': '', 'arg0': length, 'arg1': (__ball_index(m, 'value') ?? __ball_index(m, 'arg1')) }; } async _stdInvoke(input: any): Promise { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('std.invoke: expected message'); } let callee = __ball_index(m, 'callee'); if (!((typeof callee === 'function'))) { throw new BallRuntimeError('std.invoke: callee is not callable'); } let args = (() => { let __cascade_self__ = ({ ...m }); __cascade_self__.remove('callee'); __cascade_self__.remove('__type__'); return __cascade_self__; })(); let result; if (__ball_eq(args.length, 1)) { result = Function.apply(callee, [args.values.first]); } else { if ((args.length === 0)) { result = Function.apply(callee, [null]); } else { result = Function.apply(callee, [args]); } } if ((result != null)) { result = await result; } return result; } _stdNullAwareAccess(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return null; } let target = __ball_index(m, 'target'); let field = __ball_index(m, 'field'); if (__ball_eq(target, null)) { return null; } let targetMap = this._stdAsMap(target); if ((!__ball_eq(targetMap, null) && !__ball_eq(field, null))) { return __ball_index(targetMap, field); } } _stdNullAwareCall(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return null; } let target = __ball_index(m, 'target'); if (__ball_eq(target, null)) { return null; } } _stdTypeCheck(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return false; } let value = __ball_index(m, 'value'); let type = __ball_index(m, 'type'); if (__ball_eq(type, null)) { return false; } return this._typeMatches(value, type); } _typeMatches(value: any, type: any): any { let genericMatch = new RegExp('^(\\w+)<(.+)>$').firstMatch(type); if (!__ball_eq(genericMatch, null)) { let baseType = genericMatch.group(1); let typeArgsStr = genericMatch.group(2); let typeArgs = this._splitTypeArgs(typeArgsStr); let listVal = this._stdAsList(value); if ((__ball_eq(baseType, 'List') && !__ball_eq(listVal, null))) { if (__ball_eq(typeArgs.length, 1)) { return listVal.every(((e) => { const input = e; return this._typeMatches(e, __ball_index(typeArgs, 0)); })); } return true; } let mapVal = this._stdAsMap(value); if ((__ball_eq(baseType, 'Map') && (!__ball_eq(mapVal, null) || (typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof BallDouble) && !(value instanceof Set))))) { let entries = ((__ball_eq(mapVal, null) ? null : mapVal.entries) ?? value.entries); if (__ball_eq(typeArgs.length, 2)) { return entries.every(((e) => { const input = e; return (this._typeMatches(e.key, __ball_index(typeArgs, 0)) && this._typeMatches(e.value, __ball_index(typeArgs, 1))); })); } return true; } if ((__ball_eq(baseType, 'Set') && this._isBallSet(value))) { if (__ball_eq(typeArgs.length, 1)) { return this._ballSetItems(value).every(((e) => { const input = e; return this._typeMatches(e, __ball_index(typeArgs, 0)); })); } return true; } let objMap = this._stdAsMap(value); if ((!__ball_eq(objMap, null) && this._typeNameMatches(__ball_index(objMap, '__type__'), baseType))) { let objArgs = __ball_index(objMap, '__type_args__'); let objTypeArgs = []; if ((typeof objArgs === 'string')) { let argsStr = objArgs.trim(); if ((argsStr.startsWith('<') && argsStr.endsWith('>'))) { objTypeArgs = [...argsStr.substring(1, __ball_sub(argsStr.length, 1)).split(',').map(((s) => { const input = s; return s.trim(); }))]; } else { objTypeArgs = [argsStr]; } } else { if (Array.isArray(objArgs)) { objTypeArgs = [...objArgs.map(((e) => { const input = e; return __ball_to_string(e); }))]; } } if (__ball_eq(objTypeArgs.length, typeArgs.length)) { for (let i = 0; __ball_lt(i, typeArgs.length); (i++)) { if (!__ball_eq(__ball_index(objTypeArgs, i), __ball_index(typeArgs, i))) { return false; } } return true; } } return false; } if (__ball_eq(type, 'int')) { return _ballIsInt(value); } if (__ball_eq(type, 'double')) { return _ballIsDouble(value); } if (__ball_eq(type, 'num')) { return _ballIsNum(value); } if (__ball_eq(type, 'String')) { return _ballIsString(value); } if (__ball_eq(type, 'bool')) { return _ballIsBool(value); } if (__ball_eq(type, 'List')) { return _ballIsList(value); } if (__ball_eq(type, 'Map')) { return _ballIsMap(value); } if (__ball_eq(type, 'Set')) { return this._isBallSet(value); } if ((__ball_eq(type, 'Null') || __ball_eq(type, 'void'))) { return (__ball_eq(value, null) || (value == null)); } if ((__ball_eq(type, 'Object') || __ball_eq(type, 'dynamic'))) { return true; } if (__ball_eq(type, 'Function')) { return ((typeof value === 'function') || (typeof value === 'function')); } return this._objectTypeMatches(value, type); } _objectTypeMatches(value: any, type: any): any { let m = this._stdAsMap(value); if (__ball_eq(m, null)) { return false; } if (this._typeNameMatches(__ball_index(m, '__type__'), type)) { return true; } let superObj = __ball_index(m, '__super__'); while (!__ball_eq(superObj, null)) { let superMap = this._stdAsMap(superObj); if (__ball_eq(superMap, null)) { break; } if (this._typeNameMatches(__ball_index(superMap, '__type__'), type)) { return true; } superObj = __ball_index(superMap, '__super__'); } return false; } _typeNameMatches(objType: any, checkType: any): any { if (__ball_eq(objType, null)) { return false; } if (__ball_eq(objType, checkType)) { return true; } if (objType.endsWith((':' + __ball_to_string(checkType)))) { return true; } if (checkType.endsWith((':' + __ball_to_string(objType)))) { return true; } let objColon = objType.indexOf(':'); let checkColon = checkType.indexOf(':'); if ((__ball_ge(objColon, 0) && __ball_ge(checkColon, 0))) { return __ball_eq(objType.substring(__ball_add(objColon, 1)), checkType.substring(__ball_add(checkColon, 1))); } return false; } _splitTypeArgs(str: any): any { const input = str; let args = []; let depth = 0; let start = 0; for (let i = 0; __ball_lt(i, str.length); (i++)) { if (__ball_eq(__ball_index(str, i), '<')) { (depth++); } if (__ball_eq(__ball_index(str, i), '>')) { (depth--); } if ((__ball_eq(__ball_index(str, i), ',') && __ball_eq(depth, 0))) { args = (args.push(str.substring(start, i).trim()), args); start = __ball_add(i, 1); } } args = (args.push(str.substring(start).trim()), args); return args; } async _stdMapCreate(input: any): Promise { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return _ballUserMap(); } let entries = (__ball_index(m, 'entries') ?? __ball_index(m, 'entry')); let entriesList = this._stdAsList(entries); if (!__ball_eq(entriesList, null)) { this._trackMemoryAllocation(__ball_mul(entriesList.length, _ballMapEntryBytes)); let result = _ballUserMap(); for (const entry of entriesList) { let entryMap = this._stdAsMap(entry); if (!__ball_eq(entryMap, null)) { let key = await this._ballToStringAsync((__ball_index(entryMap, 'key') ?? __ball_index(entryMap, 'name'))); result[key] = __ball_index(entryMap, 'value'); } } return result; } let entriesMap = this._stdAsMap(entries); if (!__ball_eq(entriesMap, null)) { this._trackMemoryAllocation(_ballMapEntryBytes); let key = await this._ballToStringAsync((__ball_index(entriesMap, 'key') ?? __ball_index(entriesMap, 'name'))); return (() => { let __cascade_self__ = _ballUserMap(); __cascade_self__[key] = __ball_index(entriesMap, 'value'); return __cascade_self__; })(); } return _ballUserMap(); } _stdSetCreate(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return this._ballSetOf([]); } let elements = __ball_index(m, 'elements'); let elementsList = this._stdAsList(elements); if (!__ball_eq(elementsList, null)) { this._trackMemoryAllocation(__ball_mul(elementsList.length, _ballPointerBytes)); return this._ballSetOf(elementsList); } return this._ballSetOf([]); } _collectionMisuse(_: any): any { const input = _; return (() => { throw new BallRuntimeError(('collection_for/collection_if must appear directly inside a list, set, ' + 'or map literal and cannot be evaluated as a standalone call.')); })(); } _stdRecord(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return input; } return (__ball_index(m, 'fields') ?? m); } async _stdSwitchExpr(input: any): Promise { let im = this._stdAsMap(input); if (__ball_eq(im, null)) { return null; } let subject = __ball_index(im, 'subject'); let rawCases = __ball_index(im, 'cases'); let cases = this._stdAsList(rawCases); if (__ball_eq(cases, null)) { return null; } let defaultBody; for (const c of cases) { let cMap = this._stdAsMap(c); if (__ball_eq(cMap, null)) { continue; } let pattern = __ball_index(cMap, 'pattern'); let patternExpr = __ball_index(cMap, 'pattern_expr'); let body = __ball_index(cMap, 'body'); let guard = __ball_index(cMap, 'guard'); if ((__ball_eq(__ball_index(cMap, 'is_default'), true) || __ball_eq(pattern, '_'))) { defaultBody = body; continue; } let bindings = {}; if (this._matchPattern(subject, (patternExpr ?? pattern), bindings)) { if ((!__ball_eq(guard, null) && (typeof guard === 'function'))) { let guardResult = guard(bindings); if ((guardResult != null)) { guardResult = await guardResult; } if (!__ball_eq(guardResult, true)) { continue; } } if ((typeof body === 'function')) { let result = body(bindings); if ((result != null)) { result = await result; } return result; } return body; } } if (!__ball_eq(defaultBody, null)) { return defaultBody; } throw new BallRuntimeError('Non-exhaustive switch expression'); } _matchPattern(value: any, pattern: any, bindings: any): any { if ((__ball_eq(pattern, null) || __ball_eq(pattern, '_'))) { return true; } if ((typeof pattern === 'string')) { return this._matchStringPattern(value, pattern, bindings); } let patternMap = this._stdAsMap(pattern); if (!__ball_eq(patternMap, null)) { return this._matchStructuredPattern(value, patternMap, bindings); } return (__ball_eq(pattern, value) || __ball_eq(__ball_to_string(pattern), (__ball_eq(value, null) ? null : value.toString()))); } _matchStringPattern(value: any, pattern: any, bindings: any): any { let trimmed = pattern.trim(); if (__ball_eq(trimmed, '_')) { return true; } let typeBindMatch = new RegExp('^(\\w+)\\s+(\\w+)$').firstMatch(trimmed); if (!__ball_eq(typeBindMatch, null)) { let typeName = typeBindMatch.group(1); let varName = typeBindMatch.group(2); if (this._matchesTypePattern(value, typeName)) { bindings[varName] = value; return true; } return false; } if (__ball_eq(trimmed, 'null')) { return __ball_eq(value, null); } if (__ball_eq(trimmed, 'true')) { return __ball_eq(value, true); } if (__ball_eq(trimmed, 'false')) { return __ball_eq(value, false); } let relMatch = new RegExp('^(==|!=|>=|<=|>|<)\\s*(.+)$').firstMatch(trimmed); if ((!__ball_eq(relMatch, null) && (typeof value === 'number' || value instanceof BallDouble))) { let op = relMatch.group(1); let rhsStr = relMatch.group(2).trim(); let rhs = num.tryParse(rhsStr); if (!__ball_eq(rhs, null)) { return ((op === '==') ? (__ball_eq(value, rhs)) : ((op === '!=') ? (!__ball_eq(value, rhs)) : ((op === '>') ? (__ball_gt(value, rhs)) : ((op === '<') ? (__ball_lt(value, rhs)) : ((op === '>=') ? (__ball_ge(value, rhs)) : ((op === '<=') ? (__ball_le(value, rhs)) : false)))))); } } if (this._matchesTypePattern(value, trimmed)) { return true; } if (__ball_eq(trimmed, (__ball_eq(value, null) ? null : value.toString()))) { return true; } return false; } _matchStructuredPattern(value: any, pattern: any, bindings: any): any { let kind = this._patternKind(pattern); do { const __sw = kind; if ((__sw === 'type_test')) { let typeName = __ball_index(pattern, 'type'); let varName = __ball_index(pattern, 'name'); if ((!__ball_eq(typeName, null) && this._matchesTypePattern(value, typeName))) { if (!__ball_eq(varName, null)) { bindings[varName] = value; } return true; } return false; } else if ((__sw === 'var')) { let typeName = __ball_index(pattern, 'type'); if ((!__ball_eq(typeName, null) && !this._matchesTypePattern(value, typeName))) { return false; } let varName = __ball_index(pattern, 'name'); if ((!__ball_eq(varName, null) && !__ball_eq(varName, '_'))) { bindings[varName] = value; } return true; } else if ((__sw === 'wildcard')) { let typeName = __ball_index(pattern, 'type'); return (__ball_eq(typeName, null) || this._matchesTypePattern(value, typeName)); } else if ((__sw === 'const')) { return this._ballEquals(value, __ball_index(pattern, 'value')); } else if ((__sw === 'relational')) { return this._matchRelationalPattern(value, __ball_index(pattern, 'operator'), __ball_index(pattern, 'operand')); } else if ((__sw === 'list')) { let listVal = this._stdAsList(value); if (__ball_eq(listVal, null)) { return false; } let elements = (this._stdAsList(__ball_index(pattern, 'elements')) ?? []); let restIndex = elements.indexWhere(((e) => { const input = e; let em = this._stdAsMap(e); return (!__ball_eq(em, null) && __ball_eq(this._patternKind(em), 'rest')); })); let fixedCount = (__ball_eq(restIndex, __ball_negate(1)) ? elements.length : __ball_sub(elements.length, 1)); if ((__ball_eq(restIndex, __ball_negate(1)) && !__ball_eq(listVal.length, fixedCount))) { return false; } if ((!__ball_eq(restIndex, __ball_negate(1)) && __ball_lt(listVal.length, fixedCount))) { return false; } for (let i = 0; __ball_lt(i, elements.length); (i++)) { let elem = __ball_index(elements, i); let elemMap = this._stdAsMap(elem); if ((!__ball_eq(elemMap, null) && __ball_eq(this._patternKind(elemMap), 'rest'))) { let restValues = listVal.slice(i, __ball_add(__ball_sub(listVal.length, fixedCount), i)); let subpattern = __ball_index(elemMap, 'subpattern'); if ((!__ball_eq(subpattern, null) && !this._matchPattern(restValues, subpattern, bindings))) { return false; } continue; } let valueIndex = ((__ball_eq(restIndex, __ball_negate(1)) || __ball_lt(i, restIndex)) ? i : __ball_sub(listVal.length, __ball_sub(elements.length, i))); if (!this._matchPattern(__ball_index(listVal, valueIndex), elem, bindings)) { return false; } } let rest = __ball_index(pattern, 'rest'); if (!__ball_eq(rest, null)) { bindings[rest] = listVal.slice(fixedCount); } return true; } else if ((__sw === 'map')) { if (this._isBallSet(value)) { return false; } let mapVal = this._stdAsMap(value); if ((__ball_eq(mapVal, null) && !((typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof BallDouble) && !(value instanceof Set))))) { return false; } let rawMap = ((typeof value === 'object' && value !== null && !Array.isArray(value) && !(value instanceof BallDouble) && !(value instanceof Set)) ? value : mapVal); let entries = (this._stdAsList(__ball_index(pattern, 'entries')) ?? []); for (const entry of entries) { let entryMap = this._stdAsMap(entry); if (__ball_eq(entryMap, null)) { return false; } let key = __ball_index(entryMap, 'key'); if (!(key in __ball_require_map(rawMap, 'map_contains_key'))) { return false; } if (!this._matchPattern(__ball_index(rawMap, key), __ball_index(entryMap, 'value'), bindings)) { return false; } } return true; } else if ((__sw === 'object')) { let objMap = this._stdAsMap(value); if (__ball_eq(objMap, null)) { return false; } let objType = __ball_index(pattern, 'type'); if ((!__ball_eq(objType, null) && !this._matchesObjectType(objMap, objType))) { return false; } for (const entry of this._patternFields(__ball_index(pattern, 'fields')).entries) { let fieldVal = __ball_index(objMap, entry.key); if (!this._matchPattern(fieldVal, entry.value, bindings)) { return false; } } return true; } else if ((__sw === 'record')) { let recMap = this._stdAsMap(value); if (__ball_eq(recMap, null)) { return false; } let recFields = this._patternFields(__ball_index(pattern, 'fields')); let valueKeys = recMap.keys.filter(((k) => { const input = k; return !k.startsWith('__'); })).toSet(); if (!__ball_eq(valueKeys.length, recFields.length)) { return false; } for (const entry of recFields.entries) { if (!(entry.key in __ball_require_map(recMap, 'map_contains_key'))) { return false; } let fieldVal = __ball_index(recMap, entry.key); if (!this._matchPattern(fieldVal, entry.value, bindings)) { return false; } } return true; } else if ((__sw === 'logical_or')) { let leftBindings = {}; if (this._matchPattern(value, __ball_index(pattern, 'left'), leftBindings)) { __ball_push_all(bindings, leftBindings); return true; } return this._matchPattern(value, __ball_index(pattern, 'right'), bindings); } else if ((__sw === 'logical_and')) { let tempBindings = {}; if ((this._matchPattern(value, __ball_index(pattern, 'left'), tempBindings) && this._matchPattern(value, __ball_index(pattern, 'right'), tempBindings))) { __ball_push_all(bindings, tempBindings); return true; } return false; } else if ((__sw === 'cast')) { let typeName = __ball_index(pattern, 'type'); if ((!__ball_eq(typeName, null) && !this._matchesTypePattern(value, typeName))) { throw new BallException('TypeError', ('type cast failed: not a ' + __ball_to_string(typeName))); } let subpattern = __ball_index(pattern, 'pattern'); if ((!__ball_eq(subpattern, null) && !this._matchPattern(value, subpattern, bindings))) { return false; } let varName = __ball_index(pattern, 'name'); if (!__ball_eq(varName, null)) { bindings[varName] = value; } return true; } else if ((__sw === 'null_check') || (__sw === 'null_assert')) { return (!__ball_eq(value, null) && this._matchPattern(value, __ball_index(pattern, 'pattern'), bindings)); } else if ((__sw === 'rest')) { return this._matchPattern(value, __ball_index(pattern, 'subpattern'), bindings); } else { let defMap = this._stdAsMap(value); if (!__ball_eq(defMap, null)) { for (const entry of pattern.entries) { if (entry.key.startsWith('__')) { continue; } if (!this._matchPattern(__ball_index(defMap, entry.key), entry.value, bindings)) { return false; } } return true; } return false; } } while (false); } _patternKind(pattern: any): any { const input = pattern; let explicit = __ball_index(pattern, '__pattern_kind__'); if (!__ball_eq(explicit, null)) { return explicit; } let type = __ball_index(pattern, '__type__'); return ((type === 'VarPattern') ? ('var') : ((type === 'WildcardPattern') ? ('wildcard') : ((type === 'ConstPattern') ? ('const') : ((type === 'ListPattern') ? ('list') : ((type === 'MapPattern') ? ('map') : ((type === 'RecordPattern') ? ('record') : ((type === 'ObjectPattern') ? ('object') : ((type === 'LogicalAndPattern') ? ('logical_and') : ((type === 'LogicalOrPattern') ? ('logical_or') : ((type === 'CastPattern') ? ('cast') : ((type === 'NullCheckPattern') ? ('null_check') : ((type === 'NullAssertPattern') ? ('null_assert') : ((type === 'RelationalPattern') ? ('relational') : ((type === 'RestPattern') ? ('rest') : null)))))))))))))); } _patternFields(fields: any): any { const input = fields; let map = this._stdAsMap(fields); if (!__ball_eq(map, null)) { return map; } let list = this._stdAsList(fields); if (__ball_eq(list, null)) { return {}; } let result = {}; let positional = 1; for (const field of list) { let fieldMap = this._stdAsMap(field); if (__ball_eq(fieldMap, null)) { continue; } let name = __ball_index(fieldMap, 'name'); result[((__ball_eq(name, null) || (name.length === 0)) ? ('$' + __ball_to_string((positional++))) : name)] = __ball_index(fieldMap, 'pattern'); } return result; } _matchRelationalPattern(value: any, operator: any, operand: any): any { if (__ball_eq(operator, null)) { return false; } return ((operator === '==') ? (this._ballEquals(value, operand)) : ((operator === '!=') ? (!this._ballEquals(value, operand)) : ((operator === '>') ? ((((typeof value === 'number' || value instanceof BallDouble) && (typeof operand === 'number' || operand instanceof BallDouble)) && __ball_gt(value, operand))) : ((operator === '<') ? ((((typeof value === 'number' || value instanceof BallDouble) && (typeof operand === 'number' || operand instanceof BallDouble)) && __ball_lt(value, operand))) : ((operator === '>=') ? ((((typeof value === 'number' || value instanceof BallDouble) && (typeof operand === 'number' || operand instanceof BallDouble)) && __ball_ge(value, operand))) : ((operator === '<=') ? ((((typeof value === 'number' || value instanceof BallDouble) && (typeof operand === 'number' || operand instanceof BallDouble)) && __ball_le(value, operand))) : false)))))); } _matchesObjectType(value: any, patternType: any): any { let actual = (() => { let __nac_22 = __ball_index(value, '__type__'); return (__ball_eq(__nac_22, null) ? null : __nac_22.toString()); })(); if (__ball_eq(actual, null)) { return false; } if (__ball_eq(actual, patternType)) { return true; } let actualBare = (actual.includes(':') ? actual.split(':').last : actual); let patternBare = (patternType.includes(':') ? patternType.split(':').last : patternType); return __ball_eq(actualBare, patternBare); } _ballToStringSimple(v: any): any { const input = v; if ((__ball_eq(v, null) || (v == null))) { return 'null'; } if ((typeof v === 'string')) { return v; } if ((typeof v === 'string')) { return v.value; } if ((typeof v === 'boolean')) { return __ball_to_string(v); } if ((typeof v === 'boolean')) { return __ball_to_string(v.value); } if ((typeof v === 'number' && Number.isInteger(v))) { return __ball_to_string(v); } if ((typeof v === 'number' && Number.isInteger(v))) { return __ball_to_string(v.value); } if ((v instanceof BallDouble || (typeof v === 'number' && !Number.isInteger(v)))) { return __ball_to_string(v); } if ((typeof v === 'number' || v instanceof BallDouble)) { return __ball_to_string(v); } if (_isBallFuture(v)) { return this._ballToStringSimple(_unwrapBallFuture(v)); } if (this._isBallSet(v)) { return (('{' + __ball_to_string(this._ballSetItems(v).map(this._ballToStringSimple.bind(this)).join(', '))) + '}'); } if (false /* BallList is List in TS */) { return (('[' + __ball_to_string(v.items.map(this._ballToStringSimple.bind(this)).join(', '))) + ']'); } if (Array.isArray(v)) { return (('[' + __ball_to_string(v.map(this._ballToStringSimple.bind(this)).join(', '))) + ']'); } let map = this._stdAsMap(v); if (!__ball_eq(map, null)) { let typeName = __ball_index(map, '__type__'); if ((!__ball_eq(typeName, null) && (typeName in __ball_require_map(this._enumValues, 'map_contains_key')))) { let shortType = (typeName.includes(':') ? typeName.substring(__ball_add(typeName.lastIndexOf(':'), 1)) : typeName); let valName = __ball_index(map, 'name'); if (!__ball_eq(valName, null)) { return ((__ball_to_string(shortType) + '.') + __ball_to_string(this._ballToStringSimple(valName))); } } } return __ball_to_string(v); } _matchesTypePattern(value: any, pattern: any): any { let p = ((typeof pattern === 'string') ? pattern : this._ballToStringSimple(pattern)); if (((__ball_gt(p.length, 1) && p.endsWith('?')) && !p.includes(' '))) { if ((__ball_eq(value, null) || (value == null))) { return true; } return this._matchesTypePattern(value, p.substring(0, __ball_sub(p.length, 1))); } if ((__ball_eq(p, 'Null') || __ball_eq(p, 'null'))) { return (__ball_eq(value, null) || (value == null)); } if (__ball_eq(p, 'Object')) { return (!__ball_eq(value, null) && !((value == null))); } if (__ball_eq(p, 'dynamic')) { return true; } if (__ball_eq(p, 'int')) { return _ballIsInt(value); } if (__ball_eq(p, 'double')) { return _ballIsDouble(value); } if (__ball_eq(p, 'num')) { return _ballIsNum(value); } if (__ball_eq(p, 'String')) { return _ballIsString(value); } if (__ball_eq(p, 'bool')) { return _ballIsBool(value); } if (__ball_eq(p, 'List')) { return _ballIsList(value); } if (__ball_eq(p, 'Map')) { return _ballIsMap(value); } if (__ball_eq(p, 'Set')) { return this._isBallSet(value); } return false; } _stdAssert(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { return null; } let condition = __ball_index(m, 'condition'); let message = __ball_index(m, 'message'); if (!this._toBool(condition)) { throw new BallRuntimeError(('Assertion failed' + __ball_to_string((!__ball_eq(message, null) ? (': ' + __ball_to_string(message)) : '')))); } } _stdAdd(input: any): any { let __ball_rec_1 = this._extractBinaryArgs(input); let left = __ball_rec_1[0]; let right = __ball_rec_1[1]; if (((typeof left === 'string') || (typeof right === 'string'))) { return (__ball_to_string((left ?? '')) + __ball_to_string((right ?? ''))); } return __ball_add(this._toNum(left), this._toNum(right)); } _repeatString(s: any, count: any): any { let out = ''; for (let k = 0; __ball_lt(k, count); (k++)) { out = (__ball_to_string(out) + __ball_to_string(s)); } return out; } _stdBinary(input: any, op: any): any { let __ball_rec_2 = this._extractBinaryArgs(input); let left = __ball_rec_2[0]; let right = __ball_rec_2[1]; const __lBD = left instanceof BallDouble; const __rBD = right instanceof BallDouble; const __result = op(this._toNum(left), this._toNum(right)); if ((__lBD || __rBD) && typeof __result === 'number') return new BallDouble(__result); return __result; } _stdBinaryInt(input: any, op: any): any { let __ball_rec_3 = this._extractBinaryArgs(input); let left = __ball_rec_3[0]; let right = __ball_rec_3[1]; return op(this._toInt(left), this._toInt(right)); } _stdBinaryDouble(input: any, op: any): any { const __origOp2 = op; op = (a: any, b: any) => new BallDouble(__origOp2(a instanceof BallDouble ? a.value : a, b instanceof BallDouble ? b.value : b)); let __ball_rec_4 = this._extractBinaryArgs(input); let left = __ball_rec_4[0]; let right = __ball_rec_4[1]; return op(this._toDouble(left), this._toDouble(right)); } _stdBinaryComp(input: any, op: any): any { let __ball_rec_5 = this._extractBinaryArgs(input); let left = __ball_rec_5[0]; let right = __ball_rec_5[1]; return op(this._toNum(left), this._toNum(right)); } _stdBinaryBool(input: any, op: any): any { let __ball_rec_6 = this._extractBinaryArgs(input); let left = __ball_rec_6[0]; let right = __ball_rec_6[1]; return op(this._toBool(left), this._toBool(right)); } _stdBinaryAny(input: any, op: any): any { let __ball_rec_7 = this._extractBinaryArgs(input); let left = __ball_rec_7[0]; let right = __ball_rec_7[1]; return op(left, right); } _stdUnaryNum(input: any, op: any): any { let value = this._extractUnaryArg(input); const __vBD = value instanceof BallDouble; const __result = op(this._toNum(value)); if (__vBD && typeof __result === 'number') return new BallDouble(__result); return __result; } _stdNot(input: any): any { let value = this._extractUnaryArg(input); return !this._toBool(value); } _stdConcat(input: any): any { let __ball_rec_8 = this._extractBinaryArgs(input); let left = __ball_rec_8[0]; let right = __ball_rec_8[1]; let result = (__ball_to_string(left) + __ball_to_string(right)); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; } _stdLength(input: any): any { let value = this._extractUnaryArg(input); if ((typeof value === 'string')) { return value.length; } if ((typeof value === 'string')) { return value.value.length; } let listVal = this._stdAsList(value); if (!__ball_eq(listVal, null)) { return listVal.length; } throw new BallRuntimeError(('std.length: unsupported type ' + __ball_to_string(value.runtimeType))); } _stdConvert(input: any, converter: any): any { let value = this._extractUnaryArg(input); return converter(value); } _extractBinaryArgs(input: any): any { let m = this._stdAsMap(input); if (!__ball_eq(m, null)) { return [__ball_index(m, 'left'), __ball_index(m, 'right')]; } throw new BallRuntimeError('Expected message with left/right fields'); } _extractUnaryArg(input: any): any { let m = this._stdAsMap(input); if (!__ball_eq(m, null)) { return __ball_index(m, 'value'); } return input; } _extractField(input: any, name: any): any { let m = this._stdAsMap(input); if (!__ball_eq(m, null)) { return __ball_index(m, name); } } _stringFieldVal(fields: any, name: any): any { let expr = __ball_index(fields, name); if (__ball_eq(expr, null)) { return null; } if ((__ball_eq(whichExpr(expr), Expression_Expr.literal) && __ball_eq(whichValue(expr.literal), Literal_Value.stringValue))) { return expr.literal.stringValue; } } _toInt(v: any): any { const input = v; if ((typeof v === 'number' && Number.isInteger(v))) { return v; } if ((typeof v === 'number' && Number.isInteger(v))) { return v.value; } if ((v instanceof BallDouble || (typeof v === 'number' && !Number.isInteger(v)))) { return _ballDoubleToInt64(v); } if ((typeof v === 'number' || v instanceof BallDouble)) { return _ballDoubleToInt64(v.value); } if ((typeof v === 'string')) { return (int.tryParse(v) ?? 0); } if ((typeof v === 'string')) { return (int.tryParse(v.value) ?? 0); } if ((typeof v === 'boolean')) { return (v ? 1 : 0); } if ((typeof v === 'boolean')) { return (v.value ? 1 : 0); } return 0; } _toDouble(v: any): any { const input = v; if ((v instanceof BallDouble || (typeof v === 'number' && !Number.isInteger(v)))) { return v; } if ((typeof v === 'number' || v instanceof BallDouble)) { return v.value; } if ((typeof v === 'number' && Number.isInteger(v))) { return new BallDouble(Number(v)); } if ((typeof v === 'number' && Number.isInteger(v))) { return new BallDouble(Number(v.value)); } if ((typeof v === 'string')) { return __ball_parse_double(v); } if ((typeof v === 'string')) { return __ball_parse_double(v.value); } if (v instanceof BallDouble) return v; if (typeof v === 'string') { const n = Number(v); return isNaN(n) ? new BallDouble(0.0) : new BallDouble(n); } if (typeof v === 'boolean') return new BallDouble(v ? 1.0 : 0.0); return new BallDouble(0.0); } _toNum(v: any): any { const input = v; if ((typeof v === 'number' || v instanceof BallDouble)) { return v; } if ((typeof v === 'number' && Number.isInteger(v))) { return v.value; } if ((typeof v === 'number' || v instanceof BallDouble)) { return v.value; } if ((typeof v === 'string')) { return (num.tryParse(v) ?? 0); } if ((typeof v === 'string')) { return (num.tryParse(v.value) ?? 0); } if ((typeof v === 'boolean')) { return (v ? 1 : 0); } if ((typeof v === 'boolean')) { return (v.value ? 1 : 0); } if ((__ball_eq(v, null) || (v == null))) { return 0; } if (v instanceof BallDouble) return v.value; if (typeof v === 'string') { const n = Number(v); return isNaN(n) ? 0 : n; } if (typeof v === 'boolean') return v ? 1 : 0; return 0; } _toIterable(v: any): any { const input = v; if (false /* BallList is List in TS */) { return v.items; } if (this._isBallSet(v)) { return this._ballSetItems(v); } if (Array.isArray(v)) { return v; } if ((v instanceof Set)) { return [...v]; } if (false /* BallMap is Map in TS */) { return [...v.entries.entries.map(((e) => { const input = e; return { ['key']: e.key, ['value']: e.value }; }))]; } if ((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set))) { return [...v.entries.map(((e) => { const input = e; return { ['key']: e.key, ['value']: e.value }; }))]; } if ((typeof v === 'string')) { return v.split(''); } throw new BallRuntimeError((('for_in: value is not iterable (' + __ball_to_string(v.runtimeType)) + ')')); } _toBool(v: any): any { const input = v; if ((typeof v === 'boolean')) { return v; } if ((typeof v === 'boolean')) { return v.value; } throw new BallRuntimeError((('Cannot convert ' + __ball_to_string(v.runtimeType)) + ' to bool')); } _stdStringSubstring(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('Expected message'); } let value = __ball_index(m, 'value'); let start = this._toInt(__ball_index(m, 'start')); let end = __ball_index(m, 'end'); let result = (!__ball_eq(end, null) ? value.substring(start, this._toInt(end)) : value.substring(start)); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; } _stdStringCharAt(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('Expected message'); } let target = __ball_index(m, 'target'); let index = this._toInt(__ball_index(m, 'index')); return __ball_index(target, index); } _stdStringCharCodeAt(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('Expected message'); } let target = ((__ball_index(m, 'target') ?? __ball_index(m, 'value')) ?? __ball_index(m, 'string')); let index = this._toInt(__ball_index(m, 'index')); return _ballCodeUnitAt(target, index); } _stdStringReplace(input: any, all: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('Expected message'); } let value = __ball_index(m, 'value'); let from = __ball_index(m, 'from'); let to = __ball_index(m, 'to'); let result = (all ? value.split(from).join(to) : value.replace(from, to)); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; } _stdRegexReplace(input: any, all: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('Expected message'); } let value = __ball_index(m, 'value'); let from = __ball_index(m, 'from'); let to = __ball_index(m, 'to'); let pattern = new RegExp(from); let result = (all ? value.split(pattern).join(to) : value.replace(pattern, to)); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; } _stdStringRepeat(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('Expected message'); } let value = __ball_index(m, 'value'); let count = this._toInt(__ball_index(m, 'count')); let result = __ball_mul(value, count); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; } _stdStringPad(input: any, left: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('Expected message'); } let value = __ball_index(m, 'value'); let width = this._toInt(__ball_index(m, 'width')); let padding = (__ball_index(m, 'padding') ?? ' '); let result = (left ? value.padStart(width, padding) : value.padEnd(width, padding)); this._trackMemoryAllocation(__ball_mul(result.length, _ballStringCodeUnitBytes)); return result; } _stdMathUnary(input: any, op: any): any { let value = this._extractUnaryArg(input); return op(this._toDouble(value)); } _stdMathBinary(input: any, op: any): any { let __ball_rec_9 = this._extractBinaryArgs(input); let left = __ball_rec_9[0]; let right = __ball_rec_9[1]; return op(this._toDouble(left), this._toDouble(right)); } _stdMathClamp(input: any): any { let m = this._stdAsMap(input); if (__ball_eq(m, null)) { throw new BallRuntimeError('Expected message'); } let rawValue = __ball_index(m, 'value'); let value; let min; let max; if ((__ball_is_type(rawValue, "Map") || false /* BallMap is Map in TS */)) { value = this._toNum(__ball_index(m, 'min')); min = this._toNum(__ball_index(m, 'max')); max = this._toNum(__ball_index(m, 'arg2')); } else { value = this._toNum(rawValue); min = this._toNum(__ball_index(m, 'min')); max = this._toNum(__ball_index(m, 'max')); } return Math.min(Math.max(value, min), max); } _jsonEncode(value: any): any { const input = value; return { '__type': 'main:JsonEncoder' }.convert(this._toJsonSafe(value)); } _jsonDecode(text: any): any { const input = text; return { '__type': 'main:JsonDecoder' }.convert(text); } _toJsonSafe(v: any): any { const input = v; if ((__ball_eq(v, null) || (v == null))) { return null; } if ((typeof v === 'number' && Number.isInteger(v))) { return v.value; } if ((typeof v === 'number' || v instanceof BallDouble)) { return v.value; } if ((typeof v === 'boolean')) { return v.value; } if ((typeof v === 'string')) { return v.value; } if ((((typeof v === 'number' || v instanceof BallDouble) || (typeof v === 'boolean')) || (typeof v === 'string'))) { return v; } if (this._isBallSet(v)) { return [...this._ballSetItems(v).map(this._toJsonSafe.bind(this))]; } let mapVal = this._stdAsMap(v); if (!__ball_eq(mapVal, null)) { return (() => { const __r: any = {}; for (const e of mapVal.entries) { if (!e.key.startsWith('__')) { __r[e.key] = this._toJsonSafe(e.value); } } return __r; })(); } if ((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set))) { return (() => { const __r: any = {}; for (const e of v.entries) { if (((typeof e.key === 'string') && !e.key.startsWith('__'))) { __r[e.key] = this._toJsonSafe(e.value); } } return __r; })(); } let listVal = this._stdAsList(v); if (!__ball_eq(listVal, null)) { return [...listVal.map(this._toJsonSafe.bind(this))]; } if ((v instanceof Set)) { return [...v.map(this._toJsonSafe.bind(this))]; } return __ball_to_string(v); } _utf8Encode(s: any): any { const input = s; return [...new TextEncoder().encode(s)]; } _utf8Decode(bytes: any): any { const input = bytes; return new TextDecoder().decode(new Uint8Array(bytes)); } _base64Encode(bytes: any): any { const input = bytes; return btoa(String.fromCharCode(...bytes)); } _base64Decode(s: any): any { const input = s; return [...atob(s)].map(c => c.charCodeAt(0)); } _checkSandbox(op: any): any { const input = op; return (this.sandbox ? (() => { throw new BallRuntimeError((('Sandbox violation: ' + __ball_to_string(op)) + ' is not allowed')); })() : undefined); } _stdFileRead(input: any): any { this._checkSandbox('file_read'); let m = this._stdAsMap(input); let path = (!__ball_eq(m, null) ? (__ball_index(m, 'path') ?? '') : __ball_to_string(input)); return File(path).readAsStringSync(); } _stdFileReadBytes(input: any): any { this._checkSandbox('file_read_bytes'); let m = this._stdAsMap(input); let path = (!__ball_eq(m, null) ? (__ball_index(m, 'path') ?? '') : __ball_to_string(input)); return [...File(path).readAsBytesSync()]; } _stdFileWrite(input: any): any { this._checkSandbox('file_write'); let m = this._stdAsMap(input); File(__ball_index(m, 'path')).writeAsStringSync(__ball_index(m, 'content')); } _stdFileWriteBytes(input: any): any { this._checkSandbox('file_write_bytes'); let m = this._stdAsMap(input); File(__ball_index(m, 'path')).writeAsBytesSync(__ball_index(m, 'content')); } _stdFileAppend(input: any): any { this._checkSandbox('file_append'); let m = this._stdAsMap(input); File(__ball_index(m, 'path')).writeAsStringSync(__ball_index(m, 'content'), io_FileMode.append); } _stdFileExists(input: any): any { this._checkSandbox('file_exists'); let m = this._stdAsMap(input); let path = (!__ball_eq(m, null) ? (__ball_index(m, 'path') ?? '') : __ball_to_string(input)); return File(path).existsSync(); } _stdFileDelete(input: any): any { this._checkSandbox('file_delete'); let m = this._stdAsMap(input); let path = (!__ball_eq(m, null) ? (__ball_index(m, 'path') ?? '') : __ball_to_string(input)); File(path).deleteSync(); } _stdDirList(input: any): any { this._checkSandbox('dir_list'); let m = this._stdAsMap(input); let path = (!__ball_eq(m, null) ? (__ball_index(m, 'path') ?? '') : __ball_to_string(input)); return [...Directory(path).listSync().map(((e) => { const input = e; return e.path; }))]; } _stdDirCreate(input: any): any { this._checkSandbox('dir_create'); let m = this._stdAsMap(input); let path = (!__ball_eq(m, null) ? (__ball_index(m, 'path') ?? '') : __ball_to_string(input)); Directory(path).createSync(true); } _stdDirExists(input: any): any { this._checkSandbox('dir_exists'); let m = this._stdAsMap(input); let path = (!__ball_eq(m, null) ? (__ball_index(m, 'path') ?? '') : __ball_to_string(input)); return Directory(path).existsSync(); } } export class _FlowSignal extends BallValue { readonly kind: string = ''; readonly label: string = null; readonly value: any = null; constructor(kind: any, label: any, value: any) { super(); if (typeof label === 'object' && label !== null && !Array.isArray(label) && ('label' in label || 'value' in label)) { let __n = label; label = __n.label; value = __n.value; } this.kind = kind; this.label = label; this.value = value; } } export class _Scope { readonly _bindings: Map = {}; readonly _parent: _Scope = null; constructor(_parent: any) { this._parent = _parent; } lookup(name: any): any { const input = name; if ((name in __ball_require_map(this._bindings, 'map_contains_key'))) { return __ball_index(this._bindings, name); } if (!__ball_eq(this._parent, null)) { return this._parent.lookup(name); } throw new BallRuntimeError((('Undefined variable: "' + __ball_to_string(name)) + '"')); } bind(name: any, value: any): any { return (this._bindings[name] = value); } has(name: any): any { const input = name; if ((name in __ball_require_map(this._bindings, 'map_contains_key'))) { return true; } return ((__ball_eq(this._parent, null) ? null : this._parent.has(name)) ?? false); } set(name: any, value: any): any { if ((name in __ball_require_map(this._bindings, 'map_contains_key'))) { this._bindings[name] = value; return; } if ((!__ball_eq(this._parent, null) && this._parent.has(name))) { this._parent.set(name, value); return; } this._bindings[name] = value; } child(): any { return new _Scope(this); } } export class BallRuntimeError { readonly message: string = ''; constructor(message: any) { this.message = message; } toString(): any { return ('BallRuntimeError: ' + __ball_to_string(this.message)); } } export class BallGenerator extends BallValue { readonly values: Array = []; completed: boolean = false; yield_(value: any): any { const input = value; return (this.values = (this.values.push(value), this.values)); } yieldAll(items: any): any { const input = items; return (__ball_push_all(this.values, items), this.values); } toString(): any { return (('BallGenerator(' + __ball_to_string(this.values.length)) + ' values)'); } } export class BallException extends BallValue { readonly typeName: string = ''; readonly value: any = null; constructor(typeName: any, value: any) { super(); this.typeName = typeName; this.value = value; } toString(): any { return ((__ball_eq(this.value, null) ? null : this.value.toString()) ?? this.typeName); } } export class _ExitSignal extends BallValue { readonly code: number = 0; constructor(code: any) { super(); this.code = code; } } export abstract class BallModuleHandler { handles(module: any): any { const input = module; } call(function_: any, input: any, engine: any): any { } init(engine: any): any { const input = engine; } } export class StdModuleHandler extends BallModuleHandler { readonly _dispatch: any = {}; readonly _composedDispatch: any = {}; readonly _allowlist: Array = null; readonly _tombstones: Array = new Set(); constructor() { super(); } get registeredFunctions(): any { return Set.unmodifiable((() => { const __r = new Set(); for (const __e of this._dispatch.keys) { __r.add(__e); } for (const __e of this._composedDispatch.keys) { __r.add(__e); } return __r; })()); } static subset(functions: any): any { const __inst = Object.create(StdModuleHandler.prototype); __inst._allowlist = functions.toSet(); return __inst; } handles(module: any): any { const input = module; return (((((((((module === 'std') || (module === 'std_collections')) || (module === 'std_io')) || (module === 'std_memory')) || (module === 'std_convert')) || (module === 'std_fs')) || (module === 'std_time')) || (module === 'std_concurrency')) ? (true) : false); } init(engine: any): any { const input = engine; let full = engine._buildStdDispatch(); let allowlist = this._allowlist; for (const entry of full.entries) { if (this._tombstones.includes(entry.key)) { continue; } if ((entry.key in __ball_require_map(this._composedDispatch, 'map_contains_key'))) { continue; } if ((!__ball_eq(allowlist, null) && !allowlist.includes(entry.key))) { continue; } (this._dispatch[entry.key] ??= ((() => { return entry.value; }))()); } } register(function_: any, handler: any): any { this._tombstones.remove(function_); this._composedDispatch.remove(function_); this._dispatch[function_] = handler; } registerComposer(function_: any, handler: any): any { this._tombstones.remove(function_); this._dispatch.remove(function_); this._composedDispatch[function_] = handler; } unregister(function_: any): any { const input = function_; this._tombstones = (this._tombstones.push(function_), this._tombstones); this._dispatch.remove(function_); this._composedDispatch.remove(function_); } call(function_: any, input: any, engine: any): any { let composed = __ball_index(this._composedDispatch, function_); if (!__ball_eq(composed, null)) { return composed(input, engine); } let handler = __ball_index(this._dispatch, function_); if (__ball_eq(handler, null)) { // Try camelCase to snake_case conversion before throwing const __snakeCase = function_.replace(/([A-Z])/g, '_$1').toLowerCase(); if (__snakeCase !== function_ && this._dispatch[__snakeCase]) { return this._dispatch[__snakeCase](input); } throw new BallRuntimeError('Unknown std function: "' + __ball_to_string(function_) + '"'); } return handler(input); } } let _kBallSetTag = (() => { return '__ball_set__'; })(); let _sentinel = (() => { return { '__type': 'main:Object' }; })(); let _builtinTypeNames = (() => { return new Set(['int', 'double', 'num', 'String', 'bool', 'List', 'Map', 'Set', 'Null', 'void', 'Object', 'dynamic', 'Function', 'Future', 'Stream', 'Iterable', 'Iterator', 'Type', 'Symbol', 'Never']); })(); let _ballPointerBytes = (() => { return 8; })(); let _ballStringCodeUnitBytes = (() => { return 2; })(); let _ballMapEntryBytes = (() => { return __ball_mul(_ballPointerBytes, 2); })(); let _stdFunctionToOperator = (() => { return { ['equals']: '__op_eq__', ['add']: '__op_add__', ['subtract']: '__op_sub__', ['multiply']: '__op_mul__', ['divide']: '__op_idiv__', ['divide_double']: '__op_div__', ['modulo']: '__op_mod__', ['less_than']: '__op_lt__', ['greater_than']: '__op_gt__', ['lte']: '__op_le__', ['gte']: '__op_ge__', ['index']: '__op_get_index__' }; })(); let _stdFunctionToOperatorSymbol = (() => { return { ['equals']: '==', ['add']: '+', ['subtract']: '-', ['multiply']: '*', ['divide']: '~/', ['divide_double']: '/', ['modulo']: '%', ['less_than']: '<', ['greater_than']: '>', ['lte']: '<=', ['gte']: '>=', ['index']: '[]' }; })(); function _ballUserMap(): any { return ({ ...{} }); } function _ballNewGenerator(): any { return new BallGenerator(); } function _ballDoubleToInt64(value: any): any { const input = value; if ((typeof value === 'number' && Number.isInteger(value))) { return value; } if ((typeof value === 'number' && Number.isInteger(value))) { return value.value; } let d = (((typeof value === 'number' || value instanceof BallDouble) ? value.value : new BallDouble(Number(value)))); if (__ball_ge(d, new BallDouble(9223372036854776000))) { return 9223372036854775807n; } if (__ball_le(d, __ball_negate(new BallDouble(9223372036854776000)))) { return __ball_negate(0); } let r = __ball_to_int(d); if ((__ball_gt(d, new BallDouble(0)) && __ball_lt(r, 0))) { return 9223372036854775807n; } return r; } function _ballCodeUnitAt(s: any, index: any): any { return s.charCodeAt(index); } function _ballToDouble(value: any): any { const input = value; if ((value instanceof BallDouble || (typeof value === 'number' && !Number.isInteger(value)))) { return value; } if ((typeof value === 'number' || value instanceof BallDouble)) { return value.value; } if ((typeof value === 'number' && Number.isInteger(value))) { return new BallDouble(Number(value)); } if ((typeof value === 'number' && Number.isInteger(value))) { return new BallDouble(Number(value.value)); } if ((typeof value === 'number' || value instanceof BallDouble)) { return new BallDouble(Number(value)); } return new BallDouble(0); } function _ballValueIsSet(v: any): any { const input = v; return ((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) && (_kBallSetTag in __ball_require_map(v, 'map_contains_key'))); } function _ballIsInt(v: any): any { const input = v; return ((typeof v === 'number' && Number.isInteger(v)) || (typeof v === 'number' && Number.isInteger(v))); } function _ballIsDouble(v: any): any { const input = v; return ((v instanceof BallDouble || (typeof v === 'number' && !Number.isInteger(v))) || (typeof v === 'number' || v instanceof BallDouble)); } function _ballIsNum(v: any): any { const input = v; return (((typeof v === 'number' || v instanceof BallDouble) || (typeof v === 'number' && Number.isInteger(v))) || (typeof v === 'number' || v instanceof BallDouble)); } function _ballIsString(v: any): any { const input = v; return ((typeof v === 'string') || (typeof v === 'string')); } function _ballIsBool(v: any): any { const input = v; return ((typeof v === 'boolean') || (typeof v === 'boolean')); } function _ballIsList(v: any): any { const input = v; return (Array.isArray(v) || false /* BallList is List in TS */); } function _ballIsMap(v: any): any { const input = v; return (((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) || false /* BallMap is Map in TS */) && !_ballValueIsSet(v)); } function _ballGeneratorValues(gen: any): any { const input = gen; return gen.values; } function _ballMapValues(map: any): any { const input = map; return [...map.values]; } function _ballMapHandleEntries(map: any): any { const input = map; if (false /* BallMap is Map in TS */) { return map.entries; } return map; } function _ballMapKeysDyn(map: any): any { const input = map; let handle = _ballMapHandleEntries(map); if ((typeof handle === 'object' && handle !== null && !Array.isArray(handle) && !(handle instanceof BallDouble) && !(handle instanceof Set))) { return [...handle.keys]; } return []; } function _ballMapValuesDyn(map: any): any { const input = map; let handle = _ballMapHandleEntries(map); if ((typeof handle === 'object' && handle !== null && !Array.isArray(handle) && !(handle instanceof BallDouble) && !(handle instanceof Set))) { return _ballMapValues(handle); } return []; } function _ballMapContainsKeyDyn(map: any, key: any): any { let handle = _ballMapHandleEntries(map); if ((typeof handle === 'object' && handle !== null && !Array.isArray(handle) && !(handle instanceof BallDouble) && !(handle instanceof Set))) { return (key in __ball_require_map(handle, 'map_contains_key')); } return false; } function _ballMapSetDyn(map: any, key: any, value: any): any { let handle = _ballMapHandleEntries(map); if ((typeof handle === 'object' && handle !== null && !Array.isArray(handle) && !(handle instanceof BallDouble) && !(handle instanceof Set))) { handle[key] = value; } } function ballObjectSetField(target: any, fieldName: any, val: any): any { if ((target instanceof BallObject)) { target.setField(fieldName, val); return; } if (false /* BallMap is Map in TS */) { if (('__type__' in __ball_require_map(target.entries, 'map_contains_key'))) { target[fieldName] = val; } return; } if ((__ball_is_type(target, "Map") && ('__type__' in __ball_require_map(target, 'map_contains_key')))) { target[fieldName] = val; } } function _metadataBool(field: any): any { const input = field; if (__ball_eq(field, null)) { return false; } if ((typeof field === 'boolean')) { return field; } if ((field != null)) { return (hasBoolValue(field) && field.boolValue); } if ((typeof field === 'object' && field !== null && !Array.isArray(field) && !(field instanceof BallDouble) && !(field instanceof Set))) { let bv = __ball_index(field, 'boolValue'); if ((typeof bv === 'boolean')) { return bv; } } return false; } function _ballNumIsNaN(v: any): any { const input = v; if ((typeof v === 'number' || v instanceof BallDouble)) { v = v.value; } if ((typeof v === 'number' && Number.isInteger(v))) { v = v.value; } if ((typeof v === 'number' && Number.isInteger(v))) { return false; } if ((v instanceof BallDouble || (typeof v === 'number' && !Number.isInteger(v)))) { let d = v; return !__ball_eq(d, d); } return false; } function _ballNumIsFinite(v: any): any { const input = v; if ((typeof v === 'number' || v instanceof BallDouble)) { v = v.value; } if ((typeof v === 'number' && Number.isInteger(v))) { v = v.value; } if ((typeof v === 'number' && Number.isInteger(v))) { return true; } if ((v instanceof BallDouble || (typeof v === 'number' && !Number.isInteger(v)))) { let d = v; if (!__ball_eq(d, d)) { return false; } return Number.isFinite(Number(d)); } return false; } function _ballNumIsInfinite(v: any): any { const input = v; if ((typeof v === 'number' || v instanceof BallDouble)) { v = v.value; } if ((typeof v === 'number' && Number.isInteger(v))) { v = v.value; } if ((typeof v === 'number' && Number.isInteger(v))) { return false; } if ((v instanceof BallDouble || (typeof v === 'number' && !Number.isInteger(v)))) { let d = v; return (Math.abs(Number(d)) === Infinity); } return false; } function _ballFuture(value: any): any { const input = value; return { ['__ball_future__']: true, ['value']: value, ['completed']: true }; } function _ballFutureError(error: any): any { const input = error; return { ['__ball_future__']: true, ['error']: error, ['completed']: true }; } function _isBallFuture(value: any): any { const input = value; return (__ball_is_type(value, "Map") && __ball_eq(__ball_index(value, '__ball_future__'), true)); } function _unwrapBallFuture(value: any): any { const input = value; if (_isBallFuture(value)) { let map = value; if (('error' in __ball_require_map(map, 'map_contains_key'))) { let error = __ball_index(map, 'error'); if ((error instanceof BallException)) { throw error; } if ((error instanceof BallRuntimeError)) { throw error; } throw new BallRuntimeError(((__ball_eq(error, null) ? null : error.toString()) ?? 'Unknown async error')); } return __ball_index(map, 'value'); } return value; } function _mathSqrt(v: any): any { const input = v; return sqrt(v); } function _mathPow(a: any, b: any): any { return new BallDouble(Number(pow(a, b))); } function _mathLog(v: any): any { const input = v; return log(v); } function _mathExp(v: any): any { const input = v; return exp(v); } function _mathSin(v: any): any { const input = v; return sin(v); } function _mathCos(v: any): any { const input = v; return cos(v); } function _mathTan(v: any): any { const input = v; return tan(v); } function _mathAsin(v: any): any { const input = v; return asin(v); } function _mathAcos(v: any): any { const input = v; return acos(v); } function _mathAtan(v: any): any { const input = v; return atan(v); } function _mathAtan2(a: any, b: any): any { return atan2(a, b); }