Skip to main content

pmcp_workbook_runtime/sheet_ir/
mod.rs

1//! `sheet_ir` skeleton + the Excel-semantics layer (CMP-03).
2//!
3//! Holds the eval-boundary value type ([`value::CellValue`], D-04), the
4//! range-capable [`eval_value::EvalValue`] (finding #4), the D-03/D-04
5//! [`eval_bridge`] (now over the PURE-RUST [`crate::scalar_eval`], Phase 11 Plan
6//! 05), the deterministic [`rounding`] helpers, the [`semantics`] bodies for all
7//! 13 whitelisted functions, and the topo-ordered [`executor`] SERVE-time
8//! [`executor::run`].
9//!
10//! The `Cell`/`CellExpr` skeleton below is the per-cell IR unit the topo executor
11//! fills and runs.
12
13use serde::{Deserialize, Serialize};
14
15pub mod eval_bridge;
16pub mod eval_value;
17pub mod executor;
18pub mod rounding;
19pub mod semantics;
20pub mod value;
21
22pub use eval_bridge::CellEnv;
23pub use eval_value::EvalValue;
24pub use executor::{build_dag, run, EvalTrace, RunResult};
25pub use value::{CellValue, ExcelError};
26
27/// The expression a [`Cell`] holds: either a parsed formula AST or a literal
28/// cell value (a constant / input cell with no `<f>`).
29#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, schemars::JsonSchema)]
30pub enum CellExpr {
31    /// A parsed formula expression (the [`crate::formula::Expr`] AST).
32    Formula(crate::formula::Expr),
33    /// A literal value (a constant or input cell carrying no formula).
34    Literal(CellValue),
35}
36
37/// A single cell in the `sheet_ir`: its canonical `cell_key(sheet, addr)` and
38/// the expression it evaluates to. The topo executor walks these in dependency
39/// order, lowering each [`CellExpr::Formula`]'s leaf arithmetic through
40/// [`eval_bridge`] and dispatching its calls through [`semantics`].
41#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, schemars::JsonSchema)]
42pub struct Cell {
43    /// The canonical cell key (`sheet!addr`, e.g. `"5_Quantities!C6"`).
44    pub key: String,
45    /// The expression this cell computes.
46    pub expr: CellExpr,
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn cell_holds_a_literal_expr() {
55        let c = Cell {
56            key: "2_Constants!C17".to_string(),
57            expr: CellExpr::Literal(CellValue::Number(1.05)),
58        };
59        let j = serde_json::to_value(&c).unwrap();
60        assert_eq!(j["key"], "2_Constants!C17");
61        assert_eq!(j["expr"]["Literal"]["Number"], 1.05);
62    }
63
64    #[test]
65    fn cell_holds_a_formula_expr() {
66        let c = Cell {
67            key: "S!A1".to_string(),
68            expr: CellExpr::Formula(crate::formula::Expr::Number(2.0)),
69        };
70        let j = serde_json::to_value(&c).unwrap();
71        assert_eq!(j["expr"]["Formula"]["Number"], 2.0);
72    }
73}