use super::literal::Literal;
use super::operators::{BinOp, UnaryOp};
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
Literal(Literal),
Variable(String),
Binary {
op: BinOp,
left: Box<Expr>,
right: Box<Expr>,
},
Unary { op: UnaryOp, operand: Box<Expr> },
Call { name: String, args: Vec<Expr> },
Index { base: Box<Expr>, index: Box<Expr> },
Member { base: Box<Expr>, name: String },
Cast {
expr: Box<Expr>,
target_type: String,
},
Array(Vec<Expr>),
Map(Vec<(Expr, Expr)>),
Ternary {
condition: Box<Expr>,
then_expr: Box<Expr>,
else_expr: Box<Expr>,
},
StackTemp(usize),
}
impl Expr {
#[must_use]
pub fn int(n: i64) -> Self {
Expr::Literal(Literal::Int(n))
}
#[must_use]
pub fn var(name: impl Into<String>) -> Self {
Expr::Variable(name.into())
}
#[must_use]
pub fn binary(op: BinOp, left: Expr, right: Expr) -> Self {
Expr::Binary {
op,
left: Box::new(left),
right: Box::new(right),
}
}
#[must_use]
pub fn unary(op: UnaryOp, operand: Expr) -> Self {
Expr::Unary {
op,
operand: Box::new(operand),
}
}
#[must_use]
pub fn call(name: impl Into<String>, args: Vec<Expr>) -> Self {
Expr::Call {
name: name.into(),
args,
}
}
#[must_use]
pub fn index(base: Expr, index: Expr) -> Self {
Expr::Index {
base: Box::new(base),
index: Box::new(index),
}
}
}