somni_expr/
value.rs

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