stack_assembly/value.rs
1use std::fmt;
2
3/// # A unit of data
4///
5/// StackAssembly is an _untyped_ languages. All of its values, both on the
6/// [`OperandStack`] and in [`Memory`], are 32 bits wide. Depending on the
7/// situation, they may be interpreted as unsigned or signed.
8///
9/// You can create an instance of `Value` through its `From` implementations.
10///
11/// ```
12/// use stack_assembly::Value;
13///
14/// Value::from(3i32);
15/// Value::from(5u32);
16/// ```
17///
18/// [`OperandStack`]: crate::OperandStack
19/// [`Memory`]: crate::Memory
20#[derive(Clone, Copy, Eq, PartialEq, bytemuck::Pod, bytemuck::Zeroable)]
21#[repr(transparent)]
22pub struct Value {
23 inner: u32,
24}
25
26impl Value {
27 /// # Convert the value to an `i32`
28 ///
29 /// Since all values are 32 bits wide, this is always possible. Interprets
30 /// the bits of the value as a signed (two's complement) integer.
31 pub fn to_i32(self) -> i32 {
32 i32::from_le_bytes(self.inner.to_le_bytes())
33 }
34
35 /// # Convert the value to a `u32`
36 ///
37 /// Since all values are 32 bits wide, this is always possible. Interprets
38 /// the bits of the value as an unsigned integer.
39 pub fn to_u32(self) -> u32 {
40 self.inner
41 }
42
43 /// # Convert to a `bool`
44 ///
45 /// A zero value is considered `false`, while any other value is considered
46 /// `true`.
47 pub fn to_bool(self) -> bool {
48 self.inner != 0
49 }
50}
51
52impl From<bool> for Value {
53 fn from(value: bool) -> Self {
54 let inner = if value { 1 } else { 0 };
55 Self { inner }
56 }
57}
58
59impl From<i32> for Value {
60 fn from(value: i32) -> Self {
61 let inner = u32::from_le_bytes(value.to_le_bytes());
62 Self { inner }
63 }
64}
65
66impl From<u32> for Value {
67 fn from(inner: u32) -> Self {
68 Self { inner }
69 }
70}
71
72impl fmt::Debug for Value {
73 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
74 // Let's bypass this type and format the inner value. This is just a
75 // wrapper anyway, and showing it in debug output is unnecessary noise.
76 self.inner.fmt(f)
77 }
78}