From e445fc4fa99845f93d6d66db1bd7d36e935645d2 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Thu, 23 Apr 2026 23:53:41 +0100 Subject: [PATCH] feat(base-formula): add pretty-printer --- packages/base-formula/src/format.ts | 32 +++++++++++++++++++++++ packages/base-formula/src/index.client.ts | 1 + packages/base-formula/src/index.server.ts | 1 + 3 files changed, 34 insertions(+) create mode 100644 packages/base-formula/src/format.ts diff --git a/packages/base-formula/src/format.ts b/packages/base-formula/src/format.ts new file mode 100644 index 000000000..baf2abb8e --- /dev/null +++ b/packages/base-formula/src/format.ts @@ -0,0 +1,32 @@ +// packages/base-formula/src/format.ts +import type { FormulaAST, OpCode } from "./ast"; + +const OP_STR: Partial> = { + "+": " + ", "-": " - ", "*": " * ", "/": " / ", "%": " % ", + "==": " == ", "!=": " != ", ">": " > ", "<": " < ", ">=": " >= ", "<=": " <= ", +}; + +export function format( + ast: FormulaAST, + idToName: ReadonlyMap, +): 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(", ")})`; + } +} diff --git a/packages/base-formula/src/index.client.ts b/packages/base-formula/src/index.client.ts index 5b2d44562..6d02d42f1 100644 --- a/packages/base-formula/src/index.client.ts +++ b/packages/base-formula/src/index.client.ts @@ -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"; diff --git a/packages/base-formula/src/index.server.ts b/packages/base-formula/src/index.server.ts index 4684e0ebe..4ff549b70 100644 --- a/packages/base-formula/src/index.server.ts +++ b/packages/base-formula/src/index.server.ts @@ -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";