@ball-lang/engine 1.3.7 → 1.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"engine_setup.d.ts","sourceRoot":"","sources":["../src/engine_setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,GAAG,CAAC;IAChB,gBAAgB,EAAE,GAAG,CAAC;IACtB,aAAa,EAAE,GAAG,CAAC;IACnB,WAAW,EAAE,GAAG,CAAC;IACjB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY;qBA8TzB,GAAG,2BAAuB,GAAG;qBA6E7B,GAAG,KAAG,GAAG;eAqCf,GAAG,KAAG,MAAM;;;;4BA8CZ,GAAG,GAAG,OAAO;0BACf,GAAG,GAAG,IAAI;qBACf,MAAM,SAAS,GAAG,WAAW,GAAG,GAAG,GAAG;;;yDAqIkB,GAAG,KAAG,IAAI;0CA0iBvB,IAAI;sCAgfR,IAAI;sCA0Bb,GAAG,KAAG,IAAI;uBA5nDzB,GAAG,KAAG,OAAO;0BAwmCV,GAAG,KAAG,GAAG;EA0jBvC"}
1
+ {"version":3,"file":"engine_setup.d.ts","sourceRoot":"","sources":["../src/engine_setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,GAAG,CAAC;IAChB,gBAAgB,EAAE,GAAG,CAAC;IACtB,aAAa,EAAE,GAAG,CAAC;IACnB,WAAW,EAAE,GAAG,CAAC;IACjB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY;qBAoUzB,GAAG,2BAAuB,GAAG;qBA6E7B,GAAG,KAAG,GAAG;eAqCf,GAAG,KAAG,MAAM;;;;4BA8CZ,GAAG,GAAG,OAAO;0BACf,GAAG,GAAG,IAAI;qBACf,MAAM,SAAS,GAAG,WAAW,GAAG,GAAG,GAAG;;;yDAkJkB,GAAG,KAAG,IAAI;0CA0iBvB,IAAI;sCAshBR,IAAI;sCA0Bb,GAAG,KAAG,IAAI;uBArrDzB,GAAG,KAAG,OAAO;0BA2nCV,GAAG,KAAG,GAAG;EAgmBvC"}
@@ -223,6 +223,13 @@ export function createEngineSetup(mod) {
223
223
  return rem < 0 ? rem + Math.abs(r) : rem;
224
224
  }
225
225
  function _mathAbs(v) {
226
+ // `_coerceInt` unconditionally truncates through int64 coercion (needed
227
+ // for BigInt-magnitude int abs), which silently dropped double-ness for
228
+ // a BallDouble operand — e.g. `(2.5).abs()` returned `2` instead of
229
+ // `2.5` (#115). Route a BallDouble operand through double abs instead.
230
+ const BD = globalThis.BallDouble;
231
+ if (BD && v instanceof BD)
232
+ return new BD(Math.abs(v.value));
226
233
  const coerced = _coerceInt(v);
227
234
  if (typeof coerced === 'bigint') {
228
235
  return _int64Result(coerced < 0n ? -coerced : coerced);
@@ -601,6 +608,19 @@ export function createEngineSetup(mod) {
601
608
  case 'ceil': return Math.ceil(self);
602
609
  case 'compareTo': return self < arg0 ? -1 : self > arg0 ? 1 : 0;
603
610
  case 'clamp': return Math.min(Math.max(self, arg0), arg1);
611
+ case 'remainder': return self % Number(_coerceNum(arg0));
612
+ }
613
+ }
614
+ // A BallDouble-wrapped receiver (e.g. `double d = 2.5; d.remainder(2)`)
615
+ // falls through every case above (`typeof self !== 'number'`), and the
616
+ // compiled engine's own dispatch calls `self.remainder(...)` — a real
617
+ // method call that doesn't exist on the BallDouble class (unlike
618
+ // floor/ceil/round/abs, which work by accident via Math.* coercing
619
+ // through BallDouble.valueOf()) (#115). Handle it explicitly here.
620
+ {
621
+ const BD = globalThis.BallDouble;
622
+ if (BD && self instanceof BD && fn === 'remainder') {
623
+ return new BD(self.value % Number(_coerceNum(arg0)));
604
624
  }
605
625
  }
606
626
  if (typeof self === 'object' && self !== null && '__type__' in self) {
@@ -1530,7 +1550,17 @@ export function createEngineSetup(mod) {
1530
1550
  return op(l, r);
1531
1551
  };
1532
1552
  e._stdUnaryNum = function (input, op) {
1533
- return op(_coerceNum(e._extractUnaryArg(input)));
1553
+ // Preserve BallDouble-ness through negate (#67): a whole-number
1554
+ // double like `-7.0` must not collapse to a bare JS integer. Mirrors
1555
+ // the _stdBinary patch above. bitwise_not (the only other consumer)
1556
+ // always operates on int, so it never sees a BallDouble operand here.
1557
+ const value = e._extractUnaryArg(input);
1558
+ const BD = globalThis.BallDouble;
1559
+ const vBD = BD && value instanceof BD;
1560
+ const result = op(_coerceNum(value));
1561
+ if (vBD && typeof result === 'number')
1562
+ return new BD(result);
1563
+ return result;
1534
1564
  };
1535
1565
  e._stdBinaryComp = function (input, op) {
1536
1566
  const rec = e._extractBinaryArgs(input);
@@ -1561,6 +1591,24 @@ export function createEngineSetup(mod) {
1561
1591
  }
1562
1592
  return result;
1563
1593
  };
1594
+ // `remainder` is the one num instance method the compiled engine's own
1595
+ // `_dispatchBuiltinInstanceMethod` calls as a literal Dart method
1596
+ // (`self.remainder(...)`) rather than routing through a Math.*-backed
1597
+ // std function (floor/ceil/round/abs/truncate all get encoder-routed to
1598
+ // math_floor/math_ceil/etc, which is why they survive a BallDouble
1599
+ // receiver via valueOf() coercion). A BallDouble-wrapped receiver has no
1600
+ // `.remainder` method, so it throws (#115). Intercept just that case.
1601
+ const origDispatchBuiltinInstanceMethod = e._dispatchBuiltinInstanceMethod.bind(e);
1602
+ e._dispatchBuiltinInstanceMethod = async function (self, method, input) {
1603
+ const BD = globalThis.BallDouble;
1604
+ if (BD && self instanceof BD && method === 'remainder') {
1605
+ const rec = e._cfAsMap(input) ?? {};
1606
+ const rawArg = rec['arg0'] ?? rec['value'];
1607
+ const other = (BD && rawArg instanceof BD) ? rawArg.value : _coerceNum(rawArg);
1608
+ return new BD(self.value % Number(other));
1609
+ }
1610
+ return origDispatchBuiltinInstanceMethod(self, method, input);
1611
+ };
1564
1612
  const origPatternKind = e._patternKind?.bind(e);
1565
1613
  e._patternKind = function (pattern) {
1566
1614
  const explicit = pattern?.['__pattern_kind__'];
@@ -1965,7 +2013,18 @@ export function createEngineSetup(mod) {
1965
2013
  const rec = e._extractBinaryArgs(i);
1966
2014
  return _int64Modulo(rec[0], rec[1]);
1967
2015
  });
1968
- handler.register('negate', (i) => _int64Negate(e._extractUnaryArg(i)));
2016
+ handler.register('negate', (i) => {
2017
+ // `_int64Negate` unconditionally coerces through `_coerceInt` (it's
2018
+ // the int64-safe path for `bigint`-magnitude values), which silently
2019
+ // truncated a double operand to an int — losing double-ness for
2020
+ // e.g. `-7.0` (#67). Route a BallDouble operand through double
2021
+ // negation instead; only a genuine int reaches `_int64Negate`.
2022
+ const value = e._extractUnaryArg(i);
2023
+ const BD = globalThis.BallDouble;
2024
+ if (BD && value instanceof BD)
2025
+ return new BD(-value.value);
2026
+ return _int64Negate(value);
2027
+ });
1969
2028
  handler.register('bitwise_and', (i) => e._stdBinaryInt(i, (a, b) => _int64Binary((l, r) => l & r, a, b)));
1970
2029
  handler.register('bitwise_or', (i) => e._stdBinaryInt(i, (a, b) => _int64Binary((l, r) => l | r, a, b)));
1971
2030
  handler.register('bitwise_xor', (i) => e._stdBinaryInt(i, (a, b) => _int64Binary((l, r) => l ^ r, a, b)));