1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use crate::{bits::Boolean, traits::integers::Integer};
use std::fmt::Debug;
macro_rules! int_impl {
($name: ident, $type_: ty, $utype_: ty, $size: expr) => {
#[derive(Clone, Debug)]
pub struct $name {
pub bits: Vec<Boolean>,
pub value: Option<$type_>,
}
impl Integer for $name {
type IntegerType = $type_;
const SIZE: usize = $size;
fn constant(value: $type_) -> Self {
let mut bits = Vec::with_capacity($size);
for i in 0..$size {
let mask = 1 << i as $type_;
let result = value & mask;
if result == mask {
bits.push(Boolean::constant(true))
} else {
bits.push(Boolean::constant(false))
}
}
Self {
bits,
value: Some(value),
}
}
fn one() -> Self {
Self::constant(1 as $type_)
}
fn zero() -> Self {
Self::constant(0 as $type_)
}
fn new(bits: Vec<Boolean>, value: Option<Self::IntegerType>) -> Self {
Self { bits, value }
}
fn is_constant(&self) -> bool {
self.bits.iter().all(|bit| matches!(bit, Boolean::Constant(_)))
}
fn to_bits_le(&self) -> Vec<Boolean> {
self.bits.clone()
}
fn from_bits_le(bits: &[Boolean]) -> Self {
assert_eq!(bits.len(), $size);
let bits = bits.to_vec();
let mut value = Some(0 as $utype_);
for b in bits.iter().rev() {
value.as_mut().map(|v| *v <<= 1);
match *b {
Boolean::Constant(b) => {
if b {
value.as_mut().map(|v| *v |= 1);
}
}
Boolean::Is(ref b) => match b.get_value() {
Some(true) => {
value.as_mut().map(|v| *v |= 1);
}
Some(false) => {}
None => value = None,
},
Boolean::Not(ref b) => match b.get_value() {
Some(false) => {
value.as_mut().map(|v| *v |= 1);
}
Some(true) => {}
None => value = None,
},
}
}
Self {
value: value.map(|x| x as $type_),
bits,
}
}
fn get_value(&self) -> Option<String> {
self.value.map(|num| num.to_string())
}
}
};
}
int_impl!(Int8, i8, u8, 8);
int_impl!(Int16, i16, u16, 16);
int_impl!(Int32, i32, u32, 32);
int_impl!(Int64, i64, u64, 64);
int_impl!(Int128, i128, u128, 128);