Skip to content

Commit

Permalink
Merge pull request sl-sh-dev#158 from sl-sh-dev/more-str-macros
Browse files Browse the repository at this point in the history
More str macros
  • Loading branch information
gpwclark authored Mar 27, 2024
2 parents 2545bf0 + 121ad31 commit db3e0a2
Show file tree
Hide file tree
Showing 10 changed files with 357 additions and 396 deletions.
55 changes: 55 additions & 0 deletions bridge_adapters/src/lisp_adapters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,33 @@ where
fn sl_from(value: T, vm: &mut SloshVm) -> VMResult<Self>;
}

impl<T> SlFrom<Vec<T>> for Value
where
T: SlInto<Value>,
{
fn sl_from(value: Vec<T>, vm: &mut SloshVm) -> VMResult<Self> {
let mut u = Vec::with_capacity(value.len());
for v in value {
u.push(v.sl_into(vm)?);
}
Ok(vm.alloc_vector(u))
}
}

impl<'a, T> SlFromRef<'a, slvm::Value> for Vec<T>
where
T: SlFromRef<'a, Value> + 'a + ?Sized,
{
fn sl_from_ref(value: slvm::Value, vm: &'a SloshVm) -> VMResult<Self> {
let mut res = vec![];
for val in value.iter(vm) {
let t: T = val.sl_into_ref(vm)?;
res.push(t);
}
Ok(res)
}
}

/// Inverse of [`SlFrom`]
pub trait SlInto<T>: Sized
where
Expand Down Expand Up @@ -164,6 +191,34 @@ where
}
}

