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