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
20pub type ErrorMsg = Immediate<Arc<str>>;
22
23pub enum Immediate<T> {
25 Value(Span<T>),
27 Constant(Ident),
34}
35
36impl<T> Immediate<T> {
38 pub fn is_literal(&self) -> bool {
39 matches!(self, Self::Value(_))
40 }
41
42 pub fn with_span(self, span: SourceSpan) -> Self {
44 match self {
45 Self::Constant(id) => Self::Constant(id.with_span(span)),
46 Self::Value(value) => Self::Value(Span::new(span, value.into_inner())),
47 }
48 }
49
50 pub fn map<U, F>(self, map: F) -> Immediate<U>
52 where
53 F: FnMut(T) -> U,
54 {
55 match self {
56 Self::Constant(id) => Immediate::Constant(id),
57 Self::Value(value) => Immediate::Value(value.map(map)),
58 }
59 }
60}
61
62impl<T: Copy> Immediate<T> {
64 pub fn expect_value(&self) -> T {
65 match self {
66 Self::Value(value) => value.into_inner(),
67 Self::Constant(name) => panic!("tried to unwrap unresolved constant: '{name}'"),
68 }
69 }
70
71 pub fn expect_spanned_value(&self) -> Span<T> {
72 match self {
73 Self::Value(value) => *value,
74 Self::Constant(name) => panic!("tried to unwrap unresolved constant: '{name}'"),
75 }
76 }
77}
78
79impl Immediate<Arc<str>> {
80 pub fn expect_string(&self) -> Arc<str> {
81 match self {
82 Self::Value(value) => value.clone().into_inner(),
83 Self::Constant(name) => panic!("tried to unwrap unresolved constant: '{name}'"),
84 }
85 }
86}
87
88impl<T> Spanned for Immediate<T> {
89 fn span(&self) -> SourceSpan {
90 match self {
91 Self::Value(spanned) => spanned.span(),
92 Self::Constant(spanned) => spanned.span(),
93 }
94 }
95}
96
97impl<T> From<T> for Immediate<T> {
98 fn from(value: T) -> Self {
99 Self::Value(Span::unknown(value))
100 }
101}
102
103impl<T> From<Span<T>> for Immediate<T> {
104 fn from(value: Span<T>) -> Self {
105 Self::Value(value)
106 }
107}
108
109impl<T: Clone> Clone for Immediate<T> {
110 fn clone(&self) -> Self {
111 match self {
112 Self::Value(value) => Self::Value(value.clone()),
113 Self::Constant(name) => Self::Constant(name.clone()),
114 }
115 }
116}
117
118impl<T: Eq> Eq for Immediate<T> {}
119
120impl<T: PartialEq> PartialEq for Immediate<T> {
121 fn eq(&self, other: &Self) -> bool {
122 match (self, other) {
123 (Self::Value(l), Self::Value(r)) => l == r,
124 (Self::Constant(l), Self::Constant(r)) => l == r,
125 _ => false,
126 }
127 }
128}
129
130impl<T: PartialEq> PartialEq<T> for Immediate<T> {
131 fn eq(&self, other: &T) -> bool {
132 match self {
133 Self::Value(l) => l == other,
134 _ => false,
135 }
136 }
137}
138
139impl<T: core::hash::Hash> core::hash::Hash for Immediate<T> {
140 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
141 core::mem::discriminant(self).hash(state);
142 match self {
143 Self::Value(v) => v.hash(state),
144 Self::Constant(name) => name.hash(state),
145 }
146 }
147}
148
149impl<T: fmt::Debug> fmt::Debug for Immediate<T> {
150 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
151 match self {
152 Self::Value(value) if f.alternate() => write!(f, "Value({value:#?})"),
153 Self::Value(value) => write!(f, "Value({value:?})"),
154 Self::Constant(name) => write!(f, "Constant({name})"),
155 }
156 }
157}
158
159impl<T: fmt::Display> fmt::Display for Immediate<T> {
160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161 match self {
162 Self::Value(value) => write!(f, "{value}"),
163 Self::Constant(name) => write!(f, "{name}"),
164 }
165 }
166}
167
168impl<T: crate::prettier::PrettyPrint> crate::prettier::PrettyPrint for Immediate<T> {
169 fn render(&self) -> crate::prettier::Document {
170 use crate::prettier::*;
171
172 match self {
173 Self::Value(value) => value.render(),
174 Self::Constant(name) => text(name),
175 }
176 }
177}