solar_codegen/mir/
value.rs1use super::{InstId, MirType};
4use alloy_primitives::U256;
5use solar_interface::diagnostics::ErrorGuaranteed;
6use std::fmt;
7
8#[derive(Clone, Debug)]
10pub enum Value {
11 Inst(InstId),
13 Arg {
15 index: u32,
17 ty: MirType,
19 },
20 Immediate(Immediate),
22 Undef(MirType),
24 Error(ErrorGuaranteed),
31}
32
33impl Value {
34 #[must_use]
36 pub fn ty(&self) -> MirType {
37 match self {
38 Self::Inst(_) | Self::Error(_) => MirType::uint256(),
39 Self::Arg { ty, .. } | Self::Undef(ty) => *ty,
40 Self::Immediate(imm) => imm.ty(),
41 }
42 }
43
44 #[must_use]
46 pub const fn is_immediate(&self) -> bool {
47 matches!(self, Self::Immediate(_))
48 }
49
50 #[must_use]
52 pub const fn as_immediate(&self) -> Option<&Immediate> {
53 match self {
54 Self::Immediate(imm) => Some(imm),
55 _ => None,
56 }
57 }
58}
59
60#[derive(Clone, Debug, PartialEq, Eq, Hash)]
62pub enum Immediate {
63 Bool(bool),
65 UInt(U256, u16),
67 Int(U256, u16),
69 Address([u8; 20]),
71 FixedBytes(Vec<u8>, u8),
73}
74
75impl Immediate {
76 #[must_use]
78 pub const fn ty(&self) -> MirType {
79 match self {
80 Self::Bool(_) => MirType::Bool,
81 Self::UInt(_, bits) => MirType::UInt(*bits),
82 Self::Int(_, bits) => MirType::Int(*bits),
83 Self::Address(_) => MirType::Address,
84 Self::FixedBytes(_, n) => MirType::FixedBytes(*n),
85 }
86 }
87
88 #[must_use]
90 pub const fn uint256(value: U256) -> Self {
91 Self::UInt(value, 256)
92 }
93
94 #[must_use]
96 pub const fn bool(value: bool) -> Self {
97 Self::Bool(value)
98 }
99
100 #[must_use]
102 pub fn zero(ty: MirType) -> Self {
103 match ty {
104 MirType::Bool => Self::Bool(false),
105 MirType::UInt(bits) => Self::UInt(U256::ZERO, bits),
106 MirType::Int(bits) => Self::Int(U256::ZERO, bits),
107 MirType::Address => Self::Address([0u8; 20]),
108 MirType::FixedBytes(n) => Self::FixedBytes(vec![0u8; n as usize], n),
109 _ => Self::UInt(U256::ZERO, 256),
110 }
111 }
112
113 #[must_use]
115 pub fn as_u256(&self) -> Option<U256> {
116 match self {
117 Self::Bool(b) => Some(U256::from(*b as u64)),
118 Self::UInt(v, _) | Self::Int(v, _) => Some(*v),
119 Self::Address(addr) => Some(U256::from_be_slice(addr)),
120 Self::FixedBytes(bytes, _) => {
121 let mut padded = [0u8; 32];
122 let len = bytes.len().min(32);
123 padded[..len].copy_from_slice(&bytes[..len]);
124 Some(U256::from_be_bytes(padded))
125 }
126 }
127 }
128}
129
130impl fmt::Display for Immediate {
131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132 match self {
133 Self::Bool(b) => write!(f, "{b}"),
134 Self::UInt(v, _) | Self::Int(v, _) => write!(f, "{v}"),
135 Self::Address(addr) => write!(f, "0x{}", alloy_primitives::hex::encode(addr)),
136 Self::FixedBytes(bytes, _) => write!(f, "0x{}", alloy_primitives::hex::encode(bytes)),
137 }
138 }
139}