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.rs44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/interpret/scope.rs b/src/interpret/scope.rs
index 478b24d..0db34c2 100644
--- a/src/interpret/scope.rs
+++ b/src/interpret/scope.rs
@@ -3,17 +3,37 @@ use crate::parse::ast::nodes::Identifier;
 use std::{cell::RefCell, collections::HashMap, rc::Rc};
 use thiserror::Error;
 
-pub struct Scope {
-    scopes: Vec<HashMap<Identifier, AssignedValue>>,
-}
+type InnerScope = HashMap<Identifier, AssignedValue>;
+
+#[derive(Debug, Clone)]
+pub struct Scope(Rc<RefCell<InnerScope>>);
 
 impl Scope {
+    fn new() -> Self {
+        Scope(Rc::new(RefCell::new(HashMap::new())))
+    }
+
+    fn get(&self, ident: &str) -> Option<AssignedValue> {
+        self.0.borrow().get(ident).cloned()
+    }
+
+    fn insert(&self, ident: Identifier, value: AssignedValue) {
+        self.0.borrow_mut().insert(ident, value);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct ScopeChain {
+    scopes: Vec<Scope>,
+}
+
+impl ScopeChain {
     pub fn new() -> Self {
-        Scope { scopes: Vec::new() }
+        ScopeChain { scopes: Vec::new() }
     }
 
     pub fn nest(&mut self) {
-        self.scopes.push(HashMap::new());
+        self.scopes.push(Scope::new());
     }
 
     pub fn unnest(&mut self) {
@@ -70,9 +90,21 @@ impl Scope {
         }
         Err(ScopeError::UnknownIdentifier(ident.to_string()))
     }
+
+    // In contrast to set_var sets the var in the most inner scope so that it's always found first.
+    // This is used when setting parameters.
+    pub fn set_var_shadowed(&mut self, ident: &str, value: Value) {
+        let inner_scope = self
+            .scopes
+            .last_mut()
+            .expect("Tried accessing scope after last frame is gone.");
+
+        // Can shadowed values be constant? No idea!
+        inner_scope.insert(ident.to_string(), AssignedValue::Mutable(value));
+    }
 }
 
-#[derive(Debug)]
+#[derive(Debug, Clone)]
 enum AssignedValue {
     Constant(Value),
     Mutable(Value),