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}