about summary refs log tree commit diff
path: root/src/interpret/scope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpret/scope.rs')
-rw-r--r--src/interpret/scope.rs45
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
+    }
+}