Skip to content

Commit

Permalink
Support scientific notation
Browse files Browse the repository at this point in the history
  • Loading branch information
silentmatt committed Oct 10, 2016
1 parent 2e9b77b commit e2a6f77
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 1 deletion.
36 changes: 35 additions & 1 deletion parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -769,8 +769,10 @@ TokenStream.prototype.isNumber = function () {
var startColumn = this.column;
var foundDot = false;
var foundDigits = false;
var char;

while (this.pos < this.expression.length) {
var char = this.expression.charAt(this.pos);
char = this.expression.charAt(this.pos);
if ((char >= '0' && char <= '9') || (!foundDot && char === '.')) {
if (char === '.') {
foundDot = true;
Expand All @@ -786,6 +788,38 @@ TokenStream.prototype.isNumber = function () {
}
}

if (r) {
startPos = this.pos;
startColumn = this.column;
}

if (char === 'e' || char === 'E') {
this.pos++;
this.column++;
var expString = 'e';
var validExponent = false;
while (this.pos < this.expression.length) {
char = this.expression.charAt(this.pos);
if ((char === '+' || char === '-') && expString === 'e') {
expString += char;
} else if (char >= '0' && char <= '9') {
validExponent = true;
expString += char;
} else {
break;
}
this.pos++;
this.column++;
}

if (validExponent) {
str += expString;
} else {
this.pos = startPos;
this.column = startPos;
}
}

if (r) {
this.current = this.newToken(TNUMBER, parseFloat(str));
} else {
Expand Down
41 changes: 41 additions & 0 deletions test/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,53 @@ describe('Parser', function () {
expect(parser.evaluate('2/123')).to.equal(2 / 123);
});

it('should parse numbers using scientific notation', function () {
expect(parser.evaluate('123e2')).to.equal(12300);
expect(parser.evaluate('123E2')).to.equal(12300);
expect(parser.evaluate('123e12')).to.equal(123000000000000);
expect(parser.evaluate('123e+12')).to.equal(123000000000000);
expect(parser.evaluate('123E+12')).to.equal(123000000000000);
expect(parser.evaluate('123e-12')).to.equal(0.000000000123);
expect(parser.evaluate('123E-12')).to.equal(0.000000000123);
expect(parser.evaluate('1.7e308')).to.equal(1.7e308);
expect(parser.evaluate('1.7e-308')).to.equal(1.7e-308);
expect(parser.evaluate('123.e3')).to.equal(123000);
expect(parser.evaluate('123.456e+1')).to.equal(1234.56);
expect(parser.evaluate('.456e-3')).to.equal(0.000456);
expect(parser.evaluate('0.456')).to.equal(0.456);
expect(parser.evaluate('0e3')).to.equal(0);
expect(parser.evaluate('0e-3')).to.equal(0);
expect(parser.evaluate('0e+3')).to.equal(0);
expect(parser.evaluate('.0e+3')).to.equal(0);
expect(parser.evaluate('.0e-3')).to.equal(0);
expect(parser.evaluate('123e5+4')).to.equal(12300004);
expect(parser.evaluate('123e+5+4')).to.equal(12300004);
expect(parser.evaluate('123e-5+4')).to.equal(4.00123);
expect(parser.evaluate('123e0')).to.equal(123);
expect(parser.evaluate('123e01')).to.equal(1230);
expect(parser.evaluate('123e+00000000002')).to.equal(12300);
expect(parser.evaluate('123e-00000000002')).to.equal(1.23);
expect(parser.evaluate('e1', { e1: 42 })).to.equal(42);
expect(parser.evaluate('e+1', { e: 12 })).to.equal(13);
});

it('should fail on invalid numbers', function () {
expect(function () { parser.parse('123..'); }).to.throw(Error);
expect(function () { parser.parse('0..123'); }).to.throw(Error);
expect(function () { parser.parse('0..'); }).to.throw(Error);
expect(function () { parser.parse('.0.'); }).to.throw(Error);
expect(function () { parser.parse('.'); }).to.throw(Error);
expect(function () { parser.parse('1.23e'); }).to.throw(Error);
expect(function () { parser.parse('1.23e+'); }).to.throw(Error);
expect(function () { parser.parse('1.23e-'); }).to.throw(Error);
expect(function () { parser.parse('1.23e++4'); }).to.throw(Error);
expect(function () { parser.parse('1.23e--4'); }).to.throw(Error);
expect(function () { parser.parse('1.23e+-4'); }).to.throw(Error);
expect(function () { parser.parse('1.23e4-'); }).to.throw(Error);
expect(function () { parser.parse('1.23ee4'); }).to.throw(Error);
expect(function () { parser.parse('1.23ee.4'); }).to.throw(Error);
expect(function () { parser.parse('1.23e4.0'); }).to.throw(Error);
expect(function () { parser.parse('123e.4'); }).to.throw(Error);
});

it('should fail on unknown characters', function () {
Expand Down

0 comments on commit e2a6f77

Please sign in to comment.