use crate::value::{CellId, Value};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Binding {
Cell(CellId),
Direct(Value),
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub enum Env {
#[default]
Empty,
Cons {
name: String,
binding: Binding,
rest: Box<Env>,
},
}
impl Env {
#[must_use]
pub fn empty() -> Self {
Self::Empty
}
#[must_use]
pub fn extend_cell(&self, name: impl Into<String>, cell: CellId) -> Self {
Self::Cons {
name: name.into(),
binding: Binding::Cell(cell),
rest: Box::new(self.clone()),
}
}
#[must_use]
pub fn extend_direct(&self, name: impl Into<String>, value: Value) -> Self {
Self::Cons {
name: name.into(),
binding: Binding::Direct(value),
rest: Box::new(self.clone()),
}
}
#[must_use]
pub fn lookup(&self, name: &str) -> Option<&Binding> {
match self {
Self::Empty => None,
Self::Cons {
name: n,
binding,
rest,
} => {
if n == name {
Some(binding)
} else {
rest.lookup(name)
}
}
}
}
}