1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use voile_util::uid::GI;
use crate::{
check::{
monad::{TCM, TCS},
rules::{
clause::clause,
data::check_data,
term::{check, HasMeta},
ERROR_MSG,
},
},
syntax::{
abs::AbsDecl,
core::{Decl, FuncInfo, TYPE_OMEGA},
},
};
pub fn check_decls(mut tcs: TCS, decls: Vec<AbsDecl>) -> TCM {
let mut decls = decls.into_iter().map(Some).collect::<Vec<_>>();
let range = 0..decls.len();
let take = |decls: &mut [Option<AbsDecl>], i: usize| decls[i].take().expect(ERROR_MSG);
for i in range {
tcs.enter_def(GI(i));
if decls[i].is_none() {
continue;
}
let decl = take(&mut decls, i);
tcs.tc_reset_depth();
match decl {
AbsDecl::Data(i) => {
let cs = (i.conses.iter())
.map(|GI(j)| match take(&mut decls, *j) {
AbsDecl::Cons(i) => i,
_ => unreachable!(ERROR_MSG),
})
.collect();
tcs = check_data(tcs, i, cs)?;
}
AbsDecl::Cons(_) => unreachable!(ERROR_MSG),
AbsDecl::Defn(i) => {
let (ty, new_tcs) = check(tcs, &i.ty, &TYPE_OMEGA)?;
let (signature, new_tcs) = ty.ast.inline_meta(new_tcs)?;
tcs = new_tcs;
let func = FuncInfo {
loc: i.source,
name: i.name,
signature,
clauses: Vec::with_capacity(2),
};
tcs.sigma.push(Decl::Func(func));
}
AbsDecl::Clause(i) => {
let def_ix = i.definition;
let signature = match tcs.def(def_ix) {
Decl::Func(f) => f.signature.clone(),
_ => unreachable!(),
};
let (cls, new_tcs) = clause(tcs, i, signature)?;
tcs = new_tcs;
match tcs.mut_def(def_ix) {
Decl::Func(f) => f.clauses.push(cls),
_ => unreachable!(),
};
tcs.sigma.push(Decl::ClausePlaceholder);
}
_ => unimplemented!(),
}
tcs.exit_def();
tcs.sanity_check();
}
Ok(tcs)
}