1use std::num::Wrapping;
19use std::u64;
20
21use quickcheck::{Arbitrary,Gen};
22
23use {NameRef,Result,SegmentRef};
24
25#[derive(Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Debug,Hash)]
27pub struct Variable {
28 pub name: NameRef,
30 pub bits: usize,
32}
33
34impl Variable {
35 pub fn new(name: NameRef, bits: usize) -> Result<Variable> {
37 if bits == 0 { return Err("Variable can't have size 0".into()); }
38
39 Ok(Variable{
40 name: name,
41 bits: bits
42 })
43 }
44}
45
46#[derive(Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Debug,Hash)]
48pub struct Constant {
49 pub value: u64,
51 pub bits: usize,
53}
54
55impl Constant {
56 pub fn new(value: u64, bits: usize) -> Result<Constant> {
58 if bits == 0 { return Err("Variable can't have size 0".into()); }
59
60 Ok(Constant{
61 value: value,
62 bits: bits
63 })
64 }
65
66 pub fn mask(&self) -> Wrapping<u64> {
68 Wrapping(if self.bits < 64 { (1u64 << self.bits) - 1 } else { u64::MAX })
69 }
70}
71
72impl Into<Wrapping<u64>> for Constant {
73 fn into(self) -> Wrapping<u64> {
74 Wrapping(self.value) & self.mask()
75 }
76}
77
78#[derive(Clone,Copy,PartialEq,Eq,PartialOrd,Ord,Debug,Hash)]
80pub enum Value {
81 Undefined,
83 Variable(Variable),
85 Constant(Constant),
87}
88
89impl Value {
90 pub fn val(val: u64, bits: usize) -> Result<Value> {
92 Ok(Value::Constant(Constant::new(val,bits)?))
93 }
94
95 pub fn var(name: NameRef, bits: usize) -> Result<Value> {
97 Ok(Value::Variable(Variable::new(name,bits)?))
98 }
99
100 pub fn undef() -> Value {
102 Value::Undefined
103 }
104
105 pub fn bits(&self) -> Option<usize> {
107 match self {
108 &Value::Variable(Variable{ bits,.. }) => Some(bits),
109 &Value::Constant(Constant{ bits,.. }) => Some(bits),
110 &Value::Undefined => None,
111 }
112 }
113
114
115}
116
117impl From<Variable> for Value {
118 fn from(v: Variable) -> Value {
119 Value::Variable(v)
120 }
121}
122
123impl From<Constant> for Value {
124 fn from(v: Constant) -> Value {
125 Value::Constant(v)
126 }
127}
128
129#[derive(Clone,Copy,PartialEq,Eq,Debug,Hash)]
131pub struct Segment {
132 pub name: SegmentRef,
134}
135
136impl Arbitrary for Variable {
137 fn arbitrary<G: Gen>(g: &mut G) -> Self {
138 Variable {
139 name: NameRef::arbitrary(g),
140 bits: 1 << g.gen_range(0, 11),
141 }
142 }
143}
144
145impl Arbitrary for Constant {
146 fn arbitrary<G: Gen>(g: &mut G) -> Self {
147 Constant{
148 value: g.gen(),
149 bits: 1 << g.gen_range(0, 11),
150 }
151 }
152}
153
154impl Arbitrary for Segment {
155 fn arbitrary<G: Gen>(g: &mut G) -> Self {
156 Segment{ name: SegmentRef::new(g.gen_range(0,100)) }
157 }
158}
159
160impl Arbitrary for Value {
161 fn arbitrary<G: Gen>(g: &mut G) -> Self {
162 match g.gen_range(0, 2) {
163 0 => Value::Undefined,
164 1 => Value::Variable(Variable::arbitrary(g)),
165 2 => Value::Constant(Constant::arbitrary(g)),
166 _ => unreachable!(),
167 }
168 }
169}