1use indexmap::IndexMap;
4use somni_parser::parser::DefaultTypeSet;
5use std::rc::Rc;
6
7use crate::{OperatorError, RefPointee, Type, TypeSet};
8
9pub trait ValueType: Sized + Clone + PartialEq + std::fmt::Debug {
11 const TYPE: Type;
13
14 type NegateOutput: ValueType;
16
17 fn equals(_a: Self, _b: Self) -> Result<bool, OperatorError> {
19 unimplemented!("Operation not supported")
20 }
21 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> {
28 let less = Self::less_than(a.clone(), b.clone())?;
29 Ok(less || Self::equals(a, b)?)
30 }
31
32 fn not_equals(a: Self, b: Self) -> Result<bool, OperatorError> {
34 let equals = Self::equals(a, b)?;
35 Ok(!equals)
36 }
37 fn bitwise_or(_a: Self, _b: Self) -> Result<Self, OperatorError> {
39 unimplemented!("Operation not supported")
40 }
41 fn bitwise_xor(_a: Self, _b: Self) -> Result<Self, OperatorError> {
43 unimplemented!("Operation not supported")
44 }
45 fn bitwise_and(_a: Self, _b: Self) -> Result<Self, OperatorError> {
47 unimplemented!("Operation not supported")
48 }
49 fn shift_left(_a: Self, _b: Self) -> Result<Self, OperatorError> {
51 unimplemented!("Operation not supported")
52 }
53 fn shift_right(_a: Self, _b: Self) -> Result<Self, OperatorError> {
55 unimplemented!("Operation not supported")
56 }
57 fn add(_a: Self, _b: Self) -> Result<Self, OperatorError> {
59 unimplemented!("Operation not supported")
60 }
61 fn subtract(_a: Self, _b: Self) -> Result<Self, OperatorError> {
63 unimplemented!("Operation not supported")
64 }
65 fn multiply(_a: Self, _b: Self) -> Result<Self, OperatorError> {
67 unimplemented!("Operation not supported")
68 }
69 fn divide(_a: Self, _b: Self) -> Result<Self, OperatorError> {
71 unimplemented!("Operation not supported")
72 }
73 fn modulo(_a: Self, _b: Self) -> Result<Self, OperatorError> {
75 unimplemented!("Operation not supported")
76 }
77 fn not(_a: Self) -> Result<Self, OperatorError> {
79 unimplemented!("Operation not supported")
80 }
81 fn negate(_a: Self) -> Result<Self::NegateOutput, OperatorError> {
83 unimplemented!("Operation not supported")
84 }
85}
86
87impl ValueType for () {
88 type NegateOutput = Self;
89 const TYPE: Type = Type::Void;
90}
91
92macro_rules! value_type_int {
93 ($type:ty, $negate:ty, $kind:ident) => {
94 impl ValueType for $type {
95 const TYPE: Type = Type::$kind;
96 type NegateOutput = $negate;
97
98 fn less_than(a: Self, b: Self) -> Result<bool, OperatorError> {
99 Ok(a < b)
100 }
101 fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
102 Ok(a == b)
103 }
104 fn add(a: Self, b: Self) -> Result<Self, OperatorError> {
105 a.checked_add(b).ok_or(OperatorError::RuntimeError)
106 }
107 fn subtract(a: Self, b: Self) -> Result<Self, OperatorError> {
108 a.checked_sub(b).ok_or(OperatorError::RuntimeError)
109 }
110 fn multiply(a: Self, b: Self) -> Result<Self, OperatorError> {
111 a.checked_mul(b).ok_or(OperatorError::RuntimeError)
112 }
113 fn divide(a: Self, b: Self) -> Result<Self, OperatorError> {
114 if b == 0 {
115 Err(OperatorError::RuntimeError)
116 } else {
117 Ok(a / b)
118 }
119 }
120 fn modulo(a: Self, b: Self) -> Result<Self, OperatorError> {
121 if b == 0 {
122 Err(OperatorError::RuntimeError)
123 } else {
124 Ok(a % b)
125 }
126 }
127 fn bitwise_or(a: Self, b: Self) -> Result<Self, OperatorError> {
128 Ok(a | b)
129 }
130 fn bitwise_xor(a: Self, b: Self) -> Result<Self, OperatorError> {
131 Ok(a ^ b)
132 }
133 fn bitwise_and(a: Self, b: Self) -> Result<Self, OperatorError> {
134 Ok(a & b)
135 }
136 fn shift_left(a: Self, b: Self) -> Result<Self, OperatorError> {
137 if b < std::mem::size_of::<$type>() as Self * 8 {
138 Ok(a << b)
139 } else {
140 Err(OperatorError::RuntimeError)
141 }
142 }
143 fn shift_right(a: Self, b: Self) -> Result<Self, OperatorError> {
144 if b < std::mem::size_of::<$type>() as Self * 8 {
145 Ok(a >> b)
146 } else {
147 Err(OperatorError::RuntimeError)
148 }
149 }
150 fn not(a: Self) -> Result<Self, OperatorError> {
151 Ok(!a)
152 }
153 fn negate(a: Self) -> Result<Self::NegateOutput, OperatorError> {
154 Ok(-(a as $negate))
155 }
156 }
157 };
158}
159
160value_type_int!(u32, i32, Int);
161value_type_int!(u64, i64, Int);
162value_type_int!(u128, i128, Int);
163value_type_int!(i32, i32, SignedInt);
164value_type_int!(i64, i64, SignedInt);
165value_type_int!(i128, i128, SignedInt);
166
167impl ValueType for f32 {
168 const TYPE: Type = Type::Float;
169
170 type NegateOutput = Self;
171
172 fn less_than(a: Self, b: Self) -> Result<bool, OperatorError> {
173 Ok(a < b)
174 }
175 fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
176 Ok(a == b)
177 }
178 fn add(a: Self, b: Self) -> Result<Self, OperatorError> {
179 Ok(a + b)
180 }
181 fn subtract(a: Self, b: Self) -> Result<Self, OperatorError> {
182 Ok(a - b)
183 }
184 fn multiply(a: Self, b: Self) -> Result<Self, OperatorError> {
185 Ok(a * b)
186 }
187 fn divide(a: Self, b: Self) -> Result<Self, OperatorError> {
188 Ok(a / b)
189 }
190 fn modulo(a: Self, b: Self) -> Result<Self, OperatorError> {
191 Ok(a % b)
192 }
193 fn negate(a: Self) -> Result<Self::NegateOutput, OperatorError> {
194 Ok(-a)
195 }
196}
197
198impl ValueType for f64 {
199 const TYPE: Type = Type::Float;
200
201 type NegateOutput = Self;
202
203 fn less_than(a: Self, b: Self) -> Result<bool, OperatorError> {
204 Ok(a < b)
205 }
206 fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
207 Ok(a == b)
208 }
209 fn add(a: Self, b: Self) -> Result<Self, OperatorError> {
210 Ok(a + b)
211 }
212 fn subtract(a: Self, b: Self) -> Result<Self, OperatorError> {
213 Ok(a - b)
214 }
215 fn multiply(a: Self, b: Self) -> Result<Self, OperatorError> {
216 Ok(a * b)
217 }
218 fn divide(a: Self, b: Self) -> Result<Self, OperatorError> {
219 Ok(a / b)
220 }
221 fn modulo(a: Self, b: Self) -> Result<Self, OperatorError> {
222 Ok(a % b)
223 }
224 fn negate(a: Self) -> Result<Self::NegateOutput, OperatorError> {
225 Ok(-a)
226 }
227}
228
229impl ValueType for bool {
230 const TYPE: Type = Type::Bool;
231
232 type NegateOutput = Self;
233
234 fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
235 Ok(a == b)
236 }
237
238 fn bitwise_and(a: Self, b: Self) -> Result<bool, OperatorError> {
239 Ok(a & b)
240 }
241
242 fn bitwise_or(a: Self, b: Self) -> Result<bool, OperatorError> {
243 Ok(a | b)
244 }
245
246 fn bitwise_xor(a: Self, b: Self) -> Result<bool, OperatorError> {
247 Ok(a ^ b)
248 }
249
250 fn not(a: Self) -> Result<bool, OperatorError> {
251 Ok(!a)
252 }
253}
254
255for_each! {
256 ($string:ty) in [&str, String, Box<str>] => {
257 impl ValueType for $string {
258 const TYPE: Type = Type::String;
259 type NegateOutput = Self;
260
261 fn equals(a: Self, b: Self) -> Result<bool, OperatorError> {
262 Ok(a == b)
263 }
264 }
265 };
266}
267
268#[derive(Debug)]
270pub enum TypedValue<T: TypeSet = DefaultTypeSet> {
271 Void,
273 MaybeSignedInt(T::Integer),
277 Int(T::Integer),
279 SignedInt(T::SignedInteger),
281 Float(T::Float),
283 Bool(bool),
285 String(T::String),
287 Iter(T::Iterator),
289 Struct(SomniStruct<T>),
291 Ref(Reference),
293}
294
295pub struct SomniStruct<T: TypeSet = DefaultTypeSet> {
308 inner: Rc<SomniStructInner<T>>,
309}
310
311struct SomniStructInner<T: TypeSet> {
313 name: Box<str>,
314 fields: IndexMap<Box<str>, TypedValue<T>>,
315}
316
317impl<T: TypeSet> Clone for SomniStructInner<T> {
318 fn clone(&self) -> Self {
319 Self {
320 name: self.name.clone(),
321 fields: self.fields.clone(),
322 }
323 }
324}
325
326impl<T: TypeSet> SomniStruct<T> {
327 pub fn new(name: Box<str>, fields: IndexMap<Box<str>, TypedValue<T>>) -> Self {
329 Self {
330 inner: Rc::new(SomniStructInner { name, fields }),
331 }
332 }
333
334 pub fn name(&self) -> &str {
336 &self.inner.name
337 }
338
339 pub fn fields(&self) -> &IndexMap<Box<str>, TypedValue<T>> {
341 &self.inner.fields
342 }
343
344 pub fn fields_mut(&mut self) -> &mut IndexMap<Box<str>, TypedValue<T>> {
346 &mut Rc::make_mut(&mut self.inner).fields
347 }
348
349 pub fn into_parts(self) -> (Box<str>, IndexMap<Box<str>, TypedValue<T>>) {
351 let inner = Rc::try_unwrap(self.inner).unwrap_or_else(|shared| (*shared).clone());
352 (inner.name, inner.fields)
353 }
354}
355
356impl<T: TypeSet> Clone for SomniStruct<T> {
357 fn clone(&self) -> Self {
358 Self {
359 inner: Rc::clone(&self.inner),
360 }
361 }
362}
363
364impl<T: TypeSet> std::fmt::Debug for SomniStruct<T> {
365 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
366 f.debug_struct("SomniStruct")
367 .field("name", &self.inner.name)
368 .field("fields", &self.inner.fields)
369 .finish()
370 }
371}
372
373impl<T: TypeSet> PartialEq for SomniStruct<T> {
374 fn eq(&self, other: &Self) -> bool {
375 Rc::ptr_eq(&self.inner, &other.inner)
378 || (self.inner.name == other.inner.name && self.inner.fields == other.inner.fields)
379 }
380}
381
382#[derive(Clone, Debug, PartialEq, Eq)]
391pub struct Place {
392 pub root: usize,
394 pub path: Box<[Box<str>]>,
396}
397
398#[derive(Clone, Debug, PartialEq, Eq)]
405pub struct Reference {
406 inner: Box<ReferenceInner>,
407}
408
409#[derive(Clone, Debug, PartialEq, Eq)]
411struct ReferenceInner {
412 pointee: RefPointee,
413 place: Place,
414}
415
416impl Reference {
417 pub fn new(pointee: RefPointee, place: Place) -> Self {
419 Self {
420 inner: Box::new(ReferenceInner { pointee, place }),
421 }
422 }
423
424 pub fn pointee(&self) -> RefPointee {
426 self.inner.pointee
427 }
428
429 pub fn place(&self) -> &Place {
431 &self.inner.place
432 }
433
434 pub fn into_place(self) -> Place {
436 self.inner.place
437 }
438}
439
440impl<T: TypeSet> PartialEq for TypedValue<T> {
441 fn eq(&self, other: &Self) -> bool {
442 match (self, other) {
443 (Self::MaybeSignedInt(lhs), Self::MaybeSignedInt(rhs) | Self::Int(rhs)) => lhs == rhs,
444 (Self::Int(lhs), Self::MaybeSignedInt(rhs) | Self::Int(rhs)) => lhs == rhs,
445 (Self::SignedInt(lhs), Self::SignedInt(rhs)) => lhs == rhs,
446 (Self::SignedInt(lhs), Self::MaybeSignedInt(rhs)) => {
447 T::to_signed(*rhs).map(|rhs| rhs == *lhs).unwrap_or(false)
448 }
449 (Self::MaybeSignedInt(lhs), Self::SignedInt(rhs)) => {
450 T::to_signed(*lhs).map(|lhs| lhs == *rhs).unwrap_or(false)
451 }
452 (Self::Float(lhs), Self::Float(rhs)) => lhs == rhs,
453 (Self::Bool(lhs), Self::Bool(rhs)) => lhs == rhs,
454 (Self::String(lhs), Self::String(rhs)) => lhs == rhs,
455 (Self::Iter(lhs), Self::Iter(rhs)) => lhs == rhs,
456 (Self::Struct(lhs), Self::Struct(rhs)) => lhs == rhs,
457 (Self::Ref(lhs), Self::Ref(rhs)) => lhs == rhs,
458 _ => core::mem::discriminant(self) == core::mem::discriminant(other),
459 }
460 }
461}
462
463impl<T: TypeSet> Clone for TypedValue<T> {
464 fn clone(&self) -> Self {
465 match self {
466 Self::Void => Self::Void,
467 Self::MaybeSignedInt(inner) => Self::MaybeSignedInt(*inner),
468 Self::Int(inner) => Self::Int(*inner),
469 Self::SignedInt(inner) => Self::SignedInt(*inner),
470 Self::Float(inner) => Self::Float(*inner),
471 Self::Bool(inner) => Self::Bool(*inner),
472 Self::String(inner) => Self::String(inner.clone()),
473 Self::Iter(inner) => Self::Iter(inner.clone()),
474 Self::Struct(inner) => Self::Struct(inner.clone()),
475 Self::Ref(inner) => Self::Ref(inner.clone()),
476 }
477 }
478}
479
480impl<T: TypeSet> TypedValue<T> {
481 pub fn type_of(&self) -> Type {
483 match self {
484 TypedValue::Void => Type::Void,
485 TypedValue::Int(_) => Type::Int,
486 TypedValue::MaybeSignedInt(_) => Type::MaybeSignedInt,
487 TypedValue::SignedInt(_) => Type::SignedInt,
488 TypedValue::Float(_) => Type::Float,
489 TypedValue::Bool(_) => Type::Bool,
490 TypedValue::String(_) => Type::String,
491 TypedValue::Iter(_) => Type::Iter,
492 TypedValue::Struct(_) => Type::Struct,
493 TypedValue::Ref(r) => Type::Ref(r.pointee()),
494 }
495 }
496}
497
498pub trait LoadOwned<T: TypeSet = DefaultTypeSet> {
500 type Output;
502
503 fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output>;
505}
506
507pub trait LoadStore<T: TypeSet = DefaultTypeSet> {
509 type Output<'s>
511 where
512 T: 's;
513
514 fn load<'s>(_ctx: &'s T, typed: &'s TypedValue<T>) -> Option<Self::Output<'s>>;
516
517 fn store(&self, _ctx: &mut T) -> TypedValue<T>;
519}
520
521for_each! {
522 ($type:ty) in [u32, u64, u128] => {
524 impl<T: TypeSet<Integer = Self>> LoadOwned<T> for $type {
525 type Output = Self;
526 fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output> {
527 match typed {
528 TypedValue::MaybeSignedInt(value) => Some(*value),
529 TypedValue::Int(value) => Some(*value),
530 _ => None,
531 }
532 }
533 }
534 impl<T: TypeSet<Integer = Self>> LoadStore<T> for $type {
535 type Output<'s> = Self;
536 fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
537 <Self as LoadOwned<T>>::load_owned(ctx, typed)
538 }
539 fn store(&self, _ctx: &mut T) -> TypedValue<T> {
540 TypedValue::Int(*self)
541 }
542 }
543 };
544
545 ($type:ty) in [i32, i64, i128] => {
547 impl<T: TypeSet<SignedInteger = Self>> LoadOwned<T> for $type {
548 type Output = Self;
549 fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output> {
550 match typed {
551 TypedValue::MaybeSignedInt(value) => T::to_signed(*value).ok(),
552 TypedValue::SignedInt(value) => Some(*value),
553 _ => None,
554 }
555 }
556 }
557 impl<T: TypeSet<SignedInteger = Self>> LoadStore<T> for $type {
558 type Output<'s> = Self;
559 fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
560 <Self as LoadOwned<T>>::load_owned(ctx, typed)
561 }
562 fn store(&self, _ctx: &mut T) -> TypedValue<T> {
563 TypedValue::SignedInt(*self)
564 }
565 }
566 };
567
568 ($type:ty) in [String, Box<str>] => {
570 impl<T: TypeSet> LoadOwned<T> for $type {
571 type Output = Self;
572 fn load_owned(ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output> {
573 <&str as LoadStore<T>>::load(ctx, typed).map(Into::into)
574 }
575 }
576 impl<T: TypeSet> LoadStore<T> for $type {
577 type Output<'s> = Self;
578 fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
579 <Self as LoadOwned<T>>::load_owned(ctx, typed)
580 }
581 fn store(&self, ctx: &mut T) -> TypedValue<T> {
582 TypedValue::String(ctx.store_string(self))
583 }
584 }
585 };
586
587 ($type:ty) in [f32, f64] => {
589 impl<T: TypeSet<Float = Self>> LoadOwned<T> for $type {
590 type Output = Self;
591 fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output> {
592 match typed {
593 TypedValue::Float(value) => Some(*value),
594 _ => None,
595 }
596 }
597 }
598 impl<T: TypeSet<Float = Self>> LoadStore<T> for $type {
599 type Output<'s> = Self;
600 fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
601 <Self as LoadOwned<T>>::load_owned(ctx, typed)
602 }
603 fn store(&self, _ctx: &mut T) -> TypedValue<T> {
604 TypedValue::Float(*self)
605 }
606 }
607 };
608}
609
610impl<T: TypeSet> LoadOwned<T> for TypedValue<T> {
613 type Output = Self;
614 fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
615 Some(typed.clone())
616 }
617}
618impl<T: TypeSet> LoadStore<T> for TypedValue<T> {
619 type Output<'s> = Self;
620 fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
621 <Self as LoadOwned<T>>::load_owned(ctx, typed)
622 }
623 fn store(&self, _ctx: &mut T) -> TypedValue<T> {
624 self.clone()
625 }
626}
627
628impl<T: TypeSet> LoadOwned<T> for () {
629 type Output = Self;
630 fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
631 if let TypedValue::Void = typed {
632 Some(())
633 } else {
634 None
635 }
636 }
637}
638impl<T: TypeSet> LoadStore<T> for () {
639 type Output<'s> = Self;
640 fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
641 <Self as LoadOwned<T>>::load_owned(ctx, typed)
642 }
643 fn store(&self, _ctx: &mut T) -> TypedValue<T> {
644 TypedValue::Void
645 }
646}
647
648impl<T: TypeSet> LoadOwned<T> for bool {
649 type Output = Self;
650 fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
651 if let TypedValue::Bool(value) = typed {
652 Some(*value)
653 } else {
654 None
655 }
656 }
657}
658impl<T: TypeSet> LoadStore<T> for bool {
659 type Output<'s> = Self;
660 fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
661 <Self as LoadOwned<T>>::load_owned(ctx, typed)
662 }
663 fn store(&self, _ctx: &mut T) -> TypedValue<T> {
664 TypedValue::Bool(*self)
665 }
666}
667
668impl<T: TypeSet> LoadStore<T> for &str {
669 type Output<'s>
670 = &'s str
671 where
672 T: 's;
673
674 fn load<'s>(ctx: &'s T, typed: &'s TypedValue<T>) -> Option<Self::Output<'s>> {
675 if let TypedValue::String(index) = typed {
676 Some(ctx.load_string(index))
677 } else {
678 None
679 }
680 }
681 fn store(&self, ctx: &mut T) -> TypedValue<T> {
682 TypedValue::String(ctx.store_string(self))
683 }
684}
685
686impl<T: TypeSet> LoadOwned<T> for SomniStruct<T> {
689 type Output = SomniStruct<T>;
690 fn load_owned(_ctx: &T, typed: &TypedValue<T>) -> Option<Self::Output> {
691 if let TypedValue::Struct(s) = typed {
692 Some(s.clone())
693 } else {
694 None
695 }
696 }
697}
698impl<T: TypeSet> LoadStore<T> for SomniStruct<T> {
699 type Output<'s> = SomniStruct<T>;
700 fn load(ctx: &T, typed: &TypedValue<T>) -> Option<Self> {
701 <Self as LoadOwned<T>>::load_owned(ctx, typed)
702 }
703 fn store(&self, _ctx: &mut T) -> TypedValue<T> {
704 TypedValue::Struct(self.clone())
705 }
706}