prjunnamed_pattern/
simple.rs1use prjunnamed_netlist::{Cell, Const, Net, Trit, Value};
2
3use crate::{DesignDyn, NetOrValue, Pattern};
4
5pub struct PAny;
6
7impl PAny {
8 pub fn new() -> PAny {
9 PAny
10 }
11}
12
13impl<T: Clone> Pattern<T> for PAny {
14 type Capture = (T,);
15
16 #[inline]
17 fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
18 Some((target.clone(),))
19 }
20}
21
22pub struct PBind<P>(P);
23
24impl<P> PBind<P> {
25 pub fn new(pat: P) -> PBind<P> {
26 PBind(pat)
27 }
28}
29
30impl<T: Clone, P: Pattern<T>> Pattern<T> for PBind<P> {
31 type Capture = (T, P::Capture);
32
33 #[inline]
34 fn execute(&self, design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
35 self.0.execute(design, target).and_then(|capture| Some((target.clone(), capture)))
36 }
37}
38
39pub struct PConst;
40
41impl PConst {
42 pub fn new() -> PConst {
43 PConst
44 }
45}
46
47impl Pattern<Net> for PConst {
48 type Capture = (Trit,);
49
50 #[inline]
51 fn execute(&self, _design: &dyn DesignDyn, target: &Net) -> Option<Self::Capture> {
52 Net::as_const(*target).map(|value| (value,))
53 }
54}
55
56impl Pattern<Value> for PConst {
57 type Capture = (Const,);
58
59 #[inline]
60 fn execute(&self, _design: &dyn DesignDyn, target: &Value) -> Option<Self::Capture> {
61 Value::as_const(&target).map(|value| (value,))
62 }
63}
64
65pub struct PZero;
66
67impl PZero {
68 pub fn new() -> PZero {
69 PZero
70 }
71}
72
73impl Pattern<u32> for PZero {
74 type Capture = ((),);
75
76 #[inline]
77 fn execute(&self, _design: &dyn DesignDyn, target: &u32) -> Option<Self::Capture> {
78 if *target == 0 {
79 Some(((),))
80 } else {
81 None
82 }
83 }
84}
85
86impl<T: NetOrValue> Pattern<T> for PZero {
87 type Capture = ((),);
88
89 #[inline]
90 fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
91 match target.as_const() {
92 Some(value) if value.iter().all(|net| net == Trit::Zero) => Some(((),)),
93 _ => None,
94 }
95 }
96}
97
98pub struct POnes;
99
100impl POnes {
101 pub fn new() -> POnes {
102 POnes
103 }
104}
105
106impl<T: NetOrValue> Pattern<T> for POnes {
107 type Capture = ((),);
108
109 #[inline]
110 fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
111 match target.as_const() {
112 Some(value) if value.is_empty() => None,
113 Some(value) if value.iter().all(|net| net == Trit::One) => Some(((),)),
114 _ => None,
115 }
116 }
117}
118
119pub struct PUndef;
120
121impl PUndef {
122 pub fn new() -> PUndef {
123 PUndef
124 }
125}
126
127impl<T: NetOrValue> Pattern<T> for PUndef {
128 type Capture = ((),);
129
130 #[inline]
131 fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
132 match target.as_const() {
133 Some(value) if value.is_empty() => None,
134 Some(value) if value.iter().all(|net| net == Trit::Undef) => Some(((),)),
135 _ => None,
136 }
137 }
138}
139
140pub struct PHasX;
141
142impl PHasX {
143 pub fn new() -> PHasX {
144 PHasX
145 }
146}
147
148impl<T: NetOrValue> Pattern<T> for PHasX {
149 type Capture = ((),);
150
151 #[inline]
152 fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
153 match target.as_const() {
154 Some(value) if value.has_undef() => Some(((),)),
155 _ => None,
156 }
157 }
158}
159
160pub struct PPow2;
161
162impl PPow2 {
163 pub fn new() -> PPow2 {
164 PPow2
165 }
166}
167
168impl<T: NetOrValue> Pattern<T> for PPow2 {
169 type Capture = (u32,);
170
171 #[inline]
172 fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
173 target.as_const().and_then(|value| value.as_power_of_two().map(|exp| (exp,)))
174 }
175}
176
177pub type POneHot = PPow2;
178
179pub struct PInput(&'static str);
180
181impl PInput {
182 pub fn new(name: &'static str) -> PInput {
183 PInput(name)
184 }
185}
186
187impl<T: NetOrValue> Pattern<T> for PInput {
188 type Capture = (T,);
189
190 #[inline]
191 fn execute(&self, design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
192 if let Some(net) = target.iter().next() {
193 if let Ok((cell_ref, 0)) = design.find_cell(net) {
194 if let Cell::Input(name, _size) = &*cell_ref.get() {
195 if target.as_value() == cell_ref.output() && name == self.0 {
196 return Some((target.clone(),));
197 }
198 }
199 }
200 }
201 None
202 }
203}
204
205pub struct PZExt<P>(P);
206
207impl<P> PZExt<P> {
208 pub fn new(pat: P) -> PZExt<P> {
209 PZExt(pat)
210 }
211}
212
213impl<P: Pattern<Value>> Pattern<Value> for PZExt<P> {
214 type Capture = (Value, P::Capture);
216
217 #[inline]
218 fn execute(&self, design: &dyn DesignDyn, target: &Value) -> Option<Self::Capture> {
219 let zext_count = target.iter().rev().take_while(|net| *net == Net::ZERO).count();
220 self.0.execute(design, &target.slice(..target.len() - zext_count)).map(|capture| (target.clone(), capture))
221 }
222}
223
224pub struct PSExt<P>(P);
225
226impl<P> PSExt<P> {
227 pub fn new(pat: P) -> PSExt<P> {
228 PSExt(pat)
229 }
230}
231
232impl<P: Pattern<Value>> Pattern<Value> for PSExt<P> {
233 type Capture = (Value, P::Capture);
235
236 #[inline]
237 fn execute(&self, design: &dyn DesignDyn, target: &Value) -> Option<Self::Capture> {
238 if target.is_empty() {
239 return None;
240 }
241 let sext_count = target.iter().rev().take_while(|net| *net == target.msb()).count() - 1;
242 self.0.execute(design, &target.slice(..target.len() - sext_count)).map(|capture| (target.clone(), capture))
243 }
244}