Skip to main content

haloumi_ir/
expr.rs

1//! Structs for handling expressions.
2
3mod aexpr;
4mod bexpr;
5
6use std::{
7    iter::{Product, Sum},
8    ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign},
9};
10
11pub use aexpr::*;
12pub use bexpr::*;
13use bit_set::BitSet;
14
15/// Marker enum for different properties of expressions.
16#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
17#[repr(u8)]
18pub enum ExprProperty {
19    /// Constant expression
20    Const,
21}
22
23impl ExprProperty {
24    const fn value(self) -> usize {
25        match self {
26            ExprProperty::Const => 0,
27        }
28    }
29}
30
31impl BitOr for ExprProperty {
32    type Output = ExprProperties;
33
34    fn bitor(self, rhs: Self) -> Self::Output {
35        ExprProperties(BitSet::from_iter([self.value(), rhs.value()]))
36    }
37}
38
39impl BitOr<ExprProperties> for ExprProperty {
40    type Output = ExprProperties;
41
42    fn bitor(self, mut rhs: ExprProperties) -> Self::Output {
43        rhs.0.insert(self.value());
44        rhs
45    }
46}
47
48impl PartialEq<ExprProperties> for ExprProperty {
49    fn eq(&self, other: &ExprProperties) -> bool {
50        other.eq(self)
51    }
52}
53
54/// Set of properties for expressions.
55#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
56pub struct ExprProperties(BitSet);
57
58impl ExprProperties {
59    /// Creates a new property set.
60    pub fn new() -> Self {
61        Self::default()
62    }
63
64    /// Creates a new property set with only one property.
65    pub fn with(prop: ExprProperty) -> Self {
66        Self(BitSet::from_iter([prop.value()]))
67    }
68
69    fn full() -> Self {
70        Self(BitSet::from_bytes(&usize::MAX.to_be_bytes()))
71    }
72}
73
74impl From<ExprProperty> for ExprProperties {
75    fn from(value: ExprProperty) -> Self {
76        Self::with(value)
77    }
78}
79
80impl BitOr for ExprProperties {
81    type Output = Self;
82
83    fn bitor(mut self, rhs: Self) -> Self::Output {
84        self |= rhs;
85        self
86    }
87}
88
89impl BitAnd for ExprProperties {
90    type Output = Self;
91
92    fn bitand(mut self, rhs: Self) -> Self::Output {
93        self &= rhs;
94        self
95    }
96}
97
98impl BitOr<ExprProperty> for ExprProperties {
99    type Output = Self;
100
101    fn bitor(mut self, rhs: ExprProperty) -> Self::Output {
102        self |= rhs;
103        self
104    }
105}
106impl BitAnd<ExprProperty> for ExprProperties {
107    type Output = Self;
108
109    fn bitand(mut self, rhs: ExprProperty) -> Self::Output {
110        self &= rhs;
111        self
112    }
113}
114
115impl BitOrAssign for ExprProperties {
116    fn bitor_assign(&mut self, rhs: Self) {
117        self.0.union_with(&rhs.0)
118    }
119}
120
121impl BitAndAssign for ExprProperties {
122    fn bitand_assign(&mut self, rhs: Self) {
123        self.0.intersect_with(&rhs.0)
124    }
125}
126
127impl BitOrAssign<ExprProperty> for ExprProperties {
128    fn bitor_assign(&mut self, rhs: ExprProperty) {
129        self.0.insert(rhs.value());
130    }
131}
132
133impl BitAndAssign<ExprProperty> for ExprProperties {
134    fn bitand_assign(&mut self, rhs: ExprProperty) {
135        self.0
136            .intersect_with(&BitSet::from_bytes(&rhs.value().to_le_bytes()));
137    }
138}
139
140impl PartialEq<ExprProperty> for ExprProperties {
141    fn eq(&self, other: &ExprProperty) -> bool {
142        self.0.contains(other.value())
143    }
144}
145
146impl Sum for ExprProperties {
147    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
148        iter.fold(Default::default(), |acc, e| acc | e)
149    }
150}
151
152impl Sum<ExprProperty> for ExprProperties {
153    fn sum<I: Iterator<Item = ExprProperty>>(iter: I) -> Self {
154        iter.fold(Default::default(), |acc, e| acc | e)
155    }
156}
157
158impl Product for ExprProperties {
159    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
160        iter.fold(Self::full(), |acc, e| acc & e)
161    }
162}
163
164impl Product<ExprProperty> for ExprProperties {
165    fn product<I: Iterator<Item = ExprProperty>>(iter: I) -> Self {
166        iter.fold(Self::full(), |acc, e| acc & e)
167    }
168}