diff options
| author | Mel <einebeere@gmail.com> | 2021-10-21 23:46:01 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2021-10-21 23:46:01 +0200 |
| commit | cff714c07e5e2c0f11c121504500a554d60c08cc (patch) | |
| tree | 6c9e98696530b2661343942948b9f1a50a8665e7 /src/interpret/scope.rs | |
| parent | a4980b8dbf1394c2b302f1de7c72d2264426b86e (diff) | |
| download | rabbithole-cff714c07e5e2c0f11c121504500a554d60c08cc.tar.zst rabbithole-cff714c07e5e2c0f11c121504500a554d60c08cc.zip | |
Implement program walking.
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 + } +} |
