use crate::{env::Env, expression::Expression, function::FunctionMap}; #[derive(Debug, Clone, PartialEq)] pub enum Statement { Assignment(String, Expression, bool), Expression(Expression), While(Expression, Box), If(Vec<(Expression, Statement)>, Option>), Body(Vec), } impl Statement { pub fn eval(&self, env: &Env, f: &FunctionMap) { match self { Statement::Assignment(name, expr, explicit_let) => { let value = expr.eval(env, f); if *explicit_let { env.set_here(name, value); } else { env.set(name, value); } } Statement::Expression(expr) => { expr.eval(env, f); } Statement::While(expr, body) => { while expr.eval(env, f).is_truthy() { let body_env = Env::new_with_parent(env); body.eval(&body_env, f); } } Statement::If(if_side, else_side) => { let mut did_if = false; for (expr, body) in if_side { if expr.eval(env, f).is_truthy() { body.eval(env, f); did_if = true; break; } } if !did_if { if let Some(else_side) = else_side { else_side.eval(env, f); } } } Statement::Body(body) => { let body_env = Env::new_with_parent(env); for stmt in body.iter() { stmt.eval(&body_env, f); } } } } }