cl-typeck: Refactor display for Def.
- Use the FmtAdapter from cl-ast - Add a new delimiter-constructing delimit_with function.
This commit is contained in:
		| @@ -1,4 +1,3 @@ | |||||||
|  |  | ||||||
| use delimiters::Delimiters; | use delimiters::Delimiters; | ||||||
| use std::fmt::Write; | use std::fmt::Write; | ||||||
|  |  | ||||||
| @@ -7,9 +6,14 @@ pub trait FmtAdapter: Write { | |||||||
|     fn indent(&mut self) -> Indent<Self> { |     fn indent(&mut self) -> Indent<Self> { | ||||||
|         Indent { f: self } |         Indent { f: self } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn delimit(&mut self, delim: Delimiters) -> Delimit<Self> { |     fn delimit(&mut self, delim: Delimiters) -> Delimit<Self> { | ||||||
|         Delimit::new(self, delim) |         Delimit::new(self, delim) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fn delimit_with(&mut self, open: &'static str, close: &'static str) -> Delimit<Self> { | ||||||
|  |         Delimit::new(self, Delimiters { open, close }) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| /// Pads text with leading indentation after every newline | /// Pads text with leading indentation after every newline | ||||||
|   | |||||||
| @@ -1,34 +1,9 @@ | |||||||
| //! [Display] implementations for [TypeKind], [Adt], and [Intrinsic] | //! [Display] implementations for [TypeKind], [Adt], and [Intrinsic] | ||||||
|  |  | ||||||
| use crate::node::Node; |  | ||||||
|  |  | ||||||
| use super::{Adt, Def, DefKind, Intrinsic, TypeKind, ValueKind}; | use super::{Adt, Def, DefKind, Intrinsic, TypeKind, ValueKind}; | ||||||
|  | use crate::{format_utils::*, node::Node}; | ||||||
| use cl_ast::format::FmtAdapter; | use cl_ast::format::FmtAdapter; | ||||||
| use std::{ | use std::fmt::{self, Display, Write}; | ||||||
|     fmt::{self, Display, Write}, |  | ||||||
|     iter, |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| fn sep<'f, 's, Item, F>( |  | ||||||
|     before: &'s str, |  | ||||||
|     after: &'s str, |  | ||||||
|     t: F, |  | ||||||
| ) -> impl FnOnce(&mut fmt::Formatter<'f>) -> fmt::Result + 's |  | ||||||
| where |  | ||||||
|     Item: FnMut(&mut fmt::Formatter<'f>) -> fmt::Result, |  | ||||||
|     F: FnMut() -> Option<Item> + 's, |  | ||||||
| { |  | ||||||
|     move |f| { |  | ||||||
|         f.write_str(before)?; |  | ||||||
|         for (idx, mut disp) in iter::from_fn(t).enumerate() { |  | ||||||
|             if idx > 0 { |  | ||||||
|                 f.write_str(", ")?; |  | ||||||
|             } |  | ||||||
|             disp(f)?; |  | ||||||
|         } |  | ||||||
|         f.write_str(after) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl Display for Def<'_> { | impl Display for Def<'_> { | ||||||
|     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||||
| @@ -92,10 +67,10 @@ impl Display for TypeKind { | |||||||
|             TypeKind::Array(def, size) => write!(f, "array [#{def}; {size}]"), |             TypeKind::Array(def, size) => write!(f, "array [#{def}; {size}]"), | ||||||
|             TypeKind::Tuple(defs) => { |             TypeKind::Tuple(defs) => { | ||||||
|                 let mut defs = defs.iter(); |                 let mut defs = defs.iter(); | ||||||
|                 sep("tuple (", ")", || { |                 separate(", ", || { | ||||||
|                     let def = defs.next()?; |                     let def = defs.next()?; | ||||||
|                     Some(move |f: &mut fmt::Formatter| write!(f, "#{def}")) |                     Some(move |f: &mut Delimit<_>| write!(f, "#{def}")) | ||||||
|                 })(f) |                 })(f.delimit_with("tuple (", ")")) | ||||||
|             } |             } | ||||||
|             TypeKind::FnSig { args, rety } => write!(f, "fn (#{args}) -> #{rety}"), |             TypeKind::FnSig { args, rety } => write!(f, "fn (#{args}) -> #{rety}"), | ||||||
|             TypeKind::Empty => f.write_str("()"), |             TypeKind::Empty => f.write_str("()"), | ||||||
| @@ -110,43 +85,43 @@ impl Display for Adt { | |||||||
|         match self { |         match self { | ||||||
|             Adt::Enum(variants) => { |             Adt::Enum(variants) => { | ||||||
|                 let mut variants = variants.iter(); |                 let mut variants = variants.iter(); | ||||||
|                 sep("enum {", "}", || { |                 separate(", ", || { | ||||||
|                     let (name, def) = variants.next()?; |                     let (name, def) = variants.next()?; | ||||||
|                     Some(move |f: &mut fmt::Formatter| match def { |                     Some(move |f: &mut Delimit<_>| match def { | ||||||
|                         Some(def) => write!(f, "{name}: #{def}"), |                         Some(def) => write!(f, "{name}: #{def}"), | ||||||
|                         None => write!(f, "{name}"), |                         None => write!(f, "{name}"), | ||||||
|                     }) |                     }) | ||||||
|                 })(f) |                 })(f.delimit_with("enum {", "}")) | ||||||
|             } |             } | ||||||
|             Adt::CLikeEnum(variants) => { |             Adt::CLikeEnum(variants) => { | ||||||
|                 let mut variants = variants.iter(); |                 let mut variants = variants.iter(); | ||||||
|                 sep("enum {", "}", || { |                 separate(", ", || { | ||||||
|                     let (name, descrim) = variants.next()?; |                     let (name, descrim) = variants.next()?; | ||||||
|                     Some(move |f: &mut fmt::Formatter| write!(f, "{name} = {descrim}")) |                     Some(move |f: &mut Delimit<_>| write!(f, "{name} = {descrim}")) | ||||||
|                 })(f) |                 })(f.delimit_with("enum {", "}")) | ||||||
|             } |             } | ||||||
|             Adt::FieldlessEnum => write!(f, "enum"), |             Adt::FieldlessEnum => write!(f, "enum"), | ||||||
|             Adt::Struct(members) => { |             Adt::Struct(members) => { | ||||||
|                 let mut members = members.iter(); |                 let mut members = members.iter(); | ||||||
|                 sep("struct {", "}", || { |                 separate(", ", || { | ||||||
|                     let (name, vis, def) = members.next()?; |                     let (name, vis, def) = members.next()?; | ||||||
|                     Some(move |f: &mut fmt::Formatter| write!(f, "{vis}{name}: #{def}")) |                     Some(move |f: &mut Delimit<_>| write!(f, "{vis}{name}: #{def}")) | ||||||
|                 })(f) |                 })(f.delimit_with("struct {", "}")) | ||||||
|             } |             } | ||||||
|             Adt::TupleStruct(members) => { |             Adt::TupleStruct(members) => { | ||||||
|                 let mut members = members.iter(); |                 let mut members = members.iter(); | ||||||
|                 sep("struct (", ")", || { |                 separate(", ", || { | ||||||
|                     let (vis, def) = members.next()?; |                     let (vis, def) = members.next()?; | ||||||
|                     Some(move |f: &mut fmt::Formatter| write!(f, "{vis}#{def}")) |                     Some(move |f: &mut Delimit<_>| write!(f, "{vis}#{def}")) | ||||||
|                 })(f) |                 })(f.delimit_with("struct (", ")")) | ||||||
|             } |             } | ||||||
|             Adt::UnitStruct => write!(f, "struct ()"), |             Adt::UnitStruct => write!(f, "struct"), | ||||||
|             Adt::Union(variants) => { |             Adt::Union(variants) => { | ||||||
|                 let mut variants = variants.iter(); |                 let mut variants = variants.iter(); | ||||||
|                 sep("union {", "}", || { |                 separate(", ", || { | ||||||
|                     let (name, def) = variants.next()?; |                     let (name, def) = variants.next()?; | ||||||
|                     Some(move |f: &mut fmt::Formatter| write!(f, "{name}: #{def}")) |                     Some(move |f: &mut Delimit<_>| write!(f, "{name}: #{def}")) | ||||||
|                 })(f) |                 })(f.delimit_with("union {", "}")) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
							
								
								
									
										23
									
								
								compiler/cl-typeck/src/format_utils.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								compiler/cl-typeck/src/format_utils.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | |||||||
|  | pub use cl_ast::format::*; | ||||||
|  | use std::{fmt, iter}; | ||||||
|  |  | ||||||
|  | /// Separates the items yielded by iterating the provided function | ||||||
|  | pub const fn separate<'f, 's, Item, F, W>( | ||||||
|  |     sep: &'s str, | ||||||
|  |     t: F, | ||||||
|  | ) -> impl FnOnce(W) -> fmt::Result + 's | ||||||
|  | where | ||||||
|  |     Item: FnMut(&mut W) -> fmt::Result, | ||||||
|  |     F: FnMut() -> Option<Item> + 's, | ||||||
|  |     W: fmt::Write, | ||||||
|  | { | ||||||
|  |     move |mut f| { | ||||||
|  |         for (idx, mut disp) in iter::from_fn(t).enumerate() { | ||||||
|  |             if idx > 0 { | ||||||
|  |                 f.write_str(sep)?; | ||||||
|  |             } | ||||||
|  |             disp(&mut f)?; | ||||||
|  |         } | ||||||
|  |         Ok(()) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -87,6 +87,8 @@ pub mod type_resolver; | |||||||
|  |  | ||||||
| pub mod inference; | pub mod inference; | ||||||
|  |  | ||||||
|  | pub(crate) mod format_utils; | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  |  | ||||||
| LET THERE BE NOTES: | LET THERE BE NOTES: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user