1use super::functions::*;
6use crate::ast_impl::*;
7use std::fmt::{self, Write};
8
9#[derive(Clone, Debug, Default, PartialEq, Eq)]
11pub enum ParensMode {
12 #[default]
14 Minimal,
15 Full,
17}
18#[allow(dead_code)]
20#[allow(missing_docs)]
21pub struct ColumnLayout {
22 pub widths: Vec<usize>,
24}
25impl ColumnLayout {
26 #[allow(dead_code)]
28 pub fn new(widths: Vec<usize>) -> Self {
29 ColumnLayout { widths }
30 }
31 #[allow(dead_code)]
33 pub fn total_width(&self, sep_width: usize) -> usize {
34 let sum: usize = self.widths.iter().sum();
35 sum + sep_width * self.widths.len().saturating_sub(1)
36 }
37 #[allow(dead_code)]
39 pub fn num_cols(&self) -> usize {
40 self.widths.len()
41 }
42}
43#[derive(Clone, Debug)]
45pub struct PrettyConfig {
46 pub max_width: usize,
48 pub indent_size: usize,
50 pub show_implicit: bool,
52 pub show_universes: bool,
54 pub use_unicode: bool,
56 pub use_notation: bool,
58 pub parens_mode: ParensMode,
60}
61impl PrettyConfig {
62 #[allow(dead_code)]
64 pub fn new() -> Self {
65 Self::default()
66 }
67 #[allow(dead_code)]
69 pub fn with_max_width(mut self, width: usize) -> Self {
70 self.max_width = width;
71 self
72 }
73 #[allow(dead_code)]
75 pub fn with_indent_size(mut self, size: usize) -> Self {
76 self.indent_size = size;
77 self
78 }
79 #[allow(dead_code)]
81 pub fn with_show_implicit(mut self, show: bool) -> Self {
82 self.show_implicit = show;
83 self
84 }
85 #[allow(dead_code)]
87 pub fn with_show_universes(mut self, show: bool) -> Self {
88 self.show_universes = show;
89 self
90 }
91 #[allow(dead_code)]
93 pub fn with_unicode(mut self, unicode: bool) -> Self {
94 self.use_unicode = unicode;
95 self
96 }
97 #[allow(dead_code)]
99 pub fn with_notation(mut self, notation: bool) -> Self {
100 self.use_notation = notation;
101 self
102 }
103 #[allow(dead_code)]
105 pub fn with_parens_mode(mut self, mode: ParensMode) -> Self {
106 self.parens_mode = mode;
107 self
108 }
109}
110#[derive(Clone, Debug)]
112#[allow(dead_code)]
113struct NotationEntry {
114 func_name: String,
116 symbol: String,
118 precedence: u32,
120 is_infix: bool,
122}
123pub struct PrettyPrinter {
125 indent: usize,
127 buffer: String,
129 pub(super) config: PrettyConfig,
131 #[allow(dead_code)]
133 notations: Vec<NotationEntry>,
134}
135impl PrettyPrinter {
136 pub fn new() -> Self {
138 Self {
139 indent: 0,
140 buffer: String::new(),
141 config: PrettyConfig::default(),
142 notations: Vec::new(),
143 }
144 }
145 #[allow(dead_code)]
147 pub fn with_config(config: PrettyConfig) -> Self {
148 Self {
149 indent: 0,
150 buffer: String::new(),
151 config,
152 notations: Vec::new(),
153 }
154 }
155 pub fn output(self) -> String {
157 self.buffer
158 }
159 #[allow(dead_code)]
161 fn current_len(&self) -> usize {
162 self.buffer.len()
163 }
164 #[allow(dead_code)]
166 fn current_column(&self) -> usize {
167 match self.buffer.rfind('\n') {
168 Some(idx) => self.buffer.len() - idx - 1,
169 None => self.buffer.len(),
170 }
171 }
172 #[allow(dead_code)]
174 pub fn register_notation(
175 &mut self,
176 func_name: &str,
177 symbol: &str,
178 precedence: u32,
179 is_infix: bool,
180 ) {
181 self.notations.push(NotationEntry {
182 func_name: func_name.to_string(),
183 symbol: symbol.to_string(),
184 precedence,
185 is_infix,
186 });
187 }
188 fn arrow(&self) -> &str {
190 if self.config.use_unicode {
191 "\u{2192}"
192 } else {
193 "->"
194 }
195 }
196 fn forall_sym(&self) -> &str {
198 if self.config.use_unicode {
199 "\u{2200}"
200 } else {
201 "forall"
202 }
203 }
204 fn lambda_sym(&self) -> &str {
206 if self.config.use_unicode {
207 "\u{03bb}"
208 } else {
209 "fun"
210 }
211 }
212 #[allow(dead_code)]
214 fn prod_sym(&self) -> &str {
215 if self.config.use_unicode {
216 "\u{00d7}"
217 } else {
218 "Prod"
219 }
220 }
221 #[allow(dead_code)]
223 fn not_sym(&self) -> &str {
224 if self.config.use_unicode {
225 "\u{00ac}"
226 } else {
227 "Not"
228 }
229 }
230 fn write_indent(&mut self) {
232 for _ in 0..(self.indent * self.config.indent_size) {
233 self.buffer.push(' ');
234 }
235 }
236 fn increase_indent(&mut self) {
238 self.indent += 1;
239 }
240 fn decrease_indent(&mut self) {
242 if self.indent > 0 {
243 self.indent -= 1;
244 }
245 }
246 #[allow(dead_code)]
249 pub fn try_single_line(&mut self, expr: &SurfaceExpr) -> Option<String> {
250 let mut sub = PrettyPrinter::with_config(self.config.clone());
251 sub.notations = self.notations.clone();
252 if sub.print_expr(expr).is_err() {
253 return None;
254 }
255 let result = sub.output();
256 let col = self.current_column();
257 if col + result.len() <= self.config.max_width {
258 Some(result)
259 } else {
260 None
261 }
262 }
263 #[allow(dead_code)]
266 fn print_expr_auto(&mut self, expr: &SurfaceExpr) -> fmt::Result {
267 if let Some(s) = self.try_single_line(expr) {
268 write!(self.buffer, "{}", s)
269 } else {
270 self.print_expr_multiline(expr)
271 }
272 }
273 #[allow(dead_code)]
275 fn print_expr_multiline(&mut self, expr: &SurfaceExpr) -> fmt::Result {
276 match expr {
277 SurfaceExpr::Lam(binders, body) => {
278 let sym = self.lambda_sym().to_string();
279 write!(self.buffer, "{}", sym)?;
280 for binder in binders {
281 self.print_binder(binder)?;
282 }
283 writeln!(self.buffer, " =>")?;
284 self.increase_indent();
285 self.write_indent();
286 self.print_expr(&body.value)?;
287 self.decrease_indent();
288 Ok(())
289 }
290 SurfaceExpr::Let(name, ty, val, body) => {
291 write!(self.buffer, "let {}", name)?;
292 if let Some(ty) = ty {
293 write!(self.buffer, " : ")?;
294 self.print_expr(&ty.value)?;
295 }
296 write!(self.buffer, " := ")?;
297 self.print_expr(&val.value)?;
298 writeln!(self.buffer)?;
299 self.write_indent();
300 write!(self.buffer, "in ")?;
301 self.print_expr(&body.value)
302 }
303 SurfaceExpr::If(c, t, e) => {
304 write!(self.buffer, "if ")?;
305 self.print_expr(&c.value)?;
306 writeln!(self.buffer)?;
307 self.increase_indent();
308 self.write_indent();
309 write!(self.buffer, "then ")?;
310 self.print_expr(&t.value)?;
311 writeln!(self.buffer)?;
312 self.write_indent();
313 write!(self.buffer, "else ")?;
314 self.print_expr(&e.value)?;
315 self.decrease_indent();
316 Ok(())
317 }
318 _ => self.print_expr(expr),
319 }
320 }
321 pub(super) fn print_binder(&mut self, binder: &Binder) -> fmt::Result {
323 let (open, close) = match binder.info {
324 BinderKind::Default => ("(", ")"),
325 BinderKind::Implicit => {
326 if !self.config.show_implicit {
327 return Ok(());
328 }
329 ("{", "}")
330 }
331 BinderKind::Instance => ("[", "]"),
332 BinderKind::StrictImplicit => ("{{", "}}"),
333 };
334 write!(self.buffer, " {}{}", open, binder.name)?;
335 if let Some(ty) = &binder.ty {
336 write!(self.buffer, " : ")?;
337 self.print_expr(&ty.value)?;
338 }
339 write!(self.buffer, "{}", close)
340 }
341 fn print_binder_always(&mut self, binder: &Binder) -> fmt::Result {
343 let (open, close) = match binder.info {
344 BinderKind::Default => ("(", ")"),
345 BinderKind::Implicit => ("{", "}"),
346 BinderKind::Instance => ("[", "]"),
347 BinderKind::StrictImplicit => ("{{", "}}"),
348 };
349 write!(self.buffer, " {}{}", open, binder.name)?;
350 if let Some(ty) = &binder.ty {
351 write!(self.buffer, " : ")?;
352 self.print_expr(&ty.value)?;
353 }
354 write!(self.buffer, "{}", close)
355 }
356 #[allow(dead_code)]
358 fn expr_prec(&self, expr: &SurfaceExpr) -> u32 {
359 match expr {
360 SurfaceExpr::Sort(_)
361 | SurfaceExpr::Var(_)
362 | SurfaceExpr::Lit(_)
363 | SurfaceExpr::Hole
364 | SurfaceExpr::ListLit(_)
365 | SurfaceExpr::Tuple(_)
366 | SurfaceExpr::AnonymousCtor(_) => prec::ATOM,
367 SurfaceExpr::Proj(_, _) => prec::ATOM,
368 SurfaceExpr::App(_, _) => prec::APP,
369 SurfaceExpr::Ann(_, _) => prec::ATOM,
370 SurfaceExpr::Pi(binders, _) => {
371 if binders.len() == 1 && binders[0].name == "_" {
372 prec::ARROW
373 } else {
374 prec::LAMBDA
375 }
376 }
377 SurfaceExpr::Lam(_, _) => prec::LAMBDA,
378 SurfaceExpr::Let(_, _, _, _) => prec::LET,
379 SurfaceExpr::If(_, _, _) => prec::IF,
380 SurfaceExpr::Match(_, _) => prec::LET,
381 SurfaceExpr::Do(_) => prec::LET,
382 SurfaceExpr::Have(_, _, _, _) => prec::LET,
383 SurfaceExpr::Suffices(_, _, _) => prec::LET,
384 SurfaceExpr::Show(_, _) => prec::LET,
385 SurfaceExpr::NamedArg(_, _, _) => prec::APP,
386 SurfaceExpr::Return(_) => prec::LET,
387 SurfaceExpr::StringInterp(_) => prec::ATOM,
388 SurfaceExpr::Range(_, _) => prec::LET,
389 SurfaceExpr::ByTactic(_) => prec::LET,
390 SurfaceExpr::Calc(_) => prec::LET,
391 }
392 }
393 #[allow(dead_code)]
398 pub fn print_expr_prec(&mut self, expr: &SurfaceExpr, outer_prec: u32) -> fmt::Result {
399 let inner_prec = self.expr_prec(expr);
400 let needs_parens = match self.config.parens_mode {
401 ParensMode::Full => !matches!(
402 expr,
403 SurfaceExpr::Sort(_)
404 | SurfaceExpr::Var(_)
405 | SurfaceExpr::Lit(_)
406 | SurfaceExpr::Hole
407 ),
408 ParensMode::Minimal => inner_prec < outer_prec,
409 };
410 if needs_parens {
411 write!(self.buffer, "(")?;
412 self.print_expr(expr)?;
413 write!(self.buffer, ")")
414 } else {
415 self.print_expr(expr)
416 }
417 }
418 pub fn print_pattern(&mut self, pat: &Pattern) -> fmt::Result {
420 match pat {
421 Pattern::Wild => write!(self.buffer, "_"),
422 Pattern::Var(name) => write!(self.buffer, "{}", name),
423 Pattern::Ctor(name, args) => {
424 if args.is_empty() {
425 write!(self.buffer, "{}", name)
426 } else {
427 write!(self.buffer, "{}", name)?;
428 for arg in args {
429 write!(self.buffer, " ")?;
430 self.print_pattern_atom(&arg.value)?;
431 }
432 Ok(())
433 }
434 }
435 Pattern::Lit(lit) => write!(self.buffer, "{}", lit),
436 Pattern::Or(left, right) => {
437 self.print_pattern(&left.value)?;
438 write!(self.buffer, " | ")?;
439 self.print_pattern(&right.value)
440 }
441 }
442 }
443 fn print_pattern_atom(&mut self, pat: &Pattern) -> fmt::Result {
445 match pat {
446 Pattern::Wild | Pattern::Var(_) | Pattern::Lit(_) => self.print_pattern(pat),
447 Pattern::Ctor(_, args) if args.is_empty() => self.print_pattern(pat),
448 _ => {
449 write!(self.buffer, "(")?;
450 self.print_pattern(pat)?;
451 write!(self.buffer, ")")
452 }
453 }
454 }
455 #[allow(dead_code)]
457 pub fn print_match(&mut self, scrutinee: &SurfaceExpr, arms: &[MatchArm]) -> fmt::Result {
458 write!(self.buffer, "match ")?;
459 self.print_expr(scrutinee)?;
460 write!(self.buffer, " with")?;
461 for arm in arms {
462 writeln!(self.buffer)?;
463 self.write_indent();
464 write!(self.buffer, "| ")?;
465 self.print_pattern(&arm.pattern.value)?;
466 if let Some(guard) = &arm.guard {
467 write!(self.buffer, " when ")?;
468 self.print_expr(&guard.value)?;
469 }
470 write!(self.buffer, " => ")?;
471 self.print_expr(&arm.rhs.value)?;
472 }
473 Ok(())
474 }
475 #[allow(dead_code)]
477 pub fn print_do(&mut self, actions: &[DoAction]) -> fmt::Result {
478 writeln!(self.buffer, "do")?;
479 self.increase_indent();
480 for action in actions {
481 self.write_indent();
482 match action {
483 DoAction::Let(name, expr) => {
484 write!(self.buffer, "let {} := ", name)?;
485 self.print_expr(&expr.value)?;
486 }
487 DoAction::LetTyped(name, ty, expr) => {
488 write!(self.buffer, "let {} : ", name)?;
489 self.print_expr(&ty.value)?;
490 write!(self.buffer, " := ")?;
491 self.print_expr(&expr.value)?;
492 }
493 DoAction::Bind(name, expr) => {
494 let la = self.left_arrow().to_string();
495 write!(self.buffer, "let {} {} ", name, la)?;
496 self.print_expr(&expr.value)?;
497 }
498 DoAction::Expr(expr) => {
499 self.print_expr(&expr.value)?;
500 }
501 DoAction::Return(expr) => {
502 write!(self.buffer, "return ")?;
503 self.print_expr(&expr.value)?;
504 }
505 }
506 writeln!(self.buffer)?;
507 }
508 self.decrease_indent();
509 Ok(())
510 }
511 fn left_arrow(&self) -> &str {
513 if self.config.use_unicode {
514 "\u{2190}"
515 } else {
516 "<-"
517 }
518 }
519 #[allow(dead_code)]
521 pub fn print_inductive(
522 &mut self,
523 name: &str,
524 univ_params: &[String],
525 params: &[Binder],
526 ty: &SurfaceExpr,
527 ctors: &[Constructor],
528 ) -> fmt::Result {
529 write!(self.buffer, "inductive {}", name)?;
530 if !univ_params.is_empty() {
531 write!(self.buffer, ".{{{}}}", univ_params.join(", "))?;
532 }
533 for param in params {
534 self.print_binder_always(param)?;
535 }
536 write!(self.buffer, " : ")?;
537 self.print_expr(ty)?;
538 write!(self.buffer, " where")?;
539 for ctor in ctors {
540 writeln!(self.buffer)?;
541 self.write_indent();
542 write!(self.buffer, "| {} : ", ctor.name)?;
543 self.print_expr(&ctor.ty.value)?;
544 }
545 Ok(())
546 }
547 pub fn print_expr(&mut self, expr: &SurfaceExpr) -> fmt::Result {
549 match expr {
550 SurfaceExpr::Sort(sort) => {
551 if !self.config.show_universes {
552 match sort {
553 SortKind::Type | SortKind::Prop => {
554 write!(self.buffer, "{}", sort)
555 }
556 SortKind::TypeU(_) => write!(self.buffer, "Type"),
557 SortKind::SortU(_) => write!(self.buffer, "Sort"),
558 }
559 } else {
560 write!(self.buffer, "{}", sort)
561 }
562 }
563 SurfaceExpr::Var(name) => write!(self.buffer, "{}", name),
564 SurfaceExpr::App(fun, arg) => {
565 self.print_expr(&fun.value)?;
566 write!(self.buffer, " ")?;
567 self.print_atom(&arg.value)
568 }
569 SurfaceExpr::Lam(binders, body) => {
570 let sym = self.lambda_sym().to_string();
571 write!(self.buffer, "{}", sym)?;
572 for binder in binders {
573 self.print_binder_always(binder)?;
574 }
575 write!(self.buffer, " => ")?;
576 self.print_expr(&body.value)
577 }
578 SurfaceExpr::Pi(binders, body) => {
579 if binders.len() == 1 && binders[0].name == "_" {
580 if let Some(ty) = &binders[0].ty {
581 self.print_atom(&ty.value)?;
582 }
583 let arr = self.arrow().to_string();
584 write!(self.buffer, " {} ", arr)?;
585 self.print_expr(&body.value)
586 } else {
587 let sym = self.forall_sym().to_string();
588 write!(self.buffer, "{}", sym)?;
589 for binder in binders {
590 self.print_binder_always(binder)?;
591 }
592 write!(self.buffer, ", ")?;
593 self.print_expr(&body.value)
594 }
595 }
596 SurfaceExpr::Let(name, ty, val, body) => {
597 write!(self.buffer, "let {} ", name)?;
598 if let Some(ty) = ty {
599 write!(self.buffer, ": ")?;
600 self.print_expr(&ty.value)?;
601 write!(self.buffer, " ")?;
602 }
603 write!(self.buffer, ":= ")?;
604 self.print_expr(&val.value)?;
605 write!(self.buffer, " in ")?;
606 self.print_expr(&body.value)
607 }
608 SurfaceExpr::Lit(lit) => write!(self.buffer, "{}", lit),
609 SurfaceExpr::Ann(expr, ty) => {
610 write!(self.buffer, "(")?;
611 self.print_expr(&expr.value)?;
612 write!(self.buffer, " : ")?;
613 self.print_expr(&ty.value)?;
614 write!(self.buffer, ")")
615 }
616 SurfaceExpr::Hole => write!(self.buffer, "_"),
617 SurfaceExpr::Proj(expr, field) => {
618 self.print_atom(&expr.value)?;
619 write!(self.buffer, ".{}", field)
620 }
621 SurfaceExpr::If(c, t, e) => {
622 write!(self.buffer, "if ")?;
623 self.print_expr(&c.value)?;
624 write!(self.buffer, " then ")?;
625 self.print_expr(&t.value)?;
626 write!(self.buffer, " else ")?;
627 self.print_expr(&e.value)
628 }
629 SurfaceExpr::Match(scrutinee, arms) => self.print_match(&scrutinee.value, arms),
630 SurfaceExpr::Do(actions) => self.print_do(actions),
631 SurfaceExpr::Have(name, ty, proof, body) => {
632 write!(self.buffer, "have {} : ", name)?;
633 self.print_expr(&ty.value)?;
634 write!(self.buffer, " := ")?;
635 self.print_expr(&proof.value)?;
636 write!(self.buffer, "; ")?;
637 self.print_expr(&body.value)
638 }
639 SurfaceExpr::Suffices(name, ty, body) => {
640 write!(self.buffer, "suffices {} : ", name)?;
641 self.print_expr(&ty.value)?;
642 write!(self.buffer, " from ")?;
643 self.print_expr(&body.value)
644 }
645 SurfaceExpr::Show(ty, proof) => {
646 write!(self.buffer, "show ")?;
647 self.print_expr(&ty.value)?;
648 write!(self.buffer, " from ")?;
649 self.print_expr(&proof.value)
650 }
651 SurfaceExpr::NamedArg(func, name, arg) => {
652 self.print_expr(&func.value)?;
653 write!(self.buffer, " ({} := ", name)?;
654 self.print_expr(&arg.value)?;
655 write!(self.buffer, ")")
656 }
657 SurfaceExpr::AnonymousCtor(fields) => {
658 write!(self.buffer, "<")?;
659 for (i, f) in fields.iter().enumerate() {
660 if i > 0 {
661 write!(self.buffer, ", ")?;
662 }
663 self.print_expr(&f.value)?;
664 }
665 write!(self.buffer, ">")
666 }
667 SurfaceExpr::ListLit(elems) => {
668 write!(self.buffer, "[")?;
669 for (i, e) in elems.iter().enumerate() {
670 if i > 0 {
671 write!(self.buffer, ", ")?;
672 }
673 self.print_expr(&e.value)?;
674 }
675 write!(self.buffer, "]")
676 }
677 SurfaceExpr::Tuple(elems) => {
678 write!(self.buffer, "(")?;
679 for (i, e) in elems.iter().enumerate() {
680 if i > 0 {
681 write!(self.buffer, ", ")?;
682 }
683 self.print_expr(&e.value)?;
684 }
685 write!(self.buffer, ")")
686 }
687 SurfaceExpr::Return(expr) => {
688 write!(self.buffer, "return ")?;
689 self.print_expr(&expr.value)
690 }
691 SurfaceExpr::StringInterp(_parts) => write!(self.buffer, "s!\"...\""),
692 SurfaceExpr::Range(lo, hi) => {
693 if let Some(lo) = lo {
694 self.print_expr(&lo.value)?;
695 }
696 write!(self.buffer, "..")?;
697 if let Some(hi) = hi {
698 self.print_expr(&hi.value)?;
699 }
700 Ok(())
701 }
702 SurfaceExpr::ByTactic(tactics) => {
703 write!(self.buffer, "by")?;
704 for (i, t) in tactics.iter().enumerate() {
705 if i > 0 {
706 write!(self.buffer, ";")?;
707 }
708 write!(self.buffer, " {}", t.value)?;
709 }
710 Ok(())
711 }
712 SurfaceExpr::Calc(steps) => {
713 write!(self.buffer, "calc")?;
714 for step in steps {
715 write!(self.buffer, "\n ")?;
716 self.print_expr(&step.lhs.value)?;
717 write!(self.buffer, " {} ", step.rel)?;
718 self.print_expr(&step.rhs.value)?;
719 write!(self.buffer, " := ")?;
720 self.print_expr(&step.proof.value)?;
721 }
722 Ok(())
723 }
724 }
725 }
726 fn print_atom(&mut self, expr: &SurfaceExpr) -> fmt::Result {
728 match expr {
729 SurfaceExpr::Sort(_)
730 | SurfaceExpr::Var(_)
731 | SurfaceExpr::Lit(_)
732 | SurfaceExpr::Hole => self.print_expr(expr),
733 _ => {
734 write!(self.buffer, "(")?;
735 self.print_expr(expr)?;
736 write!(self.buffer, ")")
737 }
738 }
739 }
740 pub fn print_decl(&mut self, decl: &Decl) -> fmt::Result {
742 match decl {
743 Decl::Axiom {
744 name,
745 univ_params,
746 ty,
747 ..
748 } => {
749 write!(self.buffer, "axiom {}", name)?;
750 if !univ_params.is_empty() {
751 write!(self.buffer, " {{{}}}", univ_params.join(", "))?;
752 }
753 write!(self.buffer, " : ")?;
754 self.print_expr(&ty.value)
755 }
756 Decl::Definition {
757 name,
758 univ_params,
759 ty,
760 val,
761 ..
762 } => {
763 write!(self.buffer, "definition {}", name)?;
764 if !univ_params.is_empty() {
765 write!(self.buffer, " {{{}}}", univ_params.join(", "))?;
766 }
767 if let Some(ty) = ty {
768 write!(self.buffer, " : ")?;
769 self.print_expr(&ty.value)?;
770 }
771 write!(self.buffer, " := ")?;
772 self.print_expr(&val.value)
773 }
774 Decl::Theorem {
775 name,
776 univ_params,
777 ty,
778 proof,
779 ..
780 } => {
781 write!(self.buffer, "theorem {}", name)?;
782 if !univ_params.is_empty() {
783 write!(self.buffer, " {{{}}}", univ_params.join(", "))?;
784 }
785 write!(self.buffer, " : ")?;
786 self.print_expr(&ty.value)?;
787 write!(self.buffer, " := ")?;
788 self.print_expr(&proof.value)
789 }
790 Decl::Inductive {
791 name,
792 univ_params,
793 params,
794 ty,
795 ctors,
796 ..
797 } => self.print_inductive(name, univ_params, params, &ty.value, ctors),
798 Decl::Import { path } => write!(self.buffer, "import {}", path.join(".")),
799 Decl::Namespace { name, .. } => write!(self.buffer, "namespace {} ...", name),
800 Decl::Structure {
801 name,
802 univ_params,
803 extends,
804 fields,
805 } => self.print_structure(name, univ_params, extends, fields),
806 Decl::ClassDecl {
807 name,
808 univ_params,
809 extends,
810 fields,
811 } => self.print_class(name, univ_params, extends, fields),
812 Decl::InstanceDecl { class_name, .. } => {
813 write!(self.buffer, "instance {} ...", class_name)
814 }
815 Decl::SectionDecl { name, .. } => write!(self.buffer, "section {} ...", name),
816 Decl::Variable { binders } => {
817 write!(self.buffer, "variable")?;
818 for b in binders {
819 self.print_binder_always(b)?;
820 }
821 Ok(())
822 }
823 Decl::Open { path, names } => {
824 write!(self.buffer, "open {}", path.join("."))?;
825 if !names.is_empty() {
826 write!(self.buffer, " ({})", names.join(", "))?;
827 }
828 Ok(())
829 }
830 Decl::Attribute { attrs, decl } => {
831 write!(self.buffer, "@[{}] ", attrs.join(", "))?;
832 self.print_decl(&decl.value)
833 }
834 Decl::HashCmd { cmd, arg } => {
835 write!(self.buffer, "#{} ", cmd)?;
836 self.print_expr(&arg.value)
837 }
838 Decl::Mutual { decls } => {
839 write!(self.buffer, "mutual")?;
840 for d in decls {
841 writeln!(self.buffer)?;
842 self.print_decl(&d.value)?;
843 }
844 writeln!(self.buffer)?;
845 write!(self.buffer, "end")
846 }
847 Decl::Derive {
848 instances,
849 type_name,
850 } => {
851 write!(
852 self.buffer,
853 "deriving {} for {}",
854 instances.join(", "),
855 type_name
856 )
857 }
858 Decl::NotationDecl {
859 kind,
860 prec,
861 name,
862 notation,
863 } => {
864 write!(self.buffer, "{}", kind)?;
865 if let Some(p) = prec {
866 write!(self.buffer, " {}", p)?;
867 }
868 write!(self.buffer, " {} := {}", name, notation)
869 }
870 Decl::Universe { names } => {
871 write!(self.buffer, "universe {}", names.join(" "))
872 }
873 }
874 }
875 #[allow(dead_code)]
877 fn print_structure(
878 &mut self,
879 name: &str,
880 univ_params: &[String],
881 extends: &[String],
882 fields: &[FieldDecl],
883 ) -> fmt::Result {
884 write!(self.buffer, "structure {}", name)?;
885 if !univ_params.is_empty() {
886 write!(self.buffer, " {{{}}}", univ_params.join(", "))?;
887 }
888 if !extends.is_empty() {
889 write!(self.buffer, " extends {}", extends.join(", "))?;
890 }
891 write!(self.buffer, " where")?;
892 self.increase_indent();
893 for field in fields {
894 writeln!(self.buffer)?;
895 self.write_indent();
896 write!(self.buffer, "{} : ", field.name)?;
897 self.print_expr(&field.ty.value)?;
898 if let Some(default) = &field.default {
899 write!(self.buffer, " := ")?;
900 self.print_expr(&default.value)?;
901 }
902 }
903 self.decrease_indent();
904 Ok(())
905 }
906 #[allow(dead_code)]
908 fn print_class(
909 &mut self,
910 name: &str,
911 univ_params: &[String],
912 extends: &[String],
913 fields: &[FieldDecl],
914 ) -> fmt::Result {
915 write!(self.buffer, "class {}", name)?;
916 if !univ_params.is_empty() {
917 write!(self.buffer, " {{{}}}", univ_params.join(", "))?;
918 }
919 if !extends.is_empty() {
920 write!(self.buffer, " extends {}", extends.join(", "))?;
921 }
922 write!(self.buffer, " where")?;
923 self.increase_indent();
924 for field in fields {
925 writeln!(self.buffer)?;
926 self.write_indent();
927 write!(self.buffer, "{} : ", field.name)?;
928 self.print_expr(&field.ty.value)?;
929 if let Some(default) = &field.default {
930 write!(self.buffer, " := ")?;
931 self.print_expr(&default.value)?;
932 }
933 }
934 self.decrease_indent();
935 Ok(())
936 }
937}
938#[allow(dead_code)]
940#[allow(missing_docs)]
941pub struct IndentManager {
942 pub level: usize,
944 pub tab_width: usize,
946}
947impl IndentManager {
948 #[allow(dead_code)]
950 pub fn new(tab_width: usize) -> Self {
951 IndentManager {
952 level: 0,
953 tab_width,
954 }
955 }
956 #[allow(dead_code)]
958 pub fn indent(&mut self) {
959 self.level += 1;
960 }
961 #[allow(dead_code)]
963 pub fn dedent(&mut self) {
964 if self.level > 0 {
965 self.level -= 1;
966 }
967 }
968 #[allow(dead_code)]
970 pub fn current(&self) -> String {
971 " ".repeat(self.level * self.tab_width)
972 }
973 #[allow(dead_code)]
975 pub fn apply_to(&self, s: &str) -> String {
976 let prefix = self.current();
977 s.lines()
978 .map(|line| format!("{}{}", prefix, line))
979 .collect::<Vec<_>>()
980 .join("\n")
981 }
982}
983#[allow(dead_code)]
985#[allow(missing_docs)]
986pub struct BreadcrumbTrail {
987 pub crumbs: Vec<String>,
989}
990impl BreadcrumbTrail {
991 #[allow(dead_code)]
993 pub fn new() -> Self {
994 BreadcrumbTrail { crumbs: Vec::new() }
995 }
996 #[allow(dead_code)]
998 pub fn push(&mut self, label: &str) {
999 self.crumbs.push(label.to_string());
1000 }
1001 #[allow(dead_code)]
1003 pub fn pop(&mut self) {
1004 self.crumbs.pop();
1005 }
1006 #[allow(dead_code)]
1008 pub fn format(&self) -> String {
1009 self.crumbs.join(" > ")
1010 }
1011}
1012#[allow(dead_code)]
1014#[allow(missing_docs)]
1015pub struct DocFormatter {
1016 pub width: usize,
1018 pub col: usize,
1020 pub out: String,
1022}
1023impl DocFormatter {
1024 #[allow(dead_code)]
1026 pub fn new(width: usize) -> Self {
1027 DocFormatter {
1028 width,
1029 col: 0,
1030 out: String::new(),
1031 }
1032 }
1033 #[allow(dead_code)]
1035 pub fn write_text(&mut self, s: &str) {
1036 self.out.push_str(s);
1037 self.col += s.chars().count();
1038 }
1039 #[allow(dead_code)]
1041 pub fn newline(&mut self, indent: usize) {
1042 self.out.push('\n');
1043 self.out.push_str(&" ".repeat(indent));
1044 self.col = indent;
1045 }
1046 #[allow(dead_code)]
1048 pub fn finish(self) -> String {
1049 self.out
1050 }
1051}
1052#[allow(dead_code)]
1054#[allow(missing_docs)]
1055pub struct TableFormatter {
1056 pub rows: Vec<Vec<String>>,
1058 pub sep: String,
1060}
1061impl TableFormatter {
1062 #[allow(dead_code)]
1064 pub fn new(sep: &str) -> Self {
1065 TableFormatter {
1066 rows: Vec::new(),
1067 sep: sep.to_string(),
1068 }
1069 }
1070 #[allow(dead_code)]
1072 pub fn add_row(&mut self, row: Vec<&str>) {
1073 self.rows
1074 .push(row.into_iter().map(|s| s.to_string()).collect());
1075 }
1076 #[allow(dead_code)]
1078 pub fn col_widths(&self) -> Vec<usize> {
1079 if self.rows.is_empty() {
1080 return Vec::new();
1081 }
1082 let ncols = self.rows.iter().map(|r| r.len()).max().unwrap_or(0);
1083 (0..ncols)
1084 .map(|c| {
1085 self.rows
1086 .iter()
1087 .filter_map(|r| r.get(c))
1088 .map(|s| s.chars().count())
1089 .max()
1090 .unwrap_or(0)
1091 })
1092 .collect()
1093 }
1094 #[allow(dead_code)]
1096 pub fn render(&self) -> String {
1097 let widths = self.col_widths();
1098 let mut out = String::new();
1099 for row in &self.rows {
1100 let parts: Vec<String> = row
1101 .iter()
1102 .enumerate()
1103 .map(|(i, cell)| {
1104 let w = widths.get(i).copied().unwrap_or(0);
1105 format!("{:width$}", cell, width = w)
1106 })
1107 .collect();
1108 out.push_str(&parts.join(&self.sep));
1109 out.push('\n');
1110 }
1111 out
1112 }
1113}
1114#[allow(dead_code)]
1116#[allow(missing_docs)]
1117pub struct AnsiHighlighter;
1118impl AnsiHighlighter {
1119 const RESET: &'static str = "\x1b[0m";
1120 const BOLD: &'static str = "\x1b[1m";
1121 const RED: &'static str = "\x1b[31m";
1122 const GREEN: &'static str = "\x1b[32m";
1123 #[allow(dead_code)]
1124 const YELLOW: &'static str = "\x1b[33m";
1125 const BLUE: &'static str = "\x1b[34m";
1126 #[allow(dead_code)]
1128 pub fn keyword(s: &str) -> String {
1129 format!("{}{}{}", Self::BOLD, s, Self::RESET)
1130 }
1131 #[allow(dead_code)]
1133 pub fn error(s: &str) -> String {
1134 format!("{}{}{}", Self::RED, s, Self::RESET)
1135 }
1136 #[allow(dead_code)]
1138 pub fn literal(s: &str) -> String {
1139 format!("{}{}{}", Self::GREEN, s, Self::RESET)
1140 }
1141 #[allow(dead_code)]
1143 pub fn type_name(s: &str) -> String {
1144 format!("{}{}{}", Self::BLUE, s, Self::RESET)
1145 }
1146 #[allow(dead_code)]
1148 pub fn strip_ansi(s: &str) -> String {
1149 let mut result = String::new();
1150 let mut in_escape = false;
1151 for c in s.chars() {
1152 if c == '\x1b' {
1153 in_escape = true;
1154 } else if in_escape {
1155 if c == 'm' {
1156 in_escape = false;
1157 }
1158 } else {
1159 result.push(c);
1160 }
1161 }
1162 result
1163 }
1164}
1165#[allow(dead_code)]
1167#[allow(missing_docs)]
1168#[derive(Debug, Clone)]
1169pub struct BoxModel {
1170 pub width: usize,
1172 pub lines: Vec<String>,
1174}
1175impl BoxModel {
1176 #[allow(dead_code)]
1178 pub fn empty() -> Self {
1179 BoxModel {
1180 width: 0,
1181 lines: Vec::new(),
1182 }
1183 }
1184 #[allow(dead_code)]
1186 pub fn of_str(s: &str) -> Self {
1187 let width = s.chars().count();
1188 BoxModel {
1189 width,
1190 lines: vec![s.to_string()],
1191 }
1192 }
1193 #[allow(dead_code)]
1195 pub fn vstack(mut self, other: BoxModel) -> Self {
1196 self.width = self.width.max(other.width);
1197 self.lines.extend(other.lines);
1198 self
1199 }
1200 #[allow(dead_code)]
1202 pub fn hstack(self, other: BoxModel) -> Self {
1203 let h = self.lines.len().max(other.lines.len());
1204 let lw = self.width;
1205 let mut lines = Vec::new();
1206 for i in 0..h {
1207 let l = self.lines.get(i).cloned().unwrap_or_else(|| " ".repeat(lw));
1208 let r = other.lines.get(i).cloned().unwrap_or_default();
1209 let padded = format!("{:width$}{}", l, r, width = lw);
1210 lines.push(padded);
1211 }
1212 BoxModel {
1213 width: lw + other.width,
1214 lines,
1215 }
1216 }
1217 #[allow(dead_code)]
1219 pub fn render(&self) -> String {
1220 self.lines.join("\n")
1221 }
1222}
1223#[allow(dead_code)]
1225#[allow(missing_docs)]
1226#[derive(Debug, Clone)]
1227pub enum DocNode {
1228 Empty,
1230 Text(String),
1232 Line(usize),
1234 Cat(Box<DocNode>, Box<DocNode>),
1236 Indent(usize, Box<DocNode>),
1238 Group(Box<DocNode>),
1240}
1241impl DocNode {
1242 #[allow(dead_code)]
1244 pub fn text(s: &str) -> Self {
1245 DocNode::Text(s.to_string())
1246 }
1247 #[allow(dead_code)]
1249 pub fn line(indent: usize) -> Self {
1250 DocNode::Line(indent)
1251 }
1252 #[allow(dead_code)]
1254 pub fn cat(a: DocNode, b: DocNode) -> Self {
1255 DocNode::Cat(Box::new(a), Box::new(b))
1256 }
1257 #[allow(dead_code)]
1259 pub fn indent(n: usize, doc: DocNode) -> Self {
1260 DocNode::Indent(n, Box::new(doc))
1261 }
1262 #[allow(dead_code)]
1264 pub fn group(doc: DocNode) -> Self {
1265 DocNode::Group(Box::new(doc))
1266 }
1267 #[allow(dead_code)]
1269 pub fn render(&self, width: usize) -> String {
1270 let mut out = String::new();
1271 render_doc(self, 0, width, &mut out);
1272 out
1273 }
1274}