mirror of
https://github.com/samsonjs/elisp.js.git
synced 2026-04-27 15:07:47 +00:00
Support exponent notation, trailing . for ints and other parsing details.
This commit is contained in:
parent
19ac65cb2b
commit
22856cc925
1 changed files with 47 additions and 8 deletions
49
el/parser.js
49
el/parser.js
|
|
@ -6,9 +6,6 @@
|
||||||
// Released under the terms of the MIT license. See the included file
|
// Released under the terms of the MIT license. See the included file
|
||||||
// LICENSE.
|
// LICENSE.
|
||||||
|
|
||||||
/****************************************************************
|
|
||||||
**** Parser ****************************************************
|
|
||||||
****************************************************************/
|
|
||||||
|
|
||||||
EL.Parser = function(data) {
|
EL.Parser = function(data) {
|
||||||
this.data = data || '';
|
this.data = data || '';
|
||||||
|
|
@ -148,23 +145,65 @@ EL.Parser.prototype.parseRegex = function() {
|
||||||
}, true /* consume terminator */));
|
}, true /* consume terminator */));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// In Emacs Lisp a trailing . is allowed on integers.
|
||||||
|
// Valid kinds of numbers we parse here are:
|
||||||
|
//
|
||||||
|
// * Integers of the form 42, +17, -300, 7300. (trailing .), +1. and
|
||||||
|
// -1.
|
||||||
|
//
|
||||||
|
// * Floating point numbers of the form -4.5, 0.0, and +933825.3450133492
|
||||||
|
//
|
||||||
|
// * Exponential notation for floats, e.g. 1.5e2 (150.0) or 420e-1 (42.0)
|
||||||
|
// (There is no trailing . allowed anywhere in exponent notation)
|
||||||
EL.Parser.prototype.parseNumber = function() {
|
EL.Parser.prototype.parseNumber = function() {
|
||||||
var sign = this.peek() == '-' ? this.consumeChar() : '+',
|
var value = this.parseIntOrFloat(),
|
||||||
|
exponentAllowed = value === parseInt(value),
|
||||||
|
exp;
|
||||||
|
|
||||||
|
// now check for an exponent
|
||||||
|
if (this.exponentAllowed && (this.peek() == 'e' || this.peek() == 'E')) {
|
||||||
|
this.consumeChar();
|
||||||
|
|
||||||
|
// Technically this is an error as a float is not allowed for exponents
|
||||||
|
// but the regex is strict enough to keep us from trying to do that.
|
||||||
|
exp = this.parseIntOrFloat();
|
||||||
|
|
||||||
|
value *= Math.pow(10, exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pack int and float parsing together for simplicity's sake.
|
||||||
|
EL.Parser.prototype.parseIntOrFloat = function() {
|
||||||
|
this.exponentAllowed = true;
|
||||||
|
var sign = this.peek() == '-' || this.peek() == '+' ? this.consumeChar() : '+',
|
||||||
value = this.parseUntil(/[^\d]/, 0, function(n,c) {
|
value = this.parseUntil(/[^\d]/, 0, function(n,c) {
|
||||||
return n*10 + parseInt(c);
|
return n*10 + parseInt(c);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// if we see a . there might be a float to parse
|
||||||
if (this.peek() == '.') {
|
if (this.peek() == '.') {
|
||||||
|
this.exponentAllowed = false;
|
||||||
this.consumeChar();
|
this.consumeChar();
|
||||||
|
if (this.peek() && this.peek().match(/\d/)) {
|
||||||
var decimal = this.parseUntil(/[^\d]/, '', function(s,c) {return s + c;});
|
var decimal = this.parseUntil(/[^\d]/, '', function(s,c) {return s + c;});
|
||||||
value = parseFloat('' + value + '.' + decimal);
|
value = parseFloat('' + value + '.' + decimal);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return sign == '-' ? -1*value : value;
|
return sign == '-' ? -1*value : value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// These regexes matches all the inputs specified above parseNumber.
|
||||||
EL.Parser.prototype.lookingAtNumber = function() {
|
EL.Parser.prototype.lookingAtNumber = function() {
|
||||||
var pos = this.pos,
|
var pos = this.pos,
|
||||||
rest = this.rest(),
|
rest = this.rest(),
|
||||||
match = rest.match(/^(-)?\d+(\.\d+)?[\s)\n]/) || rest.match(/^(-)?\d+(\.\d+)?$/);
|
match = rest.match(/^[+-]?\d+(\.\d*)?[)\s\n]/)
|
||||||
|
|| rest.match(/^[+-]?\d+(\.\d*)?$/)
|
||||||
|
|| rest.match(/^[+-]?\d+(\.\d+)?([eE][+-]?\d+)?[)\s\n]/)
|
||||||
|
|| rest.match(/^[+-]?\d+(\.\d+)?([eE][+-]?\d+)?$/);
|
||||||
return (match != null);
|
return (match != null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue