diff --git a/interpreter/src/evaluator/builtins.rs b/interpreter/src/evaluator/builtins.rs index d42938a..6b34ef5 100644 --- a/interpreter/src/evaluator/builtins.rs +++ b/interpreter/src/evaluator/builtins.rs @@ -358,26 +358,31 @@ fn three_body_threading(args: Vec) -> Object { Object::Function(params, ast, env ) => { let stmts = ast.clone(); - let mut handle = std::thread::spawn(move || { - let local_set = tokio::task::LocalSet::new(); - let rt = tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap(); - - local_set.spawn_local(async move { - let mut ev = Evaluator { - env: Rc::new(RefCell::new(Env::from(new_builtins()))), - }; - ev.eval(&stmts); - }); - - rt.block_on(local_set); - }); - - let handle = Box::leak(Box::new(handle)); - let handle_ptr = &mut *handle as *mut std::thread::JoinHandle<()>; - Object::Native(Box::new(NativeObject::Thread(handle_ptr))) + let env_clone = std::sync::Arc::clone(&env); + + // let runtime = + + // let mut handle = std::thread::spawn(move || { + // let local_set = tokio::task::LocalSet::new(); + // let rt = tokio::runtime::Builder::new_current_thread() + // .enable_all() + // .build() + // .unwrap(); + // + // local_set.spawn_local(async move { + // let mut ev = Evaluator { + // env: std::sync::Arc::new(tokio::sync::Mutex::new(Env::from(new_builtins()))), + // }; + // ev.eval(&stmts); + // }); + // + // rt.block_on(local_set); + // }); + // + // let handle = Box::leak(Box::new(handle)); + // let handle_ptr = &mut *handle as *mut std::thread::JoinHandle<()>; + // Object::Native(Box::new(NativeObject::Thread(handle_ptr))) + Object::Null } _ => panic!() } @@ -605,12 +610,12 @@ mod tests { Object::Function( vec![ast::Ident(String::from("x"))], vec![], - Rc::new(RefCell::new(Env::new())), + std::sync::Arc::new(tokio::sync::Mutex::new(Env::new())), ), Object::Function( vec![ast::Ident(String::from("x"))], vec![], - Rc::new(RefCell::new(Env::new())), + std::sync::Arc::new(tokio::sync::Mutex::new(Env::new())), ), ], Object::Bool(true), @@ -620,12 +625,12 @@ mod tests { Object::Function( vec![ast::Ident(String::from("x"))], vec![], - Rc::new(RefCell::new(Env::new())), + std::sync::Arc::new(tokio::sync::Mutex::new(Env::new())), ), Object::Function( vec![ast::Ident(String::from("y"))], vec![], - Rc::new(RefCell::new(Env::new())), + std::sync::Arc::new(tokio::sync::Mutex::new(Env::new())), ), ], Object::Bool(false), @@ -636,7 +641,7 @@ mod tests { Object::Function( vec![ast::Ident(String::from("x"))], vec![], - Rc::new(RefCell::new(Env::new())), + std::sync::Arc::new(tokio::sync::Mutex::new(Env::new())), ), ], Object::Bool(false), diff --git a/interpreter/src/evaluator/env.rs b/interpreter/src/evaluator/env.rs index e6d80c5..c179e1f 100644 --- a/interpreter/src/evaluator/env.rs +++ b/interpreter/src/evaluator/env.rs @@ -8,14 +8,20 @@ struct VariableStatus { constant: bool, } -#[derive(PartialEq, Clone, Debug)] +#[derive(Clone, Debug)] pub struct Env { pub identifiers: HashMap, variables_status: HashMap, - outer: Option>>, + outer: Option>>, } -#[derive(PartialEq, Clone, Debug)] +impl PartialEq for Env { + fn eq(&self, _: &Env) -> bool { + false + } +} + +#[derive(PartialEq, Clone, Debug, Future)] pub enum UpdateInfo { ConstantForbidden, NoIdentifier, @@ -46,7 +52,7 @@ impl Env { } } - pub fn new_with_outer(outer: Rc>) -> Self { + pub fn new_with_outer(outer: std::sync::Arc>) -> Self { Env { identifiers: HashMap::new(), variables_status: HashMap::new(), @@ -72,7 +78,7 @@ impl Env { self.identifiers.insert(name, value.clone()); } - pub fn update(&mut self, name: String, value: Object) -> UpdateInfo { + pub async fn update(&mut self, name: String, value: Object) -> UpdateInfo { match self.identifiers.contains_key(&name) { true => { if self.is_constant(name.clone()) { @@ -83,18 +89,22 @@ impl Env { }, false => { match self.outer { - Some(ref outer) => outer.borrow_mut().update(name, value), + Some(ref outer) => { + let mut o = outer.lock().await; + o.update(name, value); + UpdateInfo::Succeed + }, None => UpdateInfo::NoIdentifier, } } } } - pub fn get(&mut self, name: String) -> Option { + pub async fn get(&mut self, name: String) -> Option { match self.identifiers.get(&name) { Some(value) => Some(value.clone()), None => match self.outer { - Some(ref outer) => outer.borrow_mut().get(name), + Some(ref outer) => outer.lock().await.get(name), None => None, }, } @@ -148,7 +158,7 @@ mod tests { #[test] fn test_env_new_with_outer() { - let outer = Rc::new(RefCell::new(Env::new())); + let outer = std::sync::Arc::new(tokio::sync::Mutex::new(Env::new())); let env = Env::new_with_outer(outer.clone()); assert_eq!(env.identifiers.len(), 0); assert_eq!(env.outer, Some(outer)); @@ -193,8 +203,8 @@ mod tests { #[test] fn test_update_out_identifier() { - let global = Rc::new(RefCell::new(Env::new())); - let outer = Rc::new(RefCell::new(Env::new_with_outer(global.clone()))); + let global = std::sync::Arc::new(tokio::sync::Mutex::new(Env::new())); + let outer = std::sync::Arc::new(tokio::sync::Mutex::new(Env::new_with_outer(global.clone()))); let mut env = Env::new_with_outer(outer.clone()); outer.as_ref().borrow_mut().set("key".to_string(), Object::Int(2)); assert_eq!(outer.as_ref().borrow_mut().update("key".to_string(), Object::Int(2)), UpdateInfo::Succeed); diff --git a/interpreter/src/evaluator/mod.rs b/interpreter/src/evaluator/mod.rs index 675855b..5f08b26 100644 --- a/interpreter/src/evaluator/mod.rs +++ b/interpreter/src/evaluator/mod.rs @@ -6,16 +6,16 @@ pub mod env; pub mod object; use crate::ast; -#[derive(PartialEq, Clone, Debug)] +#[derive(Clone, Debug)] pub struct Evaluator { - pub env: Rc>, + pub env: std::sync::Arc>, } /// // Evaluator Basic Implement /// impl Evaluator { - pub fn new(env: Rc>) -> Self { + pub fn new(env: std::sync::Arc>) -> Self { Evaluator { env } } @@ -46,7 +46,7 @@ impl Evaluator { Some(value) } else { let ast::Ident(name) = ident; - let mut env_borrow_mut = self.env.borrow_mut(); + let mut env_borrow_mut = self.env.lock(); match env_borrow_mut.check_inner(name.clone()) { env::CheckInnerInfo::ConstantExist => Some(object::Object::Error(format!( "{} {}!", @@ -72,7 +72,7 @@ impl Evaluator { Some(value) } else { let ast::Ident(name) = ident; - let mut env_borrow_mut = self.env.borrow_mut(); + let mut env_borrow_mut = self.env.lock(); match env_borrow_mut.check_inner(name.clone()) { env::CheckInnerInfo::ConstantExist => Some(object::Object::Error(format!( "{} {}!", @@ -109,7 +109,7 @@ impl Evaluator { Some(value) } else { let ast::Ident(name) = ident; - match self.env.borrow_mut().update(name.clone(), value) { + match self.env.lock().update(name.clone(), value) { env::UpdateInfo::ConstantForbidden => Some(object::Object::Error(format!( "{} {}!", "Can not assign to constant variable", name @@ -298,7 +298,7 @@ impl Evaluator { ast::Expr::Function { params, body } => Some(object::Object::Function( params.clone(), body.clone(), - Rc::clone(&self.env), + std::sync::Arc::clone(&self.env), )), ast::Expr::Call { func, args } => Some(self.eval_call_expr(func, args)), _ => None, @@ -426,15 +426,15 @@ impl Evaluator { )); } - let current_env = Rc::clone(&self.env); - let mut scoped_env = env::Env::new_with_outer(Rc::clone(&env)); + let current_env = std::sync::Arc::clone(&self.env); + let mut scoped_env = env::Env::new_with_outer(std::sync::Arc::clone(&env)); let list = params.iter().zip(args.iter()); for (_, (ident, o)) in list.enumerate() { let ast::Ident(name) = ident.clone(); scoped_env.set(name, o.clone()); } - self.env = Rc::new(RefCell::new(scoped_env)); + self.env = std::sync::Arc::new(tokio::sync::Mutex::new(scoped_env)); let object = self.eval_block_stmt(&body); @@ -455,7 +455,7 @@ impl Evaluator { fn eval_ident(&mut self, ident: &ast::Ident) -> object::Object { let ast::Ident(name) = ident; - match self.env.borrow_mut().get(name.clone()) { + match self.env.lock().get(name.clone()) { Some(value) => value, None => object::Object::Error(format!("identifier not found: {}", name)), } @@ -557,7 +557,7 @@ mod tests { fn eval(input: &str) -> Option { Evaluator { - env: Rc::new(RefCell::new(env::Env::from(new_builtins()))), + env: std::sync::Arc::new(tokio::sync::Mutex::new(env::Env::from(new_builtins()))), } .eval(&Parser::new(Lexer::new(input)).parse()) } @@ -902,7 +902,7 @@ identity(100); Box::new(ast::Expr::Ident(ast::Ident(String::from("x")))), Box::new(ast::Expr::Literal(ast::Literal::Int(2))), ))], - Rc::new(RefCell::new(env::Env::from(new_builtins()))), + std::sync::Arc::new(tokio::sync::Mutex::new(env::Env::from(new_builtins()))), )), eval(input), ); diff --git a/interpreter/src/evaluator/object.rs b/interpreter/src/evaluator/object.rs index 3a0234d..eaf6550 100644 --- a/interpreter/src/evaluator/object.rs +++ b/interpreter/src/evaluator/object.rs @@ -20,14 +20,14 @@ pub enum NativeObject { Thread(*mut std::thread::JoinHandle<()>), } -#[derive(PartialEq, Clone, Debug)] +#[derive(Clone, Debug)] pub enum Object { Int(i64), String(String), Bool(bool), Array(Vec), Hash(HashMap), - Function(Vec, ast::BlockStmt, Rc>), + Function(Vec, ast::BlockStmt, std::sync::Arc>), Builtin(i32, BuiltinFunc), ReturnValue(Box), BreakStatement, @@ -37,6 +37,7 @@ pub enum Object { Native(Box), } + /// This is actually repr impl fmt::Display for Object { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -88,7 +89,14 @@ impl fmt::Display for Object { } } -impl Eq for Object {} +impl PartialEq for Object { + fn eq(&self, other: &Self) -> bool { + false + } +} +impl Eq for Object { + +} impl Hash for Object { fn hash(&self, state: &mut H) { @@ -145,7 +153,7 @@ mod tests { let obj = Object::Function( vec![Ident("x".to_string()), Ident("y".to_string())], vec![], - Rc::new(RefCell::new(Env::new())), + std::sync::Arc::new(tokio::sync::Mutex::new(Env::new())), ); assert_eq!(format!("{}", obj), "fn(x, y) { ... }"); } diff --git a/src/bin/repl/mod.rs b/src/bin/repl/mod.rs index 58a7c7c..7932a78 100644 --- a/src/bin/repl/mod.rs +++ b/src/bin/repl/mod.rs @@ -20,7 +20,7 @@ fn main() { rl.set_helper(Some(helper::Helper::new())); let mut evaluator = Evaluator { - env: Rc::new(RefCell::new(env::Env::from(new_builtins()))), + env: std::sync::Arc::new(tokio::sync::Mutex::new(env::Env::from(new_builtins()))), }; let args: Vec = std::env::args().collect();