From 2a987ae4658988be5443831d926f1cb39d3fd88a Mon Sep 17 00:00:00 2001 From: minneelyyyy Date: Tue, 22 Oct 2024 13:50:28 -0400 Subject: [PATCH] final version with Arc> --- src/executor.rs | 56 +++++++++++++++++++++++++++++++++++-------------- src/function.rs | 10 ++++----- src/lib.rs | 26 ++++++++++++++--------- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/src/executor.rs b/src/executor.rs index 394ccee..b20834c 100644 --- a/src/executor.rs +++ b/src/executor.rs @@ -5,7 +5,7 @@ use std::collections::HashMap; use std::fmt::Display; use std::error::Error; use std::io; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::cell::RefCell; #[derive(Debug)] @@ -51,15 +51,15 @@ where I: Iterator> { exprs: &'a mut I, - globals: &'a mut HashMap>>, - locals: HashMap>>, + globals: &'a mut HashMap>>, + locals: HashMap>>, } impl<'a, I> Executor<'a, I> where I: Iterator>, { - pub fn new(exprs: &'a mut I, globals: &'a mut HashMap>>) -> Self { + pub fn new(exprs: &'a mut I, globals: &'a mut HashMap>>) -> Self { Self { exprs, globals, @@ -67,27 +67,27 @@ where } } - pub fn _add_global(self, k: String, v: Arc>) -> Self { + pub fn _add_global(self, k: String, v: Arc>) -> Self { self.globals.insert(k, v); self } - pub fn locals(mut self, locals: HashMap>>) -> Self { + pub fn locals(mut self, locals: HashMap>>) -> Self { self.locals = locals; self } - pub fn add_local(mut self, k: String, v: Arc>) -> Self { + pub fn add_local(mut self, k: String, v: Arc>) -> Self { self.locals.insert(k, v); self } - fn _get_object(&self, ident: &String) -> Result<&Arc>, RuntimeError> { + fn _get_object(&self, ident: &String) -> Result<&Arc>, RuntimeError> { self.locals.get(ident).or(self.globals.get(ident)) .ok_or(RuntimeError::VariableUndefined(ident.clone())) } - fn get_object_mut(&mut self, ident: &String) -> Result<&mut Arc>, RuntimeError> { + fn get_object_mut(&mut self, ident: &String) -> Result<&mut Arc>, RuntimeError> { self.locals.get_mut(ident).or(self.globals.get_mut(ident)) .ok_or(RuntimeError::VariableUndefined(ident.clone())) } @@ -96,6 +96,30 @@ where self.locals.contains_key(ident) || self.globals.contains_key(ident) } + fn eval(obj: &mut Arc>) -> Result { + let mut guard = obj.lock().unwrap(); + + let v = guard.eval()?; + + Ok(v) + } + + fn obj_locals(obj: &Arc>) -> HashMap>> { + let guard = obj.lock().unwrap(); + + let locals = guard.locals(); + + locals + } + + fn obj_globals(obj: &Arc>) -> HashMap>> { + let guard = obj.lock().unwrap(); + + let locals = guard.globals(); + + locals + } + pub fn exec(&mut self, tree: Box) -> Result { match *tree { ParseTree::Add(x, y) => match (self.exec(x)?, self.exec(y)?) { @@ -238,7 +262,7 @@ where Executor::new(self.exprs, &mut self.globals) .locals(self.locals.clone()) - .add_local(ident, Arc::new(RefCell::new(Object::value(value, g, self.locals.to_owned())))) + .add_local(ident, Arc::new(Mutex::new(Object::value(value, g, self.locals.to_owned())))) .exec(scope) } }, @@ -249,7 +273,7 @@ where let g = self.globals.clone(); Executor::new(self.exprs, &mut self.globals) .locals(self.locals.clone()) - .add_local(ident, Arc::new(RefCell::new(Object::variable(*body, g, self.locals.to_owned())))) + .add_local(ident, Arc::new(Mutex::new(Object::variable(*body, g, self.locals.to_owned())))) .exec(scope) } }, @@ -257,7 +281,7 @@ where let g = self.globals.clone(); Executor::new(self.exprs, &mut self.globals) .locals(self.locals.clone()) - .add_local(func.name().unwrap().to_string(), Arc::new(RefCell::new(Object::function(func, g, self.locals.clone())))) + .add_local(func.name().unwrap().to_string(), Arc::new(Mutex::new(Object::function(func, g, self.locals.clone())))) .exec(scope) }, ParseTree::Compose(x, y) => { @@ -294,17 +318,17 @@ where ParseTree::FunctionCall(ident, args) => { let args = args.into_iter().map(|x| Object::variable(x, self.globals.clone(), self.locals.clone())).collect(); let obj = self.get_object_mut(&ident)?; - let v = obj.borrow_mut().eval()?; + let v = Self::eval(obj)?; match v { - Value::Function(mut f) => f.call(obj.borrow().globals(), obj.borrow().locals(), args), + Value::Function(mut f) => f.call(Self::obj_globals(obj), Self::obj_locals(obj), args), _ => Err(RuntimeError::FunctionUndefined(ident.clone())) } }, ParseTree::Variable(ident) => { let obj = self.get_object_mut(&ident)?; - let v = obj.borrow_mut().eval()?; + let v = obj.lock().unwrap().eval()?; Ok(v) }, @@ -352,7 +376,7 @@ where ParseTree::NonCall(name) => { let obj = self.get_object_mut(&name)?; - let v = obj.borrow_mut().eval()?; + let v = obj.lock().unwrap().eval()?; Ok(v) } diff --git a/src/function.rs b/src/function.rs index c357454..bf9fd7c 100644 --- a/src/function.rs +++ b/src/function.rs @@ -5,7 +5,7 @@ use crate::{Type, Object, Value}; use std::collections::HashMap; use std::fmt::{self, Display}; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; #[derive(Clone, Debug, PartialEq)] pub struct FunctionType(pub Box, pub Vec); @@ -52,8 +52,8 @@ impl Function { } pub(crate) fn call(&mut self, - mut globals: HashMap>>, - locals: HashMap>>, + mut globals: HashMap>>, + locals: HashMap>>, args: Vec) -> Result { let mut tree = vec![Ok(*self.body.clone())].into_iter(); @@ -63,11 +63,11 @@ impl Function { .locals(locals.clone()); for (obj, name) in std::iter::zip(args.into_iter(), self.arg_names.clone().into_iter()) { - exec = exec.add_local(name.clone(), Arc::new(RefCell::new(obj))); + exec = exec.add_local(name.clone(), Arc::new(Mutex::new(obj))); } if let Some(name) = self.name().map(|x| x.to_string()) { - exec = exec.add_local(name, Arc::new(RefCell::new(Object::function(self.clone(), g, locals)))); + exec = exec.add_local(name, Arc::new(Mutex::new(Object::function(self.clone(), g, locals)))); } exec.next().unwrap() diff --git a/src/lib.rs b/src/lib.rs index 4cc12e4..de35b96 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,7 +13,7 @@ use std::fmt::Display; use std::io::BufRead; use std::fmt; use std::iter::Peekable; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::cell::RefCell; #[derive(Clone, Debug)] @@ -101,15 +101,21 @@ enum Cache { Uncached(ParseTree), } -#[derive(Clone, Debug, PartialEq)] +#[derive(Clone, Debug)] struct Object { - locals: HashMap>>, - globals: HashMap>>, + locals: HashMap>>, + globals: HashMap>>, value: Cache, } +impl PartialEq for Object { + fn eq(&self, other: &Self) -> bool { + self.value == other.value + } +} + impl Object { - pub fn variable(tree: ParseTree, globals: HashMap>>, locals: HashMap>>) -> Self { + pub fn variable(tree: ParseTree, globals: HashMap>>, locals: HashMap>>) -> Self { Self { locals, globals, @@ -117,7 +123,7 @@ impl Object { } } - pub fn value(v: Value, globals: HashMap>>, locals: HashMap>>) -> Self { + pub fn value(v: Value, globals: HashMap>>, locals: HashMap>>) -> Self { Self { locals, globals, @@ -125,7 +131,7 @@ impl Object { } } - pub fn function(func: Function, globals: HashMap>>, locals: HashMap>>) -> Self { + pub fn function(func: Function, globals: HashMap>>, locals: HashMap>>) -> Self { Self { locals, globals, @@ -152,11 +158,11 @@ impl Object { } } - pub fn locals(&self) -> HashMap>> { + pub fn locals(&self) -> HashMap>> { self.locals.clone() } - pub fn globals(&self) -> HashMap>> { + pub fn globals(&self) -> HashMap>> { self.globals.clone() } } @@ -164,7 +170,7 @@ impl Object { pub struct Runtime<'a, R: BufRead> { tokenizer: Peekable>, global_types: HashMap, - globals: HashMap>>, + globals: HashMap>>, parser: Option>>, }