sphinx/runtime/types/
dispatch.rs1use crate::language::{IntType, FloatType};
4use crate::runtime::Variant;
5use crate::runtime::gc::Gc;
6use crate::runtime::function::{Call, Function, NativeFunction};
7use crate::runtime::strings::StringValue;
8use crate::runtime::iter::IterState;
9use crate::runtime::types::{Type, MetaObject, Tuple, UserData, Nil, Marker, UserIterator};
10use crate::runtime::errors::{ExecResult, RuntimeError};
11
12
13struct MetaDispatch<'a>(&'a Variant);
15
16impl Variant {
17 #[inline]
18 pub fn as_meta(&self) -> impl MetaObject + '_ {
19 MetaDispatch(self)
20 }
21
22 pub fn type_tag(&self) -> Type {
23 self.as_meta().type_tag()
24 }
25
26 pub fn type_name(&self) -> ExecResult<StringValue> {
27 self.as_meta().type_name()
28 }
29}
30
31macro_rules! static_dispatch {
32 { fn $name:tt ( $( $arg:tt : $argty:ty ),* ) -> $return:ty } => {
33 fn $name (&self, $( $arg : $argty ),* ) -> $return {
34 match self.0 {
35 Variant::Nil => <Nil as MetaObject>::$name(&Nil, $( $arg ),* ),
36 Variant::BoolTrue => <bool as MetaObject>::$name(&true, $( $arg ),* ),
37 Variant::BoolFalse => <bool as MetaObject>::$name(&false, $( $arg ),* ),
38
39 Variant::Marker(marker) => <Marker as MetaObject>::$name(marker, $( $arg ),* ),
40
41 Variant::Integer(value) => <IntType as MetaObject>::$name(value, $( $arg ),* ),
42 Variant::Float(value) => <FloatType as MetaObject>::$name(value, $( $arg ),* ),
43
44 Variant::InternStr(symbol) => <StringValue as MetaObject>::$name(&(*symbol).into(), $( $arg ),* ),
45 Variant::InlineStr(inline) => <StringValue as MetaObject>::$name(&(*inline).into(), $( $arg ),* ),
46 Variant::GCStr(gc_str) => <StringValue as MetaObject>::$name(&(*gc_str).into(), $( $arg ),* ),
47
48 Variant::Tuple(tuple) => <Tuple as MetaObject>::$name(tuple, $( $arg ),* ),
49
50 Variant::Function(fun) => <Gc<Function> as MetaObject>::$name(fun, $( $arg ),* ),
51 Variant::NativeFunction(fun) => <Gc<NativeFunction> as MetaObject>::$name(fun, $( $arg ),* ),
52
53 Variant::Error(error) => <Gc<RuntimeError> as MetaObject>::$name(error, $( $arg ),* ),
54
55 Variant::Iterator(iter) => <Gc<dyn UserIterator> as MetaObject>::$name(iter, $( $arg ),* ),
56
57 Variant::UserData(data) => <(dyn UserData + 'static) as MetaObject>::$name(&**data, $( $arg ),* ),
58 }
59 }
60 };
61}
62
63impl MetaObject for MetaDispatch<'_> {
64
65 static_dispatch!{ fn type_tag() -> Type }
66 static_dispatch!{ fn type_name() -> ExecResult<StringValue> }
67
68 static_dispatch!{ fn fmt_repr() -> ExecResult<StringValue> }
69
70 static_dispatch!{ fn as_bool() -> ExecResult<bool> }
71 static_dispatch!{ fn as_bits() -> Option<ExecResult<IntType>> }
72 static_dispatch!{ fn as_int() -> Option<ExecResult<IntType>> }
73 static_dispatch!{ fn as_float() -> Option<ExecResult<FloatType>> }
74
75 static_dispatch!{ fn iter_init() -> Option<ExecResult<IterState>> }
77 static_dispatch!{ fn iter_get(state: &Variant) -> Option<ExecResult<Variant>> }
78 static_dispatch!{ fn iter_next(state: &Variant) -> Option<ExecResult<Variant>> }
79
80 static_dispatch!{ fn len() -> Option<ExecResult<usize>> }
82
83 static_dispatch!{ fn invoke(args: &[Variant]) -> Option<ExecResult<Call>> }
85
86 static_dispatch!{ fn op_neg() -> Option<ExecResult<Variant>> }
88 static_dispatch!{ fn op_pos() -> Option<ExecResult<Variant>> }
89 static_dispatch!{ fn op_inv() -> Option<ExecResult<Variant>> }
90
91 static_dispatch!{ fn op_mul(rhs: &Variant) -> Option<ExecResult<Variant>> }
93 static_dispatch!{ fn op_rmul(lhs: &Variant) -> Option<ExecResult<Variant>> }
94
95 static_dispatch!{ fn op_div(rhs: &Variant) -> Option<ExecResult<Variant>> }
96 static_dispatch!{ fn op_rdiv(lhs: &Variant) -> Option<ExecResult<Variant>> }
97
98 static_dispatch!{ fn op_mod(rhs: &Variant) -> Option<ExecResult<Variant>> }
99 static_dispatch!{ fn op_rmod(lhs: &Variant) -> Option<ExecResult<Variant>> }
100
101 static_dispatch!{ fn op_add(rhs: &Variant) -> Option<ExecResult<Variant>> }
102 static_dispatch!{ fn op_radd(lhs: &Variant) -> Option<ExecResult<Variant>> }
103
104 static_dispatch!{ fn op_sub(rhs: &Variant) -> Option<ExecResult<Variant>> }
105 static_dispatch!{ fn op_rsub(lhs: &Variant) -> Option<ExecResult<Variant>> }
106
107 static_dispatch!{ fn op_and(rhs: &Variant) -> Option<ExecResult<Variant>> }
109 static_dispatch!{ fn op_rand(lhs: &Variant) -> Option<ExecResult<Variant>> }
110
111 static_dispatch!{ fn op_xor(rhs: &Variant) -> Option<ExecResult<Variant>> }
112 static_dispatch!{ fn op_rxor(lhs: &Variant) -> Option<ExecResult<Variant>> }
113
114 static_dispatch!{ fn op_or(rhs: &Variant) -> Option<ExecResult<Variant>> }
115 static_dispatch!{ fn op_ror(lhs: &Variant) -> Option<ExecResult<Variant>> }
116
117 static_dispatch!{ fn op_shl(rhs: &Variant) -> Option<ExecResult<Variant>> }
118 static_dispatch!{ fn op_rshl(lhs: &Variant) -> Option<ExecResult<Variant>> }
119
120 static_dispatch!{ fn op_shr(rhs: &Variant) -> Option<ExecResult<Variant>> }
121 static_dispatch!{ fn op_rshr(lhs: &Variant) -> Option<ExecResult<Variant>> }
122
123 static_dispatch!{ fn cmp_eq(other: &Variant) -> Option<ExecResult<bool>> }
126 static_dispatch!{ fn cmp_lt(other: &Variant) -> Option<ExecResult<bool>> }
127 static_dispatch!{ fn cmp_le(other: &Variant) -> Option<ExecResult<bool>> }
128
129
130}