Skip to content

Commit

Permalink
feat: mutex try
Browse files Browse the repository at this point in the history
  • Loading branch information
meloalright committed Oct 8, 2024
1 parent 1009675 commit d702472
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 54 deletions.
55 changes: 30 additions & 25 deletions interpreter/src/evaluator/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,26 +358,31 @@ fn three_body_threading(args: Vec<Object>) -> 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!()
}
Expand Down Expand Up @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand Down
32 changes: 21 additions & 11 deletions interpreter/src/evaluator/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@ struct VariableStatus {
constant: bool,
}

#[derive(PartialEq, Clone, Debug)]
#[derive(Clone, Debug)]
pub struct Env {
pub identifiers: HashMap<String, Object>,
variables_status: HashMap<String, VariableStatus>,
outer: Option<Rc<RefCell<Env>>>,
outer: Option<std::sync::Arc<tokio::sync::Mutex<Env>>>,
}

#[derive(PartialEq, Clone, Debug)]
impl PartialEq for Env {
fn eq(&self, _: &Env) -> bool {
false
}
}

#[derive(PartialEq, Clone, Debug, Future)]
pub enum UpdateInfo {
ConstantForbidden,
NoIdentifier,
Expand Down Expand Up @@ -46,7 +52,7 @@ impl Env {
}
}

pub fn new_with_outer(outer: Rc<RefCell<Env>>) -> Self {
pub fn new_with_outer(outer: std::sync::Arc<tokio::sync::Mutex<Env>>) -> Self {
Env {
identifiers: HashMap::new(),
variables_status: HashMap::new(),
Expand All @@ -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()) {
Expand All @@ -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<Object> {
pub async fn get(&mut self, name: String) -> Option<Object> {
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,
},
}
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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);
Expand Down
26 changes: 13 additions & 13 deletions interpreter/src/evaluator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<RefCell<env::Env>>,
pub env: std::sync::Arc<tokio::sync::Mutex<env::Env>>,
}

///
// Evaluator Basic Implement
///
impl Evaluator {
pub fn new(env: Rc<RefCell<env::Env>>) -> Self {
pub fn new(env: std::sync::Arc<tokio::sync::Mutex<env::Env>>) -> Self {
Evaluator { env }
}

Expand Down Expand Up @@ -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!(
"{} {}!",
Expand All @@ -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!(
"{} {}!",
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand All @@ -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)),
}
Expand Down Expand Up @@ -557,7 +557,7 @@ mod tests {

fn eval(input: &str) -> Option<object::Object> {
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())
}
Expand Down Expand Up @@ -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),
);
Expand Down
16 changes: 12 additions & 4 deletions interpreter/src/evaluator/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Object>),
Hash(HashMap<Object, Object>),
Function(Vec<ast::Ident>, ast::BlockStmt, Rc<RefCell<env::Env>>),
Function(Vec<ast::Ident>, ast::BlockStmt, std::sync::Arc<tokio::sync::Mutex<env::Env>>),
Builtin(i32, BuiltinFunc),
ReturnValue(Box<Object>),
BreakStatement,
Expand All @@ -37,6 +37,7 @@ pub enum Object {
Native(Box<NativeObject>),
}


/// This is actually repr
impl fmt::Display for Object {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down Expand Up @@ -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<H: Hasher>(&self, state: &mut H) {
Expand Down Expand Up @@ -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) { ... }");
}
Expand Down
2 changes: 1 addition & 1 deletion src/bin/repl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> = std::env::args().collect();
Expand Down

0 comments on commit d702472

Please sign in to comment.