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#[derive(Debug, Clone, Copy, PartialEq)]
318pub enum TypedValue<T = DefaultTypeSet>
319where
320 T: TypeSet,
321 T::Integer: ValueType,
322 T::Float: ValueType,
323{
324 Void,
326 MaybeSignedInt(T::Integer),
328 Int(T::Integer),
330 SignedInt(T::SignedInteger),
332 Float(T::Float),
334 Bool(bool),
336 String(StringIndex),
338}
339
340impl<T> TypedValue<T>
341where
342 T: TypeSet,
343 T::Integer: ValueType,
344 T::Float: ValueType,
345{
346 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}