prism_compiler/lang/
simplify.rs

1use crate::lang::env::{Env, EnvEntry, UniqueVariableId};
2use crate::lang::UnionIndex;
3use crate::lang::{PartialExpr, TcEnv};
4use std::collections::HashMap;
5
6impl TcEnv {
7    pub fn simplify(&mut self, i: UnionIndex) -> UnionIndex {
8        self.simplify_inner(i, &Env::new(), &mut HashMap::new())
9    }
10
11    fn simplify_inner(
12        &mut self,
13        i: UnionIndex,
14        s: &Env,
15        var_map: &mut HashMap<UniqueVariableId, usize>,
16    ) -> UnionIndex {
17        let e_new = match self.values[*i] {
18            PartialExpr::Type => PartialExpr::Type,
19            PartialExpr::Let(v, b) => {
20                let v = self.simplify_inner(v, s, var_map);
21                let id = self.new_tc_id();
22                var_map.insert(id, var_map.len());
23                let b = self.simplify_inner(b, &s.cons(EnvEntry::RType(id)), var_map);
24                var_map.remove(&id);
25                PartialExpr::Let(v, b)
26            }
27            PartialExpr::DeBruijnIndex(v) => match s.get(v) {
28                Some(EnvEntry::CType(_, _)) | Some(EnvEntry::CSubst(_, _)) => unreachable!(),
29                Some(EnvEntry::RType(id)) => {
30                    PartialExpr::DeBruijnIndex(var_map.len() - var_map[id] - 1)
31                }
32                Some(EnvEntry::RSubst(subst, subst_env)) => {
33                    return self.simplify_inner(*subst, subst_env, var_map)
34                }
35                None => PartialExpr::DeBruijnIndex(v),
36            },
37            PartialExpr::FnType(a, b) => {
38                let a = self.simplify_inner(a, s, var_map);
39                let id = self.new_tc_id();
40                var_map.insert(id, var_map.len());
41                let b = self.simplify_inner(b, &s.cons(EnvEntry::RType(id)), var_map);
42                var_map.remove(&id);
43                PartialExpr::FnType(a, b)
44            }
45            PartialExpr::FnConstruct(b) => {
46                let id = self.new_tc_id();
47                var_map.insert(id, var_map.len());
48                let b = self.simplify_inner(b, &s.cons(EnvEntry::RType(id)), var_map);
49                var_map.remove(&id);
50                PartialExpr::FnConstruct(b)
51            }
52            PartialExpr::FnDestruct(a, b) => {
53                let a = self.simplify_inner(a, s, var_map);
54                let b = self.simplify_inner(b, s, var_map);
55                PartialExpr::FnDestruct(a, b)
56            }
57            PartialExpr::Free => PartialExpr::Free,
58            PartialExpr::Shift(b, i) => {
59                return self.simplify_inner(b, &s.shift(i.min(s.len())), var_map)
60            }
61            PartialExpr::TypeAssert(e, typ) => {
62                let e = self.simplify_inner(e, s, var_map);
63                let typ = self.simplify_inner(typ, s, var_map);
64                PartialExpr::TypeAssert(e, typ)
65            }
66        };
67        self.store(e_new, self.value_origins[*i])
68    }
69}