Skip to main content

ganit_core/parser/
ast.rs

1/// Byte range of a node within the original formula string.
2#[derive(Debug, Clone, PartialEq)]
3pub struct Span {
4    pub offset: usize, // byte offset from start of formula
5    pub length: usize,
6}
7
8impl Span {
9    pub fn new(offset: usize, length: usize) -> Self {
10        Self { offset, length }
11    }
12}
13
14#[derive(Debug, Clone, PartialEq)]
15pub enum UnaryOp {
16    Neg,     // -x
17    Percent, // x% → x/100
18}
19
20#[derive(Debug, Clone, PartialEq)]
21pub enum BinaryOp {
22    Add, Sub, Mul, Div, Pow,
23    Concat,         // &
24    Eq, Ne, Lt, Gt, Le, Ge,
25}
26
27#[derive(Debug, Clone, PartialEq)]
28pub enum Expr {
29    Number(f64, Span),
30    Text(String, Span),
31    Bool(bool, Span),
32    Variable(String, Span),
33    UnaryOp {
34        op: UnaryOp,
35        operand: Box<Expr>,
36        span: Span,
37    },
38    BinaryOp {
39        op: BinaryOp,
40        left: Box<Expr>,
41        right: Box<Expr>,
42        span: Span,
43    },
44    FunctionCall {
45        name: String,   // always uppercased
46        args: Vec<Expr>,
47        span: Span,
48    },
49}
50
51impl Expr {
52    pub fn span(&self) -> &Span {
53        match self {
54            Expr::Number(_, s) | Expr::Text(_, s) | Expr::Bool(_, s) | Expr::Variable(_, s) => s,
55            Expr::UnaryOp { span, .. }
56            | Expr::BinaryOp { span, .. }
57            | Expr::FunctionCall { span, .. } => span,
58        }
59    }
60}