1use super::*;
2use std::{cell::LazyCell, collections::HashMap};
3use terl::{Span, WithSpan};
4
5#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash)]
6pub struct GroupIdx {
7 pub(crate) idx: usize,
8}
9
10impl GroupIdx {
11 pub fn new(idx: usize) -> Self {
12 Self { idx }
13 }
14}
15
16#[derive(Debug, Clone)]
17pub enum DeclareState {
18 Empty,
19 Declared(usize, Type),
20 Declaring(HashMap<usize, Type>),
21}
22
23impl DeclareState {
24 pub fn alives<'t, A, T: 't>(&'t self, gidx: GroupIdx, active: A) -> T
25 where
26 A: FnOnce(&mut dyn Iterator<Item = (Branch, &'t Type)>) -> T,
27 {
28 let alives: &mut dyn Iterator<Item = (Branch, &Type)> = match self {
29 DeclareState::Empty => &mut std::iter::empty(),
30 DeclareState::Declared(branch, ty) => {
31 &mut std::iter::once((Branch::new(gidx, *branch), ty))
32 }
33 DeclareState::Declaring(alives) => &mut alives
34 .iter()
35 .map(|(branch, ty)| (Branch::new(gidx, *branch), ty)),
36 };
37 active(alives)
38 }
39}
40
41impl From<(usize, Type)> for DeclareState {
42 fn from((v1, v2): (usize, Type)) -> Self {
43 Self::Declared(v1, v2)
44 }
45}
46
47impl From<HashMap<usize, Type>> for DeclareState {
48 fn from(v: HashMap<usize, Type>) -> Self {
49 match v.len() {
50 0 => Self::Empty,
51 1 => {
52 let Some((branch, unique)) = v.into_iter().next() else {
53 unreachable!()
54 };
55 Self::Declared(branch, unique)
56 }
57 _ => Self::Declaring(v),
58 }
59 }
60}
61
62impl FromIterator<Type> for DeclareState {
63 fn from_iter<T: IntoIterator<Item = Type>>(iter: T) -> Self {
64 Self::from_iter(iter.into_iter().enumerate())
65 }
66}
67
68impl FromIterator<(usize, Type)> for DeclareState {
69 fn from_iter<T: IntoIterator<Item = (usize, Type)>>(iter: T) -> Self {
70 let mut iter = iter.into_iter().peekable();
71 let Some(next) = iter.next() else {
72 return Self::Empty;
73 };
74 if iter.peek().is_some() {
75 Self::Declaring(std::iter::once(next).chain(iter).collect())
76 } else {
77 Self::Declared(next.0, next.1)
78 }
79 }
80}
81
82#[derive(Debug, Clone)]
83pub struct DeclareGroup {
84 span: Span,
85 group: GroupIdx,
86 failds: HashMap<usize, DeclareError>,
87 status: DeclareState,
88}
89
90impl DeclareGroup {
91 pub fn new(
92 span: Span,
93 group: GroupIdx,
94 fails: HashMap<usize, DeclareError>,
95 status: DeclareState,
96 ) -> Self {
97 Self {
98 span,
99 group,
100 failds: fails,
101 status,
102 }
103 }
104
105 pub fn push_error(&mut self, at: usize, error: DeclareError) {
106 self.failds.insert(at, error);
107 }
108
109 fn update_state<U>(&mut self, updater: U)
110 where
111 U: FnOnce(DeclareState) -> DeclareState,
112 {
113 let previous = std::mem::replace(&mut self.status, DeclareState::Empty);
114 self.status = updater(previous);
115 }
116
117 pub fn filter_alive<F, C>(&mut self, mut filter: F) -> C
118 where
119 F: FnMut(Branch, Type) -> Result<(Branch, Type), DeclareError>,
120 C: Default + Extend<(Branch, DeclareError)>,
121 {
122 let mut remove = C::default();
123 let belong_to = self.group;
124 let filter_map = |(branch, ty)| {
125 let branch = Branch::new(belong_to, branch);
126 filter(branch, ty)
127 .map_err(|e| remove.extend(Some((branch, e))))
128 .map(|(branch, ty)| (branch.branch_idx, ty))
129 .ok()
130 };
131
132 self.update_state(|state| match state {
133 DeclareState::Empty => DeclareState::Empty,
134 DeclareState::Declared(branch, ty) => {
135 let iter = std::iter::once((branch, ty)).filter_map(filter_map);
136 DeclareState::from_iter(iter)
137 }
138 DeclareState::Declaring(branches) => {
139 let iter = branches.into_iter().filter_map(filter_map);
140 DeclareState::from_iter(iter)
141 }
142 });
143 remove
144 }
145
146 pub fn remove_branch(&mut self, branch: usize, reason: DeclareError) -> DeclareError {
150 let mut new_reason = DeclareError::Empty;
151 self.update_state(|state| match state {
152 DeclareState::Declared(unique, previous) => {
153 if unique == branch {
154 new_reason = reason.with_previous(previous);
155 DeclareState::Empty
156 } else {
157 DeclareState::Declared(unique, previous)
158 }
159 }
160 DeclareState::Declaring(mut items) => {
161 let previous = items.remove(&branch);
162 new_reason = reason.with_previous(previous.unwrap_or_else(|| unreachable!()));
163 items.into()
164 }
165 _ => unreachable!(),
166 });
167 new_reason
168 }
169
170 pub fn remove_branches<F, R>(&mut self, remove_if: F, reason: R) -> Vec<(Branch, DeclareError)>
179 where
180 F: Fn(Branch, &Type) -> bool,
181 R: FnOnce() -> DeclareError,
182 {
183 let reason = LazyCell::new(reason);
184
185 self.filter_alive(move |branch, ty| {
186 if remove_if(branch, &ty) {
187 Err((*reason).clone().with_previous(ty))
188 } else {
189 Ok((branch, ty))
190 }
191 })
192 }
193
194 pub fn alives<'t, A, T: 't>(&'t self, active: A) -> T
195 where
196 A: FnOnce(&mut dyn Iterator<Item = (Branch, &'t Type)>) -> T,
197 {
198 self.status.alives(self.group, active)
199 }
200
201 pub fn is_declared(&self) -> bool {
202 matches!(self.status, DeclareState::Declared(..))
203 }
204
205 pub fn result(&self) -> &Type {
211 match &self.status {
212 DeclareState::Declared(_, ty) => ty,
213 _ => panic!("group is not declared yet"),
214 }
215 }
216
217 pub fn make_error(&self) -> terl::Error {
218 let mut err = <Self as terl::WithSpan>::make_error(self, "cant infer type");
219 match &self.status {
220 DeclareState::Empty => err += "this cant be declared as any type!",
221 DeclareState::Declaring(alives) => {
222 err += "this cant be declared as:";
223 for alives in alives.values() {
224 err += format!("\t{alives}")
225 }
226 }
227 DeclareState::Declared(_, _) => unreachable!(),
228 }
229
230 err.extend(self.failds.values().flat_map(|faild| faild.generate()));
231 err
232 }
233
234 pub fn get_branch(&self, branch: Branch) -> &Type {
238 debug_assert_eq!(
239 branch.belong_to, self.group,
240 "the branch is not belong to this group"
241 );
242
243 let branch = branch.branch_idx;
244 match &self.status {
245 DeclareState::Declared(idx, ty) if *idx == branch => ty,
246 DeclareState::Declaring(alives) if alives.contains_key(&branch) => &alives[&branch],
247 _ => panic!("the branch isnot exist, or faild"),
248 }
249 }
250}
251
252impl WithSpan for DeclareGroup {
253 fn get_span(&self) -> Span {
254 self.span
255 }
256}
257
258pub struct GroupBuilder {
259 pub(crate) span: Span,
260 pub(crate) branches: Vec<BranchesBuilder>,
261}
262
263impl GroupBuilder {
264 pub fn new(span: Span, branches: Vec<BranchesBuilder>) -> GroupBuilder {
265 GroupBuilder { span, branches }
266 }
267}
268
269impl WithSpan for GroupBuilder {
270 fn get_span(&self) -> Span {
271 self.span
272 }
273}