prism_compiler/lang/
simplify.rs1use 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}