bridge_adapters

Module lisp_adapters

Source
Expand description

Notes on how conversion works:

§Accepting argumets

Check rust docs for SlFrom, SlFromRef, and SlFromRefMut to get a feel for which rust types will work as parameters to the procedural macro.

§Returning Arguments

SlInto, SlIntoRef, and SlIntoRefMut are all inverses of their respective from implementations and are used to transform the rust types tha function return into slosh values from the procedural macro.

§On accepting arguments from a dynamically typed language to a static one

Helper types in this crate like LooseString use the rust type system to model various slosh types to avoid accepting a raw slosh Value as a parameter in the procedural macro. This is not necessary, however, and should only be done if one finds oneself constantly accepting a Value type in multiple procedural macro functions and functionally duplicating similar parsing code.

§On returning arguments from a statically typed language to a dynamically one

It is also possible to manually return a VMResult of Ok<Value> if the return type of the function should not be bound by strict typing.

§Borrowing and Mutable Borrowing when a rust type does not implement Copy, demonstration with &str and &mut String

SlAsRef and SlAsMut can be used to avoid cloning from the SloshVm into the scope of function generated by the procedural macro but the traits must be structured properly.

§For regular borrows, copy this pattern used for &str


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 {
            Value::String(h) => Ok(vm.get_string(*h)),
            Value::StringConst(i) => Ok(vm.get_interned(*i)),
            _ => Err(VMError::new_conversion(
                ErrorStrings::fix_me_mismatched_type(
                    String::from(ValueTypes::from([
                        ValueType::String,
                        ValueType::StringConst,
                    ])),
                    self.display_type(vm),
                ),
            )),
        }
    }
}

§Mutable borrowing when a rust type does not implement copy


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 {
            Value::String(h) => vm.get_string_mut(*h),
            _ => Err(VMError::new_conversion(
                ErrorStrings::fix_me_mismatched_type(
                    <&'static str>::from(ValueType::String),
                    self.display_type(vm),
                ),
            )),
        }
    }
}

§rosetta stone for bridge macros

Rust TypeSlosh Type & Traits

S -> R Convert Slosh -> Rust
  - Occurs when coercing slush arguments to the parameter types in the signature of the annotated Rust function.
R -> S Convert Rust -> Slosh
  - Occurs when coercing some returned Rust type to a Slosh type.
StringValue::String
S -> R
 - SlIntoRef String for &Value
R -> S
 - SlFrom &Value for String
&StringValue::String
S -> R
 - SlIntoRef &String for &Value
R -> S
 - take String
 * uses Clone unless TODO PC ISSUE #7 the extant value problem
&mut StringValue::String
S -> R
 - SlAsMut String for &Value
R -> S
 - take &mut String
 * uses Clone unless TODO PC ISSUE #7 the extant value problem
&strValue::String / Value::StringConst
S -> R
 - SlAsRef &str for &Value
 - SlIntoRef &str for &Value
R -> S
 - SlFrom for Value
 * uses Clone unless TODO PC ISSUE #7 - the extant value problem
 - TODO PC ISSUE #7 adjacent is it even possible to call vm.alloc_string_ro on something that was newly created in the current fcn and returned as a RO value OR should that be made as a custom type so the user can declare their intent.
charValue::CodePoint
S -> R
 - SlIntoRef char for &Value
R -> S
 - SlFrom &Value for char
SloshCharValue::CharClusterLong / Value::CharCluster / Value::CodePoint
S -> R
 - SlIntoRef SloshChar for &Value
R -> S
 - SlFromRef &Value for SloshChar
LooseStringValue::String / Value::CodePoint / Value::CharCluster / Value::CharClusterLong / Value::Symbol / Value::Keyword / Value::StringConst
S -> R
 - SlIntoRef LooseString for &Value
R -> S
 * Note: Always does an allocation and returns a Value::String type.
 - SlFromRef &Value for LooseString
boolValue::True / Value::False / Value::Nil
S -> R
 - SlIntoRef bool for &Value
R -> S
 - SlFrom &Value for primitives
u8Value::Byte
S -> R
 - SlIntoRef u8 for &Value
R -> S
 - SlFrom &Value for i8
u32/i32/u64/i64/usizeValue::Int
TODO PC current behavior overflowsValue::Int([[u8; 7]]), // Store a 7 byte int (i56…).
f32/f64Value::Float(F56)
Value::Pair(Handle)
Value::List(Handle, u16)
Value::Vector(Handle)
Value::Map(Handle)
Value::Symbol(Interned)
Value::Keyword(Interned)
Value::Special(Interned) // Intended for symbols that are compiled.
Value::Builtin(u32)
Value::Undefined
Value::Nil
Value::Bytes(Handle)
Value::Lambda(Handle)
Value::Closure(Handle)
Value::Continuation(Handle)
Value::CallFrame(Handle)
Value::Error(Handle)

Modules§

  • As of now for casting slosh value types to a boolean with the sl_sh_fn macro, Value::* and Value::True map to bool true rust values and Value::False, Value::Nil, and Value::Undefined map to bool false.

Traits§