bend/fun/transform/
desugar_open.rs1use crate::{
2 diagnostics::Diagnostics,
3 fun::{Adts, Ctx, Term},
4 maybe_grow,
5};
6
7impl Ctx<'_> {
8 pub fn desugar_open(&mut self) -> Result<(), Diagnostics> {
9 for def in self.book.defs.values_mut() {
10 for rule in def.rules.iter_mut() {
11 if let Err(err) = rule.body.desugar_open(&self.book.adts) {
12 self.info.add_function_error(err, def.name.clone(), def.source.clone());
13 }
14 }
15 }
16
17 self.info.fatal(())
18 }
19}
20
21impl Term {
22 fn desugar_open(&mut self, adts: &Adts) -> Result<(), String> {
23 maybe_grow(|| {
24 match self {
25 Term::Open { typ, var, bod } => {
26 bod.desugar_open(adts)?;
27 if let Some(adt) = adts.get(&*typ) {
28 if adt.ctrs.len() == 1 {
29 let ctr = adt.ctrs.keys().next().unwrap();
30 *self = Term::Mat {
31 arg: Box::new(Term::Var { nam: var.clone() }),
32 bnd: Some(std::mem::take(var)),
33 with_bnd: vec![],
34 with_arg: vec![],
35 arms: vec![(Some(ctr.clone()), vec![], std::mem::take(bod))],
36 }
37 } else {
38 return Err(format!("Type '{typ}' of an 'open' has more than one constructor"));
39 }
40 } else {
41 return Err(format!("Type '{typ}' of an 'open' is not defined"));
42 }
43 }
44 Term::Def { def, nxt } => {
45 for rule in def.rules.iter_mut() {
46 rule.body.desugar_open(adts)?;
47 }
48 nxt.desugar_open(adts)?;
49 }
50 _ => {
51 for child in self.children_mut() {
52 child.desugar_open(adts)?;
53 }
54 }
55 }
56 Ok(())
57 })
58 }
59}