use std::{cell::RefCell, collections::HashMap, rc::Rc};
use super::value::Value;
#[derive(Debug)]
pub struct Frame<'a>(Rc<RefCell<FrameData<'a>>>);
impl<'a> Frame<'a> {
pub fn new() -> Frame<'a> {
Frame(Rc::new(RefCell::new(FrameData {
bindings: HashMap::new(),
parent: None,
})))
}
pub fn new_with_parent(parent: &Frame<'a>) -> Frame<'a> {
Frame(Rc::new(RefCell::new(FrameData {
bindings: HashMap::new(),
parent: Some(parent.clone()),
})))
}
pub fn bind(&self, name: &str, value: &'a Value<'a>) {
self.0.borrow_mut().bindings.insert(name.to_string(), value);
}
pub fn lookup(&self, name: &str) -> Option<&'a Value<'a>> {
match self.0.borrow().bindings.get(name) {
Some(value) => Some(*value),
None => match &self.0.borrow().parent {
Some(parent) => parent.lookup(name),
None => None,
},
}
}
}
impl Default for Frame<'_> {
fn default() -> Self {
Self::new()
}
}
impl Clone for Frame<'_> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
#[derive(Debug)]
pub struct FrameData<'a> {
bindings: HashMap<String, &'a Value<'a>>,
parent: Option<Frame<'a>>,
}