final version with Arc<Mutex<Object>>
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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<Type>, pub Vec<Type>);
|
||||
@@ -52,8 +52,8 @@ impl Function {
|
||||
}
|
||||
|
||||
pub(crate) fn call(&mut self,
|
||||
mut globals: HashMap<String, Arc<RefCell<Object>>>,
|
||||
locals: HashMap<String, Arc<RefCell<Object>>>,
|
||||
mut globals: HashMap<String, Arc<Mutex<Object>>>,
|
||||
locals: HashMap<String, Arc<Mutex<Object>>>,
|
||||
args: Vec<Object>) -> Result<Value, RuntimeError>
|
||||
{
|
||||
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()
|
||||
|
||||
26
src/lib.rs
26
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<String, Arc<RefCell<Object>>>,
|
||||
globals: HashMap<String, Arc<RefCell<Object>>>,
|
||||
locals: HashMap<String, Arc<Mutex<Object>>>,
|
||||
globals: HashMap<String, Arc<Mutex<Object>>>,
|
||||
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<String, Arc<RefCell<Object>>>, locals: HashMap<String, Arc<RefCell<Object>>>) -> Self {
|
||||
pub fn variable(tree: ParseTree, globals: HashMap<String, Arc<Mutex<Object>>>, locals: HashMap<String, Arc<Mutex<Object>>>) -> Self {
|
||||
Self {
|
||||
locals,
|
||||
globals,
|
||||
@@ -117,7 +123,7 @@ impl Object {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn value(v: Value, globals: HashMap<String, Arc<RefCell<Object>>>, locals: HashMap<String, Arc<RefCell<Object>>>) -> Self {
|
||||
pub fn value(v: Value, globals: HashMap<String, Arc<Mutex<Object>>>, locals: HashMap<String, Arc<Mutex<Object>>>) -> Self {
|
||||
Self {
|
||||
locals,
|
||||
globals,
|
||||
@@ -125,7 +131,7 @@ impl Object {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn function(func: Function, globals: HashMap<String, Arc<RefCell<Object>>>, locals: HashMap<String, Arc<RefCell<Object>>>) -> Self {
|
||||
pub fn function(func: Function, globals: HashMap<String, Arc<Mutex<Object>>>, locals: HashMap<String, Arc<Mutex<Object>>>) -> Self {
|
||||
Self {
|
||||
locals,
|
||||
globals,
|
||||
@@ -152,11 +158,11 @@ impl Object {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn locals(&self) -> HashMap<String, Arc<RefCell<Object>>> {
|
||||
pub fn locals(&self) -> HashMap<String, Arc<Mutex<Object>>> {
|
||||
self.locals.clone()
|
||||
}
|
||||
|
||||
pub fn globals(&self) -> HashMap<String, Arc<RefCell<Object>>> {
|
||||
pub fn globals(&self) -> HashMap<String, Arc<Mutex<Object>>> {
|
||||
self.globals.clone()
|
||||
}
|
||||
}
|
||||
@@ -164,7 +170,7 @@ impl Object {
|
||||
pub struct Runtime<'a, R: BufRead> {
|
||||
tokenizer: Peekable<Tokenizer<R>>,
|
||||
global_types: HashMap<String, Type>,
|
||||
globals: HashMap<String, Arc<RefCell<Object>>>,
|
||||
globals: HashMap<String, Arc<Mutex<Object>>>,
|
||||
parser: Option<Parser<'a, Tokenizer<R>>>,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user