final version with Arc<Mutex<Object>>

This commit is contained in:
2024-10-22 13:50:28 -04:00
parent d9a576897b
commit 2a987ae465
3 changed files with 61 additions and 31 deletions

View File

@@ -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<Item = Result<ParseTree, ParseError>>
{
exprs: &'a mut I,
globals: &'a mut HashMap<String, Arc<RefCell<Object>>>,
locals: HashMap<String, Arc<RefCell<Object>>>,
globals: &'a mut HashMap<String, Arc<Mutex<Object>>>,
locals: HashMap<String, Arc<Mutex<Object>>>,
}
impl<'a, I> Executor<'a, I>
where
I: Iterator<Item = Result<ParseTree, ParseError>>,
{
pub fn new(exprs: &'a mut I, globals: &'a mut HashMap<String, Arc<RefCell<Object>>>) -> Self {
pub fn new(exprs: &'a mut I, globals: &'a mut HashMap<String, Arc<Mutex<Object>>>) -> Self {
Self {
exprs,
globals,
@@ -67,27 +67,27 @@ where
}
}
pub fn _add_global(self, k: String, v: Arc<RefCell<Object>>) -> Self {
pub fn _add_global(self, k: String, v: Arc<Mutex<Object>>) -> Self {
self.globals.insert(k, v);
self
}
pub fn locals(mut self, locals: HashMap<String, Arc<RefCell<Object>>>) -> Self {
pub fn locals(mut self, locals: HashMap<String, Arc<Mutex<Object>>>) -> Self {
self.locals = locals;
self
}
pub fn add_local(mut self, k: String, v: Arc<RefCell<Object>>) -> Self {
pub fn add_local(mut self, k: String, v: Arc<Mutex<Object>>) -> Self {
self.locals.insert(k, v);
self
}
fn _get_object(&self, ident: &String) -> Result<&Arc<RefCell<Object>>, RuntimeError> {
fn _get_object(&self, ident: &String) -> Result<&Arc<Mutex<Object>>, 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<RefCell<Object>>, RuntimeError> {
fn get_object_mut(&mut self, ident: &String) -> Result<&mut Arc<Mutex<Object>>, 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<Mutex<Object>>) -> Result<Value, RuntimeError> {
let mut guard = obj.lock().unwrap();
let v = guard.eval()?;
Ok(v)
}
fn obj_locals(obj: &Arc<Mutex<Object>>) -> HashMap<String, Arc<Mutex<Object>>> {
let guard = obj.lock().unwrap();
let locals = guard.locals();
locals
}
fn obj_globals(obj: &Arc<Mutex<Object>>) -> HashMap<String, Arc<Mutex<Object>>> {
let guard = obj.lock().unwrap();
let locals = guard.globals();
locals
}
pub fn exec(&mut self, tree: Box<ParseTree>) -> Result<Value, RuntimeError> {
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)
}