linny-r 2.0.12 → 2.1.0

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.
@@ -319,7 +319,7 @@ function compareTailFirst(a, b, tail) {
319
319
  }
320
320
 
321
321
  function endsWithDigits(str) {
322
- // Returns trailing digts of `str` (empty string will evaluate as FALSE)
322
+ // Return trailing digts of `str` (empty string will evaluate as FALSE).
323
323
  let i = str.length - 1,
324
324
  c = str[i],
325
325
  d = '';
@@ -332,8 +332,8 @@ function endsWithDigits(str) {
332
332
  }
333
333
 
334
334
  function indexOfMatchingBracket(str, offset) {
335
- // Returns index of closing bracket, ignoring matched [...] inside
336
- // NOTE: starts at offset + 1, assuming that character at offset = '['
335
+ // Return index of closing bracket, ignoring matched [...] inside.
336
+ // NOTE: Start at offset + 1, assuming that character at offset = '['.
337
337
  let ob = 0, c;
338
338
  for(let i = offset + 1; i < str.length; i++) {
339
339
  c = str.charAt(i);
@@ -347,12 +347,12 @@ function indexOfMatchingBracket(str, offset) {
347
347
  }
348
348
  }
349
349
  }
350
- // No matching bracket => return -1
350
+ // No matching bracket => return -1.
351
351
  return -1;
352
352
  }
353
353
 
