slang_backend/value/
mod.rs1pub mod operations;
2
3use std::fmt;
4use std::io::Read;
5
6use crate::bytecode::Function;
7use crate::bytecode::NativeFunction;
8
9pub use operations::{ArithmeticOps, LogicalOps, ComparisonOps, ValueOperation};
11
12pub trait DeserializeFromReader: Sized {
14 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self>;
15}
16
17pub trait DisplayValue {
19 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
20}
21
22impl DeserializeFromReader for i32 {
24 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
25 let mut bytes = [0u8; 4];
26 reader.read_exact(&mut bytes)?;
27 Ok(i32::from_le_bytes(bytes))
28 }
29}
30
31impl DeserializeFromReader for i64 {
32 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
33 let mut bytes = [0u8; 8];
34 reader.read_exact(&mut bytes)?;
35 Ok(i64::from_le_bytes(bytes))
36 }
37}
38
39impl DeserializeFromReader for u32 {
40 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
41 let mut bytes = [0u8; 4];
42 reader.read_exact(&mut bytes)?;
43 Ok(u32::from_le_bytes(bytes))
44 }
45}
46
47impl DeserializeFromReader for u64 {
48 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
49 let mut bytes = [0u8; 8];
50 reader.read_exact(&mut bytes)?;
51 Ok(u64::from_le_bytes(bytes))
52 }
53}
54
55impl DeserializeFromReader for f32 {
56 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
57 let mut bytes = [0u8; 4];
58 reader.read_exact(&mut bytes)?;
59 Ok(f32::from_le_bytes(bytes))
60 }
61}
62
63impl DeserializeFromReader for f64 {
64 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
65 let mut bytes = [0u8; 8];
66 reader.read_exact(&mut bytes)?;
67 Ok(f64::from_le_bytes(bytes))
68 }
69}
70
71impl DeserializeFromReader for bool {
72 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
73 let mut byte = [0u8; 1];
74 reader.read_exact(&mut byte)?;
75 Ok(byte[0] != 0)
76 }
77}
78
79impl DeserializeFromReader for () {
80 fn deserialize(_reader: &mut dyn Read) -> std::io::Result<Self> {
81 Ok(())
82 }
83}
84
85impl DeserializeFromReader for Box<String> {
86 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
87 let mut len_bytes = [0u8; 4];
88 reader.read_exact(&mut len_bytes)?;
89 let len = u32::from_le_bytes(len_bytes) as usize;
90
91 let mut string_bytes = vec![0u8; len];
92 reader.read_exact(&mut string_bytes)?;
93 String::from_utf8(string_bytes)
94 .map(Box::new)
95 .map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid UTF-8"))
96 }
97}
98
99impl DeserializeFromReader for Box<Function> {
100 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
101 let mut name_len_bytes = [0u8; 4];
102 reader.read_exact(&mut name_len_bytes)?;
103 let name_len = u32::from_le_bytes(name_len_bytes) as usize;
104
105 let mut name_bytes = vec![0u8; name_len];
106 reader.read_exact(&mut name_bytes)?;
107 let name = String::from_utf8(name_bytes)
108 .map_err(|_| std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid UTF-8"))?;
109
110 let mut arity_bytes = [0u8; 1];
111 reader.read_exact(&mut arity_bytes)?;
112 let arity = arity_bytes[0];
113
114 let mut code_offset_bytes = [0u8; 4];
115 reader.read_exact(&mut code_offset_bytes)?;
116 let code_offset = u32::from_le_bytes(code_offset_bytes) as usize;
117
118 let mut locals_len_bytes = [0u8; 4];
119 reader.read_exact(&mut locals_len_bytes)?;
120 let locals_len = u32::from_le_bytes(locals_len_bytes) as usize;
121
122 let mut locals = Vec::new();
123 for _ in 0..locals_len {
124 let local_string = Box::<String>::deserialize(reader)?;
125 locals.push(*local_string);
126 }
127
128 Ok(Box::new(Function {
129 name,
130 arity,
131 code_offset,
132 locals,
133 }))
134 }
135}
136
137impl DeserializeFromReader for Box<NativeFunction> {
138 fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self> {
139 let name_string = Box::<String>::deserialize(reader)?;
142
143 let mut arity_bytes = [0u8; 1];
145 reader.read_exact(&mut arity_bytes)?;
146 let arity = arity_bytes[0];
147
148 let placeholder_fn: fn(&[crate::value::Value]) -> Result<crate::value::Value, String> =
152 |_args| Err("Placeholder native function".to_string());
153
154 Ok(Box::new(NativeFunction {
155 name: *name_string,
156 arity,
157 function: placeholder_fn,
158 }))
159 }
160}
161
162impl DisplayValue for i32 {
164 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165 write!(f, "{}", self)
166 }
167}
168
169impl DisplayValue for i64 {
170 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171 write!(f, "{}", self)
172 }
173}
174
175impl DisplayValue for u32 {
176 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
177 write!(f, "{}", self)
178 }
179}
180
181impl DisplayValue for u64 {
182 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183 write!(f, "{}", self)
184 }
185}
186
187impl DisplayValue for f32 {
188 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189 write!(f, "{}", self)
190 }
191}
192
193impl DisplayValue for f64 {
194 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 write!(f, "{}", self)
196 }
197}
198
199impl DisplayValue for bool {
200 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 write!(f, "{}", self)
202 }
203}
204
205impl DisplayValue for () {
206 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 write!(f, "()")
208 }
209}
210
211impl DisplayValue for Box<String> {
212 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 write!(f, "{}", self.as_ref())
214 }
215}
216
217impl DisplayValue for Box<Function> {
218 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219 write!(f, "<fn {}>", self.name)
220 }
221}
222
223impl DisplayValue for Box<NativeFunction> {
224 fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 write!(f, "<native fn {}>", self.name)
226 }
227}
228
229macro_rules! define_value_enum {
231 (
232 $(
233 $(#[doc = $doc:expr])*
234 $variant:ident($type:ty) => $tag:expr,
235 )*
236 ) => {
237 #[derive(Debug, Clone)]
239 pub enum Value {
240 $(
241 $(#[doc = $doc])*
242 $variant($type),
243 )*
244 }
245
246 impl Value {
247 pub fn type_tag(&self) -> u8 {
249 match self {
250 $(
251 Value::$variant(_) => $tag,
252 )*
253 }
254 }
255
256 pub fn deserialize_from_type_tag(type_tag: u8, reader: &mut dyn Read) -> std::io::Result<Self> {
267 match type_tag {
268 $(
269 $tag => Ok(Value::$variant(<$type>::deserialize(reader)?)),
270 )*
271 _ => Err(std::io::Error::new(
272 std::io::ErrorKind::InvalidData,
273 format!("Invalid value type tag: {}", type_tag),
274 )),
275 }
276 }
277 }
278
279 impl fmt::Display for Value {
280 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281 match self {
282 $(
283 Value::$variant(value) => value.display_value(f),
284 )*
285 }
286 }
287 }
288 };
289}
290
291define_value_enum! {
293 I32(i32) => 0,
295 I64(i64) => 1,
297 U32(u32) => 2,
299 U64(u64) => 3,
301 String(Box<String>) => 4,
303 F64(f64) => 5,
305 Function(Box<Function>) => 6,
307 NativeFunction(Box<NativeFunction>) => 7,
309 F32(f32) => 8,
311 Boolean(bool) => 9,
313 Unit(()) => 10,
315}
316
317impl Value {
318 pub fn is_numeric(&self) -> bool {
320 matches!(self, Value::I32(_) | Value::I64(_) | Value::U32(_) | Value::U64(_) | Value::F32(_) | Value::F64(_))
321 }
322
323 pub fn is_integer(&self) -> bool {
325 matches!(self, Value::I32(_) | Value::I64(_) | Value::U32(_) | Value::U64(_))
326 }
327
328 pub fn is_float(&self) -> bool {
330 matches!(self, Value::F32(_) | Value::F64(_))
331 }
332
333 pub fn is_signed_integer(&self) -> bool {
335 matches!(self, Value::I32(_) | Value::I64(_))
336 }
337
338 pub fn is_unsigned_integer(&self) -> bool {
340 matches!(self, Value::U32(_) | Value::U64(_))
341 }
342
343 pub fn is_string(&self) -> bool {
345 matches!(self, Value::String(_))
346 }
347
348 pub fn is_boolean(&self) -> bool {
350 matches!(self, Value::Boolean(_))
351 }
352}