use std::collections::HashMap;
#[derive(Debug, Clone)]
pub enum Statement {
LetExpression { name: String, value: Expr },
Expression { value: Expr },
Print { name: String },
Call { function: String, args: Vec<Expr> },
FunctionDef {
name: String,
params: Vec<String>,
body: Vec<Statement>,
},
}
#[derive(Debug, Clone)]
pub enum Expr {
String(String),
Boolean(bool),
Float(f64),
Integer(i32),
Array(Vec<Expr>),
HashMap(HashMap<String, Expr>),
Identifier(String),
Range { start: Box<Expr>, end: Box<Expr> },
Field { target: Box<Expr>, name: String },
BinaryOp {
lhs: Box<Expr>,
op: BinaryOpKind,
rhs: Box<Expr>,
},
Lambda { param: String, body: Vec<Statement> },
Block(Vec<Statement>),
MethodCall {
target: Box<Expr>,
method: String,
arg: Box<Expr>,
},
Call { function: String, args: Vec<Expr> },
Index { target: Box<Expr>, index: Box<Expr> },
}
#[derive(Debug, Clone)]
pub enum BinaryOpKind {
Add,
Sub,
Mul,
Div,
}
impl TryFrom<&str> for BinaryOpKind {
type Error = String;
fn try_from(op: &str) -> Result<Self, Self::Error> {
match op {
"+" => Ok(BinaryOpKind::Add),
"-" => Ok(BinaryOpKind::Sub),
"*" => Ok(BinaryOpKind::Mul),
"/" => Ok(BinaryOpKind::Div),
other => Err(format!("Unknown binary operator '{other}'")),
}
}
}
impl std::fmt::Display for BinaryOpKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let symbol = match self {
BinaryOpKind::Add => "+",
BinaryOpKind::Sub => "-",
BinaryOpKind::Mul => "*",
BinaryOpKind::Div => "/",
};
write!(f, "{symbol}")
}
}