cl-typeck: Crate-spanning refactor
TODO: remove all unreferenced files TODO: Finish resolving statically known types of values TODO: Type inference
This commit is contained in:
		
							
								
								
									
										109
									
								
								compiler/cl-typeck/src/entry/display.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								compiler/cl-typeck/src/entry/display.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| use super::*; | ||||
| use crate::{format_utils::*, type_kind::Adt}; | ||||
| use std::fmt::{self, Write}; | ||||
|  | ||||
| /// Printing the name of a named type stops infinite recursion | ||||
| fn write_name_or(h: Entry, f: &mut impl Write) -> fmt::Result { | ||||
|     match h.name() { | ||||
|         Some(name) => write!(f, "{name}"), | ||||
|         None => write!(f, "{h}"), | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl fmt::Display for Entry<'_, '_> { | ||||
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||
|         if self.kind().is_none() { | ||||
|             return write!(f, "<invalid type: {}>", self.id); | ||||
|         } | ||||
|  | ||||
|         if let Some(ty) = self.ty() { | ||||
|             match ty { | ||||
|                 TypeKind::Alias(id) => write!(f, "= {}", self.with_id(*id))?, | ||||
|                 TypeKind::Intrinsic(kind) => write!(f, "{kind}")?, | ||||
|                 TypeKind::Adt(adt) => write_adt(adt, self, f)?, | ||||
|                 &TypeKind::Ref(cnt, id) => { | ||||
|                     for _ in 0..cnt { | ||||
|                         f.write_str("&")?; | ||||
|                     } | ||||
|                     let h_id = self.with_id(id); | ||||
|                     write_name_or(h_id, f)?; | ||||
|                 } | ||||
|                 TypeKind::Slice(id) => { | ||||
|                     write_name_or(self.with_id(*id), &mut f.delimit_with("[", "]"))?; | ||||
|                 } | ||||
|                 &TypeKind::Array(t, cnt) => { | ||||
|                     let mut f = f.delimit_with("[", "]"); | ||||
|                     write_name_or(self.with_id(t), &mut f)?; | ||||
|                     write!(f, "; {cnt}")?; | ||||
|                 } | ||||
|                 TypeKind::Tuple(ids) => { | ||||
|                     let mut f = f.delimit_with("(", ")"); | ||||
|                     for (index, &id) in ids.iter().enumerate() { | ||||
|                         if index > 0 { | ||||
|                             write!(f, ", ")?; | ||||
|                         } | ||||
|                         write_name_or(self.with_id(id), &mut f)?; | ||||
|                     } | ||||
|                 } | ||||
|                 TypeKind::FnSig { args, rety } => { | ||||
|                     write!(f, "fn {} -> ", self.with_id(*args))?; | ||||
|                     write_name_or(self.with_id(*rety), f)?; | ||||
|                 } | ||||
|                 TypeKind::Empty => write!(f, "()")?, | ||||
|                 TypeKind::Never => write!(f, "!")?, | ||||
|                 TypeKind::Module => write!(f, "module?")?, | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn write_adt(adt: &Adt, h: &Entry, f: &mut impl Write) -> fmt::Result { | ||||
|     match adt { | ||||
|         Adt::Enum(variants) => { | ||||
|             let mut variants = variants.iter(); | ||||
|             separate(",", || { | ||||
|                 variants.next().map(|(name, def)| { | ||||
|                     move |f: &mut Delimit<_>| match def { | ||||
|                         Some(def) => { | ||||
|                             write!(f, "\n{name}: ")?; | ||||
|                             write_name_or(h.with_id(*def), f) | ||||
|                         } | ||||
|                         None => write!(f, "\n{name}"), | ||||
|                     } | ||||
|                 }) | ||||
|             })(f.delimit_with("enum {", "\n}")) | ||||
|         } | ||||
|         Adt::CLikeEnum(variants) => { | ||||
|             let mut variants = variants.iter(); | ||||
|             separate(",", || { | ||||
|                 let (name, descrim) = variants.next()?; | ||||
|                 Some(move |f: &mut Delimit<_>| write!(f, "\n{name} = {descrim}")) | ||||
|             })(f.delimit_with("enum {", "\n}")) | ||||
|         } | ||||
|         Adt::FieldlessEnum => write!(f, "enum"), | ||||
|         Adt::Struct(members) => { | ||||
|             let mut members = members.iter(); | ||||
|             separate(",", || { | ||||
|                 let (name, vis, id) = members.next()?; | ||||
|                 Some(move |f: &mut Delimit<_>| { | ||||
|                     write!(f, "\n{vis}{name}: ")?; | ||||
|                     write_name_or(h.with_id(*id), f) | ||||
|                 }) | ||||
|             })(f.delimit_with("struct {", "\n}")) | ||||
|         } | ||||
|         Adt::TupleStruct(members) => { | ||||
|             let mut members = members.iter(); | ||||
|             separate(", ", || { | ||||
|                 let (vis, def) = members.next()?; | ||||
|                 Some(move |f: &mut Delimit<_>| { | ||||
|                     write!(f, "{vis}")?; | ||||
|                     write_name_or(h.with_id(*def), f) | ||||
|                 }) | ||||
|             })(f.delimit_with("struct (", ")")) | ||||
|         } | ||||
|         Adt::UnitStruct => write!(f, "struct"), | ||||
|         Adt::Union(_) => todo!("Display union types"), | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user