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 Type | Slosh 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. |
---|---|
String | Value::String |
S -> R | |
- SlIntoRef String for & Value | |
R -> S | |
- SlFrom & Value for String | |
& String | Value ::String |
S -> R | |
- SlIntoRef & String for & Value | |
R -> S | |
- take String | |
* uses Clone unless TODO PC ISSUE #7 the extant value problem | |
&mut String | Value ::String |
S -> R | |
- SlAsMut String for & Value | |
R -> S | |
- take &mut String | |
* uses Clone unless TODO PC ISSUE #7 the extant value problem | |
& str | Value ::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. | |
char | Value ::CodePoint |
S -> R | |
- SlIntoRef char for & Value | |
R -> S | |
- SlFrom & Value for char | |
SloshChar | Value ::CharClusterLong / Value ::CharCluster / Value ::CodePoint |
S -> R | |
- SlIntoRef SloshChar for & Value | |
R -> S | |
- SlFromRef & Value for SloshChar | |
LooseString | Value ::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 | |
bool | Value ::True / Value ::False / Value ::Nil |
S -> R | |
- SlIntoRef bool for & Value | |
R -> S | |
- SlFrom & Value for primitives | |
u8 | Value ::Byte |
S -> R | |
- SlIntoRef u8 for & Value | |
R -> S | |
- SlFrom & Value for i8 | |
u32 /i32 /u64 /i64 /usize | Value ::Int |
TODO PC current behavior overflows | Value ::Int([[u8; 7]]), // Store a 7 byte int (i56…). |
f32 /f64 | Value ::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§
- Converts a
BridgedType
to some rust type - Use mutable
SloshVm
to take a rust value and convert it to aBridgedType
. - Inverse of
SlFrom
- Inverse of
SlFromRef
- Inverse of
SlFromRefMut