miden_assembly_syntax/library/
module.rs1use alloc::{sync::Arc, vec::Vec};
2use core::ops::Index;
3
4use midenc_hir_type::FunctionType;
5
6use crate::{
7 Path, Word,
8 ast::{self, AttributeSet, ConstantValue, Ident, ItemIndex, ProcedureName},
9};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct ModuleInfo {
16 path: Arc<Path>,
17 version: Option<crate::Version>,
20 items: Vec<ItemInfo>,
21}
22
23impl ModuleInfo {
24 pub(crate) fn raw_items(&self) -> &[ItemInfo] {
25 &self.items
26 }
27
28 pub fn new(path: Arc<Path>, version: Option<crate::Version>) -> Self {
33 Self { version, path, items: Vec::new() }
34 }
35
36 pub fn set_version(&mut self, version: crate::Version) {
38 self.version = Some(version);
39 }
40
41 pub fn add_procedure(
43 &mut self,
44 name: ProcedureName,
45 digest: Word,
46 signature: Option<Arc<FunctionType>>,
47 attributes: AttributeSet,
48 ) {
49 self.items
50 .push(ItemInfo::Procedure(ProcedureInfo { name, digest, signature, attributes }));
51 }
52
53 pub fn add_constant(&mut self, name: Ident, value: ConstantValue) {
55 self.items.push(ItemInfo::Constant(ConstantInfo { name, value }));
56 }
57
58 pub fn add_type(&mut self, name: Ident, ty: ast::types::Type) {
60 self.items.push(ItemInfo::Type(TypeInfo { name, ty }));
61 }
62
63 pub fn path(&self) -> &Path {
65 &self.path
66 }
67
68 pub fn num_procedures(&self) -> usize {
70 self.items.iter().filter(|item| matches!(item, ItemInfo::Procedure(_))).count()
71 }
72
73 pub fn get_item_by_index(&self, index: ItemIndex) -> Option<&ItemInfo> {
75 self.items.get(index.as_usize())
76 }
77
78 pub fn get_item_index_by_name(&self, name: &str) -> Option<ItemIndex> {
80 self.items.iter().enumerate().find_map(|(idx, info)| {
81 if info.name().as_str() == name {
82 Some(ItemIndex::new(idx))
83 } else {
84 None
85 }
86 })
87 }
88
89 pub fn get_procedure_by_name(&self, name: &str) -> Option<&ProcedureInfo> {
91 self.items.iter().find_map(|info| match info {
92 ItemInfo::Procedure(proc) if proc.name.as_str() == name => Some(proc),
93 _ => None,
94 })
95 }
96
97 pub fn get_procedure_digest_by_name(&self, name: &str) -> Option<Word> {
99 self.get_procedure_by_name(name).map(|proc| proc.digest)
100 }
101
102 pub fn items(&self) -> impl ExactSizeIterator<Item = (ItemIndex, &ItemInfo)> {
105 self.items.iter().enumerate().map(|(idx, item)| (ItemIndex::new(idx), item))
106 }
107
108 pub fn procedures(&self) -> impl Iterator<Item = (ItemIndex, &ProcedureInfo)> {
111 self.items.iter().enumerate().filter_map(|(idx, item)| match item {
112 ItemInfo::Procedure(proc) => Some((ItemIndex::new(idx), proc)),
113 _ => None,
114 })
115 }
116
117 pub fn procedure_digests(&self) -> impl Iterator<Item = Word> + '_ {
119 self.items.iter().filter_map(|item| match item {
120 ItemInfo::Procedure(proc) => Some(proc.digest),
121 _ => None,
122 })
123 }
124
125 pub fn constants(&self) -> impl Iterator<Item = (ItemIndex, &ConstantInfo)> {
127 self.items.iter().enumerate().filter_map(|(idx, item)| match item {
128 ItemInfo::Constant(info) => Some((ItemIndex::new(idx), info)),
129 _ => None,
130 })
131 }
132
133 pub fn types(&self) -> impl Iterator<Item = (ItemIndex, &TypeInfo)> {
135 self.items.iter().enumerate().filter_map(|(idx, item)| match item {
136 ItemInfo::Type(info) => Some((ItemIndex::new(idx), info)),
137 _ => None,
138 })
139 }
140}
141
142impl Index<ItemIndex> for ModuleInfo {
143 type Output = ItemInfo;
144
145 fn index(&self, index: ItemIndex) -> &Self::Output {
146 &self.items[index.as_usize()]
147 }
148}
149
150#[derive(Debug, Clone, PartialEq, Eq)]
152pub enum ItemInfo {
153 Procedure(ProcedureInfo),
154 Constant(ConstantInfo),
155 Type(TypeInfo),
156}
157
158impl ItemInfo {
159 pub fn name(&self) -> &Ident {
160 match self {
161 Self::Procedure(info) => info.name.as_ref(),
162 Self::Constant(info) => &info.name,
163 Self::Type(info) => &info.name,
164 }
165 }
166
167 pub fn attributes(&self) -> Option<&AttributeSet> {
168 match self {
169 Self::Procedure(info) => Some(&info.attributes),
170 Self::Constant(_) | Self::Type(_) => None,
171 }
172 }
173
174 pub fn unwrap_procedure(&self) -> &ProcedureInfo {
175 match self {
176 Self::Procedure(info) => info,
177 Self::Constant(_) | Self::Type(_) => panic!("expected item to be a procedure"),
178 }
179 }
180}
181
182#[derive(Debug, Clone, PartialEq, Eq)]
184pub struct ProcedureInfo {
185 pub name: ProcedureName,
186 pub digest: Word,
187 pub signature: Option<Arc<FunctionType>>,
188 pub attributes: AttributeSet,
189}
190
191#[derive(Debug, Clone, PartialEq, Eq)]
193pub struct ConstantInfo {
194 pub name: Ident,
195 pub value: ConstantValue,
196}
197
198#[derive(Debug, Clone, PartialEq, Eq)]
200pub struct TypeInfo {
201 pub name: Ident,
202 pub ty: ast::types::Type,
203}