UNPKG

jora

Version:

JavaScript object query engine

272 lines (250 loc) 7.34 kB
// Token type constants - using numeric codes for better performance export const TOKEN_NUMBER = 0; export const TOKEN_STRING = 1; export const TOKEN_REGEXP = 2; export const TOKEN_LITERAL = 3; export const TOKEN_IDENT = 4; export const TOKEN_$IDENT = 5; // Special references export const TOKEN_AT = 6; // DATA export const TOKEN_HASH = 7; // CONTEXT export const TOKEN_$ = 8; // CURRENT export const TOKEN_$$ = 9; // ARG1 // Keywords export const TOKEN_AND = 10; export const TOKEN_OR = 11; export const TOKEN_NOT = 12; export const TOKEN_NO = 13; export const TOKEN_IS = 14; export const TOKEN_IN = 15; export const TOKEN_NOTIN = 16; export const TOKEN_HAS = 17; export const TOKEN_HASNO = 18; export const TOKEN_ORDER = 19; // Method calls export const TOKEN_METHOD_OPEN = 20; // METHOD( export const TOKEN_$METHOD_OPEN = 21; // $METHOD( // Template tokens export const TOKEN_TEMPLATE = 22; export const TOKEN_TPL_START = 23; export const TOKEN_TPL_CONTINUE = 24; export const TOKEN_TPL_END = 25; // Operators export const TOKEN_DOT = 26; export const TOKEN_DOT_DOT = 27; export const TOKEN_DOT_DOT_DOT = 28; export const TOKEN_DOT_OPEN_PAREN = 29; export const TOKEN_DOT_OPEN_BRACKET = 30; export const TOKEN_DOT_DOT_OPEN_PAREN = 31; export const TOKEN_PIPE = 32; export const TOKEN_ARROW = 33; // => export const TOKEN_EQUALS = 34; export const TOKEN_NOT_EQUALS = 35; // != export const TOKEN_MATCH = 36; // ~= export const TOKEN_LESS_THAN = 37; export const TOKEN_LESS_THAN_EQUALS = 38; export const TOKEN_GREATER_THAN = 39; export const TOKEN_GREATER_THAN_EQUALS = 40; export const TOKEN_PLUS = 41; export const TOKEN_MINUS = 42; export const TOKEN_MULTIPLY = 43; export const TOKEN_DIVIDE = 44; export const TOKEN_MODULO = 45; export const TOKEN_NULLISH_COALESCING = 46; // ?? export const TOKEN_QUESTION = 47; // Punctuation export const TOKEN_OPEN_PAREN = 48; export const TOKEN_CLOSE_PAREN = 49; export const TOKEN_OPEN_BRACKET = 50; export const TOKEN_CLOSE_BRACKET = 51; export const TOKEN_OPEN_BRACE = 52; export const TOKEN_CLOSE_BRACE = 53; export const TOKEN_COMMA = 54; export const TOKEN_COLON = 55; export const TOKEN_SEMICOLON = 56; // Special - must be last export const TOKEN_BAD = 57; export const TOKEN_EOF = 58; const TOKEN_MAX = 59; // Token names for debugging and error messages export const tokenNames = { [TOKEN_NUMBER]: 'NUMBER', [TOKEN_STRING]: 'STRING', [TOKEN_REGEXP]: 'REGEXP', [TOKEN_LITERAL]: 'LITERAL', [TOKEN_IDENT]: 'IDENT', [TOKEN_$IDENT]: '$IDENT', [TOKEN_AT]: '@', [TOKEN_HASH]: '#', [TOKEN_$]: '$', [TOKEN_$$]: '$$', [TOKEN_AND]: 'AND', [TOKEN_OR]: 'OR', [TOKEN_NOT]: 'NOT', [TOKEN_NO]: 'NO', [TOKEN_IS]: 'IS', [TOKEN_IN]: 'IN', [TOKEN_NOTIN]: 'NOTIN', [TOKEN_HAS]: 'HAS', [TOKEN_HASNO]: 'HASNO', [TOKEN_ORDER]: 'ORDER', [TOKEN_METHOD_OPEN]: 'METHOD(', [TOKEN_$METHOD_OPEN]: '$METHOD(', [TOKEN_TEMPLATE]: 'TEMPLATE', [TOKEN_TPL_START]: 'TPL_START', [TOKEN_TPL_CONTINUE]: 'TPL_CONTINUE', [TOKEN_TPL_END]: 'TPL_END', [TOKEN_DOT]: '.', [TOKEN_DOT_DOT]: '..', [TOKEN_DOT_DOT_DOT]: '...', [TOKEN_DOT_OPEN_PAREN]: '.(', [TOKEN_DOT_OPEN_BRACKET]: '.[', [TOKEN_DOT_DOT_OPEN_PAREN]: '..(', [TOKEN_PIPE]: '|', [TOKEN_ARROW]: '=>', [TOKEN_EQUALS]: '=', [TOKEN_NOT_EQUALS]: '!=', [TOKEN_MATCH]: '~=', [TOKEN_LESS_THAN]: '<', [TOKEN_LESS_THAN_EQUALS]: '<=', [TOKEN_GREATER_THAN]: '>', [TOKEN_GREATER_THAN_EQUALS]: '>=', [TOKEN_PLUS]: '+', [TOKEN_MINUS]: '-', [TOKEN_MULTIPLY]: '*', [TOKEN_DIVIDE]: '/', [TOKEN_MODULO]: '%', [TOKEN_NULLISH_COALESCING]: '??', [TOKEN_QUESTION]: '?', [TOKEN_OPEN_PAREN]: '(', [TOKEN_CLOSE_PAREN]: ')', [TOKEN_OPEN_BRACKET]: '[', [TOKEN_CLOSE_BRACKET]: ']', [TOKEN_OPEN_BRACE]: '{', [TOKEN_CLOSE_BRACE]: '}', [TOKEN_COMMA]: ',', [TOKEN_COLON]: ':', [TOKEN_SEMICOLON]: ';', [TOKEN_BAD]: 'BAD_TOKEN', [TOKEN_EOF]: 'EOF' }; // Bracket balance mappings export const BALANCE_TOKEN_PAIR = createTokenTable( TOKEN_OPEN_PAREN, TOKEN_CLOSE_PAREN, // "(" -> ")" TOKEN_DOT_OPEN_PAREN, TOKEN_CLOSE_PAREN, // ".(" -> ")" TOKEN_DOT_DOT_OPEN_PAREN, TOKEN_CLOSE_PAREN, // "..(" -> ")" TOKEN_METHOD_OPEN, TOKEN_CLOSE_PAREN, // "METHOD(" -> ")" TOKEN_$METHOD_OPEN, TOKEN_CLOSE_PAREN, // "$METHOD(" -> ")" TOKEN_OPEN_BRACKET, TOKEN_CLOSE_BRACKET, // "[" -> "]" TOKEN_DOT_OPEN_BRACKET, TOKEN_CLOSE_BRACKET, // ".[" -> "]" TOKEN_OPEN_BRACE, TOKEN_CLOSE_BRACE, // "{" -> "}" TOKEN_TPL_START, TOKEN_TPL_END // "`{" -> "}`" ); // Keyword lookup export const KEYWORDS = { 'has no': TOKEN_HASNO, 'not in': TOKEN_NOTIN, 'and': TOKEN_AND, 'or': TOKEN_OR, 'not': TOKEN_NOT, 'has': TOKEN_HAS, 'is': TOKEN_IS, 'in': TOKEN_IN, 'no': TOKEN_NO, 'asc': TOKEN_ORDER, 'ascN': TOKEN_ORDER, 'ascA': TOKEN_ORDER, 'ascNA': TOKEN_ORDER, 'ascAN': TOKEN_ORDER, 'desc': TOKEN_ORDER, 'descN': TOKEN_ORDER, 'descA': TOKEN_ORDER, 'descNA': TOKEN_ORDER, 'descAN': TOKEN_ORDER }; // String to token mapping export const STR_TO_TOKEN = { '...': TOKEN_DOT_DOT_DOT, '..(': TOKEN_DOT_DOT_OPEN_PAREN, '..': TOKEN_DOT_DOT, '.(': TOKEN_DOT_OPEN_PAREN, '.[': TOKEN_DOT_OPEN_BRACKET, '=>': TOKEN_ARROW, '!=': TOKEN_NOT_EQUALS, '~=': TOKEN_MATCH, '<=': TOKEN_LESS_THAN_EQUALS, '>=': TOKEN_GREATER_THAN_EQUALS, '??': TOKEN_NULLISH_COALESCING, '@': TOKEN_AT, '#': TOKEN_HASH, '.': TOKEN_DOT, '|': TOKEN_PIPE, '=': TOKEN_EQUALS, '<': TOKEN_LESS_THAN, '>': TOKEN_GREATER_THAN, '+': TOKEN_PLUS, '-': TOKEN_MINUS, '*': TOKEN_MULTIPLY, '/': TOKEN_DIVIDE, '%': TOKEN_MODULO, '?': TOKEN_QUESTION, '(': TOKEN_OPEN_PAREN, ')': TOKEN_CLOSE_PAREN, '[': TOKEN_OPEN_BRACKET, ']': TOKEN_CLOSE_BRACKET, '{': TOKEN_OPEN_BRACE, '}': TOKEN_CLOSE_BRACE, ',': TOKEN_COMMA, ':': TOKEN_COLON, ';': TOKEN_SEMICOLON }; // Keyword tokens — used to determine empty ident range behavior in tolerant mode export const KEYWORD_TOKENS = createTokenSet( TOKEN_AND, TOKEN_OR, TOKEN_NOT, TOKEN_NO, TOKEN_IN, TOKEN_NOTIN, TOKEN_HAS, TOKEN_HASNO, TOKEN_IS, TOKEN_ORDER ); export const PREVENT_KEYWORD = createTokenSet( TOKEN_DOT, TOKEN_DOT_DOT ); export const PREVENT_PRIMITIVE = createTokenSet( TOKEN_NUMBER, TOKEN_STRING, TOKEN_TEMPLATE, TOKEN_TPL_END, TOKEN_REGEXP, TOKEN_LITERAL, TOKEN_IDENT, TOKEN_$$, TOKEN_$IDENT, TOKEN_$, TOKEN_AT, TOKEN_HASH, TOKEN_CLOSE_PAREN, TOKEN_CLOSE_BRACKET, TOKEN_CLOSE_BRACE, TOKEN_DOT ); function createTokenSet(...tokens) { const set = new Int8Array(TOKEN_MAX); for (const token of tokens) { set[token] = 1; } return set; } function createTokenTable(...pairs) { const table = new Int8Array(TOKEN_MAX).fill(-1); for (let i = 0; i < pairs.length; i += 2) { table[pairs[i]] = pairs[i + 1]; } return table; } export { createTokenSet, createTokenTable };