sphinx/runtime/types/
misc.rs

1use core::any::Any;
2use crate::runtime::Variant;
3use crate::runtime::gc::{Gc, GcTrace};
4use crate::runtime::function::{Call, Callable};
5use crate::runtime::strings::{StringValue, StringSymbol, static_symbol};
6use crate::runtime::types::{Type, MetaObject};
7use crate::runtime::errors::{ExecResult, RuntimeError};
8
9
10pub struct Nil;
11
12// Nil
13impl MetaObject for Nil {
14    fn type_tag(&self) -> Type { Type::Nil }
15    
16    fn as_bool(&self) -> ExecResult<bool> { Ok(false) }
17    
18    fn cmp_eq(&self, other: &Variant) -> Option<ExecResult<bool>> {
19        match other {
20            Variant::Nil => Some(Ok(true)),
21            _ => None,
22        }
23    }
24    
25    fn fmt_repr(&self) -> ExecResult<StringValue> {
26        Ok(StringValue::from(static_symbol!("nil")))
27    }
28}
29
30
31// Marker type - kind of like scheme's symbols -- currently unused
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33pub struct Marker {
34    id: StringSymbol,
35}
36
37impl Marker {
38    pub fn new(id: StringSymbol) -> Self {
39        Self { id }
40    }
41}
42
43impl MetaObject for Marker {
44    fn type_tag(&self) -> Type { Type::Marker }
45    
46    fn cmp_eq(&self, other: &Variant) -> Option<ExecResult<bool>> {
47        match other {
48            Variant::Marker(other) => Some(Ok(self == other)),
49            _ => None,
50        }
51    }
52    
53    fn type_name(&self) -> ExecResult<StringValue> {
54        Ok(StringValue::from(self.id))
55    }
56    
57    fn fmt_repr(&self) -> ExecResult<StringValue> {
58        self.type_name()
59    }
60}
61
62
63impl<F> MetaObject for Gc<F> where F: GcTrace, Gc<F>: Callable {
64    fn type_tag(&self) -> Type { Type::Function }
65    
66    fn invoke(&self, args: &[Variant]) -> Option<ExecResult<Call>> {
67        Some(self.checked_call(args))
68    }
69    
70    fn cmp_eq(&self, other: &Variant) -> Option<ExecResult<bool>> {
71        match other {
72            Variant::Function(other) => Some(Ok(Gc::ptr_eq(self, other))),
73            Variant::NativeFunction(other) => Some(Ok(Gc::ptr_eq(self, other))),
74            _ => Some(Ok(false)),
75        }
76    }
77    
78    fn fmt_repr(&self) -> ExecResult<StringValue> {
79        // TODO cache this in the signature struct?
80        let result = format!(
81            "<{} at {:#X}>", self.signature().fmt_name(), Gc::as_id(self),
82        );
83        
84        Ok(StringValue::new_uninterned(result))
85    }
86}
87
88
89// Errors
90
91impl MetaObject for Gc<RuntimeError> {
92    fn type_tag(&self) -> Type { Type::Error }
93    
94    fn fmt_repr(&self) -> ExecResult<StringValue> {
95        Ok(self.kind().name())
96    }
97}
98
99
100/// Trait for custom data
101pub trait UserData: Any + GcTrace + MetaObject {
102    fn type_tag(&self) -> Type { Type::UserData }
103}
104