numenor
Version:
Customizable, safe evaluator of JavaScript-like expressions.
215 lines (164 loc) • 5.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.NumberLiteral = void 0;
var _ = require("../");
var LexerError = _interopRequireWildcard(require("../Error"));
var _CharacterClass = require("../CharacterClass");
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var HexLiteral = lex(16, _CharacterClass.isHexDigit, LexerError.ExpectedHexadecimalDigit);
var OctalLiteral = lex(8, _CharacterClass.isOctalDigit, LexerError.ExpectedOctalDigit);
var BinaryLiteral = lex(2, _CharacterClass.isBinaryDigit, LexerError.ExpectedBinaryDigit);
var NumberLiteral = function NumberLiteral(start, position, context) {
if (start === '0') {
var nextCh = context.peek();
if (nextCh === 'x') {
return HexLiteral(context.advance(2), position, context);
}
if (nextCh === 'o') {
return OctalLiteral(context.advance(2), position, context);
}
if (nextCh === 'b') {
return BinaryLiteral(context.advance(2), position, context);
}
}
if (start === '.' && (0, _CharacterClass.isDecimalDigit)(context.peek())) {
context.advance();
var _value = Number.parseFloat('0.' + handleFloat(context));
return _objectSpread({
type: _.TokenType.NumberLiteral,
lexeme: context.accept(),
radix: 10,
value: _value
}, position);
}
if (!(0, _CharacterClass.isDecimalDigit)(start)) {
return false;
}
var ch = start;
var trailingUnderscore = false;
var value = '';
while ((0, _CharacterClass.isDecimalDigit)(ch)) {
value += ch;
ch = context.advance();
trailingUnderscore = false;
if (ch === '_') {
trailingUnderscore = true;
ch = context.advance();
if (ch === '.') {
throw LexerError.SeparatorBeforePeriod;
} else if (ch === 'e' || ch === 'E') {
throw LexerError.SeparatorBeforeExponent;
}
} else if (ch === '.') {
if (context.advance() === '_') {
throw LexerError.SeparatorAfterPeriod;
}
value += '.' + handleFloat(context);
break;
} else if (ch === 'e' || ch === 'E') {
if (context.advance() === '_') {
throw LexerError.SeparatorAfterExponent;
}
value += 'e' + handleExponent(context);
break;
}
}
if (trailingUnderscore) {
throw LexerError.TrailingSeparator;
}
return _objectSpread({
type: _.TokenType.NumberLiteral,
value: Number.parseFloat(value),
lexeme: context.accept(),
radix: 10
}, position);
};
exports.NumberLiteral = NumberLiteral;
function handleFloat(context) {
var ch = context.current();
var trailingUnderscore = false;
var value = '';
while ((0, _CharacterClass.isDecimalDigit)(ch) || ch === '_' || ch === 'e' || ch === 'E') {
if (ch !== '_') {
trailingUnderscore = false;
value += ch;
if (ch === 'e' || ch === 'E') {
context.advance();
if (context.peek() === '_') {
context.advance();
throw LexerError.SeparatorAfterExponent;
}
return value + handleExponent(context);
}
} else {
trailingUnderscore = true;
var nextCh = context.peek();
if (nextCh === 'e' || nextCh === 'E') {
context.advance(2);
throw LexerError.SeparatorBeforeExponent;
}
}
ch = context.advance();
}
if (trailingUnderscore) {
context.advance();
throw LexerError.TrailingSeparator;
}
return value;
}
function handleExponent(context) {
var ch = context.current();
var value = '';
if (ch === '+' || ch === '-') {
value += ch;
ch = context.advance();
if (ch === '_') {
throw LexerError.SeparatorAfterExponentSign;
}
}
if (!(0, _CharacterClass.isDecimalDigit)(ch)) {
throw LexerError.ExpectedExponent;
}
var trailingUnderscore = false;
while ((0, _CharacterClass.isDecimalDigit)(ch) || ch === '_') {
trailingUnderscore = ch === '_';
if (!trailingUnderscore) {
value += ch;
}
ch = context.advance();
}
if (trailingUnderscore) {
throw LexerError.TrailingSeparator;
}
return value;
}
function lex(radix, isValidDigit, error) {
return function (start, position, context) {
var ch = start;
var value = '';
var trailingUnderscore = false;
while (isValidDigit(ch) || ch === '_') {
trailingUnderscore = ch === '_';
if (!trailingUnderscore) {
value += ch;
}
ch = context.advance();
}
if (value.length === 0) {
throw error;
}
if (trailingUnderscore) {
throw LexerError.TrailingSeparator;
}
return _objectSpread({
type: _.TokenType.NumberLiteral,
value: Number.parseInt(value, radix),
lexeme: context.accept(),
radix: radix
}, position);
};
}