Skip to content

Commit

Permalink
Refactor accessors
Browse files Browse the repository at this point in the history
  • Loading branch information
cowuake committed Jul 7, 2024
1 parent 47d463d commit 128cce1
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 95 deletions.
51 changes: 24 additions & 27 deletions schemius/src/core/accessor.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,50 @@
use core::fmt::Debug;
use std::{
cell::RefCell,
cell::{Ref, RefCell, RefMut},
ops::{Deref, DerefMut},
rc::Rc,
sync::{Arc, Mutex},
sync::{Arc, Mutex, MutexGuard},
};

pub trait Accessor<T: Clone> {
pub trait Accessor<T> {
fn new(src: T) -> Self;
fn borrow(&self) -> impl Deref<Target = T>;
fn borrow_mut(&self) -> impl DerefMut<Target = T>;
fn access(&self) -> impl Deref<Target = T>;
fn access_mut(&self) -> impl DerefMut<Target = T>;
fn replace(&self, src: T) -> T;
}

#[derive(Debug, Clone)]
pub struct BaseAccessor<T> {
inner: Rc<RefCell<T>>,
}
#[derive(Clone, Debug)]
pub struct BaseAccessor<T>(Rc<RefCell<T>>);

#[derive(Debug, Clone)]
pub struct ThreadSafeAccessor<T> {
inner: Arc<Mutex<T>>,
}
#[derive(Clone, Debug)]
pub struct ThreadSafeAccessor<T>(Arc<Mutex<T>>);

impl<T: Clone> Accessor<T> for BaseAccessor<T> {
impl<T> Accessor<T> for BaseAccessor<T> {
fn new(src: T) -> Self {
Self { inner: Rc::new(RefCell::new(src)) }
Self(Rc::new(RefCell::new(src)))
}
fn borrow(&self) -> impl Deref<Target = T> {
self.inner.borrow()
fn access(&self) -> Ref<T> {
self.0.try_borrow().unwrap()
}
fn borrow_mut(&self) -> impl DerefMut<Target = T> {
self.inner.borrow_mut()
fn access_mut(&self) -> RefMut<T> {
self.0.try_borrow_mut().unwrap()
}
fn replace(&self, src: T) -> T {
std::mem::replace(&mut *self.inner.borrow_mut(), src)
std::mem::replace(&mut *self.0.try_borrow_mut().unwrap(), src)
}
}

impl<T: Clone> Accessor<T> for ThreadSafeAccessor<T> {
impl<T> Accessor<T> for ThreadSafeAccessor<T> {
fn new(src: T) -> Self {
Self { inner: Arc::new(Mutex::new(src)) }
Self(Arc::new(Mutex::new(src)))
}
fn borrow(&self) -> impl Deref<Target = T> {
self.inner.try_lock().unwrap()
fn access(&self) -> MutexGuard<T> {
self.0.try_lock().unwrap()
}
fn borrow_mut(&self) -> impl DerefMut<Target = T> {
self.inner.try_lock().unwrap()
fn access_mut(&self) -> MutexGuard<T> {
self.0.try_lock().unwrap()
}
fn replace(&self, src: T) -> T {
std::mem::replace(&mut *self.inner.try_lock().unwrap(), src)
std::mem::replace(&mut *self.0.try_lock().unwrap(), src)
}
}
6 changes: 3 additions & 3 deletions schemius/src/core/builtins/base_procs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn r_apply(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {
to_be_evaluated.push(proc.clone());

match args {
SExpr::List(list) => list.borrow().iter().for_each(|arg| to_be_evaluated.push(arg.clone())),
SExpr::List(list) => list.access().iter().for_each(|arg| to_be_evaluated.push(arg.clone())),
other => return Err(format!("Exception in #<apply>: {} is not a list", other)),
}

Expand All @@ -36,7 +36,7 @@ pub fn r_display(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {
}

match args.s_car().unwrap() {
SExpr::String(string) => Ok(SExpr::Symbol(string.borrow().to_string())), // Avoids double quotes
SExpr::String(string) => Ok(SExpr::Symbol(string.access().to_string())), // Avoids double quotes
expr => Ok(SExpr::Symbol(format!("{}", expr))),
}
}
Expand All @@ -53,7 +53,7 @@ pub fn r_environment_bindings(args: ProcedureArgs, env: ProcedureEnv) -> Procedu
));
}

let env_guard = env.borrow();
let env_guard = env.access();
let mut bindings = env_guard.get_bindings().clone();
bindings.sort_by(|a, b| a.0.cmp(b.0));

Expand Down
22 changes: 11 additions & 11 deletions schemius/src/core/builtins/list_procs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ pub fn r_set_car(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {

match args.s_car().unwrap() {
SExpr::List(list) => {
list.borrow_mut().set_car(args.s_cadr().unwrap().clone());
list.access_mut().set_car(args.s_cadr().unwrap().clone());
Ok(SExpr::Unspecified)
}
SExpr::Pair(pair) => {
let old_cdr = pair.borrow().1.clone();
let old_cdr = pair.access().1.clone();
pair.replace((Box::new(args.s_cadr().unwrap().clone()), old_cdr));

Ok(SExpr::Unspecified)
Expand All @@ -36,7 +36,7 @@ pub fn r_cons(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {
SExpr::List(list) => {
let mut new_list = vec![];
new_list.push(car);
list.borrow_mut().iter().for_each(|x| new_list.push(x.clone()));
list.access_mut().iter().for_each(|x| new_list.push(x.clone()));

Ok(SExpr::List(SchemeList::new(new_list)))
}
Expand Down Expand Up @@ -84,11 +84,11 @@ pub fn r_car(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {

match &args.s_car().unwrap() {
SExpr::Pair(pair) => {
let car = pair.borrow().0.clone();
let car = pair.access().0.clone();
Ok(*car)
}
SExpr::List(list) => {
let borrowed = list.borrow();
let borrowed = list.access();
if borrowed.s_len() > 0 {
let car = if borrowed.s_car().unwrap().is_quote().unwrap() {
borrowed.s_cdr().unwrap().s_car().unwrap().clone()
Expand All @@ -111,11 +111,11 @@ pub fn r_cdr(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {

match args.s_car().unwrap() {
SExpr::Pair(pair) => {
let cdr = pair.borrow().1.clone();
let cdr = pair.access().1.clone();
Ok(*cdr)
}
SExpr::List(list) => {
let list = list.borrow();
let list = list.access();

match list.s_len() {
1.. => {
Expand Down Expand Up @@ -165,7 +165,7 @@ pub fn r_list_ref(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {
match args.s_car().unwrap() {
SExpr::List(list) => {
let index = args.s_cadr().unwrap().as_int().unwrap() as usize;
let borrowed = list.borrow();
let borrowed = list.access();
let len = borrowed.s_len();

if index >= len {
Expand All @@ -190,7 +190,7 @@ pub fn r_list_tail(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {
match args.s_car().unwrap() {
SExpr::List(list) => {
let index = args.s_cadr().unwrap().as_int()? as usize;
let borrowed = list.borrow();
let borrowed = list.access();
let len = borrowed.s_len();

if index >= len {
Expand All @@ -214,7 +214,7 @@ pub fn r_reverse(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {

match args.s_car().unwrap() {
SExpr::List(list) => {
let reversed = list.borrow().s_reverse();
let reversed = list.access().s_reverse();
Ok(SExpr::List(SchemeList::new(reversed)))
}
_ => Err(String::from("Exception in #<reverse>: expected a list")),
Expand All @@ -229,7 +229,7 @@ pub fn r_length(args: ProcedureArgs, _: ProcedureEnv) -> ProcedureOutput {

match args.s_car().unwrap() {
SExpr::List(list) => {
let len = list.borrow().s_len();
let len = list.access().s_len();
Ok(SExpr::Number(SNumber::Int(NativeInt::from(len as NativeInt))))
}
_ => Err(String::from("Exception in #<length>: expected a list")),
Expand Down
44 changes: 22 additions & 22 deletions schemius/src/core/builtins/special_forms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn r_lambda(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput {
}

let arg_names = match args.s_car().unwrap() {
SExpr::List(ref list) => match list_args(&list.borrow()) {
SExpr::List(ref list) => match list_args(&list.access()) {
Ok(names) => names,
Err(e) => return Err(e),
},
Expand All @@ -53,24 +53,24 @@ pub fn r_define(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput {
other => other,
};

match env.borrow_mut().define(name, &value) {
match env.access_mut().define(name, &value) {
Ok(_) => Ok(SExpr::Ok),
Err(_) => Err(format!("Exception: error defining {}", name)),
}
}
Err(e) => Err(e),
},
SExpr::List(list) => {
if list.borrow().s_len() == 0 {
if list.access().s_len() == 0 {
return Err(String::from("Exception (TODO?): deal with empty lists"));
}

let lambda_name = list.borrow().s_car().unwrap().to_string();
let lambda_name = list.access().s_car().unwrap().to_string();
let mut lambda_args: Vec<SExpr> = vec![];
let lambda_body = &mut args.s_cdr().unwrap();

if list.borrow().s_len() > 1 {
for arg in &list.borrow()[1..] {
if list.access().s_len() > 1 {
for arg in &list.access()[1..] {
lambda_args.push(arg.clone());
}
}
Expand All @@ -83,7 +83,7 @@ pub fn r_define(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput {
Err(e) => return Err(e),
};

match env.borrow_mut().define(&lambda_name, &lambda_proc) {
match env.access_mut().define(&lambda_name, &lambda_proc) {
Ok(_) => Ok(SExpr::Ok),
Err(_) => Err(String::from("")),
}
Expand All @@ -110,7 +110,7 @@ pub fn r_set(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput {
other => other,
};

match env.borrow_mut().set(&name, &value) {
match env.access_mut().set(&name, &value) {
Ok(_) => Ok(SExpr::Ok),
Err(e) => Err(e),
}
Expand All @@ -134,15 +134,15 @@ pub fn r_let(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput {

match args.s_car().unwrap() {
SExpr::List(list) => {
for binding in list.borrow().iter() {
for binding in list.access().iter() {
match binding {
SExpr::List(binding) => {
let borrowed_binding = binding.borrow();
let borrowed_binding = binding.access();
match borrowed_binding.s_car().unwrap() {
SExpr::Symbol(symbol) => {
match eval(&borrowed_binding[1], env.clone()) {
Ok(expr) => {
let_env.borrow_mut().define(&symbol, &expr).unwrap()
let_env.access_mut().define(&symbol, &expr).unwrap()
}
Err(e) => return Err(e),
}
Expand Down Expand Up @@ -181,17 +181,17 @@ pub fn r_let_star(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput {

match args.s_car().unwrap() {
SExpr::List(list) => {
for binding in list.borrow().iter() {
for binding in list.access().iter() {
match binding {
SExpr::List(binding) => {
let borrowed_binding = binding.borrow();
let borrowed_binding = binding.access();
match &borrowed_binding[0] {
SExpr::Symbol(symbol) => {
match eval(&borrowed_binding[1], inner_env.clone()) {
Ok(expr) => {
inner_env = Environment::new_child(inner_env.clone());
inner_env = Environment::new_child(inner_env.clone());
inner_env.borrow_mut().define(&symbol, &expr).unwrap();
inner_env.access_mut().define(&symbol, &expr).unwrap();
}
Err(e) => return Err(e),
}
Expand Down Expand Up @@ -331,7 +331,7 @@ pub fn r_quasiquote(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput

// After each and every unquoting indexes will be shifted by a certain offset
let mut offset: i32 = 0;
let mut borrowed_list = list.borrow_mut();
let mut borrowed_list = list.access_mut();

loop {
if unquotes.is_empty() {
Expand Down Expand Up @@ -382,7 +382,7 @@ pub fn r_quasiquote(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput

if let SExpr::Symbol(symbol) = suspect {
if !env
.borrow()
.access()
.get(&symbol)
.unwrap()
.is_procedure()
Expand All @@ -409,7 +409,7 @@ pub fn r_quasiquote(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput
}
// Unquoting symbol or atom
None => {
to_be_evaluated = list.borrow()[unquote_index + 1].clone();
to_be_evaluated = list.access()[unquote_index + 1].clone();
first_idx = unquote_index - 1; // Index of the left parenthesis preceding the unquote symbol
last_idx = unquote_index + 3; // Index of the right parenthesis + 1
}
Expand All @@ -425,14 +425,14 @@ pub fn r_quasiquote(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput
match evaluated {
Ok(ref res) => match res {
SExpr::List(internal) => {
let borrowed_internal = internal.borrow();
let borrowed_internal = internal.access();
offset -= (borrowed_internal.s_len() - 1) as i32;

for i in (first_idx..last_idx).rev() {
borrowed_list.remove(i);
}

for i in (0..internal.borrow().s_len()).rev() {
for i in (0..internal.access().s_len()).rev() {
borrowed_list.splice(
first_idx..first_idx,
[borrowed_internal[i].clone()],
Expand Down Expand Up @@ -484,16 +484,16 @@ pub fn r_cond(args: ProcedureArgs, env: ProcedureEnv) -> SpecialFormOutput {
for block in iterator {
match block {
SExpr::List(list) => {
if list.borrow().s_len() != 2 {
if list.access().s_len() != 2 {
return Err(String::from(
"Exception: malformed args provided to #<procedure cond>",
));
}
let first = eval(&list.borrow()[0], env.clone());
let first = eval(&list.access()[0], env.clone());
match first {
Ok(condition) => match condition {
SExpr::Boolean(val) => match val {
true => return Ok(list.borrow()[1].clone()),
true => return Ok(list.access()[1].clone()),
false => continue,
},
_ => {
Expand Down
Loading

0 comments on commit 128cce1

Please sign in to comment.