100 lines
2.2 KiB
Rust
100 lines
2.2 KiB
Rust
use wasmtime::*;
|
|
use crate::types;
|
|
|
|
pub fn immediate_p (store : impl AsContext, x : Rooted<EqRef>) -> 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<Immediate> {
|
|
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<EqRef>
|
|
) -> Result<Option<HeapObject>> {
|
|
if x.matches_ty (&store, &types::closure (&store)?)? {
|
|
Ok (Some (HeapObject::Procedure))
|
|
} else {
|
|
todo! ()
|
|
}
|
|
}
|
|
|
|
pub fn interpret (
|
|
store : impl AsContext,
|
|
x : Rooted<EqRef>
|
|
) -> Result<Option<Scm>> {
|
|
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<EqRef> {
|
|
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<EqRef> {
|
|
let x = if b { scm_true } else { scm_false };
|
|
let i31 = I31::new_u32 (x).unwrap ();
|
|
EqRef::from_i31 (store, i31)
|
|
}
|