diff --git a/src/ast2/intern.rs b/src/ast2/intern.rs index 59fc884..6f38e6d 100644 --- a/src/ast2/intern.rs +++ b/src/ast2/intern.rs @@ -39,6 +39,23 @@ impl From for SimpleType { } } +impl Display for SimpleType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + match self { + SimpleType::F32 => "f32", + SimpleType::F64 => "f64", + SimpleType::Bool => "bool", + SimpleType::Void => "void", + SimpleType::USize => "usize", + SimpleType::ISize => "isize", + SimpleType::ComptimeInt => "comptime_int", + } + ) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Tag { String, @@ -134,6 +151,86 @@ pub enum Key<'a> { FalseValue, } +struct KeyDisplay<'a> { + ip: &'a InternPool, + key: Key<'a>, +} + +struct DisplayCommaSep> { + t: T, +} + +impl> Display for DisplayCommaSep { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut iter = self.t.into_iter(); + + let Some(ref next) = iter.next() else { + return Ok(()); + }; + write!(f, "{next}")?; + + for ref item in iter { + write!(f, ", {next}")?; + } + + Ok(()) + } +} + +impl Display for KeyDisplay<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.key { + Key::String { str } => write!(f, "\"{str}\"")?, + Key::Bytes { bytes } => write!(f, "{bytes:>02x?}")?, + Key::SIntSmall { bits } => write!(f, "{bits}")?, + Key::UIntSmall { bits } => write!(f, "{bits}")?, + Key::SInt64 { bits } => write!(f, "{bits}")?, + Key::UInt64 { bits } => write!(f, "{bits}")?, + Key::F32 { bits } => write!(f, "{bits}")?, + Key::F64 { bits } => write!(f, "{bits}")?, + Key::PositiveInt { bigint } => write!(f, "{bigint}")?, + Key::NegativeInt { bigint } => write!(f, "{bigint}")?, + Key::UIntType { bit_width } => write!(f, "u{bit_width}")?, + Key::SIntType { bit_width } => write!(f, "i{bit_width}")?, + Key::SimpleType { ty } => write!(f, "{ty}")?, + Key::PointerType { pointee, flags } => { + write!(f, "*{flags}{}", self.ip.display_key(pointee))? + } + Key::ArrayType { + pointee, + flags, + length, + } => write!( + f, + "[{flags}{}; {length}]", + self.ip.display_key(pointee) + )?, + Key::FunctionType { + return_type, + parameters, + } => write!( + f, + "fn ({}) -> {}", + DisplayCommaSep { + t: parameters.iter().map(|&ty| self.ip.display_key(ty)) + }, + self.ip.display_key(return_type) + )?, + Key::StructType { + decl, + name, + packed, + c_like, + fields, + } => todo!(), + Key::TrueValue => write!(f, "true"), + Key::FalseValue => write!(f, "false"), + } + + Ok(()) + } +} + impl Hash for Key<'_> { fn hash(&self, state: &mut H) { core::mem::discriminant(self).hash(state); @@ -175,6 +272,22 @@ pub struct PointerFlags { pub noalias: bool, } +impl Display for PointerFlags { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.is_const { + write!(f, "const ")? + } + if self.volatile { + write!(f, "volatile ")? + } + if self.noalias { + write!(f, "noalias ")? + } + + Ok(()) + } +} + impl PointerFlags { pub fn new(is_const: bool, volatile: bool, noalias: bool) -> Self { Self { @@ -343,6 +456,15 @@ impl std::fmt::Debug for InternPool { } } +impl InternPool { + pub fn display_key(&self, index: Index) -> KeyDisplay<'_> { + KeyDisplay { + ip: self, + key: self.get_key(index), + } + } +} + macro_rules! static_keys { ($($name:ident => $def:expr),* $(,)?) => { impl Index { @@ -891,7 +1013,8 @@ impl InternPool { } Key::PointerType { pointee, flags } => { let flags = flags.pack(); - let i = self.extend_words([pointee.index(), flags as u32]); + let i = + self.extend_words([pointee.index() as u32, flags as u32]); self.create_item(Tag::PointerType, i) } Key::ArrayType { @@ -900,8 +1023,11 @@ impl InternPool { length, } => { let flags = flags.pack(); - let i = - self.extend_words([pointee.index(), flags as u32, length]); + let i = self.extend_words([ + pointee.index() as u32, + flags as u32, + length, + ]); self.create_item(Tag::ArrayType, i) } Key::StructType { @@ -942,8 +1068,9 @@ impl InternPool { let start = self.push_word(info.pack()); self.extend_words([return_type.into_u32()]); - _ = self - .extend_words(parameters.into_iter().map(|i| i.index())); + _ = self.extend_words( + parameters.into_iter().map(|i| i.index() as u32), + ); self.create_item(Tag::FunctionType, start) }