prism_compiler/lang/
display.rs1use std::fmt::Write;
2
3use crate::lang::UnionIndex;
4use crate::lang::{PartialExpr, TcEnv};
5
6#[derive(Ord, PartialOrd, Eq, PartialEq, Copy, Clone, Default)]
7pub enum PrecedenceLevel {
8 #[default]
9 Let,
10 Construct,
11 FnType,
12 TypeAssert,
13 Destruct,
14 Base,
15}
16
17impl PartialExpr {
18 fn precedence_level(&self) -> PrecedenceLevel {
20 match self {
21 PartialExpr::Let(_, _) => PrecedenceLevel::Let,
22 PartialExpr::FnConstruct(_) => PrecedenceLevel::Construct,
23 PartialExpr::FnType(_, _) => PrecedenceLevel::FnType,
24 PartialExpr::TypeAssert(_, _) => PrecedenceLevel::TypeAssert,
25 PartialExpr::FnDestruct(_, _) => PrecedenceLevel::Destruct,
26 PartialExpr::Free => PrecedenceLevel::Base,
27 PartialExpr::Shift(_, _) => PrecedenceLevel::Base,
28 PartialExpr::Type => PrecedenceLevel::Base,
29 PartialExpr::DeBruijnIndex(_) => PrecedenceLevel::Base,
30 }
31 }
32}
33
34impl TcEnv {
35 fn display(
36 &self,
37 i: UnionIndex,
38 w: &mut impl Write,
39 max_precedence: PrecedenceLevel,
40 ) -> std::fmt::Result {
41 let e = self.values[*i];
42
43 if e.precedence_level() < max_precedence {
44 write!(w, "(")?;
45 }
46
47 match e {
48 PartialExpr::Type => write!(w, "Type")?,
49 PartialExpr::Let(v, b) => {
50 write!(w, "let ")?;
51 self.display(v, w, PrecedenceLevel::Construct)?;
52 writeln!(w, ";")?;
53 self.display(b, w, PrecedenceLevel::Let)?;
54 }
55 PartialExpr::DeBruijnIndex(i) => write!(w, "#{i}")?,
56 PartialExpr::FnType(a, b) => {
57 self.display(a, w, PrecedenceLevel::TypeAssert)?;
58 write!(w, " -> ")?;
59 self.display(b, w, PrecedenceLevel::FnType)?;
60 }
61 PartialExpr::FnConstruct(b) => {
62 write!(w, "=> ")?;
63 self.display(b, w, PrecedenceLevel::Construct)?;
64 }
65 PartialExpr::FnDestruct(a, b) => {
66 self.display(a, w, PrecedenceLevel::Destruct)?;
67 write!(w, " ")?;
68 self.display(b, w, PrecedenceLevel::Base)?;
69 }
70 PartialExpr::Free => write!(w, "{{{}}}", i.0)?,
71 PartialExpr::Shift(v, i) => {
72 write!(w, "([SHIFT {i}] ")?;
73 self.display(v, w, PrecedenceLevel::default())?;
74 write!(w, ")")?;
75 }
76 PartialExpr::TypeAssert(e, typ) => {
77 self.display(e, w, PrecedenceLevel::Destruct)?;
78 write!(w, ": ")?;
79 self.display(typ, w, PrecedenceLevel::Destruct)?;
80 }
81 }
82
83 if e.precedence_level() < max_precedence {
84 write!(w, ")")?;
85 }
86
87 Ok(())
88 }
89
90 pub fn index_to_string(&self, i: UnionIndex) -> String {
91 let mut s = String::new();
92 self.display(i, &mut s, PrecedenceLevel::default())
93 .expect("Writing to String shouldn't fail");
94 s
95 }
96
97 pub fn index_to_sm_string(&mut self, i: UnionIndex) -> String {
98 let i = self.simplify(i);
99 self.index_to_string(i)
100 }
101
102 pub fn index_to_br_string(&mut self, i: UnionIndex) -> String {
103 let i = self.beta_reduce(i);
104 self.index_to_string(i)
105 }
106}