1use crate::{
2 uris::{ModuleURI, SymbolURI}, LocalBackend, MaybeResolved, Unchecked
3};
4
5use super::{
6 declarations::{
7 morphisms::Morphism,
8 structures::{Extension, MathStructure},
9 Declaration, OpenDeclaration
10 },
11 modules::NestedModule,
12};
13
14pub trait ModuleChecker: LocalBackend {
15 fn open(&mut self, elem: &mut OpenDeclaration<Unchecked>);
16 fn close(&mut self, elem: &mut Declaration);
17}
18
19enum Elem {
20 Extension(SymbolURI, SymbolURI),
21 NestedModule(SymbolURI),
22 MathStructure {
23 uri: SymbolURI,
24 macroname: Option<Box<str>>,
25 },
26 Morphism {
27 uri: SymbolURI,
28 domain: ModuleURI,
29 total: bool,
30 },
31}
32
33impl Elem {
34 fn close(self, v: Vec<Declaration>, checker: &mut impl ModuleChecker) -> Declaration {
35 match self {
36 Self::Extension(uri, target) => {
37 let target = MaybeResolved::resolve(target,|m| checker.get_declaration(m));
39 Declaration::Extension(Extension {
40 uri,
41 target,
42 elements: v.into_boxed_slice(),
43 })
44 }
45 Self::NestedModule(uri) => {
46 Declaration::NestedModule(NestedModule {
48 uri,
49 elements: v.into_boxed_slice(),
50 })
51 }
52 Self::MathStructure { uri, macroname } => {
53 Declaration::MathStructure(MathStructure {
55 uri,
56 macroname,
57 elements: v.into_boxed_slice(),
58 })
59 }
60 Self::Morphism { uri, domain, total } => {
61 let domain = MaybeResolved::resolve(domain,|d| checker.get_module(d));
63 Declaration::Morphism(Morphism {
64 uri,
65 domain,
66 total,
67 elements: v.into_boxed_slice(),
68 })
69 }
70 }
71 }
72}
73
74pub(super) struct ModuleCheckIter<'a, Check: ModuleChecker> {
75 stack: Vec<(
76 Elem,
77 std::vec::IntoIter<OpenDeclaration<Unchecked>>,
78 Vec<Declaration>,
79 )>,
80 curr_in: std::vec::IntoIter<OpenDeclaration<Unchecked>>,
81 curr_out: Vec<Declaration>,
82 checker: &'a mut Check,
83 uri: &'a ModuleURI,
84}
85impl<Check: ModuleChecker> ModuleCheckIter<'_, Check> {
86 pub fn go(
87 elems: Vec<OpenDeclaration<Unchecked>>,
88 checker: &mut Check,
89 uri: &ModuleURI,
90 ) -> Vec<Declaration> {
91 let mut slf = ModuleCheckIter {
92 stack: Vec::new(),
93 curr_in: elems.into_iter(),
94 curr_out: Vec::new(),
95 checker,
96 uri,
97 };
98 loop {
99 while let Some(next) = slf.curr_in.next() {
100 slf.do_elem(next);
101 }
102 if let Some((e, curr_in, curr_out)) = slf.stack.pop() {
103 slf.curr_in = curr_in;
104 let dones = std::mem::replace(&mut slf.curr_out, curr_out);
105 let mut closed = e.close(dones, slf.checker);
106 slf.checker.close(&mut closed);
107 slf.curr_out.push(closed);
108 } else {
109 return slf.curr_out;
110 }
111 }
112 }
113
114 fn do_elem(&mut self, mut e: OpenDeclaration<Unchecked>) {
115 self.checker.open(&mut e);
116 match e {
117 OpenDeclaration::Import(uri) => {
118 let m = if !uri.clone() == *self.uri {
120 MaybeResolved::unresolved(uri)
121 } else {
122 MaybeResolved::resolve(uri,|u| self.checker.get_module(u))
123 };
124 let mut m = Declaration::Import(m);
125 self.checker.close(&mut m);
126 self.curr_out.push(m);
127 }
128 OpenDeclaration::Symbol(s) => {
129 let mut m = Declaration::Symbol(s);
130 self.checker.close(&mut m);
131 self.curr_out.push(m);
132 }
133 OpenDeclaration::Extension(Extension {
134 target,
135 uri,
136 elements,
137 }) => {
138 let old_in = std::mem::replace(&mut self.curr_in, elements.into_iter());
139 let old_out = std::mem::take(&mut self.curr_out);
140 self.stack
141 .push((Elem::Extension(uri, target), old_in, old_out));
142 }
143 OpenDeclaration::NestedModule(NestedModule { uri, elements }) => {
144 let old_in = std::mem::replace(&mut self.curr_in, elements.into_iter());
145 let old_out = std::mem::take(&mut self.curr_out);
146 self.stack.push((Elem::NestedModule(uri), old_in, old_out));
147 }
148 OpenDeclaration::MathStructure(MathStructure {
149 uri,
150 macroname,
151 elements,
152 }) => {
153 let old_in = std::mem::replace(&mut self.curr_in, elements.into_iter());
154 let old_out = std::mem::take(&mut self.curr_out);
155 self.stack
156 .push((Elem::MathStructure { uri, macroname }, old_in, old_out));
157 }
158 OpenDeclaration::Morphism(Morphism {
159 uri,
160 domain,
161 total,
162 elements,
163 }) => {
164 let old_in = std::mem::replace(&mut self.curr_in, elements.into_iter());
165 let old_out = std::mem::take(&mut self.curr_out);
166 self.stack
167 .push((Elem::Morphism { uri, domain, total }, old_in, old_out));
168 }
169 }
170 }
171}