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:
2024-07-24 18:22:42 -05:00
parent b7ad285a11
commit e19127facc
17 changed files with 1270 additions and 989 deletions

View 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"),
}
}