pub trait SlFromRefMut<'a, T: BridgedType>
where
Self: Sized,
{
/// Converts to this type from the input type.
fn sl_from_ref_mut(value: T, vm: &'a mut SloshVm) -> VMResult<Self>;
}

pub trait SlIntoRefMut<'a, T>: Sized
where
T: 'a,
Self: BridgedType,
{
/// Converts to this type from the input type.
fn sl_into_ref_mut(self, vm: &'a mut SloshVm) -> VMResult<T>;
}

impl<'a, T, U> SlIntoRefMut<'a, U> for T
where
T: BridgedType,
U: SlFromRefMut<'a, T>,
U: 'a,
{
fn sl_into_ref_mut(self, vm: &'a mut SloshVm) -> VMResult<U> {
U::sl_from_ref_mut(self, vm)
}
}

/// Converts a [`BridgedType`] to some rust type
pub trait SlAsRef<'a, T: ?Sized>
where
Expand Down
36 changes: 21 additions & 15 deletions bridge_adapters/src/lisp_adapters/numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ impl SlFrom<()> for Value {
}
}

impl<'a> SlFromRef<'a, &'a Value> for () {
fn sl_from_ref(value: &Value, _vm: &'a SloshVm) -> VMResult<()> {
impl<'a> SlFromRef<'a, Value> for () {
fn sl_from_ref(value: Value, _vm: &'a SloshVm) -> VMResult<()> {
match value {
Value::Nil => Ok(()),
_ => Err(VMError::new_conversion(
Expand All @@ -35,11 +35,11 @@ impl SlFrom<u32> for Value {
}
}

impl<'a> SlFromRef<'a, &'a Value> for i32 {
fn sl_from_ref(value: &Value, vm: &'a SloshVm) -> VMResult<i32> {
impl<'a> SlFromRef<'a, Value> for i32 {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<i32> {
match value {
Value::Int(num) => {
let num = from_i56(num);
let num = from_i56(&num);
num.try_into().map_err(|_| {
VMError::new_conversion(
"Provided slosh value too small to fit desired type.".to_string(),
Expand All @@ -62,10 +62,10 @@ impl SlFrom<f64> for Value {
}
}

impl<'a> SlFromRef<'a, &'a Value> for f64 {
fn sl_from_ref(value: &Value, vm: &'a SloshVm) -> VMResult<Self> {
impl<'a> SlFromRef<'a, Value> for f64 {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<Self> {
match value {
Value::Float(f56) => Ok(f64::from(*f56)),
Value::Float(f56) => Ok(f64::from(f56)),
_ => Err(VMError::new_conversion(
ErrorStrings::fix_me_mismatched_type(
<&'static str>::from(ValueType::Float),
Expand All @@ -76,10 +76,16 @@ impl<'a> SlFromRef<'a, &'a Value> for f64 {
}
}

impl<'a> SlFromRef<'a, &'a Value> for usize {
fn sl_from_ref(value: &Value, vm: &'a SloshVm) -> VMResult<Self> {
impl SlFrom<usize> for Value {
fn sl_from(value: usize, _vm: &mut SloshVm) -> VMResult<Self> {
Ok(to_i56(value as i64))
}
}

impl<'a> SlFromRef<'a, Value> for usize {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<Self> {
match value {
Value::Int(i) => usize::try_from(from_i56(i)).map_err(|_| {
Value::Int(i) => usize::try_from(from_i56(&i)).map_err(|_| {
VMError::new_conversion(ErrorStrings::fix_me_mismatched_type(
<&'static str>::from(ValueType::Int),
value.display_type(vm),
Expand All @@ -95,10 +101,10 @@ impl<'a> SlFromRef<'a, &'a Value> for usize {
}
}

impl<'a> SlFromRef<'a, &'a Value> for i64 {
fn sl_from_ref(value: &Value, vm: &'a SloshVm) -> VMResult<Self> {
impl<'a> SlFromRef<'a, Value> for i64 {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<Self> {
match value {
Value::Int(i) => Ok(from_i56(i)),
Value::Int(i) => Ok(from_i56(&i)),
_ => Err(VMError::new_conversion(
ErrorStrings::fix_me_mismatched_type(
<&'static str>::from(ValueType::Int),
Expand Down Expand Up @@ -132,6 +138,6 @@ mod tests {
let mut vm = new_slosh_vm();
let vm = &mut vm;
let val = to_i56(7_i32 as i64);
let _val: i32 = i32::sl_from_ref(&val, vm).expect("Value can be converted to i32");
let _val: i32 = i32::sl_from_ref(val, vm).expect("Value can be converted to i32");
}
}
16 changes: 8 additions & 8 deletions bridge_adapters/src/lisp_adapters/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use crate::lisp_adapters::{SlFrom, SlFromRef};
use compile_state::state::SloshVm;
use slvm::{VMResult, Value};

impl<'a> SlFromRef<'a, &'a Value> for bool {
fn sl_from_ref(value: &Value, _vm: &SloshVm) -> VMResult<Self> {
impl<'a> SlFromRef<'a, Value> for bool {
fn sl_from_ref(value: Value, _vm: &SloshVm) -> VMResult<Self> {
match value {
Value::True => Ok(true),
Value::False => Ok(false),
Expand Down Expand Up @@ -39,11 +39,11 @@ where
}
}

impl<'a, T> SlFromRef<'a, &'a Value> for Option<T>
impl<'a, T> SlFromRef<'a, Value> for Option<T>
where
T: SlFromRef<'a, &'a Value>,
T: SlFromRef<'a, Value>,
{
fn sl_from_ref(value: &'a Value, vm: &'a SloshVm) -> VMResult<Self> {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<Self> {
if value.is_nil() {
Ok(None)
} else {
Expand Down Expand Up @@ -77,19 +77,19 @@ mod tests {
let mut vm = new_slosh_vm();
let vm = &mut vm;
let n = Value::Nil;
let n: bool = (&n)
let n: bool = n
.sl_into_ref(vm)
.expect("Value::Nil can be converted to bool");
assert_eq!(n, false);

let f = Value::False;
let f: bool = (&f)
let f: bool = f
.sl_into_ref(vm)
.expect("Value::False can be converted to bool");
assert_eq!(f, false);

let t = Value::True;
let t: bool = (&t)
let t: bool = t
.sl_into_ref(vm)
.expect("Value::True can be converted to bool");
assert_eq!(t, true);
Expand Down
69 changes: 37 additions & 32 deletions bridge_adapters/src/lisp_adapters/text.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::lisp_adapters::{SlAsMut, SlAsRef, SlFrom, SlFromRef};
use crate::lisp_adapters::{SlAsMut, SlAsRef, SlFrom, SlFromRef, SlFromRefMut};
use bridge_types::{ErrorStrings, LooseString, SloshChar};
use compile_state::state::SloshVm;
use slvm::value::ValueType;
Expand All @@ -17,22 +17,22 @@ impl<'a> SlFrom<SloshChar<'a>> for Value {
}
}

impl<'a> SlFromRef<'a, &Value> for LooseString<'a> {
fn sl_from_ref(value: &Value, vm: &'a SloshVm) -> VMResult<Self> {
impl<'a> SlFromRef<'a, Value> for LooseString<'a> {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<Self> {
match value {
Value::String(h) => Ok(LooseString::Borrowed(vm.get_string(*h))),
Value::String(h) => Ok(LooseString::Borrowed(vm.get_string(h))),
Value::CodePoint(char) => Ok(LooseString::Owned(char.to_string())),
Value::CharCluster(l, c) => Ok(LooseString::Owned(format!(
"{}",
String::from_utf8_lossy(&c[0..*l as usize])
String::from_utf8_lossy(&c[0..l as usize])
))),
Value::CharClusterLong(h) => {
let ch = vm.get_string(*h);
let ch = vm.get_string(h);
Ok(LooseString::Borrowed(ch))
}
Value::Symbol(i) => Ok(LooseString::Borrowed(vm.get_interned(*i))),
Value::Keyword(i) => Ok(LooseString::Borrowed(vm.get_interned(*i))),
Value::StringConst(i) => Ok(LooseString::Borrowed(vm.get_interned(*i))),
Value::Symbol(i) => Ok(LooseString::Borrowed(vm.get_interned(i))),
Value::Keyword(i) => Ok(LooseString::Borrowed(vm.get_interned(i))),
Value::StringConst(i) => Ok(LooseString::Borrowed(vm.get_interned(i))),
_ => Err(VMError::new_conversion(
ErrorStrings::fix_me_mismatched_type(
String::from(ValueTypes::from([
Expand All @@ -51,10 +51,10 @@ impl<'a> SlFromRef<'a, &Value> for LooseString<'a> {
}
}

impl<'a> SlFromRef<'a, &'a Value> for char {
fn sl_from_ref(value: &Value, vm: &'a SloshVm) -> VMResult<Self> {
impl<'a> SlFromRef<'a, Value> for char {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<Self> {
match value {
Value::CodePoint(char) => Ok(*char),
Value::CodePoint(char) => Ok(char),
_ => Err(VMError::new_conversion(
ErrorStrings::fix_me_mismatched_type_with_context(
String::from(ValueTypes::from([ValueType::CodePoint])),
Expand All @@ -72,12 +72,11 @@ impl SlFrom<char> for Value {
}
}

impl<'a> SlFromRef<'a, &Value> for &'a str {
fn sl_from_ref(value: &Value, vm: &'a SloshVm) -> VMResult<Self> {
value.sl_as_ref(vm)
impl<'a> SlFromRef<'a, Value> for &'a str {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<Self> {
(&value).sl_as_ref(vm)
}
}

impl<'a> SlAsRef<'a, str> for &Value {
fn sl_as_ref(&self, vm: &'a SloshVm) -> VMResult<&'a str> {
match self {
Expand All @@ -96,15 +95,15 @@ impl<'a> SlAsRef<'a, str> for &Value {
}
}

impl<'a> SlFromRef<'a, &Value> for SloshChar<'a> {
fn sl_from_ref(value: &Value, vm: &'a SloshVm) -> VMResult<Self> {
impl<'a> SlFromRef<'a, Value> for SloshChar<'a> {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<Self> {
match value {
Value::CodePoint(ch) => Ok(SloshChar::Char(*ch)),
Value::CodePoint(ch) => Ok(SloshChar::Char(ch)),
Value::CharCluster(l, c) => Ok(SloshChar::String(Cow::Owned(format!(
"{}",
String::from_utf8_lossy(&c[0..*l as usize])
String::from_utf8_lossy(&c[0..l as usize])
)))),
Value::CharClusterLong(h) => Ok(SloshChar::String(Cow::Borrowed(vm.get_string(*h)))),
Value::CharClusterLong(h) => Ok(SloshChar::String(Cow::Borrowed(vm.get_string(h)))),
_ => Err(VMError::new_conversion(
ErrorStrings::fix_me_mismatched_type(
String::from(ValueTypes::from([
Expand All @@ -119,6 +118,12 @@ impl<'a> SlFromRef<'a, &Value> for SloshChar<'a> {
}
}

impl<'a> SlFromRefMut<'a, Value> for &'a mut String {
fn sl_from_ref_mut(value: Value, vm: &'a mut SloshVm) -> VMResult<Self> {
(&value).sl_as_mut(vm)
}
}

impl<'a> SlAsMut<'a, String> for &Value {
fn sl_as_mut(&mut self, vm: &'a mut SloshVm) -> VMResult<&'a mut String> {
match self {
Expand Down Expand Up @@ -157,10 +162,10 @@ where
}
}

impl<'a> SlFromRef<'a, &'a Value> for String {
fn sl_from_ref(value: &Value, vm: &'a SloshVm) -> VMResult<Self> {
impl<'a> SlFromRef<'a, Value> for String {
fn sl_from_ref(value: Value, vm: &'a SloshVm) -> VMResult<Self> {
match value {
Value::String(h) => Ok(vm.get_string(*h).to_string()),
Value::String(h) => Ok(vm.get_string(h).to_string()),
_ => Err(VMError::new_conversion(
ErrorStrings::fix_me_mismatched_type(
<&'static str>::from(ValueType::String),
Expand Down Expand Up @@ -252,7 +257,7 @@ mod tests {
fn try_conversion_error() {
let mut vm = new_slosh_vm();
let value = create_string(&mut vm);
let c: VMResult<char> = (&value).sl_into_ref(&mut vm);
let c: VMResult<char> = value.sl_into_ref(&vm);
assert!(c.is_err());
let err = VMError::new_conversion(ErrorStrings::fix_me_mismatched_type_with_context(
String::from(ValueTypes::from([ValueType::CodePoint])),
Expand Down Expand Up @@ -362,7 +367,7 @@ mod tests {
}
_ => {
return {
let arg: String = arg_0.sl_into_ref(vm)?;
let arg: String = (*arg_0).sl_into_ref(vm)?;
arg.trim().to_string().sl_into(vm)
}
}
Expand All @@ -387,12 +392,12 @@ mod tests {
.expect("&mut String can be converted to Value");
assert!(matches!(val, Value::String(_)));

let _s: String = (&val)
let _s: String = val
.sl_into_ref(vm)
.expect("&Value::String can be converted to String");
let kwd_val = create_keyword(vm);

let e: VMResult<String> = (&kwd_val).sl_into_ref(vm);
let e: VMResult<String> = kwd_val.sl_into_ref(vm);
e.expect_err("Can not convert keyword to String");

let _s: &str = (&val)
Expand Down Expand Up @@ -446,7 +451,7 @@ mod tests {
let vm = &mut vm;

let val = create_code_point();
let _c: char = (&val)
let _c: char = val
.sl_into_ref(vm)
.expect("&Value::CodePoint can be converted to char");
}
Expand All @@ -468,12 +473,12 @@ mod tests {
let vm = &mut vm;

let val = create_char_cluster(vm);
let _c: SloshChar = (&val)
let _c: SloshChar = val
.sl_into_ref(vm)
.expect("&Value::CharCluster can be converted to SloshChar");

let val = create_char_cluster_long(vm);
let _c: SloshChar = (&val)
let _c: SloshChar = val
.sl_into_ref(vm)
.expect("&Value::CharClusterLong can be converted to SloshChar");
}
Expand Down Expand Up @@ -514,7 +519,7 @@ mod tests {
let loose_strings_as_vals = get_values_that_can_be_cast_to_loose_strings(vm);

for val in loose_strings_as_vals {
let _loose_string: LooseString = (&val)
let _loose_string: LooseString = val
.sl_into_ref(vm)
.expect("This value should be convertable to a LooseString");
}
Expand Down
Loading

0 comments on commit db3e0a2

Please sign in to comment.