use wasmtime::*; use crate::types; pub fn immediate_p (store : impl AsContext, x : Rooted) -> bool { x.is_i31 (store).unwrap () } pub enum Immediate { SmallFixnum (i32), Bool (bool), } pub enum HeapObject { Procedure } pub enum Scm { Immediate (Immediate), HeapObject (HeapObject), } #[allow(nonstandard_style)] pub type scm_bits = u32; #[allow(nonstandard_style)] pub const scm_false : scm_bits = 0b01; #[allow(nonstandard_style)] pub const scm_true : scm_bits = 0b11; pub fn interpret_immediate (x : scm_bits) -> Option { if x & 1 == 0 { Some (Immediate::SmallFixnum ((x >> 1).try_into ().unwrap ())) } else if x == scm_true { Some (Immediate::Bool (true)) } else if x == scm_false { Some (Immediate::Bool (false)) } else { None } } pub fn interpret_heap_object ( store : impl AsContext, x : Rooted ) -> Result> { if x.matches_ty (&store, &types::closure (&store)?)? { Ok (Some (HeapObject::Procedure)) } else { todo! () } } pub fn interpret ( store : impl AsContext, x : Rooted ) -> Result> { if let Some (imm) = x.as_i31 (&store)? { Ok ( interpret_immediate (imm.get_u32 ()) .map (Scm::Immediate) ) } else { Ok ( interpret_heap_object (&store, x)? .map (Scm::HeapObject) ) } } pub fn encode_immediate ( store : impl AsContext, imm : Immediate ) -> scm_bits { use Immediate::*; match imm { SmallFixnum (n) => (n << 1).try_into ().unwrap (), Bool (false) => scm_false, Bool (true) => scm_true, } } pub fn encode (store : impl AsContextMut, x : Scm) -> Rooted { match x { Scm::Immediate (imm) => { let i31 = I31::new_u32 (encode_immediate (&store, imm)) .unwrap (); EqRef::from_i31 (store, i31) } Scm::HeapObject (ho) => { todo! () } } } pub fn encode_bool (store : impl AsContextMut, b : bool) -> Rooted { let x = if b { scm_true } else { scm_false }; let i31 = I31::new_u32 (x).unwrap (); EqRef::from_i31 (store, i31) }