miden_assembly_syntax/ast/
type.rs1use alloc::{string::String, vec::Vec};
2
3use miden_debug_types::{SourceSpan, Span, Spanned};
4pub use midenc_hir_type as types;
5use midenc_hir_type::Type;
6
7use super::{ConstantExpr, DocString, Ident};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum TypeDecl {
12 Alias(TypeAlias),
14 Enum(EnumType),
16}
17
18impl TypeDecl {
19 pub fn name(&self) -> &Ident {
20 match self {
21 Self::Alias(ty) => &ty.name,
22 Self::Enum(ty) => &ty.name,
23 }
24 }
25
26 pub fn ty(&self) -> &Type {
27 match self {
28 Self::Alias(ty) => &ty.ty,
29 Self::Enum(ty) => &ty.ty,
30 }
31 }
32}
33
34impl Spanned for TypeDecl {
35 fn span(&self) -> SourceSpan {
36 match self {
37 Self::Alias(spanned) => spanned.span,
38 Self::Enum(spanned) => spanned.span,
39 }
40 }
41}
42
43impl From<TypeAlias> for TypeDecl {
44 fn from(value: TypeAlias) -> Self {
45 Self::Alias(value)
46 }
47}
48
49impl From<EnumType> for TypeDecl {
50 fn from(value: EnumType) -> Self {
51 Self::Enum(value)
52 }
53}
54
55#[derive(Debug, Clone)]
61pub struct TypeAlias {
62 span: SourceSpan,
63 docs: Option<DocString>,
65 pub name: Ident,
67 pub ty: Type,
69}
70
71impl TypeAlias {
72 pub fn new(name: Ident, ty: Type) -> Self {
74 Self { span: name.span(), docs: None, name, ty }
75 }
76
77 pub fn with_docs(mut self, docs: Option<Span<String>>) -> Self {
79 self.docs = docs.map(DocString::new);
80 self
81 }
82
83 #[inline]
85 pub fn with_span(mut self, span: SourceSpan) -> Self {
86 self.span = span;
87 self
88 }
89
90 #[inline]
92 pub fn set_span(&mut self, span: SourceSpan) {
93 self.span = span;
94 }
95}
96
97impl Spanned for TypeAlias {
98 fn span(&self) -> SourceSpan {
99 self.span
100 }
101}
102
103impl Eq for TypeAlias {}
104
105impl PartialEq for TypeAlias {
106 fn eq(&self, other: &Self) -> bool {
107 self.name == other.name && self.docs == other.docs && self.ty == other.ty
108 }
109}
110
111impl core::hash::Hash for TypeAlias {
112 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
113 let Self { span: _, docs, name, ty } = self;
114 docs.hash(state);
115 name.hash(state);
116 ty.hash(state);
117 }
118}
119
120#[derive(Debug, Clone)]
131pub struct EnumType {
132 span: SourceSpan,
133 docs: Option<DocString>,
135 name: Ident,
137 ty: Type,
141 variants: Vec<Variant>,
143}
144
145impl EnumType {
146 pub fn new(name: Ident, ty: Type, variants: impl IntoIterator<Item = Variant>) -> Self {
151 assert!(ty.is_integer(), "only integer types are allowed in enum type definitions");
152 Self {
153 span: name.span(),
154 docs: None,
155 name,
156 ty,
157 variants: Vec::from_iter(variants),
158 }
159 }
160
161 pub fn with_docs(mut self, docs: Option<Span<String>>) -> Self {
163 self.docs = docs.map(DocString::new);
164 self
165 }
166
167 pub fn with_span(mut self, span: SourceSpan) -> Self {
169 self.span = span;
170 self
171 }
172
173 pub fn set_span(&mut self, span: SourceSpan) {
175 self.span = span;
176 }
177
178 pub fn name(&self) -> &Ident {
180 &self.name
181 }
182
183 pub fn ty(&self) -> &Type {
185 &self.ty
186 }
187
188 pub fn variants(&self) -> &[Variant] {
190 &self.variants
191 }
192
193 pub fn into_parts(self) -> (TypeAlias, Vec<Variant>) {
195 let Self { span, docs, name, ty, variants } = self;
196 let alias = TypeAlias { span, docs, name, ty };
197 (alias, variants)
198 }
199}
200
201impl Spanned for EnumType {
202 fn span(&self) -> SourceSpan {
203 self.span
204 }
205}
206
207impl Eq for EnumType {}
208
209impl PartialEq for EnumType {
210 fn eq(&self, other: &Self) -> bool {
211 self.name == other.name
212 && self.docs == other.docs
213 && self.ty == other.ty
214 && self.variants == other.variants
215 }
216}
217
218impl core::hash::Hash for EnumType {
219 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
220 let Self { span: _, docs, name, ty, variants } = self;
221 docs.hash(state);
222 name.hash(state);
223 ty.hash(state);
224 variants.hash(state);
225 }
226}
227
228#[derive(Debug, Clone)]
232pub struct Variant {
233 pub span: SourceSpan,
234 pub docs: Option<DocString>,
236 pub name: Ident,
238 pub discriminant: ConstantExpr,
240}
241
242impl Variant {
243 pub fn new(name: Ident, discriminant: impl Into<ConstantExpr>) -> Self {
245 Self {
246 span: name.span(),
247 docs: None,
248 name,
249 discriminant: discriminant.into(),
250 }
251 }
252
253 pub fn with_docs(mut self, docs: Option<Span<String>>) -> Self {
255 self.docs = docs.map(DocString::new);
256 self
257 }
258}
259
260impl Spanned for Variant {
261 fn span(&self) -> SourceSpan {
262 self.span
263 }
264}
265
266impl Eq for Variant {}
267
268impl PartialEq for Variant {
269 fn eq(&self, other: &Self) -> bool {
270 self.name == other.name
271 && self.discriminant == other.discriminant
272 && self.docs == other.docs
273 }
274}
275
276impl core::hash::Hash for Variant {
277 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
278 let Self { span: _, docs, name, discriminant } = self;
279 docs.hash(state);
280 name.hash(state);
281 discriminant.hash(state);
282 }
283}