1use crate::{
2 expr::print::{PrettyBuf, PrettyDisplay},
3 typ::Type,
4 PrintFlag, PRINT_FLAGS,
5};
6use netidx::publisher::Typ;
7use std::fmt::{self, Write};
8
9impl fmt::Display for Type {
10 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11 match self {
12 Self::Abstract { id, params: _ } => write!(f, "<abstract#{}>", id.0),
13 Self::Bottom => write!(f, "_"),
14 Self::Any => write!(f, "Any"),
15 Self::Ref { scope: _, name, params } => {
16 write!(f, "{name}")?;
17 if !params.is_empty() {
18 write!(f, "<")?;
19 for (i, t) in params.iter().enumerate() {
20 write!(f, "{t}")?;
21 if i < params.len() - 1 {
22 write!(f, ", ")?;
23 }
24 }
25 write!(f, ">")?;
26 }
27 Ok(())
28 }
29 Self::TVar(tv) => write!(f, "{tv}"),
30 Self::Fn(t) => write!(f, "{t}"),
31 Self::Error(t) => write!(f, "Error<{t}>"),
32 Self::Array(t) => write!(f, "Array<{t}>"),
33 Self::Map { key, value } => write!(f, "Map<{key}, {value}>"),
34 Self::ByRef(t) => write!(f, "&{t}"),
35 Self::Tuple(ts) => {
36 write!(f, "(")?;
37 for (i, t) in ts.iter().enumerate() {
38 write!(f, "{t}")?;
39 if i < ts.len() - 1 {
40 write!(f, ", ")?;
41 }
42 }
43 write!(f, ")")
44 }
45 Self::Variant(tag, ts) if ts.len() == 0 => {
46 write!(f, "`{tag}")
47 }
48 Self::Variant(tag, ts) => {
49 write!(f, "`{tag}(")?;
50 for (i, t) in ts.iter().enumerate() {
51 write!(f, "{t}")?;
52 if i < ts.len() - 1 {
53 write!(f, ", ")?
54 }
55 }
56 write!(f, ")")
57 }
58 Self::Struct(ts) => {
59 write!(f, "{{")?;
60 for (i, (n, t)) in ts.iter().enumerate() {
61 write!(f, "{n}: {t}")?;
62 if i < ts.len() - 1 {
63 write!(f, ", ")?
64 }
65 }
66 write!(f, "}}")
67 }
68 Self::Set(s) => {
69 write!(f, "[")?;
70 for (i, t) in s.iter().enumerate() {
71 write!(f, "{t}")?;
72 if i < s.len() - 1 {
73 write!(f, ", ")?;
74 }
75 }
76 write!(f, "]")
77 }
78 Self::Primitive(s) => {
79 let replace = PRINT_FLAGS.get().contains(PrintFlag::ReplacePrims);
80 if replace && *s == Typ::number() {
81 write!(f, "Number")
82 } else if replace && *s == Typ::float() {
83 write!(f, "Float")
84 } else if replace && *s == Typ::real() {
85 write!(f, "Real")
86 } else if replace && *s == Typ::integer() {
87 write!(f, "Int")
88 } else if replace && *s == Typ::unsigned_integer() {
89 write!(f, "Uint")
90 } else if replace && *s == Typ::signed_integer() {
91 write!(f, "Sint")
92 } else if s.len() == 0 {
93 write!(f, "[]")
94 } else if s.len() == 1 {
95 write!(f, "{}", s.iter().next().unwrap())
96 } else {
97 let mut s = *s;
98 macro_rules! builtin {
99 ($set:expr, $name:literal) => {
100 if replace && s.contains($set) {
101 s.remove($set);
102 write!(f, $name)?;
103 if !s.is_empty() {
104 write!(f, ", ")?
105 }
106 }
107 };
108 }
109 write!(f, "[")?;
110 builtin!(Typ::number(), "Number");
111 builtin!(Typ::real(), "Real");
112 builtin!(Typ::float(), "Float");
113 builtin!(Typ::integer(), "Int");
114 builtin!(Typ::unsigned_integer(), "Uint");
115 builtin!(Typ::signed_integer(), "Sint");
116 for (i, t) in s.iter().enumerate() {
117 write!(f, "{t}")?;
118 if i < s.len() - 1 {
119 write!(f, ", ")?;
120 }
121 }
122 write!(f, "]")
123 }
124 }
125 }
126 }
127}
128
129impl PrettyDisplay for Type {
130 fn fmt_pretty_inner(&self, buf: &mut PrettyBuf) -> fmt::Result {
131 match self {
132 Self::Abstract { .. } => writeln!(buf, "{self}"),
133 Self::Bottom => writeln!(buf, "_"),
134 Self::Any => writeln!(buf, "Any"),
135 Self::Ref { scope: _, name, params } => {
136 if params.is_empty() {
137 writeln!(buf, "{name}")
138 } else {
139 writeln!(buf, "{name}<")?;
140 buf.with_indent(2, |buf| {
141 for (i, t) in params.iter().enumerate() {
142 t.fmt_pretty(buf)?;
143 if i < params.len() - 1 {
144 buf.kill_newline();
145 writeln!(buf, ",")?;
146 }
147 }
148 Ok(())
149 })?;
150 writeln!(buf, ">")
151 }
152 }
153 Self::TVar(tv) => writeln!(buf, "{tv}"),
154 Self::Fn(t) => t.fmt_pretty(buf),
155 Self::Error(t) => {
156 writeln!(buf, "Error<")?;
157 buf.with_indent(2, |buf| t.fmt_pretty(buf))?;
158 writeln!(buf, ">")
159 }
160 Self::Array(t) => {
161 writeln!(buf, "Array<")?;
162 buf.with_indent(2, |buf| t.fmt_pretty(buf))?;
163 writeln!(buf, ">")
164 }
165 Self::Map { key, value } => {
166 writeln!(buf, "Map<")?;
167 buf.with_indent(2, |buf| {
168 key.fmt_pretty(buf)?;
169 buf.kill_newline();
170 writeln!(buf, ",")?;
171 value.fmt_pretty(buf)
172 })?;
173 writeln!(buf, ">")
174 }
175 Self::ByRef(t) => {
176 write!(buf, "&")?;
177 t.fmt_pretty(buf)
178 }
179 Self::Tuple(ts) => {
180 writeln!(buf, "(")?;
181 buf.with_indent(2, |buf| {
182 for (i, t) in ts.iter().enumerate() {
183 t.fmt_pretty(buf)?;
184 if i < ts.len() - 1 {
185 buf.kill_newline();
186 writeln!(buf, ",")?;
187 }
188 }
189 Ok(())
190 })?;
191 writeln!(buf, ")")
192 }
193 Self::Variant(tag, ts) if ts.is_empty() => writeln!(buf, "`{tag}"),
194 Self::Variant(tag, ts) => {
195 writeln!(buf, "`{tag}(")?;
196 buf.with_indent(2, |buf| {
197 for (i, t) in ts.iter().enumerate() {
198 t.fmt_pretty(buf)?;
199 if i < ts.len() - 1 {
200 buf.kill_newline();
201 writeln!(buf, ",")?;
202 }
203 }
204 Ok(())
205 })?;
206 writeln!(buf, ")")
207 }
208 Self::Struct(ts) => {
209 writeln!(buf, "{{")?;
210 buf.with_indent(2, |buf| {
211 for (i, (n, t)) in ts.iter().enumerate() {
212 write!(buf, "{n}: ")?;
213 buf.with_indent(2, |buf| t.fmt_pretty(buf))?;
214 if i < ts.len() - 1 {
215 buf.kill_newline();
216 writeln!(buf, ",")?;
217 }
218 }
219 Ok(())
220 })?;
221 writeln!(buf, "}}")
222 }
223 Self::Set(s) => {
224 writeln!(buf, "[")?;
225 buf.with_indent(2, |buf| {
226 for (i, t) in s.iter().enumerate() {
227 t.fmt_pretty(buf)?;
228 if i < s.len() - 1 {
229 buf.kill_newline();
230 writeln!(buf, ",")?;
231 }
232 }
233 Ok(())
234 })?;
235 writeln!(buf, "]")
236 }
237 Self::Primitive(_) => {
238 writeln!(buf, "{self}")
240 }
241 }
242 }
243}