Skip to main content

spreadsheet_formulas/
ast.rs

1/// AST types for parsed formulas.
2
3use crate::cellref::CellRef;
4use crate::range::Range;
5
6#[derive(Debug, Clone, PartialEq)]
7pub enum Expr {
8    Number(f64),
9    String(String),
10    Boolean(bool),
11    CellRef(CellRef),
12    Range(Range),
13    BinaryOp {
14        op: BinOp,
15        left: Box<Expr>,
16        right: Box<Expr>,
17    },
18    UnaryOp {
19        op: UnaryOp,
20        operand: Box<Expr>,
21    },
22    FunctionCall {
23        name: String,
24        args: Vec<Expr>,
25    },
26    Percent(Box<Expr>),
27}
28
29#[derive(Debug, Clone, Copy, PartialEq)]
30pub enum BinOp {
31    Add,
32    Sub,
33    Mul,
34    Div,
35    Pow,
36    Concat,
37    Eq,
38    Neq,
39    Lt,
40    Gt,
41    Lte,
42    Gte,
43}
44
45#[derive(Debug, Clone, Copy, PartialEq)]
46pub enum UnaryOp {
47    Negate,
48}
49
50impl std::fmt::Display for Expr {
51    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52        match self {
53            Expr::Number(n) => write!(f, "{}", n),
54            Expr::String(s) => write!(f, "\"{}\"", s),
55            Expr::Boolean(b) => write!(f, "{}", if *b { "TRUE" } else { "FALSE" }),
56            Expr::CellRef(c) => write!(f, "{}", c),
57            Expr::Range(r) => write!(f, "{}", r),
58            Expr::BinaryOp { op, left, right } => {
59                write!(f, "({} {} {})", left, op, right)
60            }
61            Expr::UnaryOp { op, operand } => match op {
62                UnaryOp::Negate => write!(f, "(-{})", operand),
63            },
64            Expr::FunctionCall { name, args } => {
65                write!(f, "{}(", name)?;
66                for (i, arg) in args.iter().enumerate() {
67                    if i > 0 {
68                        write!(f, ", ")?;
69                    }
70                    write!(f, "{}", arg)?;
71                }
72                write!(f, ")")
73            }
74            Expr::Percent(e) => write!(f, "({}%)", e),
75        }
76    }
77}
78
79impl std::fmt::Display for BinOp {
80    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81        match self {
82            BinOp::Add => write!(f, "+"),
83            BinOp::Sub => write!(f, "-"),
84            BinOp::Mul => write!(f, "*"),
85            BinOp::Div => write!(f, "/"),
86            BinOp::Pow => write!(f, "^"),
87            BinOp::Concat => write!(f, "&"),
88            BinOp::Eq => write!(f, "="),
89            BinOp::Neq => write!(f, "!="),
90            BinOp::Lt => write!(f, "<"),
91            BinOp::Gt => write!(f, ">"),
92            BinOp::Lte => write!(f, "<="),
93            BinOp::Gte => write!(f, ">="),
94        }
95    }
96}