diff options
Diffstat (limited to 'src/interpret/scope.rs')
| -rw-r--r-- | src/interpret/scope.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/interpret/scope.rs b/src/interpret/scope.rs new file mode 100644 index 0000000..de32692 --- /dev/null +++ b/src/interpret/scope.rs @@ -0,0 +1,45 @@ +use super::value::Value; +use crate::parse::ast::nodes::Identifier; +use std::collections::HashMap; + +pub struct Scope { + scopes: Vec<HashMap<Identifier, Value>>, +} + +impl Scope { + pub fn new() -> Self { + Scope { scopes: Vec::new() } + } + + pub fn nest(&mut self) { + self.scopes.push(HashMap::new()); + } + + pub fn unnest(&mut self) { + self.scopes.pop(); + } + + pub fn set_var(&mut self, ident: &Identifier, value: Value) { + for scope in self.scopes.iter_mut() { + if scope.contains_key(ident) { + scope.insert(ident.clone(), value); + return; + } + } + + let inner_scope = self + .scopes + .last_mut() + .expect("Tried accessing scope after last frame is gone."); + inner_scope.insert(ident.clone(), value); + } + + pub fn get_var(&self, ident: &Identifier) -> Option<Value> { + for scope in self.scopes.iter().rev() { + if let Some(value) = scope.get(ident) { + return Some(value.clone()); + } + } + None + } +} |
