miden_assembly_syntax/ast/
immediate.rs1use alloc::sync::Arc;
2use core::fmt;
3
4use miden_debug_types::{SourceSpan, Span, Spanned};
5
6use crate::{Felt, ast::Ident};
7
8pub type ImmU8 = Immediate<u8>;
10
11pub type ImmU16 = Immediate<u16>;
13
14pub type ImmU32 = Immediate<u32>;
16
17pub type ImmFelt = Immediate<Felt>;
19
20#[derive(Clone, Debug, Eq, PartialEq)]
22pub enum EventImmediate {
23 Immediate(ImmFelt),
25 Name(Span<Arc<str>>),
27}
28
29impl EventImmediate {
30 pub fn expect_value(&self) -> Felt {
32 match self {
33 Self::Immediate(imm) => imm.expect_value(),
34 Self::Name(name) => {
35 panic!("tried to unwrap unresolved event name: '{}'", name.inner())
36 },
37 }
38 }
39}
40
41impl Spanned for EventImmediate {
42 fn span(&self) -> SourceSpan {
43 match self {
44 Self::Immediate(imm) => imm.span(),
45 Self::Name(name) => name.span(),
46 }
47 }
48}
49
50impl From<ImmFelt> for EventImmediate {
51 fn from(imm: ImmFelt) -> Self {
52 Self::Immediate(imm)
53 }
54}
55
56pub type ErrorMsg = Immediate<Arc<str>>;
58
59pub enum Immediate<T> {
61 Value(Span<T>),
63 Constant(Ident),
69}
70
71impl<T> Immediate<T> {
73 pub fn is_literal(&self) -> bool {
74 matches!(self, Self::Value(_))
75 }
76
77 pub fn with_span(self, span: SourceSpan) -> Self {
79 match self {
80 Self::Constant(id) => Self::Constant(id.with_span(span)),
81 Self::Value(value) => Self::Value(Span::new(span, value.into_inner())),
82 }
83 }
84
85 pub fn map<U, F>(self, map: F) -> Immediate<U>
87 where
88 F: FnMut(T) -> U,
89 {
90 match self {
91 Self::Constant(id) => Immediate::Constant(id),
92 Self::Value(value) => Immediate::Value(value.map(map)),
93 }
94 }
95}
96
97impl<T: Copy> Immediate<T> {
99 pub fn expect_value(&self) -> T {
100 match self {
101 Self::Value(value) => value.into_inner(),
102 Self::Constant(name) => panic!("tried to unwrap unresolved constant: '{name}'"),
103 }
104 }
105
106 pub fn expect_spanned_value(&self) -> Span<T> {
107 match self {
108 Self::Value(value) => *value,
109 Self::Constant(name) => panic!("tried to unwrap unresolved constant: '{name}'"),
110 }
111 }
112}
113
114impl Immediate<Arc<str>> {
115 pub fn expect_string(&self) -> Arc<str> {
116 match self {
117 Self::Value(value) => value.clone().into_inner(),
118 Self::Constant(name) => panic!("tried to unwrap unresolved constant: '{name}'"),
119 }
120 }
121}
122
123impl<T> Spanned for Immediate<T> {
124 fn span(&self) -> SourceSpan {
125 match self {
126 Self::Value(spanned) => spanned.span(),
127 Self::Constant(spanned) => spanned.span(),
128 }
129 }
130}
131
132impl<T> From<T> for Immediate<T> {
133 fn from(value: T) -> Self {
134 Self::Value(Span::unknown(value))
135 }
136}
137
138impl<T> From<Span<T>> for Immediate<T> {
139 fn from(value: Span<T>) -> Self {
140 Self::Value(value)
141 }
142}
143
144impl<T: Clone> Clone for Immediate<T> {
145 fn clone(&self) -> Self {
146 match self {
147 Self::Value(value) => Self::Value(value.clone()),
148 Self::Constant(name) => Self::Constant(name.clone()),
149 }
150 }
151}
152
153impl<T: Eq> Eq for Immediate<T> {}
154
155impl<T: PartialEq> PartialEq for Immediate<T> {
156 fn eq(&self, other: &Self) -> bool {
157 match (self, other) {
158 (Self::Value(l), Self::Value(r)) => l == r,
159 (Self::Constant(l), Self::Constant(r)) => l == r,
160 _ => false,
161 }
162 }
163}
164
165impl<T: PartialEq> PartialEq<T> for Immediate<T> {
166 fn eq(&self, other: &T) -> bool {
167 match self {
168 Self::Value(l) => l == other,
169 _ => false,
170 }
171 }
172}
173
174impl<T: core::hash::Hash> core::hash::Hash for Immediate<T> {
175 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
176 core::mem::discriminant(self).hash(state);
177 match self {
178 Self::Value(v) => v.hash(state),
179 Self::Constant(name) => name.hash(state),
180 }
181 }
182}
183
184impl<T: fmt::Debug> fmt::Debug for Immediate<T> {
185 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
186 match self {
187 Self::Value(value) if f.alternate() => write!(f, "Value({value:#?})"),
188 Self::Value(value) => write!(f, "Value({value:?})"),
189 Self::Constant(name) => write!(f, "Constant({name})"),
190 }
191 }
192}
193
194impl<T: fmt::Display> fmt::Display for Immediate<T> {
195 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
196 match self {
197 Self::Value(value) => write!(f, "{value}"),
198 Self::Constant(name) => write!(f, "{name}"),
199 }
200 }
201}
202
203impl<T: crate::prettier::PrettyPrint> crate::prettier::PrettyPrint for Immediate<T> {
204 fn render(&self) -> crate::prettier::Document {
205 use crate::prettier::*;
206
207 match self {
208 Self::Value(value) => value.render(),
209 Self::Constant(name) => text(name),
210 }
211 }
212}