rlox/src/parser/stmt.rs

49 lines
1.6 KiB
Rust
Raw Normal View History

2023-01-22 23:33:57 +01:00
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, "}}")
}
}
}
}