prism_compiler/lang/
display.rs

1use 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    /// Returns the precedence level of a `PartialExpr`
19    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}