1use core::cmp::Ordering;
2use core::intrinsics;
3use core::marker::PhantomData;
4use core::ops::{Neg, Not, Add, Sub, Mul, Div, Rem, BitAnd, BitOr, BitXor, Shl, Shr};
5
6use crate::symbolic::Symbolic;
7
8pub struct Bv<S: Size + ?Sized> {
10 _dummy: u8,
11 _marker: PhantomData<S>,
12}
13
14pub trait Size {
15 fn make_symbolic(desc: &str) -> Bv<Self>;
16}
17
18pub struct _128;
19impl Size for _128 {
20 fn make_symbolic(desc: &str) -> Bv<Self> { make_symbolic_128(desc) }
21}
22
23pub struct _256;
24impl Size for _256 {
25 fn make_symbolic(desc: &str) -> Bv<Self> { make_symbolic_256(desc) }
26}
27
28pub struct _512;
29impl Size for _512 {
30 fn make_symbolic(desc: &str) -> Bv<Self> { make_symbolic_512(desc) }
31}
32
33
34pub type Bv128 = Bv<_128>;
36pub type Bv256 = Bv<_256>;
38pub type Bv512 = Bv<_512>;
40
41
42impl<S: Size> Bv<S> {
43 pub const ZERO: Self = Bv { _dummy: 0, _marker: PhantomData };
51 pub const ONE: Self = Bv { _dummy: 1, _marker: PhantomData };
52 pub const MAX: Self = Bv { _dummy: 2, _marker: PhantomData };
53}
54
55
56pub fn convert<T, U>(x: T) -> U {
62 unimplemented!()
63}
64
65macro_rules! impl_from_bv {
66 ($($S1:ty, $S2:ty;)*) => {
67 $(
68 impl From<Bv<$S1>> for Bv<$S2> {
69 fn from(x: Bv<$S1>) -> Bv<$S2> {
70 convert(x)
71 }
72 }
73 )*
74 };
75}
76
77impl_from_bv! {
78 _128, _256;
79 _128, _512;
80 _256, _128;
81 _256, _512;
82 _512, _128;
83 _512, _256;
84}
85
86macro_rules! impl_into_prim {
87 ($($T:ty),*) => {
88 $(
89 impl<S: Size> From<Bv<S>> for $T {
90 fn from(x: Bv<S>) -> $T {
91 convert(x)
92 }
93 }
94 )*
95 };
96}
97
98macro_rules! impl_from_into_prim {
99 ($($T:ty),*) => {
100 $(
101 impl<S: Size> From<$T> for Bv<S> {
102 fn from(x: $T) -> Bv<S> {
103 convert(x)
104 }
105 }
106 )*
107 impl_into_prim!($($T),*);
108 };
109}
110
111macro_rules! impl_from_into_prim_signed {
112 ($($T:ty),*) => {
113 $(
114 impl<S: Size> From<$T> for Bv<S> {
115 fn from(x: $T) -> Bv<S> {
116 assert!(x >= 0, "can't convert negative integer to unsigned bitvector");
117 convert(x)
118 }
119 }
120 )*
121 impl_into_prim!($($T),*);
122 };
123}
124
125impl_from_into_prim!(u8, u16, u32, u64, u128, usize);
126impl_from_into_prim_signed!(i8, i16, i32, i64, i128, isize);
127
128
129macro_rules! impl_unops {
130 ($($Op:ident, $op:ident;)*) => {
131 $(
132 impl<S: Size> $Op for Bv<S> {
133 type Output = Bv<S>;
134 fn $op(self) -> Bv<S> {
135 unimplemented!()
136 }
137 }
138 )*
139 };
140}
141
142macro_rules! impl_binops {
143 ($($Op:ident, $op:ident;)*) => {
144 $(
145 impl<S: Size> $Op<Bv<S>> for Bv<S> {
146 type Output = Bv<S>;
147 fn $op(self, other: Bv<S>) -> Bv<S> {
148 unimplemented!()
149 }
150 }
151 )*
152 };
153}
154
155macro_rules! impl_shift_ops {
156 ($($Op:ident, $op:ident;)*) => {
157 $(
158 fn $op<S: Size>(x: Bv<S>, y: Bv<S>) -> Bv<S> {
162 unimplemented!()
163 }
164
165 impl<S: Size> $Op<usize> for Bv<S> {
166 type Output = Bv<S>;
167 fn $op(self, shift: usize) -> Bv<S> {
168 $op(self, shift.into())
169 }
170 }
171 )*
172 };
173}
174
175impl_unops! {
176 Not, not;
177}
178
179impl_binops! {
180 Add, add;
181 Sub, sub;
182 Mul, mul;
183 Div, div;
184 Rem, rem;
185 BitAnd, bitand;
186 BitOr, bitor;
187 BitXor, bitxor;
188}
189
190impl_shift_ops! {
191 Shl, shl;
192 Shr, shr;
193}
194
195
196impl<S: Size> Bv<S> {
197 pub fn overflowing_add(self, other: Bv<S>) -> (Bv<S>, bool) {
198 unimplemented!()
199 }
200
201 pub fn overflowing_sub(self, other: Bv<S>) -> (Bv<S>, bool) {
202 unimplemented!()
203 }
204
205 pub fn overflowing_mul(self, other: Bv<S>) -> (Bv<S>, bool) {
206 unimplemented!()
207 }
208
209 pub fn leading_zeros(self) -> u32 {
210 unimplemented!()
211 }
212}
213
214
215impl<S: Size> Clone for Bv<S> {
216 fn clone(&self) -> Bv<S> {
217 *self
218 }
219}
220
221impl<S: Size> Copy for Bv<S> {}
222
223impl<S: Size> PartialEq<Bv<S>> for Bv<S> {
224 fn eq(&self, other: &Bv<S>) -> bool {
225 unimplemented!()
226 }
227}
228
229impl<S: Size> Eq for Bv<S> {}
230
231impl<S: Size> PartialOrd<Bv<S>> for Bv<S> {
232 fn partial_cmp(&self, other: &Bv<S>) -> Option<Ordering> {
233 Some(self.cmp(other))
234 }
235
236 fn lt(&self, other: &Bv<S>) -> bool {
237 unimplemented!()
238 }
239}
240
241impl<S: Size> Ord for Bv<S> {
242 fn cmp(&self, other: &Bv<S>) -> Ordering {
243 if self.eq(other) { Ordering::Equal }
244 else if self.lt(other) { Ordering::Less }
245 else { Ordering::Greater }
246 }
247}
248
249impl<S: Size> Symbolic for Bv<S> {
250 fn symbolic(desc: &str) -> Bv<S> {
251 S::make_symbolic(desc)
252 }
253}
254
255fn make_symbolic_128(desc: &str) -> Bv<_128> { unimplemented!() }
257fn make_symbolic_256(desc: &str) -> Bv<_256> { unimplemented!() }
258fn make_symbolic_512(desc: &str) -> Bv<_512> { unimplemented!() }