@ball-lang/engine 1.3.7 → 1.3.8

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.
@@ -1560,7 +1560,7 @@ export class BallEngine {
1560
1560
  let enumName = enumDesc.name;
1561
1561
  let enumMap = {};
1562
1562
  let enumValueList = enumDesc.value;
1563
- for (var vi = 0; (vi < enumValueList.length); (vi++)) {
1563
+ for (let vi = 0; (vi < enumValueList.length); (vi++)) {
1564
1564
  let v = __ball_index(enumValueList, vi);
1565
1565
  let entry = { ['__type__']: enumName, ['name']: v.name, ['index']: v.number };
1566
1566
  enumMap[v.name] = entry;
@@ -1878,7 +1878,7 @@ export class BallEngine {
1878
1878
  }
1879
1879
  } else {
1880
1880
  if (!__ball_eq(inputMap, null)) {
1881
- for (var i = 0; (i < params.length); (i++)) {
1881
+ for (let i = 0; (i < params.length); (i++)) {
1882
1882
  let p = __ball_index(params, i);
1883
1883
  if ((p in inputMap)) {
1884
1884
  scope.bind(p, __ball_index(inputMap, p));
@@ -1894,7 +1894,7 @@ export class BallEngine {
1894
1894
  }
1895
1895
  } else {
1896
1896
  if (Array.isArray(input)) {
1897
- for (var i = 0; ((i < params.length) && (i < input.length)); (i++)) {
1897
+ for (let i = 0; ((i < params.length) && (i < input.length)); (i++)) {
1898
1898
  scope.bind(__ball_index(params, i), __ball_index(input, i));
1899
1899
  }
1900
1900
  }
@@ -2028,7 +2028,7 @@ export class BallEngine {
2028
2028
  let params = (hasMetadata(func) ? this._extractParams(func.metadata) : []);
2029
2029
  let paramsMeta = (hasMetadata(func) ? this._extractParamsMeta(func.metadata) : []);
2030
2030
  let resolvedParams = {};
2031
- for (var i = 0; (i < params.length); (i++)) {
2031
+ for (let i = 0; (i < params.length); (i++)) {
2032
2032
  let param = __ball_index(params, i);
2033
2033
  let value = __no_init__;
2034
2034
  if ((param in inputMap)) {
@@ -2156,7 +2156,7 @@ export class BallEngine {
2156
2156
  let resolvedParams = {};
2157
2157
  let inputMap = this._asMap(input);
2158
2158
  if (!__ball_eq(inputMap, null)) {
2159
- for (var i = 0; (i < params.length); (i++)) {
2159
+ for (let i = 0; (i < params.length); (i++)) {
2160
2160
  let p = __ball_index(params, i);
2161
2161
  let isThis = ((i < paramsMeta.length) && __ball_eq(__ball_index(__ball_index(paramsMeta, i), 'is_this'), true));
2162
2162
  let val = __no_init__;
@@ -2234,7 +2234,7 @@ export class BallEngine {
2234
2234
  })() ?? '');
2235
2235
  let argNames = this._parseSuperArgs(argsStr);
2236
2236
  let superInput = {};
2237
- for (var i = 0; (i < argNames.length); (i++)) {
2237
+ for (let i = 0; (i < argNames.length); (i++)) {
2238
2238
  let token = __ball_index(argNames, i);
2239
2239
  if ((token in resolvedParams)) {
2240
2240
  superInput[('arg' + __ball_to_string(i))] = __ball_index(resolvedParams, token);
@@ -2268,7 +2268,7 @@ export class BallEngine {
2268
2268
  let superCtorEntry = this._lookupConstructor(superclass);
2269
2269
  if (!__ball_eq(superCtorEntry, null)) {
2270
2270
  let superInput = {};
2271
- for (var i = 0; (i < resolvedParams.length); (i++)) {
2271
+ for (let i = 0; (i < resolvedParams.length); (i++)) {
2272
2272
  superInput[('arg' + __ball_to_string(i))] = resolvedParams.values.elementAt(i);
2273
2273
  }
2274
2274
  return this._callFunction(superCtorEntry.module, superCtorEntry.func, superInput);
@@ -3973,7 +3973,7 @@ export class BallEngine {
3973
3973
  if ((!__ball_eq(ctorEntry, null) && hasMetadata(ctorEntry.func))) {
3974
3974
  let params = this._extractParams(ctorEntry.func.metadata);
3975
3975
  let paramsMeta = this._extractParamsMeta(ctorEntry.func.metadata);
3976
- for (var i = 0; (i < params.length); (i++)) {
3976
+ for (let i = 0; (i < params.length); (i++)) {
3977
3977
  let param = __ball_index(params, i);
3978
3978
  let value = __no_init__;
3979
3979
  if ((param in fields)) {
@@ -4453,7 +4453,7 @@ export class BallEngine {
4453
4453
  }
4454
4454
  }
4455
4455
  if (!(paramNames.length === 0)) {
4456
- for (var i = 0; (i < paramNames.length); (i++)) {
4456
+ for (let i = 0; (i < paramNames.length); (i++)) {
4457
4457
  let p = __ball_index(paramNames, i);
4458
4458
  if (!lambdaScope.has(p)) {
4459
4459
  if ((p in inputMap)) {
@@ -5767,13 +5767,24 @@ export class BallEngine {
5767
5767
  return null;
5768
5768
  }
5769
5769
  let result = __no_init__;
5770
- do {
5771
- result = await this._evalExpression(body, scope);
5772
- if ((((result instanceof _FlowSignal) && __ball_eq(result.kind, 'goto')) && __ball_eq(result.label, label))) {
5773
- continue;
5770
+ let repeat = true;
5771
+ while (repeat) {
5772
+ repeat = false;
5773
+ try {
5774
+ result = await this._evalExpression(body, scope);
5775
+ } catch (__ball_active_error) {
5776
+ const e = __ball_active_error;
5777
+ let signal = e;
5778
+ if ((((signal instanceof _FlowSignal) && __ball_eq(signal.kind, 'goto')) && __ball_eq(signal.label, label))) {
5779
+ repeat = true;
5780
+ } else {
5781
+ throw __ball_active_error;
5782
+ }
5774
5783
  }
5775
- break;
5776
- } while (true);
5784
+ if ((((!repeat && (result instanceof _FlowSignal)) && __ball_eq(result.kind, 'goto')) && __ball_eq(result.label, label))) {
5785
+ repeat = true;
5786
+ }
5787
+ }
5777
5788
  return result;
5778
5789
  }
5779
5790
 
@@ -5854,7 +5865,19 @@ export class BallEngine {
5854
5865
  if (false /* BallMap is Map in TS */) {
5855
5866
  unwrappedSelf = self.entries;
5856
5867
  } else {
5857
- unwrappedSelf = self;
5868
+ if ((typeof self === 'number' || self instanceof BallDouble)) {
5869
+ unwrappedSelf = self;
5870
+ } else {
5871
+ if ((typeof self === 'number' && Number.isInteger(self))) {
5872
+ unwrappedSelf = self.value;
5873
+ } else {
5874
+ if ((typeof self === 'number' || self instanceof BallDouble)) {
5875
+ unwrappedSelf = self.value;
5876
+ } else {
5877
+ unwrappedSelf = self;
5878
+ }
5879
+ }
5880
+ }
5858
5881
  }
5859
5882
  }
5860
5883
  }
@@ -5907,7 +5930,7 @@ export class BallEngine {
5907
5930
  else if ((__sw === 'sort')) {
5908
5931
  if ((typeof arg0 === 'function')) {
5909
5932
  let sorted = [...self];
5910
- for (var j = 1; (j < sorted.length); (j++)) {
5933
+ for (let j = 1; (j < sorted.length); (j++)) {
5911
5934
  let key = __ball_index(sorted, j);
5912
5935
  let k = __ball_sub(j, 1);
5913
5936
  while ((k >= 0)) {
@@ -6632,7 +6655,10 @@ export class BallEngine {
6632
6655
  const input = i;
6633
6656
  return this._stdConvert(i, ((v) => {
6634
6657
  const input = v;
6635
- return __ball_to_string(v);
6658
+ if ((typeof v === 'number' || v instanceof BallDouble)) {
6659
+ return __ball_to_string(v);
6660
+ }
6661
+ return __ball_to_string(new BallDouble(v));
6636
6662
  }));
6637
6663
  }), ['string_to_int']: ((i) => {
6638
6664
  const input = i;
@@ -6644,7 +6670,7 @@ export class BallEngine {
6644
6670
  const input = i;
6645
6671
  return this._stdConvert(i, ((v) => {
6646
6672
  const input = v;
6647
- return __ball_parse_double(v);
6673
+ return new BallDouble(__ball_parse_double(v));
6648
6674
  }));
6649
6675
  }), ['to_double']: ((i) => {
6650
6676
  const input = i;
@@ -6935,7 +6961,7 @@ export class BallEngine {
6935
6961
  }));
6936
6962
  return sorted;
6937
6963
  }
6938
- for (var j = 1; (j < sorted.length); (j++)) {
6964
+ for (let j = 1; (j < sorted.length); (j++)) {
6939
6965
  let key = __ball_index(sorted, j);
6940
6966
  let k = __ball_sub(j, 1);
6941
6967
  while ((k >= 0)) {
@@ -7024,10 +7050,16 @@ export class BallEngine {
7024
7050
  if ((r != null)) {
7025
7051
  r = await r;
7026
7052
  }
7027
- if (Array.isArray(r)) {
7028
- __ball_push_all(result, r);
7053
+ if (false /* BallList is List in TS */) {
7054
+ for (const item of r.items) {
7055
+ result = (result.push(item), result);
7056
+ }
7029
7057
  } else {
7030
- result = (result.push(r), result);
7058
+ if (Array.isArray(r)) {
7059
+ __ball_push_all(result, r);
7060
+ } else {
7061
+ result = (result.push(r), result);
7062
+ }
7031
7063
  }
7032
7064
  }
7033
7065
  return result;
@@ -7373,7 +7405,8 @@ export class BallEngine {
7373
7405
  return new _FlowSignal('yield_each', { value: this._extractUnaryArg(i) });
7374
7406
  }), ['symbol']: ((i) => {
7375
7407
  const input = i;
7376
- return this._extractField(i, 'value');
7408
+ let name = this._extractField(i, 'value');
7409
+ return (('Symbol("' + __ball_to_string(name)) + '")');
7377
7410
  }), ['type_literal']: ((i) => {
7378
7411
  const input = i;
7379
7412
  return this._extractField(i, 'type');
@@ -8091,7 +8124,7 @@ export class BallEngine {
8091
8124
  }
8092
8125
  this._trackMemoryAllocation(__ball_mul(length, _ballPointerBytes));
8093
8126
  let result = [];
8094
- for (var index = 0; (index < length); (index++)) {
8127
+ for (let index = 0; (index < length); (index++)) {
8095
8128
  let value = generator(index);
8096
8129
  if ((value != null)) {
8097
8130
  value = await value;
@@ -8241,7 +8274,7 @@ export class BallEngine {
8241
8274
  }
8242
8275
  }
8243
8276
  if (__ball_eq(objTypeArgs.length, typeArgs.length)) {
8244
- for (var i = 0; (i < typeArgs.length); (i++)) {
8277
+ for (let i = 0; (i < typeArgs.length); (i++)) {
8245
8278
  if (!__ball_eq(__ball_index(objTypeArgs, i), __ball_index(typeArgs, i))) {
8246
8279
  return false;
8247
8280
  }
@@ -8335,7 +8368,7 @@ export class BallEngine {
8335
8368
  let args = [];
8336
8369
  let depth = 0;
8337
8370
  let start = 0;
8338
- for (var i = 0; (i < str.length); (i++)) {
8371
+ for (let i = 0; (i < str.length); (i++)) {
8339
8372
  if (__ball_eq(__ball_index(str, i), '<')) {
8340
8373
  (depth++);
8341
8374
  }
@@ -8572,7 +8605,7 @@ export class BallEngine {
8572
8605
  if ((!__ball_eq(restIndex, __ball_negate(1)) && (listVal.length < fixedCount))) {
8573
8606
  return false;
8574
8607
  }
8575
- for (var i = 0; (i < elements.length); (i++)) {
8608
+ for (let i = 0; (i < elements.length); (i++)) {
8576
8609
  let elem = __ball_index(elements, i);
8577
8610
  let elemMap = this._stdAsMap(elem);
8578
8611
  if ((!__ball_eq(elemMap, null) && __ball_eq(this._patternKind(elemMap), 'rest'))) {
@@ -8888,7 +8921,7 @@ export class BallEngine {
8888
8921
 
8889
8922
  _repeatString(s: any, count: any): any {
8890
8923
  let out = '';
8891
- for (var k = 0; (k < count); (k++)) {
8924
+ for (let k = 0; (k < count); (k++)) {
8892
8925
  out = (__ball_to_string(out) + __ball_to_string(s));
8893
8926
  }
8894
8927
  return out;
@@ -8944,7 +8977,10 @@ export class BallEngine {
8944
8977
 
8945
8978
  _stdUnaryNum(input: any, op: any): any {
8946
8979
  let value = this._extractUnaryArg(input);
8947
- return op(this._toNum(value));
8980
+ const __vBD = value instanceof BallDouble;
8981
+ const __result = op(this._toNum(value));
8982
+ if (__vBD && typeof __result === 'number') return new BallDouble(__result);
8983
+ return __result;
8948
8984
  }
8949
8985
 
8950
8986
  _stdNot(input: any): any {
@@ -231,6 +231,12 @@ export function createEngineSetup(mod: EngineModule) {
231
231
  }
232
232
 
233
233
  function _mathAbs(v: any): any {
234
+ // `_coerceInt` unconditionally truncates through int64 coercion (needed
235
+ // for BigInt-magnitude int abs), which silently dropped double-ness for
236
+ // a BallDouble operand — e.g. `(2.5).abs()` returned `2` instead of
237
+ // `2.5` (#115). Route a BallDouble operand through double abs instead.
238
+ const BD = (globalThis as any).BallDouble;
239
+ if (BD && v instanceof BD) return new BD(Math.abs(v.value));
234
240
  const coerced = _coerceInt(v);
235
241
  if (typeof coerced === 'bigint') {
236
242
  return _int64Result(coerced < 0n ? -coerced : coerced);
@@ -569,6 +575,19 @@ export function createEngineSetup(mod: EngineModule) {
569
575
  case 'ceil': return Math.ceil(self);
570
576
  case 'compareTo': return self < arg0 ? -1 : self > arg0 ? 1 : 0;
571
577
  case 'clamp': return Math.min(Math.max(self, arg0), arg1);
578
+ case 'remainder': return self % Number(_coerceNum(arg0));
579
+ }
580
+ }
581
+ // A BallDouble-wrapped receiver (e.g. `double d = 2.5; d.remainder(2)`)
582
+ // falls through every case above (`typeof self !== 'number'`), and the
583
+ // compiled engine's own dispatch calls `self.remainder(...)` — a real
584
+ // method call that doesn't exist on the BallDouble class (unlike
585
+ // floor/ceil/round/abs, which work by accident via Math.* coercing
586
+ // through BallDouble.valueOf()) (#115). Handle it explicitly here.
587
+ {
588
+ const BD = (globalThis as any).BallDouble;
589
+ if (BD && self instanceof BD && fn === 'remainder') {
590
+ return new BD(self.value % Number(_coerceNum(arg0)));
572
591
  }
573
592
  }
574
593
  if (typeof self === 'object' && self !== null && '__type__' in self) {
@@ -1231,7 +1250,16 @@ export function createEngineSetup(mod: EngineModule) {
1231
1250
  };
1232
1251
 
1233
1252
  e._stdUnaryNum = function(input: any, op: any) {
1234
- return op(_coerceNum(e._extractUnaryArg(input)));
1253
+ // Preserve BallDouble-ness through negate (#67): a whole-number
1254
+ // double like `-7.0` must not collapse to a bare JS integer. Mirrors
1255
+ // the _stdBinary patch above. bitwise_not (the only other consumer)
1256
+ // always operates on int, so it never sees a BallDouble operand here.
1257
+ const value = e._extractUnaryArg(input);
1258
+ const BD = (globalThis as any).BallDouble;
1259
+ const vBD = BD && value instanceof BD;
1260
+ const result = op(_coerceNum(value));
1261
+ if (vBD && typeof result === 'number') return new BD(result);
1262
+ return result;
1235
1263
  };
1236
1264
 
1237
1265
  e._stdBinaryComp = function(input: any, op: any) {
@@ -1264,6 +1292,25 @@ export function createEngineSetup(mod: EngineModule) {
1264
1292
  return result;
1265
1293
  };
1266
1294
 
1295
+ // `remainder` is the one num instance method the compiled engine's own
1296
+ // `_dispatchBuiltinInstanceMethod` calls as a literal Dart method
1297
+ // (`self.remainder(...)`) rather than routing through a Math.*-backed
1298
+ // std function (floor/ceil/round/abs/truncate all get encoder-routed to
1299
+ // math_floor/math_ceil/etc, which is why they survive a BallDouble
1300
+ // receiver via valueOf() coercion). A BallDouble-wrapped receiver has no
1301
+ // `.remainder` method, so it throws (#115). Intercept just that case.
1302
+ const origDispatchBuiltinInstanceMethod = e._dispatchBuiltinInstanceMethod.bind(e);
1303
+ e._dispatchBuiltinInstanceMethod = async function(self: any, method: any, input: any) {
1304
+ const BD = (globalThis as any).BallDouble;
1305
+ if (BD && self instanceof BD && method === 'remainder') {
1306
+ const rec = e._cfAsMap(input) ?? {};
1307
+ const rawArg = rec['arg0'] ?? rec['value'];
1308
+ const other = (BD && rawArg instanceof BD) ? rawArg.value : _coerceNum(rawArg);
1309
+ return new BD(self.value % Number(other));
1310
+ }
1311
+ return origDispatchBuiltinInstanceMethod(self, method, input);
1312
+ };
1313
+
1267
1314
  const origPatternKind = e._patternKind?.bind(e);
1268
1315
  e._patternKind = function(pattern: any): any {
1269
1316
  const explicit = pattern?.['__pattern_kind__'];
@@ -1669,7 +1716,17 @@ export function createEngineSetup(mod: EngineModule) {
1669
1716
  const rec = e._extractBinaryArgs(i);
1670
1717
  return _int64Modulo(rec[0], rec[1]);
1671
1718
  });
1672
- handler.register('negate', (i: any) => _int64Negate(e._extractUnaryArg(i)));
1719
+ handler.register('negate', (i: any) => {
1720
+ // `_int64Negate` unconditionally coerces through `_coerceInt` (it's
1721
+ // the int64-safe path for `bigint`-magnitude values), which silently
1722
+ // truncated a double operand to an int — losing double-ness for
1723
+ // e.g. `-7.0` (#67). Route a BallDouble operand through double
1724
+ // negation instead; only a genuine int reaches `_int64Negate`.
1725
+ const value = e._extractUnaryArg(i);
1726
+ const BD = (globalThis as any).BallDouble;
1727
+ if (BD && value instanceof BD) return new BD(-value.value);
1728
+ return _int64Negate(value);
1729
+ });
1673
1730
  handler.register('bitwise_and', (i: any) => e._stdBinaryInt(i, (a: any, b: any) => _int64Binary((l, r) => l & r, a, b)));
1674
1731
  handler.register('bitwise_or', (i: any) => e._stdBinaryInt(i, (a: any, b: any) => _int64Binary((l, r) => l | r, a, b)));
1675
1732
  handler.register('bitwise_xor', (i: any) => e._stdBinaryInt(i, (a: any, b: any) => _int64Binary((l, r) => l ^ r, a, b)));