UNPKG

@1771technologies/lytenyte-pro

Version:

Blazingly fast headless React data grid with 100s of features.

104 lines (103 loc) 3.49 kB
import { current, advance } from "../parser/parser-context.js"; import { parseExpression } from "../parser/parse-expression.js"; const LOGICAL_PRECEDENCE = { "||": 10, "&&": 20, "??": 25, }; export const logicalPlugin = { name: "logical", infixPrecedence: (ctx) => { const tok = current(ctx); if (tok.type === "Operator" && (tok.value === "&&" || tok.value === "||")) { return LOGICAL_PRECEDENCE[tok.value]; } if (tok.type === "NullishCoalescing") { return LOGICAL_PRECEDENCE["??"]; } return undefined; }, parseInfix: (ctx, left, minPrec) => { const tok = current(ctx); let op; let prec; if (tok.type === "Operator" && (tok.value === "&&" || tok.value === "||")) { op = tok.value; prec = LOGICAL_PRECEDENCE[op]; } else if (tok.type === "NullishCoalescing") { op = "??"; prec = LOGICAL_PRECEDENCE["??"]; } if (op === undefined || prec === undefined || prec < minPrec) return null; advance(ctx); const right = parseExpression(ctx, prec + 1); return { type: "BinaryExpression", operator: op, left, right, start: left.start, end: right.end, }; }, parseUnary: (ctx, parseNext) => { const tok = current(ctx); if (tok.type === "Operator" && tok.value === "!") { advance(ctx); const operand = parseNext(ctx); return { type: "UnaryExpression", operator: "!", operand, start: tok.start, end: operand.end, }; } return null; }, optimize: (node, opt) => { if (node.type === "UnaryExpression" && node.operator === "!") { const operand = opt(node.operand); if (operand.type === "BooleanLiteral") { return { type: "BooleanLiteral", value: !operand.value, start: node.start, end: node.end, }; } return { ...node, operand }; } if (node.type === "BinaryExpression" && (node.operator === "&&" || node.operator === "||" || node.operator === "??")) { const left = opt(node.left); const right = opt(node.right); return { ...node, left, right }; } return null; }, evaluate: (node, context, evalFn) => { if (node.type === "UnaryExpression" && node.operator === "!") { const operand = evalFn(node.operand, context); return { value: !operand }; } if (node.type === "BinaryExpression") { const op = node.operator; if (op === "&&") { const left = evalFn(node.left, context); return { value: left ? evalFn(node.right, context) : left }; } if (op === "||") { const left = evalFn(node.left, context); return { value: left ? left : evalFn(node.right, context) }; } if (op === "??") { const left = evalFn(node.left, context); return { value: left != null ? left : evalFn(node.right, context) }; } } return null; }, };