354
354
  function monoSpaced(vbl) {
355
- // Removes all non-essential spaces from variable reference `vbl`.
355
+ // Remove all non-essential spaces from variable reference `vbl`.
356
356
  // First reduce all whitespace to a single space.
357
357
  return vbl.replace(/\s+/g, ' ')
358
358
  // Then remove spaces after the opening bracket.
@@ -834,13 +834,11 @@ function customizeXML(str) {
834
834
  // and then load it again for the customization to be performed.
835
835
  if(str.indexOf('!!CUSTOMIZE</name><author>') >= 0) {
836
836
  // Modify `str` -- by default, do nothing, but typical modifications
837
- // will replace RexEx patterns by other strings.
838
-
839
- /*
837
+ // will replace RexEx patterns by other strings.
838
+
840
839
  const
841
- re = /xyz/gi,
842
- r = 'abc';
843
- */
840
+ re = /pattern/g,
841
+ r = 'replacement';
844
842
 
845
843
  // Trace the changes to the console.
846
844
  console.log('Customizing:', re, r);
@@ -7675,7 +7675,13 @@ function VMI_add(x) {
7675
7675
  const d = x.pop();
7676
7676
  if(d !== false) {
7677
7677
  if(DEBUGGING) console.log('ADD (' + d.join(', ') + ')');
7678
- x.retop(d[0] + d[1]);
7678
+ if(Math.abs(d[0]) === VM.PLUS_INFINITY) {
7679
+ x.retop(d[0]);
7680
+ } else if(Math.abs(d[1]) === VM.PLUS_INFINITY) {
7681
+ x.retop(d[1]);
7682
+ } else {
7683
+ x.retop(d[0] + d[1]);
7684
+ }
7679
7685
  }
7680
7686
  }
7681
7687
 
@@ -7685,17 +7691,27 @@ function VMI_sub(x) {
7685
7691
  const d = x.pop();
7686
7692
  if(d !== false) {
7687
7693
  if(DEBUGGING) console.log('SUB (' + d.join(', ') + ')');
7688
- x.retop(d[0] - d[1]);
7694
+ if(d[0] === VM.PLUS_INFINITY || d[1] === VM.MINUS_INFINITY) {
7695
+ x.retop(VM.PLUS_INFINITY);
7696
+ } else if(d[0] === VM.MINUS_INFINITY || d[1] === VM.PLUS_INFINITY) {
7697
+ x.retop(VM.MINUS_INFINITY);
7698
+ } else {
7699
+ x.retop(d[0] + d[1]);
7700
+ }
7689
7701
  }
7690
7702
  }
7691
7703
 
7692
7704
  function VMI_mul(x) {
7693
7705
  // Pop the top number on the stack, and multiply it with the new
7694
- // top number
7706
+ // top number.
7695
7707
  const d = x.pop();
7696
7708
  if(d !== false) {
7697
7709
  if(DEBUGGING) console.log('MUL (' + d.join(', ') + ')');
7698
- x.retop(d[0] * d[1]);
7710
+ if(Math.abs(d[0]) === VM.PLUS_INFINITY || Math.abs(d[1]) === VM.PLUS_INFINITY) {
7711
+ x.retop(VM.PLUS_INFINITY * Math.sign(d[0] * d[1]));
7712
+ } else {
7713
+ x.retop(d[0] * d[1]);
7714
+ }
7699
7715
  }
7700
7716
  }
7701
7717
 
@@ -7707,7 +7723,19 @@ function VMI_div(x) {
7707
7723
  if(DEBUGGING) console.log('DIV (' + d.join(', ') + ')');
7708
7724
  if(Math.abs(d[1]) <= VM.NEAR_ZERO) {
7709
7725
  x.retop(VM.DIV_ZERO);
7726
+ } else if(Math.abs(d[0]) === VM.PLUS_INFINITY) {
7727
+ if(Math.abs(d[1]) === VM.PLUS_INFINITY) {
7728
+ // Treat INF / INF as 1.
7729
+ x.retop(Math.sign(d[0]) * Math.sign(d[1]));
7730
+ } else {
7731
+ // Push the + or - infinity value.
7732
+ x.retop(d[0]);
7733
+ }
7734
+ } else if(Math.abs(d[1]) === VM.PLUS_INFINITY) {
7735
+ // Treat N / Infinity as 0 for any non-infinite value of N.
7736
+ x.retop(0);
7710
7737
  } else {
7738
+ // Standard division.
7711
7739
  x.retop(d[0] / d[1]);
7712
7740
  }
7713
7741
  }
@@ -7722,7 +7750,19 @@ function VMI_div_zero(x) {
7722
7750
  if(DEBUGGING) console.log('DIV-ZERO (' + d.join(', ') + ')');
7723
7751
  if(Math.abs(d[1]) <= VM.NEAR_ZERO) {
7724
7752
  x.retop(d[0]);
7753
+ } else if(Math.abs(d[0]) === VM.PLUS_INFINITY) {
7754
+ if(Math.abs(d[1]) === VM.PLUS_INFINITY) {
7755
+ // Treat INF / INF as 1.
7756
+ x.retop(Math.sign(d[0]) * Math.sign(d[1]));
7757
+ } else {
7758
+ // Push the + or - infinity value.
7759
+ x.retop(d[0]);
7760
+ }
7761
+ } else if(Math.abs(d[1]) === VM.PLUS_INFINITY) {
7762
+ // Treat N / Infinity as 0 for any non-infinite value of N.
7763
+ x.retop(0);
7725
7764
  } else {
7765
+ // Standard division.
7726
7766
  x.retop(d[0] / d[1]);
7727
7767
  }
7728
7768
  }
@@ -7738,6 +7778,9 @@ function VMI_mod(x) {
7738
7778
  if(DEBUGGING) console.log('DIV (' + d.join(', ') + ')');
7739
7779
  if(Math.abs(d[1]) <= VM.NEAR_ZERO) {
7740
7780
  x.retop(VM.DIV_ZERO);
7781
+ } else if(Math.abs(d[0]) === VM.PLUS_INFINITY || Math.abs(d[1]) === VM.PLUS_INFINITY) {
7782
+ // If either operand is infinite, return 0 as remainder.
7783
+ x.retop(0);
7741
7784
  } else {
7742
7785
  x.retop(d[0] % d[1]); // % is the modulo operator in JavaScript.
7743
7786
  }
@@ -7759,7 +7802,16 @@ function VMI_power(x) {
7759
7802
  const d = x.pop();
7760
7803
  if(d !== false) {
7761
7804
  if(DEBUGGING) console.log('POWER (' + d.join(', ') + ')');
7762
- x.retop(Math.pow(d[0], d[1]));
7805
+ const r = Math.pow(d[0], d[1]);
7806
+ if(isNaN(r)) {
7807
+ x.retop(VM.BAD_CALC);
7808
+ } else if(r >= VM.PLUS_INFINITY) {
7809
+ x.retop(VM.PLUS_INFINITY);
7810
+ } else if(r <= VM.MINUS_INFINITY) {
7811
+ x.retop(VM.MINUS_INFINITY);
7812
+ } else {
7813
+ x.retop(r);
7814
+ }
7763
7815
  }
7764
7816
  }
7765
7817
 
@@ -7771,6 +7823,8 @@ function VMI_sqrt(x) {
7771
7823
  if(DEBUGGING) console.log('SQRT ' + d);
7772
7824
  if(d < 0) {
7773
7825
  x.retop(VM.BAD_CALC);
7826
+ } else if (d === VM.PLUS_INFINITY) {
7827
+ x.retop(VM.PLUS_INFINITY);
7774
7828
  } else {
7775
7829
  x.retop(Math.sqrt(d));
7776
7830
  }
@@ -7782,7 +7836,12 @@ function VMI_sin(x) {
7782
7836
  const d = x.top();
7783
7837
  if(d !== false) {
7784
7838
  if(DEBUGGING) console.log('SIN ' + d);
7785
- x.retop(Math.sin(d));
7839
+ const r = Math.sin(d);
7840
+ if(isNaN(r) || Math.abs(d) === VM.PLUS_INFINITY) {
7841
+ x.retop(VM.BAD_CALC);
7842
+ } else {
7843
+ x.retop(r);
7844
+ }
7786
7845
  }
7787
7846
  }
7788
7847
 
@@ -7791,7 +7850,12 @@ function VMI_cos(x) {
7791
7850
  const d = x.top();
7792
7851
  if(d !== false) {
7793
7852
  if(DEBUGGING) console.log('COS ' + d);
7794
- x.retop(Math.cos(d));
7853
+ const r = Math.cos(d);
7854
+ if(isNaN(r) || Math.abs(d) === VM.PLUS_INFINITY) {
7855
+ x.retop(VM.BAD_CALC);
7856
+ } else {
7857
+ x.retop(r);
7858
+ }
7795
7859
  }
7796
7860
  }
7797
7861
 
@@ -7800,7 +7864,12 @@ function VMI_atan(x) {
7800
7864
  const d = x.top();
7801
7865
  if(d !== false) {
7802
7866
  if(DEBUGGING) console.log('ATAN ' + d);
7803
- x.retop(Math.atan(d));
7867
+ const r = Math.atan(d);
7868
+ if(isNaN(r) || Math.abs(d) === VM.PLUS_INFINITY) {
7869
+ x.retop(VM.BAD_CALC);
7870
+ } else {
7871
+ x.retop(r);
7872
+ }
7804
7873
  }
7805
7874
  }
7806
7875
 
@@ -7812,6 +7881,8 @@ function VMI_ln(x) {
7812
7881
  if(DEBUGGING) console.log('LN ' + d);
7813
7882
  if(d < 0) {
7814
7883
  x.retop(VM.BAD_CALC);
7884
+ } else if(d === VM.PLUS_INFINITY) {
7885
+ x.retop(VM.PLUS_INFINITY);
7815
7886
  } else {
7816
7887
  x.retop(Math.log(d));
7817
7888
  }
@@ -7823,7 +7894,13 @@ function VMI_exp(x) {
7823
7894
  const d = x.top();
7824
7895
  if(d !== false) {
7825
7896
  if(DEBUGGING) console.log('EXP ' + d);
7826
- x.retop(Math.exp(d));
7897
+ if(d === VM.PLUS_INFINITY) {
7898
+ x.retop(VM.PLUS_INFINITY);
7899
+ } else if(d === VM.MINUS_INFINITY) {
7900
+ x.retop(0);
7901
+ } else {
7902
+ x.retop(Math.exp(d));
7903
+ }
7827
7904
  }
7828
7905
  }
7829
7906
 
@@ -7833,12 +7910,16 @@ function VMI_log(x) {
7833
7910
  let d = x.pop();
7834
7911
  if(d !== false) {
7835
7912
  if(DEBUGGING) console.log('LOG (' + d.join(', ') + ')');
7836
- try {
7837
- d = Math.log(d[1]) / Math.log(d[0]);
7838
- } catch(err) {
7839
- d = VM.BAD_CALC;
7913
+ if(Math.abs(d[0]) === VM.PLUS_INFINITY || Math.abs(d[1]) === VM.PLUS_INFINITY) {
7914
+ x.retop(VM.BAD_CALC);
7915
+ } else {
7916
+ try {
7917
+ d = Math.log(d[1]) / Math.log(d[0]);
7918
+ } catch(err) {
7919
+ d = VM.BAD_CALC;
7920
+ }
7921
+ x.retop(d);
7840
7922
  }
7841
- x.retop(d);
7842
7923
  }
7843
7924
  }
7844
7925