Calibre.FormulaEngine 0.3.0

Calibre.FormulaEngine

Domain-neutral formula calculation engine as a pure .NET library (net10.0, zero runtime dependencies). It knows nothing about salary, leave, loans, or any other domain — consumers (payroll, attendance, lending, accounting) layer their own contracts and content on top.

Pipeline

DSL text  → FormulaParser      ┐
Excel text → ExcelFormulaParser ┴→ AST (canonical JSON form) → dependency extraction
        → DAG build + topological sort + cycle rejection
        → compile to expression-tree delegates → cached execution (+ calculation trace)

Two authoring surfaces, one AST. FormulaParser reads the engine's own DSL and is frozen. ExcelFormulaParser reads spreadsheet formula-bar text (dialect excel/1) so a rule pastes in unchanged: percent literals become PCT, AND/OR become operator chains, ROUNDUP becomes ROUND's AWAY_FROM_ZERO mode, CEILING(x,1) becomes CEIL. ExcelFormulaPrinter renders any printable AST back as that text, byte-round-trip guaranteed. Neither surface adds a node kind, an operator or a function, so canonical JSON and hashes are the same as they always were.

The AST is the canonical artifact: formula text pretty-prints from it, builder UIs emit it, the validator validates it, hosts store and hash it. See Calibre.FormulaEngine.Serialization.AstJsonSerializer for the canonical JSON contract and AstHash for content hashing.

Design laws (identity of this package)

  • Pure — no database, no clock, no network, no file or config I/O. The host hydrates an EvaluationContext (values, quantities, policies, rates, slab tables, dates, resolvers); the engine only computes. Same inputs + same versions = same outputs, forever.
  • Zero persistence — not even repository interfaces. Hosts own storage.
  • Zero domain concepts — no "employee", no "salary". Ever.
  • Decimal arithmetic only, explicit rounding at defined points.
  • Not Turing-complete — no loops, no mutation, no state. Formulas express math over resolved data; imperative data resolution is the host's job.
  • Strict SemVer — the public API surface and the canonical JSON form are contracts; breaking either is a major version bump.

Build

dotnet build Calibre.FormulaEngine.slnx
dotnet test  Calibre.FormulaEngine.slnx
dotnet pack  src/Calibre.FormulaEngine -c Release -o artifacts

Status

Stage State
AST node model + canonical JSON + hashing ✅ (released 0.1.0)
Evaluation context object model ✅ (released 0.1.0)
Parser (DSL → AST) ✅
Dependency extractor, DAG builder, cycle detection ✅
Expression-tree compiler + delegate cache ✅
Validator (schema/type checks, percent discipline, lint hooks) + test-vector runner ✅
Excel surface excel/1 (parser + printer), ROUND mode AWAY_FROM_ZERO, context function allow-list (FE015) ✅ (0.3.0)

The full pipeline is implemented. Formula contexts are host-declared: ValidationSchema.Functions is an allow-list of function names, and a call outside it is FE015 — the engine never names a surface or a domain.

No packages depend on Calibre.FormulaEngine.

.NET 10.0

  • No dependencies.

Version Downloads Last updated
0.5.0 7 10/19/2026
0.4.0 10 10/03/2026
0.3.0 13 09/19/2026
0.2.0 57 07/06/2026
0.1.0 8 07/06/2026