stak_native/
type_check.rs

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