Skip to main content

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    /// Represents an iterator.
286    Iter(T::Iterator),
287}
288
289impl<T: TypeSet> PartialEq for TypedValue<T> {
290    fn eq(&self, other: &Self) -> bool {
291        match (self, other) {
292            (Self::MaybeSignedInt(lhs), Self::MaybeSignedInt(rhs) | Self::Int(rhs)) => lhs == rhs,
293            (Self::Int(lhs), Self::MaybeSignedInt(rhs) | Self::Int(rhs)) => lhs == rhs,
294            (Self::SignedInt(lhs), Self::SignedInt(rhs)) => lhs == rhs,
295            (Self::SignedInt(lhs), Self::MaybeSignedInt(rhs)) => {
296                T::to_signed(*rhs).map(|rhs| rhs == *lhs).unwrap_or(false)
297            }
298            (Self::MaybeSignedInt(lhs), Self::SignedInt(rhs)) => {
299                T::to_signed(*lhs).map(|lhs| lhs == *rhs).unwrap_or(false)
300            }
301            (Self::Float(lhs), Self::Float(rhs)) => lhs == rhs,
302            (Self::Bool(lhs), Self::Bool(rhs)) => lhs == rhs,
303            (Self::String(lhs), Self::String(rhs)) => lhs == rhs,
304            (Self::Iter(lhs), Self::Iter(rhs)) => lhs == rhs,
305            _ => core::mem::discriminant(self) == core::mem::discriminant(other),
306        }
307    }
308}
309
310impl<T: TypeSet> Clone for TypedValue<T> {
311    fn clone(&self) -> Self {
312        match self {
313            Self::Void => Self::Void,
314            Self::MaybeSignedInt(inner) => Self::MaybeSignedInt(*inner),
315            Self::Int(inner) => Self::Int(*inner),
316            Self::SignedInt(inner) => Self::SignedInt(*inner),
317            Self::Float(inner) => Self::Float(*inner),
318            Self::Bool(inner) => Self::Bool(*inner),
319            Self::String(inner) => Self::String(inner.clone()),
320            Self::Iter(inner) => Self::Iter(inner.clone()),
321        }
322    }
323}
324
325impl<T: TypeSet> TypedValue<T> {
326    /// Returns the Somni type of this value.
327    pub fn type_of(&self) -> Type {
328        match self {
329            TypedValue::Void => Type::Void,
330            TypedValue::Int(_) => Type::Int,
331            TypedValue::MaybeSignedInt(_) => Type::MaybeSignedInt,
332            TypedValue::SignedInt(_) => Type::SignedInt,
333            TypedValue::Float(_) => Type::Float,
334            TypedValue::Bool(_) => Type::Bool,
335            TypedValue::String(_) => Type::String,
336            TypedValue::Iter(_) => Type::Iter,
337        }
338    }
339}
340
341/// Loads an owned Rust value from a TypedValue.
342pub trait LoadOwned<T: TypeSet = DefaultTypeSet> {
343    /// The type of the result.
344    type Output;
345
346    /// Loads an owned value from the given type context.
347    fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output>;
348}
349
350/// Converts between a borrowed Rust value and a TypedValue.
351pub trait LoadStore<T: TypeSet = DefaultTypeSet> {
352    /// The type of the result.
353    type Output<'s>
354    where
355        T: 's;
356
357    /// Loads a borrowed value from the given type context.
358    fn load<'s>(_ctx: &'s T, typed: &'s TypedValue<T>) -> Option<Self::Output<'s>>;
359
360    /// Stores a Rust value into a TypedValue using the given type context.
361    fn store(&self, _ctx: &mut T) -> TypedValue<T>;
362}
363
364for_each! {
365    // Unsigned integers
366    ($type:ty) in [u32, u64, u128] => {
367        impl<T: TypeSet<Integer = Self>> LoadOwned<T> for $type {
368            type Output = Self;
369            fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output> {
370                match typed {
371                    TypedValue::MaybeSignedInt(value) => Some(*value),
372                    TypedValue::Int(value) => Some(*value),
373                    _ => None,
374                }
375            }
376        }
377        impl<T: TypeSet<Integer = Self>> LoadStore<T> for $type {
378            type Output<'s> = Self;
379            fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
380                <Self as LoadOwned<T>>::load_owned(ctx, typed)
381            }
382            fn store(&self, _ctx: &mut T) -> TypedValue<T> {
383                TypedValue::Int(*self)
384            }
385        }
386    };
387
388    // Signed integers
389    ($type:ty) in [i32, i64, i128] => {
390        impl<T: TypeSet<SignedInteger = Self>> LoadOwned<T> for $type {
391            type Output = Self;
392            fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output> {
393                match typed {
394                    TypedValue::MaybeSignedInt(value) => T::to_signed(*value).ok(),
395                    TypedValue::SignedInt(value) => Some(*value),
396                    _ => None,
397                }
398            }
399        }
400        impl<T: TypeSet<SignedInteger = Self>> LoadStore<T> for $type {
401            type Output<'s> = Self;
402            fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
403                <Self as LoadOwned<T>>::load_owned(ctx, typed)
404            }
405            fn store(&self, _ctx: &mut T) -> TypedValue<T> {
406                TypedValue::SignedInt(*self)
407            }
408        }
409    };
410
411    // Strings
412    ($type:ty) in [String, Box<str>] => {
413        impl<T: TypeSet> LoadOwned<T> for $type {
414            type Output = Self;
415            fn load_owned(ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output> {
416                <&str as LoadStore<T>>::load(ctx, typed).map(Into::into)
417            }
418        }
419        impl<T: TypeSet> LoadStore<T> for $type {
420            type Output<'s> = Self;
421            fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
422                <Self as LoadOwned<T>>::load_owned(ctx, typed)
423            }
424            fn store(&self, ctx: &mut T) -> TypedValue<T> {
425                TypedValue::String(ctx.store_string(self))
426            }
427        }
428    };
429
430    // Floats
431    ($type:ty) in [f32, f64] => {
432        impl<T: TypeSet<Float = Self>> LoadOwned<T> for $type {
433            type Output = Self;
434            fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output> {
435                match typed {
436                    TypedValue::Float(value) => Some(*value),
437                    _ => None,
438                }
439            }
440        }
441        impl<T: TypeSet<Float = Self>> LoadStore<T> for $type {
442            type Output<'s> = Self;
443            fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
444                <Self as LoadOwned<T>>::load_owned(ctx, typed)
445            }
446            fn store(&self, _ctx: &mut T) -> TypedValue<T> {
447                TypedValue::Float(*self)
448            }
449        }
450    };
451}
452
453// Somewhat special cases:
454
455impl<T: TypeSet> LoadOwned<T> for TypedValue<T> {
456    type Output = Self;
457    fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
458        Some(typed.clone())
459    }
460}
461impl<T: TypeSet> LoadStore<T> for TypedValue<T> {
462    type Output<'s> = Self;
463    fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
464        <Self as LoadOwned<T>>::load_owned(ctx, typed)
465    }
466    fn store(&self, _ctx: &mut T) -> TypedValue<T> {
467        self.clone()
468    }
469}
470
471impl<T: TypeSet> LoadOwned<T> for () {
472    type Output = Self;
473    fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
474        if let TypedValue::Void = typed {
475            Some(())
476        } else {
477            None
478        }
479    }
480}
481impl<T: TypeSet> LoadStore<T> for () {
482    type Output<'s> = Self;
483    fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
484        <Self as LoadOwned<T>>::load_owned(ctx, typed)
485    }
486    fn store(&self, _ctx: &mut T) -> TypedValue<T> {
487        TypedValue::Void
488    }
489}
490
491impl<T: TypeSet> LoadOwned<T> for bool {
492    type Output = Self;
493    fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
494        if let TypedValue::Bool(value) = typed {
495            Some(*value)
496        } else {
497            None
498        }
499    }
500}
501impl<T: TypeSet> LoadStore<T> for bool {
502    type Output<'s> = Self;
503    fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
504        <Self as LoadOwned<T>>::load_owned(ctx, typed)
505    }
506    fn store(&self, _ctx: &mut T) -> TypedValue<T> {
507        TypedValue::Bool(*self)
508    }
509}
510
511impl<T: TypeSet> LoadStore<T> for &str {
512    type Output<'s>
513        = &'s str
514    where
515        T: 's;
516
517    fn load<'s>(ctx: &'s T, typed: &'s TypedValue<T>) -> Option<Self::Output<'s>> {
518        if let TypedValue::String(index) = typed {
519            Some(ctx.load_string(index))
520        } else {
521            None
522        }
523    }
524    fn store(&self, ctx: &mut T) -> TypedValue<T> {
525        TypedValue::String(ctx.store_string(self))
526    }
527}