slang_backend/value/
mod.rs

1pub mod operations;
2
3use std::fmt;
4use std::io::Read;
5
6use crate::bytecode::Function;
7use crate::bytecode::NativeFunction;
8
9// Re-export the traits and combined trait for convenience
10pub use operations::{ArithmeticOps, LogicalOps, ComparisonOps, ValueOperation};
11
12/// Trait for types that can deserialize themselves from a reader
13pub trait DeserializeFromReader: Sized {
14    fn deserialize(reader: &mut dyn Read) -> std::io::Result<Self>;
15}
16
17/// Trait for types that can display themselves as values
18pub trait DisplayValue {
19    fn display_value(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
20}
21
22// Implementations for basic types
23impl 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        // For now, we'll just read the name since NativeFunction might have 
140        // more complex deserialization requirements
141        let name_string = Box::<String>::deserialize(reader)?;
142        
143        // Read arity
144        let mut arity_bytes = [0u8; 1];
145        reader.read_exact(&mut arity_bytes)?;
146        let arity = arity_bytes[0];
147        
148        // For the function pointer, we can't really deserialize it from bytes,
149        // so we'll use a placeholder function. In a real implementation, you might
150        // have a registry of native functions that you look up by name.
151        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
162// Display implementations
163impl 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
229// Macro to define the Value enum with automatic type tag management
230macro_rules! define_value_enum {
231    (
232        $(
233            $(#[doc = $doc:expr])*
234            $variant:ident($type:ty) => $tag:expr,
235        )*
236    ) => {
237        /// Values that can be stored in the bytecode and manipulated by the VM
238        #[derive(Debug, Clone)]
239        pub enum Value {
240            $(
241                $(#[doc = $doc])*
242                $variant($type),
243            )*
244        }
245
246        impl Value {
247            /// Returns a tag byte identifying this value's type
248            pub fn type_tag(&self) -> u8 {
249                match self {
250                    $(
251                        Value::$variant(_) => $tag,
252                    )*
253                }
254            }
255
256            /// Deserialize a value from a reader based on its type tag
257            ///
258            /// ### Arguments
259            ///
260            /// * `type_tag` - The type tag of the value
261            /// * `reader` - The reader to read the value data from
262            ///
263            /// ### Returns
264            ///
265            /// The deserialized value or an IO error
266            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
291// Use the macro to define the Value enum with automatic type tag management
292define_value_enum! {
293    /// 32-bit signed integer
294    I32(i32) => 0,
295    /// 64-bit signed integer
296    I64(i64) => 1,
297    /// 32-bit unsigned integer
298    U32(u32) => 2,
299    /// 64-bit unsigned integer
300    U64(u64) => 3,
301    /// String value
302    String(Box<String>) => 4,
303    /// 64-bit floating point
304    F64(f64) => 5,
305    /// Function value
306    Function(Box<Function>) => 6,
307    /// Native function value
308    NativeFunction(Box<NativeFunction>) => 7,
309    /// 32-bit floating point
310    F32(f32) => 8,
311    /// Boolean value
312    Boolean(bool) => 9,
313    /// Unit value (similar to Rust's ())
314    Unit(()) => 10,
315}
316
317impl Value {
318    /// Check if the value is numeric (integer or float)
319    pub fn is_numeric(&self) -> bool {
320        matches!(self, Value::I32(_) | Value::I64(_) | Value::U32(_) | Value::U64(_) | Value::F32(_) | Value::F64(_))
321    }
322
323    /// Check if the value is an integer type
324    pub fn is_integer(&self) -> bool {
325        matches!(self, Value::I32(_) | Value::I64(_) | Value::U32(_) | Value::U64(_))
326    }
327
328    /// Check if the value is a float type
329    pub fn is_float(&self) -> bool {
330        matches!(self, Value::F32(_) | Value::F64(_))
331    }
332
333    /// Check if the value is a signed integer
334    pub fn is_signed_integer(&self) -> bool {
335        matches!(self, Value::I32(_) | Value::I64(_))
336    }
337
338    /// Check if the value is an unsigned integer
339    pub fn is_unsigned_integer(&self) -> bool {
340        matches!(self, Value::U32(_) | Value::U64(_))
341    }
342
343    /// Check if the value is a string
344    pub fn is_string(&self) -> bool {
345        matches!(self, Value::String(_))
346    }
347
348    /// Check if the value is a boolean
349    pub fn is_boolean(&self) -> bool {
350        matches!(self, Value::Boolean(_))
351    }
352}