59 lines
1.4 KiB
Rust
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()
|
|
}
|
|
}
|