bitsy_lang/sim/
value.rs

1use crate::types::*;
2
3/// A value used in the simulator (see [`crate::sim::Sim`]).
4#[derive(Clone, Default, PartialEq)]
5pub enum Value {
6    /// An undefined value.
7    #[default]
8    X,
9    /// An element of `Word<n>`.
10    Word(Width, u64),
11    /// An element of `Vec<T, n>`.
12    Vec(Vec<Value>),
13    /// An element of `Valid<T>`.
14    Ctor(String, Vec<Value>),
15    /// An element of a user-defined `enum`.
16    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    // TODO move this to tests.
52    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), // TODO
79            _ => 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}"), // TODO
191            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}