openbirch-rs/src/lib/node/assign.rs
2025-02-20 17:15:59 +01:00

59 lines
1.4 KiB
Rust

use std::rc::Rc;
use super::{Environment, Node, NodeEnum, Precedence, empty::Empty};
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Assign {
left: Rc<NodeEnum>,
right: Rc<NodeEnum>,
}
impl Node for Assign {
fn evaluate(&self, env: &mut Environment) -> Result<Rc<NodeEnum>, 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<NodeEnum>, right: Rc<NodeEnum>) -> Self {
Self { left, right }
}
pub fn get_left(&self) -> Rc<NodeEnum> {
self.left.clone()
}
pub fn get_right(&self) -> Rc<NodeEnum> {
self.left.clone()
}
}