Skip to main content

lisette_syntax/
display.rs

1use std::fmt;
2
3use crate::types::Type;
4
5impl Type {
6    pub fn stringify(&self) -> String {
7        match self {
8            Type::Nominal {
9                id, params: args, ..
10            } => {
11                let args_formatted = args
12                    .iter()
13                    .map(|a| a.stringify())
14                    .collect::<Vec<_>>()
15                    .join(", ");
16
17                let name = id.last_segment();
18
19                if name == "Unit" {
20                    return "()".to_string();
21                }
22
23                if name == "bool" {
24                    return "bool".to_string();
25                }
26
27                if name.starts_with("Tuple") {
28                    return format!("({})", args_formatted);
29                }
30
31                if name == "Ref" {
32                    return format!("Ref<{}>", args_formatted);
33                }
34
35                if args.is_empty() {
36                    return name.to_string();
37                }
38
39                format!("{}<{}>", name, args_formatted)
40            }
41
42            Type::Var { id, hint } => match hint {
43                Some(name) => format!("?{}", name),
44                None => format!("?{}", id.as_u32()),
45            },
46
47            Type::Function(f) => {
48                let args_formatted = f
49                    .params
50                    .iter()
51                    .enumerate()
52                    .map(|(i, a)| {
53                        let is_mut = f.param_mutability.get(i).copied().unwrap_or(false);
54                        if is_mut {
55                            format!("mut {}", a.stringify())
56                        } else {
57                            a.stringify()
58                        }
59                    })
60                    .collect::<Vec<_>>()
61                    .join(", ");
62
63                let ret_formatted = f.return_type.stringify();
64
65                format!("fn ({}) -> {}", args_formatted, ret_formatted)
66            }
67
68            Type::Forall { .. } => {
69                unreachable!("Forall types are always instantiated before display")
70            }
71
72            Type::Parameter(name) => name.to_string(),
73
74            Type::Never => "Never".to_string(),
75
76            Type::Tuple(elements) => {
77                let formatted = elements
78                    .iter()
79                    .map(|e| e.stringify())
80                    .collect::<Vec<_>>()
81                    .join(", ");
82                format!("({})", formatted)
83            }
84
85            Type::Error => "<error>".to_string(),
86
87            Type::ImportNamespace(module_id) => {
88                let path = module_id.strip_prefix("go:").unwrap_or(module_id);
89                path.rsplit('/').next().unwrap_or(module_id).to_string()
90            }
91
92            Type::ReceiverPlaceholder => "self".to_string(),
93
94            Type::Simple(kind) => match kind {
95                crate::types::SimpleKind::Unit => "()".to_string(),
96                _ => kind.leaf_name().to_string(),
97            },
98
99            Type::Compound { kind, args } => {
100                let args_formatted = args
101                    .iter()
102                    .map(|a| a.stringify())
103                    .collect::<Vec<_>>()
104                    .join(", ");
105                if args.is_empty() {
106                    kind.leaf_name().to_string()
107                } else {
108                    format!("{}<{}>", kind.leaf_name(), args_formatted)
109                }
110            }
111        }
112    }
113}
114
115impl fmt::Display for Type {
116    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117        let (types, _generics) = Self::remove_vars(&[self]);
118        write!(f, "{}", types[0].stringify())
119    }
120}