Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ jobs:
- uses: actions/checkout@v3
- name: Run tests
run: cargo test

- name: Run sync tests
run: cargo test --features sync
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ name = "tulisp"
path = "src/lib.rs"

[features]
sync = []
big_functions = []
13 changes: 8 additions & 5 deletions src/builtin/functions/hash_table.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use crate::{Error, TulispAny, TulispContext, TulispObject, destruct_eval_bind};
use std::{cell::RefCell, collections::HashMap, rc::Rc};
use crate::{
Error, TulispContext, TulispObject, destruct_eval_bind,
object::wrappers::generic::{Shared, SharedMut},
};
use std::collections::HashMap;

struct TulispObjectEql(TulispObject);

Expand Down Expand Up @@ -29,7 +32,7 @@ impl From<TulispObject> for TulispObjectEql {
}

pub(crate) struct HashTable {
inner: RefCell<HashMap<TulispObjectEql, TulispObject>>,
inner: SharedMut<HashMap<TulispObjectEql, TulispObject>>,
}

impl std::fmt::Display for HashTable {
Expand All @@ -46,8 +49,8 @@ pub(crate) fn add(ctx: &mut TulispContext) {
)
.with_trace(args.clone()));
}
let table: Rc<dyn TulispAny> = Rc::new(HashTable {
inner: RefCell::new(HashMap::new()),
let table = Shared::new_any(HashTable {
inner: SharedMut::new(HashMap::new()),
});
Ok(table.into())
});
Expand Down
19 changes: 6 additions & 13 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ mod add_function;
mod rest;
pub use rest::Rest;

use std::{collections::HashMap, fs, rc::Rc};
use std::{collections::HashMap, fs};

use crate::{
TulispObject, TulispValue, builtin,
context::add_function::TulispCallable,
error::Error,
eval::{DummyEval, eval, eval_and_then, eval_basic, funcall},
list,
object::wrappers::generic::{Shared, TulispFn},
parse::parse,
};

Expand Down Expand Up @@ -86,13 +87,9 @@ impl TulispContext {
}

