about summary refs log tree commit diff
path: root/users/tazjin/rlox/src/interpreter.rs
diff options
context:
space:
mode:
Diffstat (limited to 'users/tazjin/rlox/src/interpreter.rs')
-rw-r--r--users/tazjin/rlox/src/interpreter.rs61
1 files changed, 33 insertions, 28 deletions
diff --git a/users/tazjin/rlox/src/interpreter.rs b/users/tazjin/rlox/src/interpreter.rs
index e7f87577bb7b..c9de3831c824 100644
--- a/users/tazjin/rlox/src/interpreter.rs
+++ b/users/tazjin/rlox/src/interpreter.rs
@@ -223,8 +223,39 @@ impl Interpreter {
 
     // Interpreter itself
     pub fn interpret(&mut self, mut program: Block) -> Result<Value, Error> {
-        resolver::resolve(&mut program)?;
-        self.interpret_block(&program)
+        let globals = self.env.read()
+            .expect("static globals lock poisoned")
+            .values.keys().map(Clone::clone)
+            .collect::<Vec<String>>();
+
+        resolver::resolve(&globals, &mut program)?;
+        self.interpret_block_with_env(None, &program)
+    }
+
+    /// Interpret the block in the supplied environment. If no
+    /// environment is supplied, a new one is created using the
+    /// current one as its parent.
+    fn interpret_block_with_env(
+        &mut self,
+        env: Option<Rc<RwLock<Environment>>>,
+        block: &parser::Block,
+    ) -> Result<Value, Error> {
+        let env = match env {
+            Some(env) => env,
+            None => {
+                let env: Rc<RwLock<Environment>> = Default::default();
+                set_enclosing_env(&env, self.env.clone());
+                env
+            }
+        };
+
+        let previous = std::mem::replace(&mut self.env, env);
+        let result = self.interpret_block(block);
+
+        // Swap it back, discarding the child env.
+        self.env = previous;
+
+        return result;
     }
 
     fn interpret_block(&mut self, program: &Block) -> Result<Value, Error> {
@@ -272,32 +303,6 @@ impl Interpreter {
         Ok(value)
     }
 
-    /// Interpret the block in the supplied environment. If no
-    /// environment is supplied, a new one is created using the
-    /// current one as its parent.
-    fn interpret_block_with_env(
-        &mut self,
-        env: Option<Rc<RwLock<Environment>>>,
-        block: &parser::Block,
-    ) -> Result<Value, Error> {
-        let env = match env {
-            Some(env) => env,
-            None => {
-                let env: Rc<RwLock<Environment>> = Default::default();
-                set_enclosing_env(&env, self.env.clone());
-                env
-            }
-        };
-
-        let previous = std::mem::replace(&mut self.env, env);
-        let result = self.interpret_block(block);
-
-        // Swap it back, discarding the child env.
-        self.env = previous;
-
-        return result;
-    }
-
     fn interpret_if(&mut self, if_stmt: &parser::If) -> Result<Value, Error> {
         let condition = self.eval(&if_stmt.condition)?;