somni_expr/
value.rs

1use somni_parser::parser::DefaultTypeSet;
2
3use crate::{string_interner::StringIndex, ExprContext, OperatorError, Type, TypeSet};
4
5#[doc(hidden)]
6pub trait MemoryRepr: Sized + Copy + PartialEq {
7    const BYTES: usize;
8
9    fn write(&self, to: &mut [u8]);
10    fn from_bytes(bytes: &[u8]) -> Self;
11}
12
13#[doc(hidden)]
14pub trait ValueType: Sized + Clone + PartialEq + std::fmt::Debug {
15    const TYPE: Type;
16
17    type NegateOutput: ValueType;
18
19    fn equals(_a: Self, _b: Self) -> Result<bool, OperatorError> {
20        unimplemented!("Operation not supported")
21    }
22    fn less_than(_a: Self, _b: Self) -> Result<bool, OperatorError> {
23        unimplemented!("Operation not supported")
24    }
25
26    fn less_than_or_equal(a: Self, b: Self) -> Result<bool, OperatorError> {
27        let less = Self::less_than(a.clone(), b.clone())?;
28        Ok(less || Self::equals(a, b)?)
29    }
30    fn not_equals(a: Self, b: Self) -> Result<bool, OperatorError> {
31        let equals = Self::equals(a, b)?;
32        Ok(!equals)
33    }
34    fn bitwise_or(_a: Self, _b: Self) -> Result<Self, OperatorError> {
35        unimplemented!("Operation not supported")
36    }
37    fn bitwise_xor(_a: Self, _b: Self) -> Result<Self, OperatorError> {
38        unimplemented!("Operation not supported")
39    }
40    fn bitwise_and(_a: Self, _b: Self) -> Result<Self, OperatorError> {
41        unimplemented!("Operation not supported")
42    }
43    fn shift_left(_a: Self, _b: Self) -> Result<Self, OperatorError> {
44        unimplemented!("Operation not supported")
45    }
46    fn shift_right(_a: Self, _b: Self) -> Result<Self, OperatorError> {
47        unimplemented!("Operation not supported")
48    }
49    fn add(_a: Self, _b: Self) -> Result<Self, OperatorError> {
50        unimplemented!("Operation not supported")
51    }
52    fn subtract(_a: Self, _b: Self) -> Result<Self, OperatorError> {
53        unimplemented!("Operation not supported")
54    }
55    fn multiply(_a: Self, _b: Self) -> Result<Self, OperatorError> {
56        unimplemented!("Operation not supported")
57    }
58    fn divide(_a: Self, _b: Self) -> Result<Self, OperatorError> {
59        unimplemented!("Operation not supported")
60    }
61    fn not(_a: Self) -> Result<Self, OperatorError> {
62        unimplemented!("Operation not supported")
63    }
64    fn negate(_a: Self) -> Result<Self::NegateOutput, OperatorError> {
65        unimplemented!("Operation not supported")
66    }
67}
68
69impl MemoryRepr for () {
70    const BYTES: usize = 0;
71
72    fn write(&self, _to: &mut [u8]) {}
73
74    fn from_bytes(_: &[u8]) -> Self {}
75}
76
77impl ValueType for () {
78    type NegateOutput = Self;
79    const TYPE: Type = Type::Void;
80}
81
82macro_rules! value_type_int {
83    ($type:ty, $negate:ty, $kind:ident) => {
84        impl MemoryRepr for $type {
85            const BYTES: usize = std::mem::size_of::<$type>();
86
87            fn write(&self, to: &mut [u8]) {
88                to.copy_from_slice(&self.to_le_bytes());
89            }
90
91            fn from_bytes(bytes: &[u8]) -> Self {
92                <$type>::from_le_bytes(bytes.try_into().unwrap())
93            }
94        }
95
96        impl ValueType for $type {
97            const TYPE: Type = Type::$kind;
98            type NegateOutput = $negate;
99
100            fn less_than(a: Self, b: Self) -> Result<bool, OperatorError> {
101                Ok(a < b)
102            }
103            fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
104                Ok(a == b)
105            }
106            fn add(a: Self, b: Self) -> Result<Self, OperatorError> {
107                a.checked_add(b).ok_or(OperatorError::RuntimeError)
108            }
109            fn subtract(a: Self, b: Self) -> Result<Self, OperatorError> {
110                a.checked_sub(b).ok_or(OperatorError::RuntimeError)
111            }
112            fn multiply(a: Self, b: Self) -> Result<Self, OperatorError> {
113                a.checked_mul(b).ok_or(OperatorError::RuntimeError)
114            }
115            fn divide(a: Self, b: Self) -> Result<Self, OperatorError> {
116                if b == 0 {
117                    Err(OperatorError::RuntimeError)
118                } else {
119                    Ok(a / b)
120                }
121            }
122            fn bitwise_or(a: Self, b: Self) -> Result<Self, OperatorError> {
123                Ok(a | b)
124            }
125            fn bitwise_xor(a: Self, b: Self) -> Result<Self, OperatorError> {
126                Ok(a ^ b)
127            }
128            fn bitwise_and(a: Self, b: Self) -> Result<Self, OperatorError> {
129                Ok(a & b)
130            }
131            fn shift_left(a: Self, b: Self) -> Result<Self, OperatorError> {
132                if b < std::mem::size_of::<$type>() as Self * 8 {
133                    Ok(a << b)
134                } else {
135                    Err(OperatorError::RuntimeError)
136                }
137            }
138            fn shift_right(a: Self, b: Self) -> Result<Self, OperatorError> {
139                if b < std::mem::size_of::<$type>() as Self * 8 {
140                    Ok(a >> b)
141                } else {
142                    Err(OperatorError::RuntimeError)
143                }
144            }
145            fn not(a: Self) -> Result<Self, OperatorError> {
146                Ok(!a)
147            }
148            fn negate(a: Self) -> Result<Self::NegateOutput, OperatorError> {
149                Ok(-(a as $negate))
150            }
151        }
152    };
153}
154
155value_type_int!(u32, i32, Int);
156value_type_int!(u64, i64, Int);
157value_type_int!(u128, i128, Int);
158value_type_int!(i32, i32, SignedInt);
159value_type_int!(i64, i64, SignedInt);
160value_type_int!(i128, i128, SignedInt);
161
162impl MemoryRepr for f32 {
163    const BYTES: usize = 4;
164
165    fn write(&self, to: &mut [u8]) {
166        to.copy_from_slice(&self.to_le_bytes());
167    }
168
169    fn from_bytes(bytes: &[u8]) -> Self {
170        f32::from_le_bytes(bytes.try_into().unwrap())
171    }
172}
173impl ValueType for f32 {
174    const TYPE: Type = Type::Float;
175
176    type NegateOutput = Self;
177
178    fn less_than(a: Self, b: Self) -> Result<bool, OperatorError> {
179        Ok(a < b)
180    }
181    fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
182        Ok(a == b)
183    }
184    fn add(a: Self, b: Self) -> Result<Self, OperatorError> {
185        Ok(a + b)
186    }
187    fn subtract(a: Self, b: Self) -> Result<Self, OperatorError> {
188        Ok(a - b)
189    }
190    fn multiply(a: Self, b: Self) -> Result<Self, OperatorError> {
191        Ok(a * b)
192    }
193    fn divide(a: Self, b: Self) -> Result<Self, OperatorError> {
194        Ok(a / b)
195    }
196    fn negate(a: Self) -> Result<Self::NegateOutput, OperatorError> {
197        Ok(-a)
198    }
199}
200
201impl MemoryRepr for f64 {
202    const BYTES: usize = 8;
203
204    fn write(&self, to: &mut [u8]) {
205        to.copy_from_slice(&self.to_le_bytes());
206    }
207
208    fn from_bytes(bytes: &[u8]) -> Self {
209        f64::from_le_bytes(bytes.try_into().unwrap())
210    }
211}
212impl ValueType for f64 {
213    const TYPE: Type = Type::Float;
214
215    type NegateOutput = Self;
216
217    fn less_than(a: Self, b: Self) -> Result<bool, OperatorError> {
218        Ok(a < b)
219    }
220    fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
221        Ok(a == b)
222    }
223    fn add(a: Self, b: Self) -> Result<Self, OperatorError> {
224        Ok(a + b)
225    }
226    fn subtract(a: Self, b: Self) -> Result<Self, OperatorError> {
227        Ok(a - b)
228    }
229    fn multiply(a: Self, b: Self) -> Result<Self, OperatorError> {
230        Ok(a * b)
231    }
232    fn divide(a: Self, b: Self) -> Result<Self, OperatorError> {
233        Ok(a / b)
234    }
235    fn negate(a: Self) -> Result<Self::NegateOutput, OperatorError> {
236        Ok(-a)
237    }
238}
239
240impl MemoryRepr for bool {
241    const BYTES: usize = 1;
242
243    fn write(&self, to: &mut [u8]) {
244        to.copy_from_slice(&[*self as u8]);
245    }
246
247    fn from_bytes(bytes: &[u8]) -> Self {
248        bytes[0] != 0
249    }
250}
251
252impl ValueType for bool {
253    const TYPE: Type = Type::Bool;
254
255    type NegateOutput = Self;
256
257    fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
258        Ok(a == b)
259    }
260
261    fn bitwise_and(a: Self, b: Self) -> Result<bool, OperatorError> {
262        Ok(a & b)
263    }
264
265    fn bitwise_or(a: Self, b: Self) -> Result<bool, OperatorError> {
266        Ok(a | b)
267    }
268
269    fn bitwise_xor(a: Self, b: Self) -> Result<bool, OperatorError> {
270        Ok(a ^ b)
271    }
272
273    fn not(a: Self) -> Result<bool, OperatorError> {
274        Ok(!a)
275    }
276}
277
278impl MemoryRepr for StringIndex {
279    const BYTES: usize = 8;
280
281    fn write(&self, to: &mut [u8]) {
282        to.copy_from_slice(&self.0.to_le_bytes());
283    }
284    fn from_bytes(bytes: &[u8]) -> Self {
285        StringIndex(u64::from_le_bytes(bytes.try_into().unwrap()) as usize)
286    }
287}
288impl ValueType for StringIndex {
289    const TYPE: Type = Type::String;
290
291    type NegateOutput = Self;
292
293    fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
294        Ok(a == b)
295    }
296}
297impl ValueType for &str {
298    const TYPE: Type = Type::String;
299
300    type NegateOutput = Self;
301
302    fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
303        Ok(a == b)
304    }
305}
306impl ValueType for String {
307    const TYPE: Type = Type::String;
308
309    type NegateOutput = Self;
310
311    fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
312        Ok(a == b)
313    }
314}
315
316/// Represents any value in the expression language.
317#[derive(Debug, Clone, Copy, PartialEq)]
318pub enum TypedValue<T = DefaultTypeSet>
319where
320    T: TypeSet,
321    T::Integer: ValueType,
322    T::Float: ValueType,
323{
324    /// Represents no value.
325    Void,
326    /// Represents an integer that may be signed or unsigned.
327    MaybeSignedInt(T::Integer),
328    /// Represents an unsigned integer.
329    Int(T::Integer),
330    /// Represents a signed integer.
331    SignedInt(T::SignedInteger),
332    /// Represents a floating-point.
333    Float(T::Float),
334    /// Represents a boolean.
335    Bool(bool),
336    /// Represents an interned string.
337    String(StringIndex),
338}
339
340impl<T> TypedValue<T>
341where
342    T: TypeSet,
343    T::Integer: ValueType,
344    T::Float: ValueType,
345{
346    /// Returns the Somni type of this value.
347    pub fn type_of(&self) -> Type {
348        match self {
349            TypedValue::Void => Type::Void,
350            TypedValue::Int(_) => Type::Int,
351            TypedValue::MaybeSignedInt(_) => Type::MaybeSignedInt,
352            TypedValue::SignedInt(_) => Type::SignedInt,
353            TypedValue::Float(_) => Type::Float,
354            TypedValue::Bool(_) => Type::Bool,
355            TypedValue::String(_) => Type::String,
356        }
357    }
358}
359
360pub trait Load<T = DefaultTypeSet>: ValueType
361where
362    T: TypeSet,
363    T::Integer: ValueType,
364    T::Float: ValueType,
365{
366    type Output<'s>
367    where
368        T: 's;
369
370    fn load(_ctx: &dyn ExprContext<T>, typed: TypedValue<T>) -> Option<Self::Output<'_>>;
371}
372
373pub trait Store<T = DefaultTypeSet>: ValueType
374where
375    T: TypeSet,
376    T::Integer: ValueType,
377    T::Float: ValueType,
378{
379    fn store(self, _ctx: &mut dyn ExprContext<T>) -> TypedValue<T>;
380}
381
382macro_rules! load {
383    ($type:ty, [$($kind:ident),+] $(, $ts_kind:ident)?) => {
384        impl<T> Load<T> for $type
385        where
386            T: TypeSet$(<$ts_kind = $type>)?,
387            T::Integer: ValueType,
388            T::Float: ValueType,
389        {
390            type Output<'s> = Self where T: 's;
391            fn load(_ctx: &dyn ExprContext<T>, typed: TypedValue<T>) -> Option<Self> {
392                $(
393                    if let TypedValue::$kind(value) = typed {
394                        return Some(value);
395                    }
396                )+
397
398                None
399            }
400        }
401    };
402}
403macro_rules! load_signed {
404    ($type:ty, $kind:ident $(, $ts_kind:ident)?) => {
405        impl<T> Load<T> for $type
406        where
407            T: TypeSet$(<$ts_kind = $type>)?,
408            T::Integer: ValueType,
409            T::Float: ValueType,
410        {
411            type Output<'s> = Self where T: 's;
412            fn load(_ctx: &dyn ExprContext<T>, typed: TypedValue<T>) -> Option<Self> {
413                if let TypedValue::SignedInt(value) = typed {
414                    Some(value)
415                } else if let TypedValue::MaybeSignedInt(value) = typed {
416                    T::to_signed(value).ok()
417                } else {
418                    None
419                }
420            }
421        }
422    };
423}
424macro_rules! store {
425    ($type:ty, $kind:ident $(, $ts_kind:ident)?) => {
426        impl<T> Store<T> for $type
427        where
428            T: TypeSet$(<$ts_kind = $type>)?,
429            T::Integer: ValueType,
430            T::Float: ValueType,
431        {
432            fn store(self, _ctx: &mut dyn ExprContext<T>) -> TypedValue<T> {
433                TypedValue::$kind(self)
434            }
435        }
436    };
437}
438
439load!(u32, [Int, MaybeSignedInt], Integer);
440load!(u64, [Int, MaybeSignedInt], Integer);
441load!(u128, [Int, MaybeSignedInt], Integer);
442load!(f32, [Float], Float);
443load!(f64, [Float], Float);
444load!(bool, [Bool]);
445load!(StringIndex, [String]);
446
447load_signed!(i32, SignedInt, SignedInteger);
448load_signed!(i64, SignedInt, SignedInteger);
449load_signed!(i128, SignedInt, SignedInteger);
450
451store!(u32, Int, Integer);
452store!(u64, Int, Integer);
453store!(u128, Int, Integer);
454store!(i32, SignedInt, SignedInteger);
455store!(i64, SignedInt, SignedInteger);
456store!(i128, SignedInt, SignedInteger);
457store!(f32, Float, Float);
458store!(f64, Float, Float);
459store!(bool, Bool);
460store!(StringIndex, String);
461
462impl<T> Load<T> for ()
463where
464    T: TypeSet,
465    T::Integer: ValueType,
466    T::Float: ValueType,
467{
468    type Output<'s>
469        = Self
470    where
471        T: 's;
472    fn load(_ctx: &dyn ExprContext<T>, typed: TypedValue<T>) -> Option<Self> {
473        if let TypedValue::Void = typed {
474            Some(())
475        } else {
476            None
477        }
478    }
479}
480impl<T> Store<T> for ()
481where
482    T: TypeSet,
483    T::Integer: ValueType,
484    T::Float: ValueType,
485{
486    fn store(self, _ctx: &mut dyn ExprContext<T>) -> TypedValue<T> {
487        TypedValue::Void
488    }
489}
490
491impl<T> Store<T> for &str
492where
493    T: TypeSet,
494    T::Integer: ValueType,
495    T::Float: ValueType,
496{
497    fn store(self, ctx: &mut dyn ExprContext<T>) -> TypedValue<T> {
498        let idx = ctx.intern_string(self);
499        TypedValue::String(idx)
500    }
501}
502
503impl<T> Store<T> for String
504where
505    T: TypeSet,
506    T::Integer: ValueType,
507    T::Float: ValueType,
508{
509    fn store(self, ctx: &mut dyn ExprContext<T>) -> TypedValue<T> {
510        let idx = ctx.intern_string(&self);
511        TypedValue::String(idx)
512    }
513}
514
515impl<T> Load<T> for &str
516where
517    T: TypeSet,
518    T::Integer: ValueType,
519    T::Float: ValueType,
520{
521    type Output<'s>
522        = &'s str
523    where
524        T: 's;
525
526    fn load(ctx: &dyn ExprContext<T>, typed: TypedValue<T>) -> Option<Self::Output<'_>> {
527        if let TypedValue::String(index) = typed {
528            Some(ctx.load_interned_string(index))
529        } else {
530            None
531        }
532    }
533}