let parse = {}
// token types enumeration
const TOKENTYPE = {
NULL: 0,
DELIMITER: 1,
NUMBER: 2,
SYMBOL: 3,
UNKNOWN: 4
}
// map with all delimiters
const DELIMITERS = {
',': true,
'(': true,
')': true,
'[': true,
']': true,
'{': true,
'}': true,
'"': true,
'\'': true,
';': true,
'+': true,
'-': true,
'*': true,
'.*': true,
'/': true,
'./': true,
'%': true,
'^': true,
'.^': true,
'~': true,
'!': true,
'&': true,
'|': true,
'^|': true,
'=': true,
':': true,
'?': true,
'==': true,
'!=': true,
'<': true,
'>': true,
'<=': true,
'>=': true,
'<<': true,
'>>': true,
'>>>': true
}
// map with all named delimiters
const NAMED_DELIMITERS = {
'mod': true,
'to': true,
'in': true,
'and': true,
'xor': true,
'or': true,
'not': true
}
const CONSTANTS = {
'true': true,
'false': false,
'null': null,
'undefined': undefined
}
const NUMERIC_CONSTANTS = [
'NaN',
'Infinity'
]
function initialState () {
return {
extraNodes: {}, // current extra nodes, must be careful not to mutate
expression: '', // current expression
comment: '', // last parsed comment
index: 0, // current index in expr
token: '', // current token
tokenType: TOKENTYPE.NULL, // type of the token
nestingLevel: 0, // level of nesting inside parameters, used to ignore newline characters
conditionalLevel: null // when a conditional is being parsed, the level of the conditional is stored here
}
}
/**
* View upto `length` characters of the expression starting at the current character.
*
* @param {State} state
* @param {number} [length=1] Number of characters to view
* @returns {string}
* @private
*/
function currentString (state, length) {
return state.expression.substr(state.index, length)
}
/**
* View the current character. Returns '' if end of expression is reached.
*
* @param {State} state
* @returns {string}
* @private
*/
function currentCharacter (state) {
return currentString(state, 1)
}
/**
* Get the next character from the expression.
* The character is stored into the char c. If the end of the expression is
* reached, the function puts an empty string in c.
* @private
*/
function next (state) {
state.index++
}
/**
* Preview the previous character from the expression.
* @return {string} cNext
* @private
*/
function prevCharacter (state) {
return state.expression.charAt(state.index - 1)
}
/**
* Preview the next character from the expression.
* @return {string} cNext
* @private
*/
function nextCharacter (state) {
return state.expression.charAt(state.index + 1)
}