feat(base-formula): add pretty-printer

This commit is contained in:
Philipinho
2026-04-23 23:53:41 +01:00
parent 77897733de
commit e445fc4fa9
3 changed files with 34 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
// packages/base-formula/src/format.ts
import type { FormulaAST, OpCode } from "./ast";
const OP_STR: Partial<Record<OpCode, string>> = {
"+": " + ", "-": " - ", "*": " * ", "/": " / ", "%": " % ",
"==": " == ", "!=": " != ", ">": " > ", "<": " < ", ">=": " >= ", "<=": " <= ",
};
export function format(
ast: FormulaAST,
idToName: ReadonlyMap<string, string>,
): string {
switch (ast.t) {
case "num": return String(ast.v);
case "str": return `"${ast.v.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
case "bool": return ast.v ? "true" : "false";
case "null": return "null";
case "prop": return `prop("${idToName.get(ast.id) ?? ast.id}")`;
case "op":
if (ast.op === "neg") return `-${format(ast.args[0], idToName)}`;
if (ast.op === "not") return `not ${format(ast.args[0], idToName)}`;
return `(${format(ast.args[0], idToName)}${OP_STR[ast.op]}${format(ast.args[1], idToName)})`;
case "if":
return `if(${format(ast.cond, idToName)}, ${format(ast.then, idToName)}, ${format(ast.else, idToName)})`;
case "and":
return `(${ast.args.map((a) => format(a, idToName)).join(" and ")})`;
case "or":
return `(${ast.args.map((a) => format(a, idToName)).join(" or ")})`;
case "call":
return `${ast.fn}(${ast.args.map((a) => format(a, idToName)).join(", ")})`;
}
}
@@ -7,4 +7,5 @@ export * from "./tokenizer";
export * from "./parser";
export * from "./resolver";
export * from "./typecheck";
export * from "./format";
export type { FormulaFn } from "./functions/registry";
@@ -6,5 +6,6 @@ export * from "./tokenizer";
export * from "./parser";
export * from "./resolver";
export * from "./typecheck";
export * from "./format";
export { registry } from "./functions/registry";
export type { FormulaFn } from "./functions/registry";