Skip to content

Commit

Permalink
fix environment enclosing
Browse files Browse the repository at this point in the history
  • Loading branch information
iamgabrieloliveira committed Aug 11, 2024
1 parent 95bd909 commit f1a130c
Show file tree
Hide file tree
Showing 3 changed files with 199 additions and 266 deletions.
40 changes: 33 additions & 7 deletions src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,59 @@ use std::collections::HashMap;

type Value = Option<Literal>;

#[derive(Clone)]
pub struct Environment<'a> {
values: HashMap<&'a str, Value>,
pub enclosing: Option<Box<Environment<'a>>>,
pub parent: Box<Option<Environment<'a>>>,
}

impl<'a> Environment<'a> {
pub fn new(enclosing: Option<Box<Environment<'a>>>) -> Self {
pub fn new(parent: Option<Environment<'a>>) -> Self {
Self {
enclosing,
parent: Box::new(parent),
values: HashMap::new(),
}
}

pub fn empty() -> Self {
pub fn head() -> Self {
Self::new(None)
}

pub fn with_enclosing(enclosing: Environment<'a>) -> Self {
Self::new(Some(Box::new(enclosing)))
pub fn block(parent: Environment<'a>) -> Self {
Self::new(Some(parent))
}

pub fn get_parent(self) -> Environment<'a> {
self.parent.unwrap()
}

pub fn define(&mut self, name: &'a str, value: Option<Literal>) -> Option<Value> {
self.values.insert(name, value)
}

pub fn define_deep(&mut self, name: &'a str, value: Option<Literal>) -> Option<Value> {
match self.define(name, value.clone()) {
Some(v) => Some(v),
None => match *self.parent {
Some(ref mut parent) => parent.define(name, value),
None => None,
},
}
}

pub fn get(&self, name: &'a str) -> Option<&Value> {
self.values.get(&name)
}

pub fn get_deep(&self, name: &'a str) -> Option<&Value> {
let mut variable = self.get(name);

if variable.is_none() {
variable = match *self.parent {
Some(ref parent) => parent.get(name),
None => None,
};
}

variable
}
}
Loading

0 comments on commit f1a130c

Please sign in to comment.