stak_native/
type_check.rs

1use stak_vm::{Error, Memory, PrimitiveSet, Type};
2use winter_maybe_async::maybe_async;
3
4/// A type check primitive.
5pub enum TypeCheckPrimitive {
6    /// A null type check.
7    Null,
8    /// A pair type check.
9    Pair,
10}
11
12impl TypeCheckPrimitive {
13    const NULL: usize = Self::Null as _;
14    const PAIR: usize = Self::Pair as _;
15}
16
17/// A type check primitive set.
18#[derive(Debug, Default)]
19pub struct TypeCheckPrimitiveSet {}
20
21impl TypeCheckPrimitiveSet {
22    /// Creates a primitive set.
23    pub fn new() -> Self {
24        Self::default()
25    }
26}
27
28impl PrimitiveSet for TypeCheckPrimitiveSet {
29    type Error = Error;
30
31    #[maybe_async]
32    fn operate(&mut self, memory: &mut Memory<'_>, primitive: usize) -> Result<(), Self::Error> {
33        match primitive {
34            TypeCheckPrimitive::NULL => memory.operate_top(|memory, value| {
35                memory.boolean(value == memory.null().into()).into()
36            })?,
37            TypeCheckPrimitive::PAIR => memory.operate_top(|memory, value| {
38                memory
39                    .boolean(
40                        value
41                            .to_cons()
42                            .map(|cons| memory.cdr(cons).tag() == Type::Pair as _)
43                            .unwrap_or_default(),
44                    )
45                    .into()
46            })?,
47            _ => return Err(Error::IllegalPrimitive),
48        }
49
50        Ok(())
51    }
52}