1mod 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#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
17#[repr(u8)]
18pub enum ExprProperty {
19 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#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
56pub struct ExprProperties(BitSet);
57
58impl ExprProperties {
59 pub fn new() -> Self {
61 Self::default()
62 }
63
64 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}