@ball-lang/engine 1.4.1 → 1.4.3

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.
@@ -1743,7 +1743,7 @@ export class BallEngine {
1743
1743
  this._currentModule = module.name;
1744
1744
  let value = (hasBody(func) ? await this._evalExpression(func.body, this._globalScope) : null);
1745
1745
  if (func.outputType.startsWith('Map')) {
1746
- if (((value instanceof Set) && (value.length === 0))) {
1746
+ if ((this._isBallSet(value) && (this._ballSetItems(value).length === 0))) {
1747
1747
  value = _ballUserMap();
1748
1748
  }
1749
1749
  if ((Array.isArray(value) && (value.length === 0))) {
@@ -3489,7 +3489,7 @@ export class BallEngine {
3489
3489
  let func = staticField.func;
3490
3490
  let value = await this._callFunction(staticField.module, func, null);
3491
3491
  if (func.outputType.startsWith('Map')) {
3492
- if (((value instanceof Set) && (value.length === 0))) {
3492
+ if ((this._isBallSet(value) && (this._ballSetItems(value).length === 0))) {
3493
3493
  value = _ballUserMap();
3494
3494
  }
3495
3495
  if ((Array.isArray(value) && (value.length === 0))) {
@@ -3508,6 +3508,39 @@ export class BallEngine {
3508
3508
  if (_isBallFuture(object)) {
3509
3509
  object = __ball_index(object, 'value');
3510
3510
  }
3511
+ if (this._isBallSet(object)) {
3512
+ let items = this._ballSetItems(object);
3513
+ do {
3514
+ const __sw = fieldName;
3515
+ if ((__sw === 'length')) {
3516
+ return items.length;
3517
+ }
3518
+ else if ((__sw === 'isEmpty')) {
3519
+ return (items.length === 0);
3520
+ }
3521
+ else if ((__sw === 'isNotEmpty')) {
3522
+ return !(items.length === 0);
3523
+ }
3524
+ else if ((__sw === 'first')) {
3525
+ if (!(items.length === 0)) {
3526
+ return items.first;
3527
+ }
3528
+ throw new BallRuntimeError('First element of empty set');
3529
+ }
3530
+ else if ((__sw === 'last')) {
3531
+ if (!(items.length === 0)) {
3532
+ return items.last;
3533
+ }
3534
+ throw new BallRuntimeError('Last element of empty set');
3535
+ }
3536
+ else if ((__sw === 'single')) {
3537
+ if (__ball_eq(items.length, 1)) {
3538
+ return items.single;
3539
+ }
3540
+ throw new BallRuntimeError('Set does not have exactly one element');
3541
+ }
3542
+ } while (false);
3543
+ }
3511
3544
  let objectMap = this._asMap(object);
3512
3545
  if ((!__ball_eq(objectMap, null) && __ball_eq(__ball_index(objectMap, '__type__'), '__builtin_class__'))) {
3513
3546
  let className = __ball_index(objectMap, '__class_ref__');
@@ -4417,7 +4450,7 @@ export class BallEngine {
4417
4450
  return (__ball_eq(__naa_12, null) ? null : __naa_12.stringValue);
4418
4451
  })();
4419
4452
  if ((!__ball_eq(letType, null) && letType.startsWith('Map'))) {
4420
- if (((value instanceof Set) && (value.length === 0))) {
4453
+ if ((this._isBallSet(value) && (this._ballSetItems(value).length === 0))) {
4421
4454
  value = _ballUserMap();
4422
4455
  }
4423
4456
  if ((Array.isArray(value) && (value.length === 0))) {
@@ -5274,6 +5307,10 @@ export class BallEngine {
5274
5307
  if ((!__ball_eq(indexTarget, null) && !__ball_eq(indexExpr, null))) {
5275
5308
  let list = await this._evalExpression(indexTarget, scope);
5276
5309
  let idx = await this._evalExpression(indexExpr, scope);
5310
+ if (this._isBallSet(list)) {
5311
+ list = _ballUserMap();
5312
+ this._cfWritebackIndexed(indexTarget, list, scope);
5313
+ }
5277
5314
  if (((!__ball_eq(op, null) && !(op.length === 0)) && !__ball_eq(op, '='))) {
5278
5315
  let computed = __no_init__;
5279
5316
  let didSet = false;
@@ -5881,6 +5918,73 @@ export class BallEngine {
5881
5918
  }
5882
5919
  }
5883
5920
  }
5921
+ if (_ballValueIsSet(unwrappedSelf)) {
5922
+ let items = this._ballSetItems(unwrappedSelf);
5923
+ do {
5924
+ const __sw = method;
5925
+ if ((__sw === 'add')) {
5926
+ if (items.includes(arg0)) {
5927
+ return false;
5928
+ }
5929
+ items = (items.push(arg0), items);
5930
+ return true;
5931
+ }
5932
+ else if ((__sw === 'remove')) {
5933
+ let had = items.includes(arg0);
5934
+ items.remove(arg0);
5935
+ return had;
5936
+ }
5937
+ else if ((__sw === 'addAll')) {
5938
+ for (const e of (this._stdAsList(arg0) ?? [])) {
5939
+ if (!items.includes(e)) {
5940
+ items = (items.push(e), items);
5941
+ }
5942
+ }
5943
+ return null;
5944
+ }
5945
+ else if ((__sw === 'contains')) {
5946
+ return items.includes(arg0);
5947
+ }
5948
+ else if ((__sw === 'union')) {
5949
+ let out = [items];
5950
+ for (const e of (this._stdAsList(arg0) ?? [])) {
5951
+ if (!out.includes(e)) {
5952
+ out = (out.push(e), out);
5953
+ }
5954
+ }
5955
+ return this._ballSetOf(out);
5956
+ }
5957
+ else if ((__sw === 'intersection')) {
5958
+ let other = (this._stdAsList(arg0) ?? []);
5959
+ return this._ballSetOf(items.filter(((e) => {
5960
+ const input = e;
5961
+ return other.includes(e);
5962
+ })));
5963
+ }
5964
+ else if ((__sw === 'difference')) {
5965
+ let other = (this._stdAsList(arg0) ?? []);
5966
+ return this._ballSetOf(items.filter(((e) => {
5967
+ const input = e;
5968
+ return !other.includes(e);
5969
+ })));
5970
+ }
5971
+ else if ((__sw === 'toSet')) {
5972
+ return this._ballSetOf(items);
5973
+ }
5974
+ else if ((__sw === 'length')) {
5975
+ return items.length;
5976
+ }
5977
+ else if ((__sw === 'isEmpty')) {
5978
+ return (items.length === 0);
5979
+ }
5980
+ else if ((__sw === 'isNotEmpty')) {
5981
+ return !(items.length === 0);
5982
+ }
5983
+ else {
5984
+ return this._dispatchBuiltinInstanceMethod(items, method, input);
5985
+ }
5986
+ } while (false);
5987
+ }
5884
5988
  if (Array.isArray(unwrappedSelf)) {
5885
5989
  let self = unwrappedSelf;
5886
5990
  let _wrapList = ((result) => {
@@ -5889,7 +5993,16 @@ export class BallEngine {
5889
5993
  });
5890
5994
  do {
5891
5995
  const __sw = method;
5892
- if ((__sw === 'add')) {
5996
+ if ((__sw === 'length')) {
5997
+ return self.length;
5998
+ }
5999
+ else if ((__sw === 'isEmpty')) {
6000
+ return (self.length === 0);
6001
+ }
6002
+ else if ((__sw === 'isNotEmpty')) {
6003
+ return !(self.length === 0);
6004
+ }
6005
+ else if ((__sw === 'add')) {
5893
6006
  self = (self.push(arg0), self);
5894
6007
  return null;
5895
6008
  }
@@ -6404,11 +6517,49 @@ export class BallEngine {
6404
6517
  if (false /* BallList is List in TS */) {
6405
6518
  return v.items;
6406
6519
  }
6520
+ if (this._isBallSet(v)) {
6521
+ return this._ballSetItems(v);
6522
+ }
6407
6523
  if (Array.isArray(v)) {
6408
6524
  return v;
6409
6525
  }
6410
6526
  }
6411
6527
 
6528
+ _isBallSet(v: any): any {
6529
+ const input = v;
6530
+ return ((v instanceof Set) || _ballValueIsSet(v));
6531
+ }
6532
+
6533
+ _ballSetItems(v: any): any {
6534
+ const input = v;
6535
+ if (_ballValueIsSet(v)) {
6536
+ let setMap = v;
6537
+ let raw = __ball_index(setMap, _kBallSetTag);
6538
+ if (false /* BallList is List in TS */) {
6539
+ return raw.items;
6540
+ }
6541
+ if (Array.isArray(raw)) {
6542
+ return raw;
6543
+ }
6544
+ return [];
6545
+ }
6546
+ if ((v instanceof Set)) {
6547
+ return [...v];
6548
+ }
6549
+ return [];
6550
+ }
6551
+
6552
+ _ballSetOf(items: any): any {
6553
+ const input = items;
6554
+ let result = [];
6555
+ for (const item of items) {
6556
+ if (!result.includes(item)) {
6557
+ result = (result.push(item), result);
6558
+ }
6559
+ }
6560
+ return { [_kBallSetTag]: result };
6561
+ }
6562
+
6412
6563
  async _tryOperatorOverride(function_: any, input: any): Promise<any> {
6413
6564
  let op = __ball_index(_stdFunctionToOperator, function_);
6414
6565
  if (__ball_eq(op, null)) {
@@ -6700,7 +6851,25 @@ export class BallEngine {
6700
6851
  let m = (this._stdAsMap(i) ?? { ['value']: i });
6701
6852
  let v = (__ball_index(m, 'value') ?? __ball_index(m, 'left'));
6702
6853
  let digits = (__ball_index(m, 'digits') ?? __ball_index(m, 'fractionDigits'));
6703
- return (+(this._toNum(v))).toFixed(this._toInt(digits));
6854
+ let n = this._toNum(v);
6855
+ let s = (+(n)).toFixed(this._toInt(digits));
6856
+ if (((__ball_eq(n, 0) && (new BallDouble(Number(new BallDouble(1)) / Number(n)) < 0)) && !s.startsWith('-'))) {
6857
+ return ('-' + __ball_to_string(s));
6858
+ }
6859
+ return s;
6860
+ }), ['to_string_as_exponential']: ((i) => {
6861
+ const input = i;
6862
+ let m = (this._stdAsMap(i) ?? { ['value']: i });
6863
+ let v = (__ball_index(m, 'value') ?? __ball_index(m, 'left'));
6864
+ let digits = (__ball_index(m, 'digits') ?? __ball_index(m, 'fractionDigits'));
6865
+ let n = this._toNum(v);
6866
+ return (__ball_eq(digits, null) ? (+(n)).toExponential() : (+(n)).toExponential(this._toInt(digits)));
6867
+ }), ['to_string_as_precision']: ((i) => {
6868
+ const input = i;
6869
+ let m = (this._stdAsMap(i) ?? { ['value']: i });
6870
+ let v = (__ball_index(m, 'value') ?? __ball_index(m, 'left'));
6871
+ let precision = (__ball_index(m, 'precision') ?? __ball_index(m, 'digits'));
6872
+ return (+(this._toNum(v))).toPrecision(this._toInt(precision));
6704
6873
  }), ['string_interpolation']: (async (i) => {
6705
6874
  const input = i;
6706
6875
  let m = this._stdAsMap(i);
@@ -6759,7 +6928,16 @@ export class BallEngine {
6759
6928
  const input = i;
6760
6929
  let m = this._stdAsMap(i);
6761
6930
  let raw = __ball_index(m, 'list');
6762
- let list = (this._stdAsList(raw) ?? (((raw instanceof Set) ? [...raw] : [])));
6931
+ if (this._isBallSet(raw)) {
6932
+ let items = this._ballSetItems(raw);
6933
+ let value = __ball_index(m, 'value');
6934
+ if (!items.includes(value)) {
6935
+ this._trackMemoryAllocation(_ballPointerBytes);
6936
+ return this._ballSetOf([items, value]);
6937
+ }
6938
+ return this._ballSetOf(items);
6939
+ }
6940
+ let list = (this._stdAsList(raw) ?? []);
6763
6941
  this._trackMemoryAllocation(_ballPointerBytes);
6764
6942
  list = (list.push(__ball_index(m, 'value')), list);
6765
6943
  return list;
@@ -7090,6 +7268,9 @@ export class BallEngine {
7090
7268
  }), ['list_concat']: ((i) => {
7091
7269
  const input = i;
7092
7270
  let m = this._stdAsMap(i);
7271
+ if (this._isBallSet(__ball_index(m, 'list'))) {
7272
+ return this._ballSetOf([this._ballSetItems(__ball_index(m, 'list')), (this._stdAsList(__ball_index(m, 'value')) ?? [])]);
7273
+ }
7093
7274
  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; })();
7094
7275
  this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes));
7095
7276
  return result;
@@ -7097,6 +7278,10 @@ export class BallEngine {
7097
7278
  const input = i;
7098
7279
  let m = this._stdAsMap(i);
7099
7280
  let raw = __ball_index(m, 'list');
7281
+ if (this._isBallSet(raw)) {
7282
+ (this._ballSetItems(raw).length = 0, this._ballSetItems(raw));
7283
+ return raw;
7284
+ }
7100
7285
  let list = this._stdAsList(raw);
7101
7286
  if (!__ball_eq(list, null)) {
7102
7287
  list = (list.length = 0, list);
@@ -7198,8 +7383,8 @@ export class BallEngine {
7198
7383
  const input = i;
7199
7384
  let m = this._stdAsMap(i);
7200
7385
  let target = __ball_index(m, 'map');
7201
- if ((target instanceof Set)) {
7202
- return target.includes(__ball_index(m, 'key'));
7386
+ if (this._isBallSet(target)) {
7387
+ return this._ballSetItems(target).includes(__ball_index(m, 'key'));
7203
7388
  }
7204
7389
  if (((typeof target === 'object' && target !== null && !Array.isArray(target) && !(target instanceof BallDouble) && !(target instanceof Set)) || false /* BallMap is Map in TS */)) {
7205
7390
  return _ballMapContainsKeyDyn(target, __ball_index(m, 'key'));
@@ -7225,12 +7410,18 @@ export class BallEngine {
7225
7410
  }), ['map_keys']: ((i) => {
7226
7411
  const input = i;
7227
7412
  let m = this._stdAsMap(i);
7413
+ if (this._isBallSet(__ball_index(m, 'map'))) {
7414
+ return [];
7415
+ }
7228
7416
  let result = _ballMapKeysDyn(__ball_index(m, 'map'));
7229
7417
  this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes));
7230
7418
  return result;
7231
7419
  }), ['map_values']: ((i) => {
7232
7420
  const input = i;
7233
7421
  let m = this._stdAsMap(i);
7422
+ if (this._isBallSet(__ball_index(m, 'map'))) {
7423
+ return [];
7424
+ }
7234
7425
  let result = _ballMapValuesDyn(__ball_index(m, 'map'));
7235
7426
  this._trackMemoryAllocation(__ball_mul(result.length, _ballPointerBytes));
7236
7427
  return result;
@@ -7331,40 +7522,64 @@ export class BallEngine {
7331
7522
  }), ['set_add']: ((i) => {
7332
7523
  const input = i;
7333
7524
  let m = this._stdAsMap(i);
7334
- let s = __ball_index(m, 'set').toSet();
7335
- s = (s.push(__ball_index(m, 'value')), s);
7336
- return s;
7525
+ let items = this._ballSetItems(__ball_index(m, 'set'));
7526
+ let value = __ball_index(m, 'value');
7527
+ if (!items.includes(value)) {
7528
+ this._trackMemoryAllocation(_ballPointerBytes);
7529
+ return this._ballSetOf([items, value]);
7530
+ }
7531
+ return this._ballSetOf(items);
7337
7532
  }), ['set_remove']: ((i) => {
7338
7533
  const input = i;
7339
7534
  let m = this._stdAsMap(i);
7340
- let s = __ball_index(m, 'set').toSet();
7341
- s.remove(__ball_index(m, 'value'));
7342
- return s;
7535
+ let items = this._ballSetItems(__ball_index(m, 'set'));
7536
+ let value = __ball_index(m, 'value');
7537
+ let kept = [];
7538
+ for (const e of items) {
7539
+ if (!__ball_eq(e, value)) {
7540
+ kept = (kept.push(e), kept);
7541
+ }
7542
+ }
7543
+ return this._ballSetOf(kept);
7343
7544
  }), ['set_contains']: ((i) => {
7344
7545
  const input = i;
7345
7546
  let m = this._stdAsMap(i);
7346
- return __ball_index(m, 'set').includes(__ball_index(m, 'value'));
7547
+ return this._ballSetItems(__ball_index(m, 'set')).includes(__ball_index(m, 'value'));
7347
7548
  }), ['set_union']: ((i) => {
7348
7549
  const input = i;
7349
7550
  let m = this._stdAsMap(i);
7350
- return __ball_index(m, 'left').union(__ball_index(m, 'right'));
7551
+ return this._ballSetOf([this._ballSetItems(__ball_index(m, 'left')), this._ballSetItems(__ball_index(m, 'right'))]);
7351
7552
  }), ['set_intersection']: ((i) => {
7352
7553
  const input = i;
7353
7554
  let m = this._stdAsMap(i);
7354
- return __ball_index(m, 'left').intersection(__ball_index(m, 'right'));
7555
+ let right = this._ballSetItems(__ball_index(m, 'right'));
7556
+ let result = [];
7557
+ for (const e of this._ballSetItems(__ball_index(m, 'left'))) {
7558
+ if (right.includes(e)) {
7559
+ result = (result.push(e), result);
7560
+ }
7561
+ }
7562
+ return this._ballSetOf(result);
7355
7563
  }), ['set_difference']: ((i) => {
7356
7564
  const input = i;
7357
7565
  let m = this._stdAsMap(i);
7358
- return __ball_index(m, 'left').difference(__ball_index(m, 'right'));
7566
+ let right = this._ballSetItems(__ball_index(m, 'right'));
7567
+ let result = [];
7568
+ for (const e of this._ballSetItems(__ball_index(m, 'left'))) {
7569
+ if (!right.includes(e)) {
7570
+ result = (result.push(e), result);
7571
+ }
7572
+ }
7573
+ return this._ballSetOf(result);
7359
7574
  }), ['set_length']: ((i) => {
7360
7575
  const input = i;
7361
- return __ball_index(this._stdAsMap(i), 'set').length;
7576
+ return this._ballSetItems(__ball_index(this._stdAsMap(i), 'set')).length;
7362
7577
  }), ['set_is_empty']: ((i) => {
7363
7578
  const input = i;
7364
- return (__ball_index(this._stdAsMap(i), 'set').length === 0);
7579
+ return (this._ballSetItems(__ball_index(this._stdAsMap(i), 'set')).length === 0);
7365
7580
  }), ['set_to_list']: ((i) => {
7366
7581
  const input = i;
7367
- return [...__ball_index(this._stdAsMap(i), 'set')];
7582
+ return [this._ballSetItems(__ball_index(this._stdAsMap(i), 'set'))];
7368
7583
  }), ['switch_expr']: this._stdSwitchExpr.bind(this), ['throw']: ((i) => {
7369
7584
  const input = i;
7370
7585
  let val = this._extractUnaryArg(i);
@@ -7592,6 +7807,30 @@ export class BallEngine {
7592
7807
  const input = v;
7593
7808
  return Math.trunc(this._toNum(v));
7594
7809
  }));
7810
+ }), ['round_to_double']: ((i) => {
7811
+ const input = i;
7812
+ return this._stdConvert(i, ((v) => {
7813
+ const input = v;
7814
+ return new BallDouble(Math.round(+(this._toNum(v))));
7815
+ }));
7816
+ }), ['floor_to_double']: ((i) => {
7817
+ const input = i;
7818
+ return this._stdConvert(i, ((v) => {
7819
+ const input = v;
7820
+ return new BallDouble(Math.floor(+(this._toNum(v))));
7821
+ }));
7822
+ }), ['ceil_to_double']: ((i) => {
7823
+ const input = i;
7824
+ return this._stdConvert(i, ((v) => {
7825
+ const input = v;
7826
+ return new BallDouble(Math.ceil(+(this._toNum(v))));
7827
+ }));
7828
+ }), ['truncate_to_double']: ((i) => {
7829
+ const input = i;
7830
+ return this._stdConvert(i, ((v) => {
7831
+ const input = v;
7832
+ return new BallDouble(Math.trunc(+(this._toNum(v))));
7833
+ }));
7595
7834
  }), ['math_sqrt']: ((i) => {
7596
7835
  const input = i;
7597
7836
  return this._stdMathUnary(i, _mathSqrt);
@@ -7980,6 +8219,13 @@ export class BallEngine {
7980
8219
  if ((typeof v === 'number' || v instanceof BallDouble)) {
7981
8220
  return __ball_to_string(v);
7982
8221
  }
8222
+ if (this._isBallSet(v)) {
8223
+ let parts = [];
8224
+ for (const item of this._ballSetItems(v)) {
8225
+ parts = (parts.push(await this._ballToStringAsync(item)), parts);
8226
+ }
8227
+ return (('{' + __ball_to_string(parts.join(', '))) + '}');
8228
+ }
7983
8229
  if (false /* BallList is List in TS */) {
7984
8230
  let parts = [];
7985
8231
  for (const item of v.items) {
@@ -8046,6 +8292,15 @@ export class BallEngine {
8046
8292
  }
8047
8293
  }
8048
8294
  }
8295
+ if (__ball_eq(typeName, null)) {
8296
+ let parts = [];
8297
+ for (const e of map.entries) {
8298
+ let k = await this._ballToStringAsync(e.key);
8299
+ let val = await this._ballToStringAsync(e.value);
8300
+ parts = (parts.push(((__ball_to_string(k) + ': ') + __ball_to_string(val))), parts);
8301
+ }
8302
+ return (('{' + __ball_to_string(parts.join(', '))) + '}');
8303
+ }
8049
8304
  }
8050
8305
  return __ball_to_string(v);
8051
8306
  }
@@ -8242,9 +8497,9 @@ export class BallEngine {
8242
8497
  }
8243
8498
  return true;
8244
8499
  }
8245
- if ((__ball_eq(baseType, 'Set') && (value instanceof Set))) {
8500
+ if ((__ball_eq(baseType, 'Set') && this._isBallSet(value))) {
8246
8501
  if (__ball_eq(typeArgs.length, 1)) {
8247
- return value.every(((e) => {
8502
+ return this._ballSetItems(value).every(((e) => {
8248
8503
  const input = e;
8249
8504
  return this._typeMatches(e, __ball_index(typeArgs, 0));
8250
8505
  }));
@@ -8306,7 +8561,7 @@ export class BallEngine {
8306
8561
  return _ballIsMap(value);
8307
8562
  }
8308
8563
  if (__ball_eq(type, 'Set')) {
8309
- return (value instanceof Set);
8564
+ return this._isBallSet(value);
8310
8565
  }
8311
8566
  if ((__ball_eq(type, 'Null') || __ball_eq(type, 'void'))) {
8312
8567
  return (__ball_eq(value, null) || (value == null));
@@ -8419,15 +8674,15 @@ export class BallEngine {
8419
8674
  _stdSetCreate(input: any): any {
8420
8675
  let m = this._stdAsMap(input);
8421
8676
  if (__ball_eq(m, null)) {
8422
- return new Set(['Object?']);
8677
+ return this._ballSetOf([]);
8423
8678
  }
8424
8679
  let elements = __ball_index(m, 'elements');
8425
8680
  let elementsList = this._stdAsList(elements);
8426
8681
  if (!__ball_eq(elementsList, null)) {
8427
8682
  this._trackMemoryAllocation(__ball_mul(elementsList.length, _ballPointerBytes));
8428
- return elementsList.toSet();
8683
+ return this._ballSetOf(elementsList);
8429
8684
  }
8430
- return new Set(['Object?']);
8685
+ return this._ballSetOf([]);
8431
8686
  }
8432
8687
 
8433
8688
  _collectionMisuse(_: any): any {
@@ -8833,6 +9088,9 @@ export class BallEngine {
8833
9088
  if (_isBallFuture(v)) {
8834
9089
  return this._ballToStringSimple(_unwrapBallFuture(v));
8835
9090
  }
9091
+ if (this._isBallSet(v)) {
9092
+ return (('{' + __ball_to_string(this._ballSetItems(v).map(this._ballToStringSimple.bind(this)).join(', '))) + '}');
9093
+ }
8836
9094
  if (false /* BallList is List in TS */) {
8837
9095
  return (('[' + __ball_to_string(v.items.map(this._ballToStringSimple.bind(this)).join(', '))) + ']');
8838
9096
  }
@@ -8892,7 +9150,7 @@ export class BallEngine {
8892
9150
  return _ballIsMap(value);
8893
9151
  }
8894
9152
  if (__ball_eq(p, 'Set')) {
8895
- return (value instanceof Set);
9153
+ return this._isBallSet(value);
8896
9154
  }
8897
9155
  return false;
8898
9156
  }
@@ -9142,6 +9400,9 @@ export class BallEngine {
9142
9400
  if (false /* BallList is List in TS */) {
9143
9401
  return v.items;
9144
9402
  }
9403
+ if (this._isBallSet(v)) {
9404
+ return this._ballSetItems(v);
9405
+ }
9145
9406
  if (Array.isArray(v)) {
9146
9407
  return v;
9147
9408
  }
@@ -9325,6 +9586,9 @@ export class BallEngine {
9325
9586
  if ((((typeof v === 'number' || v instanceof BallDouble) || (typeof v === 'boolean')) || (typeof v === 'string'))) {
9326
9587
  return v;
9327
9588
  }
9589
+ if (this._isBallSet(v)) {
9590
+ return [...this._ballSetItems(v).map(this._toJsonSafe.bind(this))];
9591
+ }
9328
9592
  let mapVal = this._stdAsMap(v);
9329
9593
  if (!__ball_eq(mapVal, null)) {
9330
9594
  return (() => { const __r: Record<string, any> = {}; for (const e of mapVal.entries) { if (!e.key.startsWith('__')) { __r[e.key] = this._toJsonSafe(e.value); } } return __r; })();
@@ -9650,6 +9914,7 @@ export class StdModuleHandler extends BallModuleHandler {
9650
9914
  return handler(input);
9651
9915
  }
9652
9916
  }
9917
+ let _kBallSetTag = (() => { return '__ball_set__'; })();
9653
9918
  let _sentinel = (() => { return { '__type': 'main:Object' }; })();
9654
9919
  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']); })();
9655
9920
  let _ballPointerBytes = (() => { return 8; })();
@@ -9712,6 +9977,11 @@ function _ballToDouble(value: any): any {
9712
9977
  return new BallDouble(0);
9713
9978
  }
9714
9979
 
9980
+ function _ballValueIsSet(v: any): any {
9981
+ const input = v;
9982
+ return (((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) && __ball_eq(v.length, 1)) && (_kBallSetTag in v));
9983
+ }
9984
+
9715
9985
  function _ballIsInt(v: any): any {
9716
9986
  const input = v;
9717
9987
  return ((typeof v === 'number' && Number.isInteger(v)) || (typeof v === 'number' && Number.isInteger(v)));
@@ -9744,7 +10014,7 @@ function _ballIsList(v: any): any {
9744
10014
 
9745
10015
  function _ballIsMap(v: any): any {
9746
10016
  const input = v;
9747
- return ((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) || false /* BallMap is Map in TS */);
10017
+ return (((typeof v === 'object' && v !== null && !Array.isArray(v) && !(v instanceof BallDouble) && !(v instanceof Set)) || false /* BallMap is Map in TS */) && !_ballValueIsSet(v));
9748
10018
  }
9749
10019
 
9750
10020
  function _ballGeneratorValues(gen: any): any {
@@ -775,7 +775,7 @@ export function createEngineSetup(mod: EngineModule) {
775
775
  _r('list_reversed', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection'] ?? []; return Array.isArray(l) ? [...l].reverse() : []; });
776
776
  _r('list_sublist', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection'] ?? []; const s = Number(m['start'] ?? m['arg0'] ?? 0); const e = m['end'] ?? m['arg1']; return Array.isArray(l) ? l.slice(s, e != null ? Number(e) : undefined) : []; });
777
777
  _r('list_index_of', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection'] ?? []; const v = m['value'] ?? m['element']; if (typeof l === 'string') return l.indexOf(String(v)); return Array.isArray(l) ? l.indexOf(v) : -1; });
778
- _r('list_add', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection']; const v = m['value'] ?? m['element']; if (Array.isArray(l)) l.push(v); return null; });
778
+ _r('list_add', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection']; const v = m['value'] ?? m['element']; if (l instanceof Set) { l.add(v); return null; } if (Array.isArray(l)) l.push(v); return null; });
779
779
  _r('list_add_all', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection']; const o = m['other'] ?? m['elements'] ?? []; if (Array.isArray(l) && Array.isArray(o)) l.push(...o); return null; });
780
780
  _r('list_remove_at', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection']; const idx = Number(m['index'] ?? 0); return Array.isArray(l) ? l.splice(idx, 1)[0] : null; });
781
781
  _r('list_insert', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection']; const idx = Number(m['index'] ?? 0); const v = m['value'] ?? m['element']; if (Array.isArray(l)) l.splice(idx, 0, v); return null; });
@@ -793,7 +793,7 @@ export function createEngineSetup(mod: EngineModule) {
793
793
  if (!Array.isArray(l)) return '';
794
794
  return l.map((x: any) => { if (x === null || x === undefined) return 'null'; if (typeof x === 'boolean') return x ? 'true' : 'false'; return String(x); }).join(String(sep));
795
795
  });
796
- _r('list_push', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection']; const v = m['value'] ?? m['element']; if (Array.isArray(l)) { l.push(v); return l; } return [...(l ?? []), v]; });
796
+ _r('list_push', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection']; const v = m['value'] ?? m['element']; if (l instanceof Set) { l.add(v); return l; } if (Array.isArray(l)) { l.push(v); return l; } return [...(l ?? []), v]; });
797
797
  _r('list_pop', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection']; return (Array.isArray(l) && l.length > 0) ? l.pop() : null; });
798
798
  _r('list_peek', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection']; return (Array.isArray(l) && l.length > 0) ? l[l.length - 1] : null; });
799
799
  _r('list_take', (i: any) => { const m = _m(i); const l = m['list'] ?? m['collection'] ?? []; const n = Number(m['count'] ?? m['value'] ?? m['n'] ?? 0); return Array.isArray(l) ? l.slice(0, n) : []; });