From d9e3ef26230afe9fe9e5ca4d027bb7bc9366ad9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= <tseeker@nocternity.net>
Date: Sat, 31 Dec 2022 17:26:40 +0100
Subject: [PATCH] Environment - Rc<RefCell<...>> to store the parent

---
 src/interpreter/environment.rs | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/src/interpreter/environment.rs b/src/interpreter/environment.rs
index c059c8d..9d6cbf3 100644
--- a/src/interpreter/environment.rs
+++ b/src/interpreter/environment.rs
@@ -1,28 +1,26 @@
-use std::collections::HashMap;
+use std::{cell::RefCell, collections::HashMap, rc::Rc};
 
 use crate::{errors::InterpreterError, tokens::Token};
 
 use super::{InterpreterResult, Value};
 
+/// A mutable reference to an environment.
+pub type EnvironmentRef = Rc<RefCell<Environment>>;
+
 /// The execution environment.
 #[derive(Debug, Default)]
 pub struct Environment {
-    enclosing: Option<Box<Environment>>,
+    enclosing: Option<EnvironmentRef>,
     values: HashMap<String, Value>,
 }
 
 impl Environment {
     /// Create an environment enclosed in another.
-    pub fn create_child(parent: Self) -> Self {
-        Self {
-            enclosing: Some(Box::new(parent)),
+    pub fn create_child(parent: &Rc<RefCell<Self>>) -> Rc<RefCell<Self>> {
+        Rc::new(RefCell::new(Self {
+            enclosing: Some(parent.clone()),
             values: HashMap::default(),
-        }
-    }
-
-    /// Restore an environment's parent.
-    pub fn restore_parent(self) -> Self {
-        *self.enclosing.unwrap()
+        }))
     }
 
     /// Define a new variable.
@@ -38,7 +36,7 @@ impl Environment {
                     name,
                     &format!("undefined variable '{}'", name.lexeme),
                 )),
-                Some(parent) => parent.get(name),
+                Some(parent) => parent.borrow().get(name),
             },
             Some(value) => Ok(value.clone()),
         }
@@ -55,7 +53,7 @@ impl Environment {
                     name,
                     &format!("undefined variable '{}'", name.lexeme),
                 )),
-                Some(parent) => parent.assign(name, value),
+                Some(parent) => parent.borrow_mut().assign(name, value),
             }
         }
     }