miden_assembly_syntax/ast/procedure/
resolver.rs1use alloc::{collections::BTreeMap, vec::Vec};
2
3use miden_debug_types::{SourceSpan, Span, Spanned};
4
5use super::{ProcedureIndex, ProcedureName, QualifiedProcedureName};
6use crate::{LibraryPath, Word, ast::Ident};
7
8#[derive(Debug, Clone)]
13pub enum ResolvedProcedure {
14 Local(Span<ProcedureIndex>),
16 External(QualifiedProcedureName),
18 MastRoot(Word),
20}
21
22impl Spanned for ResolvedProcedure {
23 fn span(&self) -> SourceSpan {
24 match self {
25 ResolvedProcedure::Local(p) => p.span(),
26 ResolvedProcedure::External(p) => p.span(),
27 ResolvedProcedure::MastRoot(_) => SourceSpan::default(),
28 }
29 }
30}
31
32pub struct LocalNameResolver {
37 imports: BTreeMap<Ident, Span<LibraryPath>>,
38 resolved: BTreeMap<ProcedureName, ProcedureIndex>,
39 resolutions: Vec<ResolvedProcedure>,
40}
41
42impl LocalNameResolver {
43 pub fn resolve(&self, name: &ProcedureName) -> Option<ResolvedProcedure> {
45 self.resolved
46 .get(name)
47 .copied()
48 .map(|index| self.resolutions[index.as_usize()].clone())
49 }
50
51 pub fn resolve_import(&self, name: &Ident) -> Option<Span<&LibraryPath>> {
53 self.imports.get(name).map(|spanned| spanned.as_ref())
54 }
55
56 pub fn get_name(&self, index: ProcedureIndex) -> &ProcedureName {
60 self.resolved
61 .iter()
62 .find_map(|(k, v)| if v == &index { Some(k) } else { None })
63 .expect("invalid procedure index")
64 }
65
66 pub fn with_imports<I>(mut self, imports: I) -> Self
68 where
69 I: IntoIterator<Item = (Ident, Span<LibraryPath>)>,
70 {
71 self.imports.extend(imports);
72 self
73 }
74}
75
76impl FromIterator<(ProcedureName, ResolvedProcedure)> for LocalNameResolver {
77 fn from_iter<T>(iter: T) -> Self
79 where
80 T: IntoIterator<Item = (ProcedureName, ResolvedProcedure)>,
81 {
82 let mut resolver = Self {
83 imports: Default::default(),
84 resolved: Default::default(),
85 resolutions: Default::default(),
86 };
87 for (name, resolution) in iter {
88 let index = ProcedureIndex::new(resolver.resolutions.len());
89 resolver.resolutions.push(resolution);
90 resolver.resolved.insert(name, index);
91 }
92 resolver
93 }
94}