@1771technologies/lytenyte-pro
Version:
Blazingly fast headless React data grid with 100s of features.
72 lines (71 loc) • 2.59 kB
JavaScript
import { current, advance } from "../parser/parser-context.js";
import { parseExpression } from "../parser/parse-expression.js";
const MEMBERSHIP_PRECEDENCE = 40;
export const membershipPlugin = {
name: "membership",
infixPrecedence: (ctx) => {
const tok = current(ctx);
if (tok.type === "Operator" && tok.value === "in") {
return MEMBERSHIP_PRECEDENCE;
}
if (tok.type === "Operator" && tok.value === "not") {
const next = ctx.tokens[ctx.pos + 1];
if (next && next.type === "Operator" && next.value === "in") {
return MEMBERSHIP_PRECEDENCE;
}
}
return undefined;
},
parseInfix: (ctx, left, minPrec) => {
const tok = current(ctx);
if (tok.type === "Operator" && tok.value === "in") {
if (MEMBERSHIP_PRECEDENCE < minPrec)
return null;
advance(ctx);
const right = parseExpression(ctx, MEMBERSHIP_PRECEDENCE + 1);
return {
type: "BinaryExpression",
operator: "in",
left,
right,
start: left.start,
end: right.end,
};
}
if (tok.type === "Operator" && tok.value === "not") {
const next = ctx.tokens[ctx.pos + 1];
if (next && next.type === "Operator" && next.value === "in") {
if (MEMBERSHIP_PRECEDENCE < minPrec)
return null;
advance(ctx); // consume "not"
advance(ctx); // consume "in"
const right = parseExpression(ctx, MEMBERSHIP_PRECEDENCE + 1);
return {
type: "BinaryExpression",
operator: "not in",
left,
right,
start: left.start,
end: right.end,
};
}
}
return null;
},
evaluate: (node, context, evalFn) => {
if (node.type === "BinaryExpression") {
const op = node.operator;
if (op === "in") {
const left = evalFn(node.left, context);
const right = evalFn(node.right, context);
return { value: left in right };
}
if (op === "not in") {
const left = evalFn(node.left, context);
const right = evalFn(node.right, context);
return { value: !(left in right) };
}
}
return null;
},
};