mirror of
https://github.com/MorizzG/rlox.git
synced 2025-12-06 04:12:42 +00:00
49 lines
1.6 KiB
Rust
49 lines
1.6 KiB
Rust
|
|
use std::fmt::Display;
|
||
|
|
|
||
|
|
use super::Expr;
|
||
|
|
|
||
|
|
pub enum Stmt {
|
||
|
|
ExprStmt { expr: Box<Expr> },
|
||
|
|
Print { expr: Box<Expr> },
|
||
|
|
VarDecl { name: String, initializer: Box<Expr> },
|
||
|
|
Block { statements: Vec<Stmt> },
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Stmt {
|
||
|
|
pub fn expr_stmt(expr: Expr) -> Self {
|
||
|
|
let expr = Box::new(expr);
|
||
|
|
Stmt::ExprStmt { expr }
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn print_stmt(expr: Expr) -> Self {
|
||
|
|
let expr = Box::new(expr);
|
||
|
|
Stmt::Print { expr }
|
||
|
|
}
|
||
|
|
|
||
|
|
pub fn var_decl(name: String, initializer: Expr) -> Self {
|
||
|
|
let initializer = Box::new(initializer);
|
||
|
|
Stmt::VarDecl { name, initializer }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
impl Display for Stmt {
|
||
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||
|
|
match self {
|
||
|
|
Stmt::ExprStmt { expr } => write!(f, "{expr}"),
|
||
|
|
Stmt::Print { expr } => write!(f, "print {expr}"),
|
||
|
|
Stmt::VarDecl { name, initializer } => write!(f, "var {name} = {initializer}"),
|
||
|
|
Stmt::Block { statements } => {
|
||
|
|
writeln!(f, "{{")?;
|
||
|
|
for statement in statements {
|
||
|
|
// for each statement: statement to string, split by lines, preprend each line with tab, print
|
||
|
|
// return first error or, on success, "collect" the resulting () into a Vec (ZST, so no allocation)
|
||
|
|
format!("{statement}")
|
||
|
|
.split("\n")
|
||
|
|
.map(|line| writeln!(f, "\t{line}"))
|
||
|
|
.collect::<Result<Vec<()>, std::fmt::Error>>()?;
|
||
|
|
}
|
||
|
|
write!(f, "}}")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|