diff --git a/interpreter/src/environment.rs b/interpreter/src/environment.rs index 1ba4947..bab4e73 100644 --- a/interpreter/src/environment.rs +++ b/interpreter/src/environment.rs @@ -1,13 +1,42 @@ +use std::cell::{Ref, RefCell, RefMut}; use std::fmt::Display; use std::io::{Read, Write}; +use std::rc::Rc; use rustc_hash::FxHashMap; use crate::error::RuntimeError; -use super::value::HeapedValue; use super::{Runtime, Value}; +#[derive(Debug, Clone)] +pub struct HeapedValue { + inner: Rc>, +} + +impl HeapedValue { + pub fn new(value: Value) -> Self { + let inner = Rc::new(RefCell::new(value)); + HeapedValue { inner } + } + + pub fn replace(&mut self, value: Value) { + *self.inner.as_ref().borrow_mut() = value; + } + + pub fn cloned(&self) -> Value { + self.inner.as_ref().borrow().clone() + } + + pub fn borrow(&self) -> Ref { + self.inner.as_ref().borrow() + } + + pub fn borrow_mut(&self) -> RefMut { + self.inner.as_ref().borrow_mut() + } +} + pub type Scope = FxHashMap, HeapedValue>; #[derive(Debug)] @@ -70,11 +99,17 @@ impl<'a> Environment<'a> { self.scope_stack.last_mut().unwrap() } - pub fn enter_scope(&mut self) { + pub fn enter_scope(&mut self) -> Result<(), RuntimeError> { // self.current_frame_mut().enter_scope(); // self.local_scopes.push(Scope::new()); + if self.scope_stack.len() >= 255 { + return Err(RuntimeError::StackOverflow); + } + self.scope_stack.push(Scope::default()); + + Ok(()) } pub fn exit_scope(&mut self) { @@ -95,19 +130,18 @@ impl<'a> Environment<'a> { self.runtime.get_global(name) } - pub fn get_local(&self, name: &str, level: usize) -> Result { + pub fn get_local(&'a self, name: &str, level: usize) -> Result { let len = self.scopes().len(); if level < len { if let Some(heap_value) = self.scopes()[len - level - 1].get(name) { - return Ok(heap_value.get_clone()); + return Ok(heap_value.cloned()); } } Err(RuntimeError::NameNotDefined { name: name.to_owned(), }) - // self.runtime.get_global(name) } pub fn define(&mut self, name: impl Into>, value: Value) { @@ -135,17 +169,8 @@ impl<'a> Environment<'a> { Err(RuntimeError::NameNotDefined { name: name.to_owned(), }) - // self.runtime.assign_global(name, value) } - /* pub fn push_frame(&mut self, base_scope: Scope) { - self.frames.push(Frame::new(base_scope)); - } - - pub fn pop_frame(&mut self) { - self.frames.pop().expect("Tried to pop global frame"); - } */ - pub fn collect_closure(&self, closure_vars: &[(Box, usize)]) -> Scope { let mut closure_scope = Scope::default(); @@ -182,7 +207,7 @@ impl Display for Environment<'_> { write!(f, "\nScope {level}:")?; for (name, value) in scope.iter() { - write!(f, "\n\t{name} = {}", value.as_ref())?; + write!(f, "\n\t{name} = {}", value.borrow())?; } } diff --git a/interpreter/src/value.rs b/interpreter/src/value.rs index 3f550b1..eef7900 100644 --- a/interpreter/src/value.rs +++ b/interpreter/src/value.rs @@ -1,4 +1,3 @@ -use std::cell::UnsafeCell; use std::fmt::{Debug, Display}; use std::rc::Rc; @@ -58,42 +57,3 @@ impl Display for Value { } } } - -/*====================================================================================================================*/ - -#[derive(Debug, Clone)] -pub struct HeapedValue { - inner: Rc>, -} - -impl HeapedValue { - pub fn new(value: Value) -> Self { - let inner = Rc::new(UnsafeCell::new(value)); - HeapedValue { inner } - } - - pub fn get_clone(&self) -> Value { - unsafe { - let ptr = self.inner.get(); - let value = &*ptr; - value.clone() - } - } - - pub fn replace(&mut self, value: Value) { - let mut value = value; - unsafe { - let ptr_mut = self.inner.get(); - std::ptr::swap(&mut value, ptr_mut); - } - } -} - -impl AsRef for HeapedValue { - fn as_ref(&self) -> &Value { - unsafe { - let ptr = self.inner.get(); - &*ptr - } - } -}