cp_ast_core/constraint/
expression.rs1use super::types::ArithOp;
2use crate::structure::{Ident, Reference};
3
4#[derive(Debug, Clone, PartialEq)]
9pub enum Expression {
10 Lit(i64),
12 Var(Reference),
14 BinOp {
16 op: ArithOp,
17 lhs: Box<Expression>,
18 rhs: Box<Expression>,
19 },
20 Pow {
22 base: Box<Expression>,
23 exp: Box<Expression>,
24 },
25 FnCall { name: Ident, args: Vec<Expression> },
27}
28
29impl Expression {
30 #[must_use]
32 pub fn evaluate_constant(&self) -> Option<i64> {
33 match self {
34 Self::Lit(v) => Some(*v),
35 Self::Var(_) | Self::FnCall { .. } => None,
36 Self::BinOp { op, lhs, rhs } => {
37 let l = lhs.evaluate_constant()?;
38 let r = rhs.evaluate_constant()?;
39 match op {
40 ArithOp::Add => l.checked_add(r),
41 ArithOp::Sub => l.checked_sub(r),
42 ArithOp::Mul => l.checked_mul(r),
43 ArithOp::Div => {
44 if r == 0 {
45 None
46 } else {
47 l.checked_div(r)
48 }
49 }
50 }
51 }
52 Self::Pow { base, exp } => {
53 let b = base.evaluate_constant()?;
54 let e = exp.evaluate_constant()?;
55 let e_u32 = u32::try_from(e).ok()?;
56 b.checked_pow(e_u32)
57 }
58 }
59 }
60}