#[inline(always)]
pub fn add_special_form(
&mut self,
name: &str,
func: impl Fn(&mut TulispContext, &TulispObject) -> Result<TulispObject, Error> + 'static,
) {
pub fn add_special_form(&mut self, name: &str, func: impl TulispFn + std::any::Any) {
self.intern(name)
.set_global(TulispValue::Func(Rc::new(func)).into_ref(None))
.set_global(TulispValue::Func(Shared::new_tulisp_fn(func)).into_ref(None))
.unwrap();
}

Expand Down Expand Up @@ -125,13 +122,9 @@ impl TulispContext {
}

#[inline(always)]
pub fn add_macro(
&mut self,
name: &str,
func: impl Fn(&mut TulispContext, &TulispObject) -> Result<TulispObject, Error> + 'static,
) {
pub fn add_macro(&mut self, name: &str, func: impl TulispFn) {
self.intern(name)
.set_global(TulispValue::Macro(Rc::new(func)).into_ref(None))
.set_global(TulispValue::Macro(Shared::new_tulisp_fn(func)).into_ref(None))
.unwrap();
}

Expand Down
25 changes: 13 additions & 12 deletions src/context/add_function.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::object::wrappers::generic::SyncSend;
use crate::{Error, Rest, TulispContext, TulispObject, destruct_bind, destruct_eval_bind};

pub trait TulispCallable<
Expand Down Expand Up @@ -25,7 +26,7 @@ macro_rules! impl_tulisp_callable {
impl<OutT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)*) , OutT, false, $args_count, $opts_count, false, true, false> for FnT
where
FnT: Fn($($arg,)* $(Option<$opt>),*) -> OutT + 'static,
FnT: Fn($($arg,)* $(Option<$opt>),*) -> OutT + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
OutT: Into<TulispObject> + 'static,
Expand All @@ -51,7 +52,7 @@ macro_rules! impl_tulisp_callable {
impl<FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)*) , (), false, $args_count, $opts_count, false, false, false> for FnT
where
FnT: Fn($($arg,)* $(Option<$opt>),*) + 'static,
FnT: Fn($($arg,)* $(Option<$opt>),*) + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
{
Expand All @@ -76,7 +77,7 @@ macro_rules! impl_tulisp_callable {
impl<OutT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)*) , OutT, true, $args_count, $opts_count, false, true,false> for FnT
where
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>),*) -> OutT + 'static,
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>),*) -> OutT + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
OutT: Into<TulispObject> + 'static,
Expand All @@ -102,7 +103,7 @@ macro_rules! impl_tulisp_callable {
impl<FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)*), (), true, $args_count, $opts_count, false, false,false> for FnT
where
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>),*) + 'static,
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>),*) + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
{
Expand All @@ -127,7 +128,7 @@ macro_rules! impl_tulisp_callable {
impl<OutT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)*) , OutT, false, $args_count, $opts_count, false, true, true> for FnT
where
FnT: Fn($($arg,)* $(Option<$opt>),*) -> Result<OutT, Error> + 'static,
FnT: Fn($($arg,)* $(Option<$opt>),*) -> Result<OutT, Error> + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
OutT: Into<TulispObject> + 'static,
Expand All @@ -153,7 +154,7 @@ macro_rules! impl_tulisp_callable {
impl<OutT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)*) , OutT, true, $args_count, $opts_count, false, true, true> for FnT
where
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>),*) -> Result<OutT, Error> + 'static,
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>),*) -> Result<OutT, Error> + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
OutT: Into<TulispObject> + 'static,
Expand All @@ -179,7 +180,7 @@ macro_rules! impl_tulisp_callable {
impl<RestT, OutT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)* RestT,), OutT, false, $args_count, $opts_count, true, true, false> for FnT
where
FnT: Fn($($arg,)* $(Option<$opt>,)* Rest<RestT>) -> OutT + 'static,
FnT: Fn($($arg,)* $(Option<$opt>,)* Rest<RestT>) -> OutT + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
RestT: TryFrom<TulispObject, Error = Error> + Into<TulispObject> + 'static,
Expand Down Expand Up @@ -216,7 +217,7 @@ macro_rules! impl_tulisp_callable {
impl<RestT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)* RestT,), (), false, $args_count, $opts_count, true, false, false> for FnT
where
FnT: Fn($($arg,)* $(Option<$opt>,)* Rest<RestT>) + 'static,
FnT: Fn($($arg,)* $(Option<$opt>,)* Rest<RestT>) + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
RestT: TryFrom<TulispObject, Error = Error> + Into<TulispObject> + 'static,
Expand Down Expand Up @@ -252,7 +253,7 @@ macro_rules! impl_tulisp_callable {
impl<RestT, OutT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)* RestT,), OutT, true, $args_count, $opts_count, true, true, false> for FnT
where
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>,)* Rest<RestT>) -> OutT + 'static,
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>,)* Rest<RestT>) -> OutT + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
RestT: TryFrom<TulispObject, Error = Error> + Into<TulispObject> + 'static,
Expand Down Expand Up @@ -290,7 +291,7 @@ macro_rules! impl_tulisp_callable {
impl<RestT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)* RestT,), (), true, $args_count, $opts_count, true, false, false> for FnT
where
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>,)* Rest<RestT>) + 'static,
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>,)* Rest<RestT>) + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
RestT: TryFrom<TulispObject, Error = Error> + Into<TulispObject> + 'static,
Expand Down Expand Up @@ -327,7 +328,7 @@ macro_rules! impl_tulisp_callable {
impl<RestT, OutT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)* RestT,), OutT, false, $args_count, $opts_count, true, true, true> for FnT
where
FnT: Fn($($arg,)* $(Option<$opt>,)* Rest<RestT>) -> Result<OutT, Error> + 'static,
FnT: Fn($($arg,)* $(Option<$opt>,)* Rest<RestT>) -> Result<OutT, Error> + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
RestT: TryFrom<TulispObject, Error = Error> + Into<TulispObject> + 'static,
Expand Down Expand Up @@ -364,7 +365,7 @@ macro_rules! impl_tulisp_callable {
impl<RestT, OutT, FnT, $($arg,)* $($opt,)*>
TulispCallable<($($arg,)* $($opt,)* RestT,), OutT, true, $args_count, $opts_count, true, true, true> for FnT
where
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>,)* Rest<RestT>) -> Result<OutT, Error> + 'static,
FnT: Fn(&mut TulispContext, $($arg,)* $(Option<$opt>,)* Rest<RestT>) -> Result<OutT, Error> + 'static + SyncSend,
$($arg: TryFrom<TulispObject, Error = Error> + 'static,)*
$($opt: TryFrom<TulispObject, Error = Error> + 'static,)*
RestT: TryFrom<TulispObject, Error = Error> + Into<TulispObject> + 'static,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ pub use value::TulispAny;
pub use value::TulispValue;

mod object;
pub use object::TulispObject;
pub use {object::TulispObject, object::wrappers::generic::Shared};

#[cfg(test)]
mod test_utils {
Expand Down
43 changes: 20 additions & 23 deletions src/object.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
pub mod wrappers;

use crate::{
TulispValue,
cons::{self, Cons},
error::Error,
object::wrappers::generic::{Shared, SharedMut, SharedRef},
value::TulispAny,
};
use std::{
any::Any,
cell::{Cell, Ref, RefCell},
rc::Rc,
};

#[derive(Debug, Clone, PartialEq, Eq, Copy)]
pub struct Span {
Expand All @@ -30,8 +28,8 @@ impl Span {
/// A type for representing tulisp objects.
#[derive(Debug, Clone)]
pub struct TulispObject {
rc: Rc<RefCell<TulispValue>>,
span: Rc<Cell<Option<Span>>>,
rc: SharedMut<TulispValue>,
span: SharedMut<Option<Span>>,
}

impl Default for TulispObject {
Expand Down Expand Up @@ -281,7 +279,7 @@ impl TulispObject {
"Returns a string if `self` contains a string, and an Error otherwise."
);
extractor_fn_with_err!(
Rc<dyn Any>,
Shared<dyn TulispAny>,
as_any,
r#"Returns a boxed value if `self` contains a boxed value, and an Error otherwise.

Expand All @@ -290,8 +288,7 @@ with `as_any`, and downcast to desired types.

## Example
```rust
# use tulisp::{TulispContext, destruct_bind, Error, TulispAny};
# use std::rc::Rc;
# use tulisp::{TulispContext, destruct_bind, Error, TulispAny, Shared};
#
# fn main() -> Result<(), Error> {
let mut ctx = TulispContext::new();
Expand All @@ -310,7 +307,7 @@ ctx.add_special_form("make_any", |_ctx, args| {
destruct_bind!((inp) = args);
let inp: i64 = inp.try_into()?;

let any_obj: Rc<dyn TulispAny> = Rc::new(TestStruct { value: inp });
let any_obj = Shared::new_any(TestStruct { value: inp });

Ok(any_obj.into())
});
Expand Down Expand Up @@ -372,8 +369,8 @@ impl TulispObject {

pub(crate) fn new(vv: TulispValue, span: Option<Span>) -> TulispObject {
Self {
rc: Rc::new(RefCell::new(vv)),
span: Rc::new(Cell::new(span)),
rc: SharedMut::new(vv),
span: SharedMut::new(span),
}
}

Expand All @@ -396,7 +393,7 @@ impl TulispObject {

#[inline(always)]
pub(crate) fn eq_ptr(&self, other: &TulispObject) -> bool {
Rc::ptr_eq(&self.rc, &other.rc)
self.rc.ptr_eq(&other.rc)
}

#[inline(always)]
Expand All @@ -405,19 +402,19 @@ impl TulispObject {
}

pub(crate) fn addr_as_usize(&self) -> usize {
self.rc.as_ptr() as usize
self.rc.addr_as_usize()
}

pub(crate) fn clone_without_span(&self) -> Self {
Self {
rc: Rc::clone(&self.rc),
span: Rc::new(Cell::new(None)),
rc: self.rc.clone(),
span: SharedMut::new(None),
}
}

#[inline(always)]
pub(crate) fn strong_count(&self) -> usize {
Rc::strong_count(&self.rc)
self.rc.strong_count()
}

#[inline(always)]
Expand All @@ -430,7 +427,7 @@ impl TulispObject {
}

#[inline(always)]
pub(crate) fn inner_ref(&self) -> Ref<'_, TulispValue> {
pub(crate) fn inner_ref(&self) -> SharedRef<'_, TulispValue> {
self.rc.borrow()
}

Expand All @@ -448,7 +445,7 @@ impl TulispObject {
}

pub(crate) fn with_span(&self, in_span: Option<Span>) -> Self {
self.span.set(in_span);
*self.span.borrow_mut() = in_span;
self.clone()
}
pub(crate) fn take(&self) -> TulispValue {
Expand All @@ -458,7 +455,7 @@ impl TulispObject {
#[doc(hidden)]
#[inline(always)]
pub fn span(&self) -> Option<Span> {
self.span.get()
self.span.borrow().clone()
}

#[doc(hidden)]
Expand Down Expand Up @@ -552,7 +549,7 @@ impl From<TulispObject> for bool {
}
}

impl TryFrom<TulispObject> for Rc<dyn Any> {
impl TryFrom<TulispObject> for Shared<dyn TulispAny> {
type Error = Error;

fn try_from(value: TulispObject) -> Result<Self, Self::Error> {
Expand All @@ -575,7 +572,7 @@ tulisp_object_from!(f64);
tulisp_object_from!(&str);
tulisp_object_from!(String);
tulisp_object_from!(bool);
tulisp_object_from!(Rc<dyn TulispAny>);
tulisp_object_from!(Shared<dyn TulispAny>);

impl FromIterator<TulispObject> for TulispObject {
fn from_iter<T: IntoIterator<Item = TulispObject>>(iter: T) -> Self {
Expand Down
Loading