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