@1771technologies/lytenyte-pro
Version:
Blazingly fast headless React data grid with 100s of features.
58 lines (57 loc) • 1.89 kB
JavaScript
import { current, advance } from "../parser/parser-context.js";
import { parsePipeTransform } from "../parser/parse-pipe-transform.js";
const PIPE_PRECEDENCE = 5;
export const pipePlugin = {
name: "pipe",
infixPrecedence: (ctx) => {
const tok = current(ctx);
if (tok.type === "Pipe") {
return PIPE_PRECEDENCE;
}
return undefined;
},
parseInfix: (ctx, left, minPrec) => {
const tok = current(ctx);
if (tok.type !== "Pipe")
return null;
if (PIPE_PRECEDENCE < minPrec)
return null;
advance(ctx);
const transform = parsePipeTransform(ctx);
return {
type: "PipeExpression",
input: left,
transform,
start: left.start,
end: transform.end,
};
},
optimize: (node, opt) => {
if (node.type === "PipeExpression") {
const n = node;
return {
...node,
input: opt(n.input),
transform: opt(n.transform),
};
}
return null;
},
evaluate: (node, context, evalFn) => {
if (node.type === "PipeExpression") {
const n = node;
const input = evalFn(n.input, context);
// If the transform is a call expression, append input as last argument
if (n.transform.type === "CallExpression") {
const args = n.transform.args.map((a) => evalFn(a, context));
args.push(input);
const fn = evalFn(n.transform.callee, context);
return { value: fn(...args) };
}
// Otherwise treat as a function and call with input as sole argument
const fn = evalFn(n.transform, context);
return { value: fn(input) };
}
return null;
},
};