1use super::*;
2use crate::fmt::FmtAdapter;
3use std::{fmt::Display, format_args as fmt};
4
5impl<T: Display + AstNode, A: AstTypes> Display for At<T, A> {
6 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
7 write!(f, "{}", self.0)
8 }
9}
10
11impl<T: AstNode, A: AstTypes> std::fmt::Debug for At<T, A> {
12 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 if f.alternate() {
14 f.write_str("/* ")?;
15 <A::Annotation as std::fmt::Display>::fmt(&self.1, f)?;
16 f.write_str(" */\n")?;
17 }
18 <T as std::fmt::Debug>::fmt(&self.0, f)
19 }
20}
21
22impl<A: AstTypes> std::fmt::Debug for Expr<A> {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 use std::fmt::Debug;
25 match self {
26 Self::Omitted => write!(f, "Omitted"),
27 Self::Id(arg0) => write!(f, "Id({arg0:?})"),
28 Self::MetId(arg0) => write!(f, "MetId({arg0:?})"),
29 Self::Lit(arg0) => write!(f, "Lit({arg0:?})"),
30 Self::Use(arg0) => f.debug_tuple("Use").field(arg0).finish(),
31 Self::Bind(arg0) => Debug::fmt(arg0, f),
32 Self::Make(arg0) => Debug::fmt(arg0, f),
33 Self::Match(arg0) => Debug::fmt(arg0, f),
34 Self::Op(arg0, arg1) => {
35 let mut tup = f.debug_tuple(&format!("{arg0:?}"));
36 for arg in arg1 {
37 tup.field(arg);
38 }
39 tup.finish()
40 }
41 }
42 }
43}
44
45impl<A: AstTypes> std::fmt::Debug for Pat<A> {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 match self {
48 Self::Ignore => write!(f, "Ignore"),
49 Self::Never => write!(f, "Never"),
50 Self::MetId(arg0) => write!(f, "MetId({arg0:?})"),
51 Self::Name(arg0) => write!(f, "Name({arg0:?})"),
52 Self::Value(arg0) => f.debug_tuple("Value").field(arg0).finish(),
53 Self::Op(arg0, arg1) => {
54 let mut tup = f.debug_tuple(&format!("{arg0:?}"));
55 for arg in arg1 {
56 tup.field(arg);
57 }
58 tup.finish()
59 }
60 }
61 }
62}
63
64impl<A: AstTypes> std::fmt::Debug for Bind<A> {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 let Self(op, generics, pat, exprs) = self;
67 f.debug_tuple(&format!("Bind::{op:?}"))
68 .field(generics)
69 .field(pat)
70 .field(exprs)
71 .finish()
72 }
73}
74
75impl<A: AstTypes> Display for Expr<A> {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 match self {
78 Self::Omitted => "...".fmt(f),
79 Self::Id(id) => id.fmt(f),
80 Self::MetId(id) => write!(f, "`{id}"),
81 Self::Lit(literal) => literal.fmt(f),
82 Self::Use(v) => write!(f, "use {v}"),
83 Self::Bind(v) => v.fmt(f),
84 Self::Make(v) => v.fmt(f),
85 Self::Match(v) => v.fmt(f),
86
87 Self::Op(op @ Op::Continue, exprs) => f.delimit(op, "").list(exprs, "!?,"),
88 Self::Op(op @ (Op::If | Op::While), exprs) => match exprs.as_slice() {
89 [cond, pass, At(Expr::Omitted, _)] => {
90 write!(f, "{op}{cond} {pass}")
91 }
92 [cond, pass, fail] => write!(f, "{op}{cond} {pass} else {fail}"),
93 other => f.delimit(fmt!("({op}, "), ")").list(other, ", "),
94 },
95 Self::Op(Op::Array, exprs) => f.delimit("[", "]").list(exprs, ", "),
96 Self::Op(Op::ArRep, exprs) => f.delimit("[", "]").list(exprs, "; "),
97 Self::Op(Op::Block, exprs) => f
98 .delimit_indented("{", "}")
99 .list_wrap("\n", exprs, "\n", "\n"),
100 Self::Op(Op::Group, exprs) if let [At(Expr::Op(Op::Do, _), _)] = &exprs[..] => {
101 f.delimit_indented("(", ")").list(exprs, ";\n")
102 }
103 Self::Op(Op::Quote, exprs) => f.delimit("`", "`").list(exprs, ", "),
104 Self::Op(Op::Group, exprs) => f.delimit("(", ")").list(exprs, ", "),
105 Self::Op(op @ (Op::MetaInner | Op::MetaOuter), exprs) => match &exprs[..] {
106 [meta, expr @ ..] => f.delimit(fmt!("{op}[{meta}]\n"), "").list(expr, ","),
107 [] => write!(f, "{op}[]"),
108 },
109
110 Self::Op(op @ Op::Call, exprs) => match exprs.as_slice() {
111 [callee, At(Expr::Op(Op::Tuple, args), _)] => {
112 f.delimit(fmt!("{callee}("), ")").list(args, ", ")
113 }
114 [callee, args @ ..] => f.delimit(fmt!("{callee}(?"), "?)").list(args, ", "),
115 [] => write!(f, "{op}"),
116 },
117 Self::Op(op @ Op::Index, exprs) => match exprs.as_slice() {
118 [callee, args @ ..] => f.delimit(fmt!("{callee}["), "]").list(args, ", "),
119 [] => write!(f, "{op}"),
120 },
121
122 Self::Op(Op::Tuple, exprs) if exprs.is_empty() => "()".fmt(f),
123 Self::Op(op @ (Op::Do | Op::Tuple | Op::Dot), exprs) => f.list(exprs, op),
124 Self::Op(op @ Op::Macro, exprs) => f.delimit(op, "").list(exprs, " => "),
125 Self::Op(op @ Op::Try, exprs) => f.delimit("(", fmt!("){op}")).list(exprs, ", "),
126 Self::Op(op, exprs) => match exprs.as_slice() {
127 [one] => write!(f, "{op}{one}"),
128 many => f.list(many, op),
129 },
130 }
131 }
132}
133
134impl Display for Op {
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 f.write_str(match self {
137 Op::Do => ";\n",
138 Op::As => " as ",
139 Op::Macro => "macro ",
140 Op::Quote => "`",
141 Op::Block => "{}",
142 Op::Array => "[]",
143 Op::ArRep => "; ",
144 Op::Group => "()",
145 Op::Tuple => ", ",
146 Op::MetaInner => "#!",
147 Op::MetaOuter => "#",
148 Op::Try => "?",
149 Op::Index => "",
150 Op::Call => "",
151 Op::Pub => "pub ",
152 Op::Const => "const ",
153 Op::Static => "static ",
154 Op::Loop => "loop ",
155 Op::If => "if ",
156 Op::While => "while ",
157 Op::Defer => "defer ",
158 Op::Break => "break ",
159 Op::Return => "return ",
160 Op::Continue => "continue",
161 Op::Dot => ".",
162 Op::RangeEx => "..",
163 Op::RangeIn => "..=",
164 Op::Neg => "-",
165 Op::Not => "!",
166 Op::Identity => "!!",
167 Op::Refer => "&",
168 Op::Deref => "*",
169 Op::Mul => " * ",
170 Op::Div => " / ",
171 Op::Rem => " % ",
172 Op::Add => " + ",
173 Op::Sub => " - ",
174 Op::Shl => " << ",
175 Op::Shr => " >> ",
176 Op::And => " & ",
177 Op::Xor => " ^ ",
178 Op::Or => " | ",
179 Op::Lt => " < ",
180 Op::Leq => " <= ",
181 Op::Eq => " == ",
182 Op::Neq => " != ",
183 Op::Geq => " >= ",
184 Op::Gt => " > ",
185 Op::LogAnd => " && ",
186 Op::LogXor => " ^^ ",
187 Op::LogOr => " || ",
188 Op::Set => " = ",
189 Op::MulSet => " *= ",
190 Op::DivSet => " /= ",
191 Op::RemSet => " %= ",
192 Op::AddSet => " += ",
193 Op::SubSet => " -= ",
194 Op::ShlSet => " <<= ",
195 Op::ShrSet => " >>= ",
196 Op::AndSet => " &= ",
197 Op::XorSet => " ^= ",
198 Op::OrSet => " |= ",
199 })
200 }
201}
202
203impl<A: AstTypes> Display for Use<A> {
204 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
205 match self {
206 Self::Glob => "*".fmt(f),
207 Self::Name(name) => name.fmt(f),
208 Self::Alias(name, alias) => write!(f, "{name} as {alias}"),
209 Self::Path(segment, rest) => write!(f, "{segment}::{rest}"),
210 Self::Tree(items) => match items.len() {
211 0 => "{}".fmt(f),
212 1..=3 => f.delimit("{ ", " }").list(items, ", "),
213 _ => f
214 .delimit_indented("{", "}")
215 .list_wrap("\n", items, ",\n", ",\n"),
216 },
217 }
218 }
219}
220
221impl<A: AstTypes> Display for Bind<A> {
222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223 let Self(op, gens, pat, exprs) = self;
224 op.fmt(f)?;
225 if !gens.is_empty() {
226 f.delimit("<", "> ").list(gens, ", ")?;
227 }
228
229 match (op, exprs.as_slice()) {
230 (_, [At(Expr::Omitted, _)]) => write!(f, "{pat}"),
231 (BindOp::Fn | BindOp::Mod | BindOp::Impl, [At(Expr::Op(Op::Block, _), _)]) => {
232 f.delimit(fmt!("{pat} "), "").list(exprs, ",!? ")
233 }
234 (BindOp::Fn, _) => f.delimit(fmt!("{pat} = "), "").list(exprs, ""),
235 (BindOp::Mod | BindOp::Impl, _) => f.delimit(fmt!("{pat} "), "").list(exprs, "!?;"),
236 (BindOp::Struct | BindOp::Enum, _) => match pat.value() {
237 Pat::Op(PatOp::TypePrefixed, bind) => match bind.as_slice() {
239 [name, At(Pat::Op(PatOp::Record, parts), ..)] => f
240 .delimit_indented(fmt!("{name} {{"), "}")
241 .list_wrap("\n", parts, ",\n", ",\n"),
242 [name, At(Pat::Op(PatOp::Tuple, parts), ..)] => {
243 f.delimit(fmt!("{name}("), ")").list(parts, ", ")
244 }
245 _ => pat.fmt(f),
246 },
247 _ => pat.fmt(f),
248 },
249 (BindOp::For, [iter, pass, At(Expr::Omitted, _)]) => {
250 write!(f, "{pat} in {iter} {pass}")
251 }
252 (BindOp::For, [iter, pass, fail]) => write!(f, "{pat} in {iter} {pass} else {fail}"),
253 (BindOp::For, other) => f.delimit(fmt!("{pat} in [["), "]]!?").list(other, ", "),
254 (_, []) => write!(f, "{pat}"),
255 (_, [value]) => write!(f, "{pat} = {value}"),
256 (_, [value, fail]) => write!(f, "{pat} = {value} else {fail}"),
257
258 (_, other) => f.delimit(fmt!("{pat} ("), ")").list(other, ", "),
259 }
260 }
261}
262
263impl Display for BindOp {
264 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
265 f.write_str(match self {
266 Self::Let => "let ",
267 Self::Type => "type ",
268 Self::Struct => "struct ",
269 Self::Enum => "enum ",
270 Self::Fn => "fn ",
271 Self::Mod => "mod ",
272 Self::Impl => "impl ",
273 Self::For => "for ",
274 })
275 }
276}
277
278impl<A: AstTypes> Display for Make<A> {
279 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
280 let Self(expr, make_arms) = self;
281 f.delimit(fmt!("({expr} {{"), "})").list(make_arms, ", ")
282 }
283}
284
285impl<A: AstTypes> Display for MakeArm<A> {
286 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
287 match self {
288 Self(name, Some(body)) => write!(f, "{name}: {body}"),
289 Self(name, None) => write!(f, "{name}"),
290 }
291 }
292}
293
294impl<A: AstTypes> Display for Match<A> {
295 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
296 let Self(scrutinee, arms) = self;
297 f.delimit_indented(fmt!("match {scrutinee} {{"), "}")
298 .list_wrap("\n", arms, ";\n", ";\n")
299 }
300}
301
302impl<A: AstTypes> Display for MatchArm<A> {
303 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
304 let Self(pat, expr) = self;
305 write!(f, "{pat} => {expr}")
306 }
307}
308
309impl<A: AstTypes> Display for Pat<A> {
310 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
311 match self {
312 Self::Ignore => "_".fmt(f),
313 Self::Never => "!".fmt(f),
314 Self::Value(literal) => literal.fmt(f),
315 Self::MetId(name) => write!(f, "`{name}"),
316 Self::Name(name) => name.fmt(f),
317 Self::Op(PatOp::Record, pats) => f
318 .delimit_indented("{", "}")
319 .list_wrap("\n", pats, ",\n", ",\n"),
320 Self::Op(PatOp::Tuple, pats) => f.delimit("(", ")").list(pats, ", "),
321 Self::Op(PatOp::Slice, pats) => f.delimit("[", "]").list(pats, ", "),
322 Self::Op(op @ PatOp::ArRep, pats) => f.delimit("[", "]").list(pats, op),
323 Self::Op(op @ (PatOp::Typed | PatOp::Fn), pats) => match &pats[..] {
324 [fun] => write!(f, "fn {fun}"), pats => f.list(pats, op),
326 },
327 Self::Op(op @ PatOp::Alt, pats) => f.list(pats, op),
328 Self::Op(op @ PatOp::Generic, pats) => match &pats[..] {
329 [] => op.fmt(f),
330 [first, rest @ ..] => f.delimit(fmt!("{first}<"), ">").list(rest, ", "),
331 },
332 Self::Op(op @ PatOp::TypePrefixed, pats) => match &pats[..] {
333 [] => op.fmt(f),
334 [first, rest @ ..] => f.delimit(fmt!("{first}"), "").list(rest, ",? "),
335 },
336
337 Self::Op(op @ (PatOp::MetaInner | PatOp::MetaOuter), pats) => match &pats[..] {
338 [meta, pat @ ..] => f.delimit(fmt!("{op}[{meta}]\n"), "").list(pat, ","),
339 [] => write!(f, "{op}[]"),
340 },
341 Self::Op(op, pats) => match &pats[..] {
342 [] => op.fmt(f),
343 [rest] => write!(f, "{op}{rest}"),
344 _ => f.delimit("(", ")").list(pats, op),
345 },
346 }
347 }
348}
349
350impl Display for PatOp {
351 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
352 f.write_str(match self {
353 Self::MetaInner => "#!",
354 Self::MetaOuter => "#",
355 Self::Pub => "pub ",
356 Self::Mut => "mut ",
357 Self::Ref => "&",
358 Self::Ptr => "*",
359 Self::Rest => "..",
360 Self::RangeEx => "..",
361 Self::RangeIn => "..=",
362 Self::Record => ", ",
363 Self::Tuple => ", ",
364 Self::Slice => ", ",
365 Self::ArRep => "; ",
366 Self::Typed => ": ",
367 Self::Generic => "T<>",
368 Self::TypePrefixed => "T()",
369 Self::Fn => " -> ",
370 Self::Guard => " if ",
371 Self::Alt => " | ",
372 })
373 }
374}