use std::rc::Rc; use super::{Environment, Node, NodeEnum, Precedence, empty::Empty}; #[derive(Debug, Clone, PartialEq, PartialOrd)] pub struct Assign { left: Rc, right: Rc, } impl Node for Assign { fn evaluate(&self, env: &mut Environment) -> Result, String> { if let NodeEnum::Symbol(symbol) = self.left.as_ref() { let name = env .id_to_str(&symbol.get_value()) .expect("Unknown symbol") .clone(); let right = self.right.evaluate(env)?; env.insert(symbol.get_value(), right.clone()); Ok(Empty::new(format!( "{name} := {}", right.as_string(Some(env)) ))) } else { Err(format!( "Cannot assign to a {}", self.left.as_string(Some(env)) )) } } fn as_string(&self, env: Option<&Environment>) -> String { format!( "{} := {}", self.left.as_string(env), self.right.as_string(env) ) } fn precedence(&self) -> Precedence { Precedence::Assign } } impl Assign { pub fn new(left: Rc, right: Rc) -> Self { Self { left, right } } pub fn get_left(&self) -> Rc { self.left.clone() } pub fn get_right(&self) -> Rc { self.left.clone() } }