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