1use core::fmt;
2use crate::language::{IntType, FloatType};
3use crate::runtime::Variant;
4use crate::runtime::iter::IterState;
5use crate::runtime::function::Call;
6use crate::runtime::strings::{StringValue, static_symbol};
7use crate::runtime::errors::{ExecResult, RuntimeError};
8
9
10mod ops;
11mod dispatch;
12mod metatable;
13mod boolean;
14mod numeric;
15mod string;
16mod tuple;
17mod iterator;
18mod misc;
19
20pub use tuple::Tuple;
21pub use misc::{Marker, UserData};
22pub use numeric::{int_from_str, float_from_str};
23pub use iterator::UserIterator;
24
25use misc::Nil;
26
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
32pub enum Type {
33 Nil,
34 Boolean,
35 Marker,
36 Integer,
37 Float,
38 String,
39 Tuple,
40 Function,
41 Iterator,
42 Metatable,
43 Object,
44 Error,
45 UserData,
46}
47
48impl Type {
49 pub fn name(&self) -> StringValue {
50 let name = match self {
51 Self::Nil => static_symbol!("nil"),
52 Self::Boolean => static_symbol!("bool"),
53 Self::Marker => static_symbol!("marker"),
54 Self::Integer => static_symbol!("int"),
55 Self::Float => static_symbol!("float"),
56 Self::String => static_symbol!("string"),
57 Self::Tuple => static_symbol!("tuple"),
58 Self::Function => static_symbol!("function"),
59 Self::Iterator => static_symbol!("iterator"),
60 Self::Metatable => static_symbol!("metatable"),
61 Self::Object => static_symbol!("object"),
62 Self::Error => static_symbol!("error"),
63 Self::UserData => static_symbol!("userdata"),
64 };
65 name.into()
66 }
67}
68
69impl fmt::Display for Type {
70 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
71 self.name().with_str(|s| fmt.write_str(s))
72 }
73}
74
75
76#[allow(unused_variables)]
77pub trait MetaObject {
78 fn type_tag(&self) -> Type;
79
80 fn type_name(&self) -> ExecResult<StringValue> {
81 Ok(self.type_tag().name())
82 }
83
84 fn fmt_repr(&self) -> ExecResult<StringValue>;
86
87 fn as_bool(&self) -> ExecResult<bool> { Ok(true) }
89 fn as_bits(&self) -> Option<ExecResult<IntType>> { self.as_int() }
90 fn as_int(&self) -> Option<ExecResult<IntType>> { None }
91 fn as_float(&self) -> Option<ExecResult<FloatType>> { None }
92
93 fn iter_init(&self) -> Option<ExecResult<IterState>> { None }
97 fn iter_next(&self, state: &Variant) -> Option<ExecResult<Variant>> { None }
98 fn iter_get(&self, state: &Variant) -> Option<ExecResult<Variant>> { None }
99
100 fn len(&self) -> Option<ExecResult<usize>> { None }
102 fn invoke(&self, args: &[Variant]) -> Option<ExecResult<Call>> { None }
107
108 fn op_neg(&self) -> Option<ExecResult<Variant>> { None }
110 fn op_pos(&self) -> Option<ExecResult<Variant>> { None }
111 fn op_inv(&self) -> Option<ExecResult<Variant>> { None }
112
113 fn op_mul(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
115 fn op_rmul(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
116
117 fn op_div(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
118 fn op_rdiv(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
119
120 fn op_mod(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
121 fn op_rmod(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
122
123 fn op_add(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
124 fn op_radd(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
125
126 fn op_sub(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
127 fn op_rsub(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
128
129 fn op_and(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
131 fn op_rand(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
132
133 fn op_xor(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
134 fn op_rxor(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
135
136 fn op_or(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
137 fn op_ror(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
138
139 fn op_shl(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
140 fn op_rshl(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
141
142 fn op_shr(&self, rhs: &Variant) -> Option<ExecResult<Variant>> { None }
143 fn op_rshr(&self, lhs: &Variant) -> Option<ExecResult<Variant>> { None }
144
145 fn cmp_eq(&self, other: &Variant) -> Option<ExecResult<bool>> { None }
148 fn cmp_lt(&self, other: &Variant) -> Option<ExecResult<bool>> { None }
149 fn cmp_le(&self, other: &Variant) -> Option<ExecResult<bool>> { None }
150}
151
152
153impl Variant {
154 pub fn as_bool(&self) -> ExecResult<bool> {
155 self.as_meta().as_bool()
156 }
157
158 pub fn as_bits(&self) -> ExecResult<IntType> {
159 self.as_meta().as_bits()
160 .ok_or_else(|| RuntimeError::metamethod_not_supported(self, MethodTag::AsBits))?
161 }
162
163 pub fn as_int(&self) -> ExecResult<IntType> {
164 self.as_meta().as_int()
165 .ok_or_else(|| RuntimeError::metamethod_not_supported(self, MethodTag::AsInt))?
166 }
167
168 pub fn as_float(&self) -> ExecResult<FloatType> {
169 self.as_meta().as_float()
170 .ok_or_else(|| RuntimeError::metamethod_not_supported(self, MethodTag::AsFloat))?
171 }
172}
173
174impl Variant {
175 pub fn len(&self) -> ExecResult<usize> {
176 self.as_meta().len()
177 .ok_or_else(|| RuntimeError::metamethod_not_supported(self, MethodTag::Len))?
178 }
179
180 pub fn is_empty(&self) -> ExecResult<bool> {
181 Ok(self.len()? == 0)
182 }
183
184 pub fn iter_init(&self) -> ExecResult<IterState> {
185 self.as_meta().iter_init()
186 .ok_or_else(|| RuntimeError::metamethod_not_supported(self, MethodTag::IterInit))?
187 }
188
189 pub fn iter_next(&self, state: &Variant) -> ExecResult<Variant> {
190 self.as_meta().iter_next(state)
191 .ok_or_else(|| RuntimeError::metamethod_not_supported(self, MethodTag::IterNext))?
192 }
193
194 pub fn iter_get(&self, state: &Variant) -> ExecResult<Variant> {
195 self.as_meta().iter_get(state)
196 .ok_or_else(|| RuntimeError::metamethod_not_supported(self, MethodTag::IterItem))?
197 }
198
199 pub fn invoke(&self, args: &[Variant]) -> ExecResult<Call> {
200 self.as_meta().invoke(args)
201 .ok_or_else(|| RuntimeError::metamethod_not_supported(self, MethodTag::Invoke))?
202 }
203
204 pub fn fmt_repr(&self) -> ExecResult<StringValue> {
205 self.as_meta().fmt_repr()
206 }
207}
208
209#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
211pub enum MethodTag {
212 Invoke,
213 Len,
214 IterInit,
215 IterNext,
216 IterItem,
217 AsBool,
218 AsBits,
219 AsInt,
220 AsFloat,
221 FmtRepr,
222}
223
224impl MethodTag {
225 pub fn method_name(&self) -> &'static str {
226 match self {
227 Self::Invoke => "call",
228
229 Self::IterInit => "iter_init",
231 Self::IterNext => "iter_next",
232 Self::IterItem => "iter_get",
233
234 Self::Len => "len",
236
237 Self::AsBool => "bool",
239 Self::AsBits => "bits",
240 Self::AsInt => "int",
241 Self::AsFloat => "float",
242
243 Self::FmtRepr => "repr",
245 }
246 }
247}
248
249impl fmt::Display for MethodTag {
250 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
251 fmt.write_str(self.method_name())
252 }
253}