1use crate::types::*;
2
3#[derive(Clone, Default, PartialEq)]
5pub enum Value {
6 #[default]
8 X,
9 Word(Width, u64),
11 Vec(Vec<Value>),
13 Ctor(String, Vec<Value>),
15 Enum(Type, String),
17 Struct(Type, Vec<(String, Value)>),
18}
19
20impl Value {
21 pub fn is_x(&self) -> bool {
22 if let Value::X = self {
23 true
24 } else {
25 false
26 }
27 }
28
29 pub fn to_u64(&self) -> Option<u64> {
30 match self {
31 Value::X => None,
32 Value::Word(w, n) => Some(n & ((1 << w) - 1)),
33 Value::Vec(_vs) => panic!(),
34 Value::Enum(_typedef, _name) => panic!(),
35 Value::Struct(_typedef, _fields) => panic!(),
36 Value::Ctor(_ctor, _e) => None,
37 }
38 }
39
40 pub fn to_bool(&self) -> Option<bool> {
41 match self {
42 Value::Word(1, 0) => Some(false),
43 Value::Word(1, 1) => Some(true),
44 _ => None,
45 }
46 }
47}
48
49#[test]
50fn value_to_usize() {
51 let v: Value = Value::Word(4, 7);
53 assert_eq!(v.to_u64(), Some(7));
54 let v: Value = Value::Word(2, 7);
55 assert_eq!(v.to_u64(), Some(3));
56}
57
58impl From<bool> for Value {
59 fn from(x: bool) -> Value {
60 Value::Word(1, if x { 1 } else { 0 })
61 }
62}
63
64impl TryFrom<Value> for bool {
65 type Error = ();
66 fn try_from(value: Value) -> Result<bool, Self::Error> {
67 match value {
68 Value::Word(1, n) => Ok(n == 1),
69 _ => Err(()),
70 }
71 }
72}
73
74impl TryFrom<Value> for u8 {
75 type Error = ();
76 fn try_from(value: Value) -> Result<u8, Self::Error> {
77 match value {
78 Value::Word(_w, n) => Ok(n as u8), _ => Err(()),
80 }
81 }
82}
83
84impl TryFrom<Value> for u64 {
85 type Error = ();
86 fn try_from(value: Value) -> Result<u64, Self::Error> {
87 match value {
88 Value::X => Err(()),
89 Value::Word(_w, n) => Ok(n),
90 Value::Enum(_typedef, _name) => Err(()),
91 _ => Err(()),
92 }
93 }
94}
95
96impl std::fmt::Debug for Value {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
98 match self {
99 Value::X => write!(f, "XXX"),
100 Value::Word(w, n) => write!(f, "{n}w{w}"),
101 Value::Vec(vs) => {
102 write!(f, "[")?;
103 for (i, v) in vs.iter().enumerate() {
104 if i + 1 < vs.len() {
105 write!(f, "{v:?}, ")?;
106 } else {
107 write!(f, "{v:?}")?;
108 }
109 }
110 write!(f, "]")
111 },
112 Value::Enum(typ, name) => write!(f, "{}::{}", typ.name(), name),
113 Value::Struct(_typedef, fields) => {
114 let field_strs: Vec<_> = fields.iter().map(|(name, val)| format!("{name} = {val:?}")).collect();
115 write!(f, "{{ {} }}", field_strs.join(", "))
116 },
117 Value::Ctor(ctor, vs) => {
118 write!(f, "@{ctor}")?;
119 if vs.len() > 0 {
120 write!(f, "(")?;
121 for (i, v) in vs.iter().enumerate() {
122 write!(f, "{v:?}")?;
123 if i + 1 < vs.len() {
124 write!(f, ", ")?;
125 }
126 }
127 write!(f, ")")
128 } else {
129 Ok(())
130 }
131 },
132 }
133 }
134}
135
136impl std::fmt::Display for Value {
137 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
138 match self {
139 Value::X => write!(f, "XXX"),
140 Value::Word(w, n) => write!(f, "{n}w{w}"),
141 Value::Vec(vs) => {
142 write!(f, "[")?;
143 for (i, v) in vs.iter().enumerate() {
144 if i + 1 < vs.len() {
145 write!(f, "{v:?}, ")?;
146 } else {
147 write!(f, "{v:?}")?;
148 }
149 }
150 write!(f, "]")
151 },
152 Value::Enum(typedef, name) => write!(f, "{}::{}", typedef.name(), name),
153 Value::Struct(_typedef, _fields) => write!(f, "{self}"),
154 Value::Ctor(ctor, vs) => {
155 write!(f, "@{ctor}")?;
156 if vs.len() > 0 {
157 write!(f, "(")?;
158 for (i, v) in vs.iter().enumerate() {
159 write!(f, "{v:?}")?;
160 if i + 1 < vs.len() {
161 write!(f, ", ")?;
162 }
163 }
164 write!(f, ")")
165 } else {
166 Ok(())
167 }
168 },
169 }
170 }
171}
172
173impl std::fmt::LowerHex for Value {
174 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175 match self {
176 Value::X => write!(f, "XXX"),
177 Value::Word(w, _n) => write!(f, "0x{:x}w{w}", self.to_u64().unwrap()),
178 Value::Vec(vs) => {
179 write!(f, "[")?;
180 for (i, v) in vs.iter().enumerate() {
181 if i + 1 < vs.len() {
182 write!(f, "{v:?}, ")?;
183 } else {
184 write!(f, "{v:?}")?;
185 }
186 }
187 write!(f, "]")
188 },
189 Value::Enum(typedef, name) => write!(f, "{}::{}", typedef.name(), name),
190 Value::Struct(_typedef, _fields) => write!(f, "{self}"), Value::Ctor(ctor, vs) => {
192 write!(f, "@{ctor}")?;
193 if vs.len() > 0 {
194 write!(f, "(")?;
195 for (i, v) in vs.iter().enumerate() {
196 write!(f, "{v:?}")?;
197 if i + 1 < vs.len() {
198 write!(f, ", ")?;
199 }
200 }
201 write!(f, ")")
202 } else {
203 Ok(())
204 }
205 },
206 }
207 }
208}
209
210impl std::fmt::UpperHex for Value {
211 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
212 match self {
213 Value::X => write!(f, "XXX"),
214 Value::Word(w, _n) => write!(f, "0x{:X}w{w}", self.to_u64().unwrap()),
215 Value::Vec(vs) => {
216 write!(f, "[")?;
217 for (i, v) in vs.iter().enumerate() {
218 if i + 1 < vs.len() {
219 write!(f, "{v:?}, ")?;
220 } else {
221 write!(f, "{v:?}")?;
222 }
223 }
224 write!(f, "]")
225 },
226 Value::Enum(typedef, name) => write!(f, "{}::{}", typedef.name(), name),
227 Value::Struct(_typedef, _fields) => write!(f, "{self}"),
228 Value::Ctor(ctor, vs) => {
229 write!(f, "@{ctor}")?;
230 if vs.len() > 0 {
231 write!(f, "(")?;
232 for (i, v) in vs.iter().enumerate() {
233 write!(f, "{v:?}")?;
234 if i + 1 < vs.len() {
235 write!(f, ", ")?;
236 }
237 }
238 write!(f, ")")
239 } else {
240 Ok(())
241 }
242 },
243 }
244 }
245}
246
247impl std::fmt::Binary for Value {
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 match self {
250 Value::X => write!(f, "XXX"),
251 Value::Word(w, _n) => write!(f, "0b{:b}w{w}", self.to_u64().unwrap()),
252 Value::Vec(vs) => {
253 write!(f, "[")?;
254 for (i, v) in vs.iter().enumerate() {
255 if i + 1 < vs.len() {
256 write!(f, "{v:?}, ")?;
257 } else {
258 write!(f, "{v:?}")?;
259 }
260 }
261 write!(f, "]")
262 },
263 Value::Enum(typedef, name) => write!(f, "{}::{}", typedef.name(), name),
264 Value::Struct(_typedef, _fields) => write!(f, "{self}"),
265 Value::Ctor(ctor, vs) => {
266 write!(f, "@{ctor}")?;
267 if vs.len() > 0 {
268 write!(f, "(")?;
269 for (i, v) in vs.iter().enumerate() {
270 write!(f, "{v:?}")?;
271 if i + 1 < vs.len() {
272 write!(f, ", ")?;
273 }
274 }
275 write!(f, ")")
276 } else {
277 Ok(())
278 }
279 },
280 }
281 }
282}