@signpostmarv/intermediary-number 0.5.2 → 0.6.1

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.
@@ -21,7 +21,7 @@ export type CanConvertTypeJson = {
21
21
  };
22
22
  export type CanDoMathWithDispose_operator_types = 'divide' | 'minus' | 'modulo' | 'plus' | 'times';
23
23
  export type operand_types = IntermediaryNumber | IntermediaryCalculation | TokenScan;
24
- type TokenSpan_types = 'ignore' | 'nesting_open' | 'nesting_close' | 'numeric' | 'operation';
24
+ type TokenSpan_types = 'ignore' | 'nesting_open' | 'nesting_close' | 'numeric' | 'operation' | 'Infinity';
25
25
  type TokenSpan_types_part_baked = Exclude<TokenSpan_types, 'ignore'>;
26
26
  type TokenScan_internals = {
27
27
  parsed: IntermediaryNumber | IntermediaryCalculation | undefined;
@@ -111,6 +111,15 @@ export declare class IntermediaryNumber implements CanDoMathWithDispose {
111
111
  static fromJson(json: CanConvertTypeJson): CanDoMath_result_types;
112
112
  static reuse_or_create(input: operand_types | input_types): operand_types;
113
113
  }
114
+ export declare class IntermediaryNumberInfinity extends IntermediaryNumber {
115
+ static readonly One: IntermediaryNumberInfinity;
116
+ static readonly Zero: IntermediaryNumberInfinity;
117
+ isOne(): boolean;
118
+ isZero(): boolean;
119
+ toFraction(): Fraction;
120
+ toString(): string;
121
+ toStringCalculation(): string;
122
+ }
114
123
  export declare class NotValid extends Error {
115
124
  readonly reason: unknown;
116
125
  readonly value: string;
@@ -121,6 +130,7 @@ export declare class IntermediaryCalculation implements CanResolveMathWithDispos
121
130
  readonly operation: operation_types;
122
131
  readonly right_operand: operand_types;
123
132
  constructor(left: operand_types, operation: operation_types, right: operand_types);
133
+ get has_infinity(): boolean;
124
134
  get left_type(): operand_type_property_types;
125
135
  get resolve_type(): string;
126
136
  get right_type(): operand_type_property_types;
@@ -115,6 +115,9 @@ function is_nesting_close(maybe) {
115
115
  function is_numeric(maybe) {
116
116
  return 'numeric' === maybe.type;
117
117
  }
118
+ function is_infinity(maybe) {
119
+ return 'Infinity' === maybe.type;
120
+ }
118
121
  export function is_operation_value(maybe) {
119
122
  if (!(maybe.length === 1
120
123
  && '+-/x*%'.includes(maybe))) {
@@ -317,6 +320,9 @@ export class IntermediaryNumber {
317
320
  }
318
321
  return new this(new Fraction(input));
319
322
  }
323
+ else if ('Infinity' === input) {
324
+ return new IntermediaryNumberInfinity(new BigNumber('Infinity'));
325
+ }
320
326
  throw new Error('Unsupported argument specified!');
321
327
  }
322
328
  static create_if_valid(input) {
@@ -358,6 +364,27 @@ export class IntermediaryNumber {
358
364
  }
359
365
  }
360
366
  //#endregion
367
+ //#region IntermediaryNumberInfinity
368
+ export class IntermediaryNumberInfinity extends IntermediaryNumber {
369
+ static One = new this(new BigNumber('Infinity'));
370
+ static Zero = new this(new BigNumber('Infinity'));
371
+ isOne() {
372
+ return false;
373
+ }
374
+ isZero() {
375
+ return false;
376
+ }
377
+ toFraction() {
378
+ throw new Error('Cannot convert infinity to Fraction');
379
+ }
380
+ toString() {
381
+ return 'Infinity';
382
+ }
383
+ toStringCalculation() {
384
+ return 'Infinity';
385
+ }
386
+ }
387
+ //#endregion
361
388
  //#region IntermediaryCalculation
362
389
  export class NotValid extends Error {
363
390
  reason;
@@ -392,6 +419,10 @@ export class IntermediaryCalculation {
392
419
  this.operation = operation;
393
420
  this.right_operand = right;
394
421
  }
422
+ get has_infinity() {
423
+ return (this.left_operand instanceof IntermediaryNumberInfinity
424
+ || this.right_operand instanceof IntermediaryNumberInfinity);
425
+ }
395
426
  get left_type() {
396
427
  if (this.left_operand instanceof IntermediaryCalculation) {
397
428
  return 'IntermediaryCalculation';
@@ -457,6 +488,10 @@ export class IntermediaryCalculation {
457
488
  return do_math(this, '+', value);
458
489
  }
459
490
  resolve() {
491
+ const reduced = IntermediaryCalculation.maybe_short_circuit(this.left_operand, this.operation, this.right_operand);
492
+ if (reduced instanceof IntermediaryNumber) {
493
+ return reduced;
494
+ }
460
495
  const left_operand = this.operand_to_IntermediaryNumber(this.left_operand);
461
496
  const right_operand = this.operand_to_IntermediaryNumber(this.right_operand);
462
497
  const left = left_operand.toBigNumberOrFraction();
@@ -464,6 +499,12 @@ export class IntermediaryCalculation {
464
499
  if ('/' === this.operation
465
500
  || left instanceof Fraction
466
501
  || right instanceof Fraction) {
502
+ if (left_operand instanceof IntermediaryNumberInfinity) {
503
+ return left_operand;
504
+ }
505
+ else if (right_operand instanceof IntermediaryNumberInfinity) {
506
+ return right_operand;
507
+ }
467
508
  return IntermediaryNumber.create(Fraction_operation_map[this.operation](((left instanceof BigNumber)
468
509
  ? left_operand.toFraction()
469
510
  : left), ((right instanceof BigNumber)
@@ -506,8 +547,14 @@ export class IntermediaryCalculation {
506
547
  return value;
507
548
  }
508
549
  toJSON() {
509
- const left = this.operand_to_IntermediaryNumber(this.left_operand);
510
- const right = this.operand_to_IntermediaryNumber(this.right_operand);
550
+ const left = (this.left_operand instanceof IntermediaryCalculation
551
+ && this.left_operand.has_infinity)
552
+ ? this.left_operand
553
+ : this.operand_to_IntermediaryNumber(this.left_operand);
554
+ const right = (this.right_operand instanceof IntermediaryCalculation
555
+ && this.right_operand.has_infinity)
556
+ ? this.right_operand
557
+ : this.operand_to_IntermediaryNumber(this.right_operand);
511
558
  const maybe = IntermediaryCalculation.maybe_short_circuit(left, this.operation, right);
512
559
  if (maybe) {
513
560
  return maybe.toJSON();
@@ -571,6 +618,55 @@ export class IntermediaryCalculation {
571
618
  }
572
619
  static maybe_short_circuit(left, operation, right) {
573
620
  let value = undefined;
621
+ if (left instanceof IntermediaryNumberInfinity
622
+ && right instanceof IntermediaryNumberInfinity) {
623
+ if ('+' === operation
624
+ || '*' === operation) {
625
+ // infinity plus or multiplied by infintiy is infinity
626
+ return left;
627
+ }
628
+ else if ('-' === operation) {
629
+ return IntermediaryNumber.Zero;
630
+ }
631
+ else if ('/' === operation) {
632
+ return IntermediaryNumber.One;
633
+ }
634
+ }
635
+ if (left instanceof IntermediaryCalculation
636
+ && left.has_infinity
637
+ && (('+' === left.operation
638
+ && '-' === operation)
639
+ || ('-' === left.operation
640
+ && '+' === operation))
641
+ && (right instanceof IntermediaryNumberInfinity)
642
+ && (!(left.left_operand instanceof IntermediaryNumberInfinity)
643
+ || !(left.right_operand instanceof IntermediaryNumberInfinity))) {
644
+ return (left.left_operand instanceof IntermediaryNumberInfinity
645
+ ? left.right_operand
646
+ : left.left_operand);
647
+ }
648
+ else if (right instanceof IntermediaryCalculation
649
+ && right.has_infinity
650
+ && (('+' === right.operation
651
+ && '-' === operation)
652
+ || ('-' === right.operation
653
+ && '+' === operation))
654
+ && (left instanceof IntermediaryNumberInfinity)
655
+ && (!(right.left_operand instanceof IntermediaryNumberInfinity)
656
+ || !(right.right_operand instanceof IntermediaryNumberInfinity))) {
657
+ return (right.left_operand instanceof IntermediaryNumberInfinity
658
+ ? right.right_operand
659
+ : right.left_operand);
660
+ }
661
+ else if ('/' === operation
662
+ && !right.isOne()
663
+ && left instanceof IntermediaryCalculation
664
+ && left.has_infinity
665
+ && !(left.left_operand instanceof IntermediaryNumberInfinity)
666
+ && '*x'.includes(left.operation)
667
+ && right instanceof IntermediaryNumberInfinity) {
668
+ return left.left_operand;
669
+ }
574
670
  if ('+' === operation) {
575
671
  if (left.isZero()) {
576
672
  value = right;
@@ -811,6 +907,9 @@ export class TokenScan {
811
907
  for (const entry of value.matchAll(/(\))/g)) {
812
908
  tokens.push(new TokenSpan(entry.index, entry.index + entry[0].length, 'nesting_close'));
813
909
  }
910
+ for (const entry of value.matchAll(/(\bInfinity\b)/g)) {
911
+ tokens.push(new TokenSpan(entry.index, entry.index + entry[0].length, 'Infinity'));
912
+ }
814
913
  tokens = tokens.sort((a, b) => {
815
914
  return a.from - b.from;
816
915
  });
@@ -974,7 +1073,7 @@ export class TokenScan {
974
1073
  }
975
1074
  }
976
1075
  }
977
- else if (is_numeric(is)) {
1076
+ else if (is_numeric(is) || is_infinity(is)) {
978
1077
  if ('left' === was.operand_mode) {
979
1078
  was.left_operand = IntermediaryNumber.create(value.substring(is.from, is.to));
980
1079
  was.operand_mode = 'right';
package/package.json CHANGED
@@ -27,5 +27,5 @@
27
27
  "bignumber.js": "^9.1.2",
28
28
  "fraction.js": "^4.3.7"
29
29
  },
30
- "version": "0.5.2"
30
+ "version": "0.6.1"
31
31
  }