From 379769bc59d6931f91533d68399413ca6ab86fe7 Mon Sep 17 00:00:00 2001 From: Janis Date: Sat, 1 Mar 2025 19:22:31 +0100 Subject: [PATCH] split ast tag arrays --- src/ast.rs | 51 +- src/ast2/intern.rs | 221 ++---- src/ast2/mod.rs | 1737 +++++++++++++++++++------------------------- src/bin/main.rs | 12 +- src/lib.rs | 5 +- src/mir.rs | 1105 +++++++--------------------- src/parser.rs | 461 +++--------- src/triples.rs | 748 ++++++------------- 8 files changed, 1379 insertions(+), 2961 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 76b10cd..7bb7ba4 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1,9 +1,6 @@ use std::num::NonZero; -use crate::{ - ast2::intern, - string_table::{self, ImmOrIndex}, -}; +use crate::ast2::intern; pub type Node = NonZero; @@ -298,21 +295,14 @@ impl core::fmt::Display for Type { Type::Integer(t) => t.fmt(f), Type::Floating(t) => t.fmt(f), Type::Pointer { constness, pointee } => { - write!( - f, - "*{}{}", - if *constness { "const " } else { "" }, - pointee - ) + write!(f, "*{}{}", if *constness { "const " } else { "" }, pointee) } Type::Fn { parameter_types, return_type, } => { write!(f, "fn (")?; - for param in - parameter_types.iter().map(|p| Some(p)).intersperse(None) - { + for param in parameter_types.iter().map(|p| Some(p)).intersperse(None) { match param { Some(param) => param.fmt(f)?, None => write!(f, ", ")?, @@ -351,13 +341,8 @@ impl Type { parameter_types: r_parameter_types, return_type: r_return_type, }, - ) => { - l_parameter_types == r_parameter_types - && l_return_type == r_return_type - } - _ => { - core::mem::discriminant(self) == core::mem::discriminant(other) - } + ) => l_parameter_types == r_parameter_types && l_return_type == r_return_type, + _ => core::mem::discriminant(self) == core::mem::discriminant(other), } } pub fn as_primitive_type(&self) -> Option { @@ -476,10 +461,9 @@ impl Type { pub fn can_add_sub(&self) -> bool { match self { - Type::ComptimeNumber - | Type::Pointer { .. } - | Type::Floating(_) - | Type::Integer(_) => true, + Type::ComptimeNumber | Type::Pointer { .. } | Type::Floating(_) | Type::Integer(_) => { + true + } _ => false, } } @@ -501,10 +485,9 @@ impl Type { } pub fn can_cmp(&self) -> bool { match self { - Type::ComptimeNumber - | Type::Pointer { .. } - | Type::Floating(_) - | Type::Integer(_) => true, + Type::ComptimeNumber | Type::Pointer { .. } | Type::Floating(_) | Type::Integer(_) => { + true + } _ => false, } } @@ -613,12 +596,7 @@ pub mod tree_visitor { pub fn new_range(start: Node, end: Node, pre: F1, post: F2) -> Self { Self::new_inner(start, End::Exclusive(end), pre, post) } - pub fn new_range_inclusive( - start: Node, - end: Node, - pre: F1, - post: F2, - ) -> Self { + pub fn new_range_inclusive(start: Node, end: Node, pre: F1, post: F2) -> Self { Self::new_inner(start, End::Inclusive(end), pre, post) } pub fn new_seek(tree: &Tree, start: Node, pre: F1, post: F2) -> Self { @@ -717,10 +695,7 @@ pub mod tree_visitor { } /// short-circuits on the first E - pub fn visit_ok( - mut self, - tree: &Tree, - ) -> core::result::Result + pub fn visit_ok(mut self, tree: &Tree) -> core::result::Result where F1: FnMut(&Tree, Node) -> core::result::Result, F2: FnMut(&Tree, Node) -> core::result::Result, diff --git a/src/ast2/intern.rs b/src/ast2/intern.rs index 8b116e3..1795b9a 100644 --- a/src/ast2/intern.rs +++ b/src/ast2/intern.rs @@ -180,19 +180,14 @@ impl Display for KeyDisplay<'_> { pointee, flags, length, - } => write!( - f, - "[{flags}{}; {length}]", - self.ip.display_key(pointee) - )?, + } => write!(f, "[{flags}{}; {length}]", self.ip.display_key(pointee))?, Key::FunctionType { return_type, ref parameters, } => { write!(f, "fn (")?; - let mut iter = - parameters.iter().map(|&ty| self.ip.display_key(ty)); + let mut iter = parameters.iter().map(|&ty| self.ip.display_key(ty)); let Some(next) = iter.next() else { return Ok(()); }; @@ -209,7 +204,10 @@ impl Display for KeyDisplay<'_> { packed, c_like, ref fields, - } => todo!(), + } => { + _ = (decl, name, packed, c_like, fields); + todo!() + } Key::TrueValue => write!(f, "true")?, Key::FalseValue => write!(f, "false")?, } @@ -293,9 +291,7 @@ impl PointerFlags { } pub fn pack(self) -> u8 { - (self.volatile as u8) << 0 - | (self.is_const as u8) << 1 - | (self.noalias as u8) << 2 + (self.volatile as u8) << 0 | (self.is_const as u8) << 1 | (self.noalias as u8) << 2 } pub fn unpack(packed: u8) -> Self { Self { @@ -325,9 +321,7 @@ impl StructFlags { } pub fn pack(self) -> u32 { assert!(self.num_fields < (1 << 30)); - (self.packed as u32) << 31 - | (self.c_like as u32) << 30 - | self.num_fields & Self::MASK + (self.packed as u32) << 31 | (self.c_like as u32) << 30 | self.num_fields & Self::MASK } pub fn unpack(packed: u32) -> Self { Self { @@ -648,11 +642,7 @@ impl InternPool { } } - pub fn to_mir_type( - &self, - index: Index, - _ptr_size: TypeInfo, - ) -> crate::mir::Type { + pub fn to_mir_type(&self, index: Index, _ptr_size: TypeInfo) -> crate::mir::Type { use crate::mir::Type; match self.get_key(index) { Key::UIntType { bit_width: bits } => { @@ -765,19 +755,18 @@ impl InternPool { Key::FunctionType { .. } => ptr_size, Key::StructType { packed, fields, .. } => { // TODO: c-like layout - let (size, align) = - fields.iter().fold((0, 0), |(size, align), (_name, ty)| { - let field_size = self.size_of_type(*ty, ptr_size); - let size = size + field_size.bitsize; + let (size, align) = fields.iter().fold((0, 0), |(size, align), (_name, ty)| { + let field_size = self.size_of_type(*ty, ptr_size); + let size = size + field_size.bitsize; - let size = if packed { - size.next_multiple_of(field_size.bitalign) - } else { - size - }; - let align = align.max(field_size.bitalign); - (size, align) - }); + let size = if packed { + size.next_multiple_of(field_size.bitalign) + } else { + size + }; + let align = align.max(field_size.bitalign); + (size, align) + }); TypeInfo { bitsize: size, @@ -791,11 +780,7 @@ impl InternPool { } } - pub fn insert_ast1_type( - &mut self, - pointer_bits: u16, - ty: &crate::ast::Type, - ) -> Index { + pub fn insert_ast1_type(&mut self, pointer_bits: u16, ty: &crate::ast::Type) -> Index { match ty { crate::ast::Type::Bool => self.get_bool_type(), crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(), @@ -806,12 +791,8 @@ impl InternPool { Key::UIntType { bit_width: i.bits } } }), - crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => { - self.get_f32_type() - } - crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => { - self.get_f64_type() - } + crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => self.get_f32_type(), + crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => self.get_f64_type(), crate::ast::Type::Pointer { constness, pointee } => { let pointee = self.insert_ast1_type(pointer_bits, &pointee); self.get_or_insert(Key::PointerType { @@ -827,8 +808,7 @@ impl InternPool { .iter() .map(|ty| self.insert_ast1_type(pointer_bits, ty)) .collect::>(); - let return_type = - self.from_ast1_type(pointer_bits, &return_type); + let return_type = self.from_ast1_type(pointer_bits, &return_type); self.get_or_insert(Key::FunctionType { return_type, parameters, @@ -841,11 +821,7 @@ impl InternPool { } } - pub fn from_ast1_type( - &self, - pointer_bits: u16, - ty: &crate::ast::Type, - ) -> Index { + pub fn from_ast1_type(&self, pointer_bits: u16, ty: &crate::ast::Type) -> Index { match ty { crate::ast::Type::Bool => self.get_bool_type(), crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(), @@ -856,12 +832,8 @@ impl InternPool { Key::UIntType { bit_width: i.bits } } }), - crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => { - self.get_f32_type() - } - crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => { - self.get_f64_type() - } + crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => self.get_f32_type(), + crate::ast::Type::Floating(crate::ast::FloatingType::Binary64) => self.get_f64_type(), crate::ast::Type::Pointer { constness, pointee } => { let pointee = self.from_ast1_type(pointer_bits, &pointee); self.get_assume_present(&Key::PointerType { @@ -877,8 +849,7 @@ impl InternPool { .iter() .map(|ty| self.from_ast1_type(pointer_bits, ty)) .collect::>(); - let return_type = - self.from_ast1_type(pointer_bits, &return_type); + let return_type = self.from_ast1_type(pointer_bits, &return_type); self.get_assume_present(&Key::FunctionType { return_type, parameters, @@ -891,34 +862,18 @@ impl InternPool { } } - pub fn as_ast1_type( - &self, - pointer_bits: u16, - index: Index, - ) -> crate::ast::Type { + pub fn as_ast1_type(&self, pointer_bits: u16, index: Index) -> crate::ast::Type { use crate::ast::Type; match self.get_key(index) { - Key::UIntType { bit_width: bits } => { - Type::Integer(IntegralType::new(false, bits)) - } - Key::SIntType { bit_width: bits } => { - Type::Integer(IntegralType::new(true, bits)) - } + Key::UIntType { bit_width: bits } => Type::Integer(IntegralType::new(false, bits)), + Key::SIntType { bit_width: bits } => Type::Integer(IntegralType::new(true, bits)), Key::SimpleType { ty } => match ty { - SimpleType::F32 => { - Type::Floating(crate::ast::FloatingType::Binary32) - } - SimpleType::F64 => { - Type::Floating(crate::ast::FloatingType::Binary64) - } + SimpleType::F32 => Type::Floating(crate::ast::FloatingType::Binary32), + SimpleType::F64 => Type::Floating(crate::ast::FloatingType::Binary64), SimpleType::Bool => Type::Bool, SimpleType::Void => Type::Void, - SimpleType::USize => { - Type::Integer(IntegralType::new(false, pointer_bits)) - } - SimpleType::ISize => { - Type::Integer(IntegralType::new(true, pointer_bits)) - } + SimpleType::USize => Type::Integer(IntegralType::new(false, pointer_bits)), + SimpleType::ISize => Type::Integer(IntegralType::new(true, pointer_bits)), SimpleType::ComptimeInt => Type::comptime_number(), }, Key::PointerType { pointee, flags } => Type::Pointer { @@ -933,9 +888,7 @@ impl InternPool { .into_iter() .map(|i| self.as_ast1_type(pointer_bits, i)) .collect(), - return_type: Box::new( - self.as_ast1_type(pointer_bits, return_type), - ), + return_type: Box::new(self.as_ast1_type(pointer_bits, return_type)), }, _ => unimplemented!(), } @@ -1008,12 +961,8 @@ impl InternPool { let words_idx = self.extend_words([start, len]); self.create_item(Tag::String, words_idx) } - Key::SIntSmall { bits } => { - self.create_item(Tag::SIntSmall, bits as u32) - } - Key::UIntSmall { bits } => { - self.create_item(Tag::UIntSmall, bits as u32) - } + Key::SIntSmall { bits } => self.create_item(Tag::SIntSmall, bits as u32), + Key::UIntSmall { bits } => self.create_item(Tag::UIntSmall, bits as u32), Key::F32 { bits } => self.create_item(Tag::F32, bits as u32), Key::F64 { bits } => { let (lo, hi) = into_lo_hi_dwords(bits as u64); @@ -1043,19 +992,12 @@ impl InternPool { self.create_item(Tag::NegativeInt, i) } - Key::UIntType { bit_width: bits } => { - self.create_item(Tag::UIntType, bits as u32) - } - Key::SIntType { bit_width: bits } => { - self.create_item(Tag::SIntType, bits as u32) - } - Key::SimpleType { ty } => { - self.create_item(Tag::SimpleType, ty as u8 as u32) - } + Key::UIntType { bit_width: bits } => self.create_item(Tag::UIntType, bits as u32), + Key::SIntType { bit_width: bits } => self.create_item(Tag::SIntType, bits as u32), + Key::SimpleType { ty } => self.create_item(Tag::SimpleType, ty as u8 as u32), Key::PointerType { pointee, flags } => { let flags = flags.pack(); - let i = - self.extend_words([pointee.index() as u32, flags as u32]); + let i = self.extend_words([pointee.index() as u32, flags as u32]); self.create_item(Tag::PointerType, i) } Key::ArrayType { @@ -1064,11 +1006,7 @@ impl InternPool { length, } => { let flags = flags.pack(); - let i = self.extend_words([ - pointee.index() as u32, - 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 { @@ -1078,15 +1016,8 @@ impl InternPool { c_like, fields, } => { - let flags = - StructFlags::new(packed, c_like, fields.len() as u32) - .pack(); - let i = self.extend_words([ - name.into_u32(), - decl.into_u32(), - flags, - u32::MAX, - ]); + let flags = StructFlags::new(packed, c_like, fields.len() as u32).pack(); + let i = self.extend_words([name.into_u32(), decl.into_u32(), flags, u32::MAX]); if !fields.is_empty() { let fields_offset = self.extend_words( fields @@ -1109,9 +1040,7 @@ 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() as u32), - ); + _ = self.extend_words(parameters.into_iter().map(|i| i.index() as u32)); self.create_item(Tag::FunctionType, start) } @@ -1150,9 +1079,7 @@ impl InternPool { let start = self.words[item.idx()]; let len = self.words[item.idx() + 1]; let str = unsafe { - core::str::from_utf8_unchecked( - &self.strings[start as usize..][..len as usize], - ) + core::str::from_utf8_unchecked(&self.strings[start as usize..][..len as usize]) }; Key::String { str } } @@ -1167,24 +1094,18 @@ impl InternPool { }, Tag::F64 => { let idx = item.idx(); - let bits = - from_lo_hi_dwords(self.words[idx], self.words[idx + 1]); + let bits = from_lo_hi_dwords(self.words[idx], self.words[idx + 1]); Key::F64 { bits: f64::from_le_bytes(bits.to_le_bytes()), } } Tag::SInt64 => { - let bits = from_lo_hi_dwords( - self.words[item.idx()], - self.words[item.idx() + 1], - ) as i64; + let bits = + from_lo_hi_dwords(self.words[item.idx()], self.words[item.idx() + 1]) as i64; Key::SInt64 { bits } } Tag::UInt64 => { - let bits = from_lo_hi_dwords( - self.words[item.idx()], - self.words[item.idx() + 1], - ); + let bits = from_lo_hi_dwords(self.words[item.idx()], self.words[item.idx() + 1]); Key::UInt64 { bits } } Tag::NegativeInt => { @@ -1218,15 +1139,13 @@ impl InternPool { } Tag::PointerType => { let pointee = Index::new(self.words[item.idx()]); - let flags = - PointerFlags::unpack(self.words[item.idx() + 1] as u8); + let flags = PointerFlags::unpack(self.words[item.idx() + 1] as u8); Key::PointerType { pointee, flags } } Tag::ArrayType => { let pointee = Index::new(self.words[item.idx()]); - let flags = - PointerFlags::unpack(self.words[item.idx() + 1] as u8); + let flags = PointerFlags::unpack(self.words[item.idx() + 1] as u8); let length = self.words[item.idx() + 2]; Key::ArrayType { @@ -1237,12 +1156,11 @@ impl InternPool { } Tag::StructType => { let name = Index::new(self.words[item.idx()]); - let decl = super::Index::new(self.words[item.idx() + 1]); + let decl = super::Index::from_u32(self.words[item.idx() + 1]).unwrap(); let flags = StructFlags::unpack(self.words[item.idx() + 2]); let fields = if flags.num_fields != 0 { let fields_offset = self.words[item.idx() + 3] as usize; - let fields_end = - fields_offset + flags.num_fields as usize * 2; + let fields_end = fields_offset + flags.num_fields as usize * 2; self.words[fields_offset..fields_end] .iter() @@ -1322,9 +1240,7 @@ impl InternPool { pub fn get_unsigned_integer(&mut self, value: u64) -> Index { let key = match value { - _ if value <= u32::MAX as u64 => { - Key::UIntSmall { bits: value as u32 } - } + _ if value <= u32::MAX as u64 => Key::UIntSmall { bits: value as u32 }, _ => Key::UInt64 { bits: value as u64 }, }; @@ -1381,11 +1297,7 @@ impl InternPool { }) } - pub fn get_pointer_type( - &mut self, - pointee: Index, - flags: Option, - ) -> Index { + pub fn get_pointer_type(&mut self, pointee: Index, flags: Option) -> Index { let key = Key::PointerType { pointee, flags: flags.unwrap_or_default(), @@ -1405,9 +1317,7 @@ impl InternPool { ) } - pub fn insert_or_replace_struct_type< - I: IntoIterator, - >( + pub fn insert_or_replace_struct_type>( &mut self, name: Index, decl: super::Index, @@ -1422,8 +1332,7 @@ impl InternPool { c_like, fields: vec![], }; - if let Some(i) = self.try_get_index(&key).and_then(|i| self.get_item(i)) - { + if let Some(i) = self.try_get_index(&key).and_then(|i| self.get_item(i)) { let fields_offset = self.extend_words( fields .into_iter() @@ -1439,11 +1348,7 @@ impl InternPool { self.get_or_insert(key) } - pub fn get_struct_type( - &mut self, - name: Index, - decl: super::Index, - ) -> Index { + pub fn get_struct_type(&mut self, name: Index, decl: super::Index) -> Index { let key = Key::StructType { name, decl, @@ -1453,11 +1358,7 @@ impl InternPool { }; self.get_or_insert(key) } - pub fn try_get_struct_type( - &self, - name: Index, - decl: super::Index, - ) -> Option { + pub fn try_get_struct_type(&self, name: Index, decl: super::Index) -> Option { self.try_get_index(&Key::StructType { name, decl, diff --git a/src/ast2/mod.rs b/src/ast2/mod.rs index 7fb873e..02690a1 100644 --- a/src/ast2/mod.rs +++ b/src/ast2/mod.rs @@ -3,21 +3,20 @@ use std::{ collections::BTreeMap, fmt::{Debug, Display}, - num::NonZero, }; use intern::{InternPool, PointerFlags, StructFlags, AMD64_POINTER_TYPE_INFO}; use num_bigint::BigInt; use crate::{ - ast::FloatingType, comptime::ComptimeNumber, lexer::SourceLocation, - tokens::Token, writeln_indented, + ast::FloatingType, comptime::ComptimeNumber, lexer::SourceLocation, tokens::Token, + writeln_indented, }; pub mod intern; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -enum Tag { +pub enum Tag { /// pseudo tag, contains a range from a..b into extra of all files. Root, /// `data` is a range from a..b into extra of all global nodes. @@ -217,31 +216,6 @@ enum ParseError { ErrorNode(Index), } -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(transparent)] -pub struct Index(NonZero); - -impl Display for Index { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "%{}", self.0.get()) - } -} - -impl Index { - pub fn new(i: u32) -> Index { - Self(NonZero::::new(i).unwrap()) - } - pub fn as_u32(&self) -> &u32 { - unsafe { core::mem::transmute(self) } - } - pub fn into_u32(self) -> u32 { - unsafe { core::mem::transmute(self) } - } - fn index(self) -> usize { - self.0.get() as usize - } -} - #[repr(packed)] #[derive(Clone, Copy)] struct Node { @@ -251,7 +225,7 @@ struct Node { } #[derive(Clone, Copy)] -union Data { +pub union Data { none: (), error: ParseError, index: Index, @@ -266,6 +240,23 @@ union Data { index_and_opaque: (Index, u32), } +impl Default for Tag { + fn default() -> Self { + Tag::Undefined + } +} +impl Default for SourceLocation { + fn default() -> Self { + Self::invalid() + } +} + +impl Default for Data { + fn default() -> Self { + Self::none() + } +} + #[derive(Debug)] #[allow(dead_code)] enum ExpandedData { @@ -346,9 +337,7 @@ impl From<(Tag, Data)> for ExpandedData { | Tag::MutVarDeclAssignment | Tag::BlockTrailingExpr | Tag::Block => Self::from_extra_range(data), - Tag::FieldDecl | Tag::Constant | Tag::Parameter => { - Self::from_index_intern(data) - } + Tag::FieldDecl | Tag::Constant | Tag::Parameter => Self::from_index_intern(data), Tag::Or | Tag::And | Tag::BitOr @@ -389,9 +378,7 @@ impl From<(Tag, Data)> for ExpandedData { | Tag::ExplicitCast => Self::from_index_intern(data), Tag::GlobalDecl => Self::from_intern_and_extra_offset(data), Tag::InternedType | Tag::StructDecl => Self::from_intern(data), - Tag::PointerType | Tag::IfElseExpr => { - Self::from_index_and_extra_offset(data) - } + Tag::PointerType | Tag::IfElseExpr => Self::from_index_and_extra_offset(data), Tag::Error => Self::from_error(data), Tag::ReturnStmt | Tag::Undefined => Self::from_none(), } @@ -493,11 +480,203 @@ impl Data { } } +mod index { + use std::num::NonZero; + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] + #[repr(u8)] + pub enum Kind { + Other = 0, + Function, + GlobalDecl, + Error, + File, + } + + impl TryFrom for Kind { + type Error = (); + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(Self::Other), + 1 => Ok(Self::Function), + 2 => Ok(Self::GlobalDecl), + 3 => Ok(Self::Error), + 4 => Ok(Self::File), + _ => Err(()), + } + } + } + + /// Index type that has 28 bits of index and 4 bits of kind. + #[repr(transparent)] + #[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] + pub struct Index(NonZero); + + impl core::fmt::Debug for Index { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Index") + .field("kind", &self.kind()) + .field("index", &self.index_u32()) + .finish() + } + } + + impl core::fmt::Display for Index { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let label = match self.kind() { + Kind::Other => "", + Kind::Function => "funcs.", + Kind::GlobalDecl => "gdecls.", + Kind::Error => "errors.", + Kind::File => "files.", + }; + + write!(f, "%{label}{}", self.index_u32()) + } + } + + impl Index { + pub fn new(kind: Kind, idx: u32) -> Option { + let inner = NonZero::new((kind as u32) << 28 | idx & ((1 << 28) - 1)); + + inner.map(Self) + } + pub fn kind(&self) -> Kind { + Kind::try_from(((self.0.get() >> 28) & 0b1111) as u8).unwrap() + } + pub fn index_u32(&self) -> u32 { + self.0.get() & ((1 << 28) - 1) + } + pub fn index_usize(&self) -> usize { + self.index_u32() as usize + } + pub fn from_u32(inner: u32) -> Option { + NonZero::new(inner).map(Self) + } + pub unsafe fn from_u32_unchecked(inner: u32) -> Self { + Self(NonZero::new_unchecked(inner)) + } + pub fn as_u32(self) -> u32 { + self.0.get() + } + pub fn into_u32(self) -> u32 { + self.0.get() + } + } +} + +pub use index::{Index, Kind}; + +#[derive(Debug, Clone)] +struct AstTables { + functions: Vec, + global_decls: Vec, + errors: Vec, + files: Vec, + other: Vec, +} + +impl core::ops::Index for AstTables { + type Output = T; + + fn index(&self, index: index::Index) -> &Self::Output { + &self.table_ref(index.kind())[index.index_usize()] + } +} + +impl core::ops::IndexMut for AstTables { + fn index_mut(&mut self, index: index::Index) -> &mut Self::Output { + &mut self.table_mut(index.kind())[index.index_usize()] + } +} + +impl AstTables { + fn new() -> Self { + Self { + functions: Vec::new(), + global_decls: Vec::new(), + errors: Vec::new(), + files: Vec::new(), + other: Vec::new(), + } + } + + fn get(&self, index: index::Index) -> Option<&T> { + self.table_ref(index.kind()).get(index.index_usize()) + } + unsafe fn get_unchecked(&self, index: index::Index) -> &T { + self.table_ref(index.kind()) + .get_unchecked(index.index_usize()) + } + + fn init() -> Self + where + T: Default, + { + Self { + functions: Vec::new(), + global_decls: Vec::new(), + errors: Vec::new(), + files: Vec::new(), + other: vec![T::default()], + } + } + + fn push(&mut self, kind: index::Kind, t: T) -> index::Index { + let table = self.table_mut(kind); + let i = table.len(); + table.push(t); + + index::Index::new(kind, i as u32).unwrap() + } + + fn reserve(&mut self, kind: index::Kind) -> index::Index + where + T: Default, + { + self.push(kind, T::default()) + } + + fn table_mut(&mut self, kind: index::Kind) -> &mut Vec { + match kind { + index::Kind::Other => &mut self.other, + index::Kind::Function => &mut self.functions, + index::Kind::GlobalDecl => &mut self.global_decls, + index::Kind::Error => &mut self.errors, + index::Kind::File => &mut self.files, + } + } + + fn table_ref(&self, kind: index::Kind) -> &Vec { + match kind { + index::Kind::Other => &self.other, + index::Kind::Function => &self.functions, + index::Kind::GlobalDecl => &self.global_decls, + index::Kind::Error => &self.errors, + index::Kind::File => &self.files, + } + } + + fn table_len(&self, kind: index::Kind) -> usize { + self.table_ref(kind).len() + } + + fn iter(&self) -> impl Iterator { + self.errors + .iter() + .chain(self.files.iter()) + .chain(self.functions.iter()) + .chain(self.global_decls.iter()) + .chain(self.other.iter()) + } +} + pub struct Ast { - tags: Vec, - datas: Vec, + tags: AstTables, + datas: AstTables, + source_locs: AstTables, extra: Vec, - source_locs: Vec, } impl Debug for Ast { @@ -507,10 +686,7 @@ impl Debug for Ast { let mut list = f.debug_list(); struct LocDisplay(SourceLocation); impl Debug for LocDisplay { - fn fmt( - &self, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "({})", self.0) } } @@ -522,12 +698,7 @@ impl Debug for Ast { .zip(self.source_locs.iter().cloned()) .enumerate() .map(|(i, ((tag, data), loc))| { - ( - i, - tag, - ExpandedData::from((tag, data)), - LocDisplay(loc), - ) + (i, tag, ExpandedData::from((tag, data)), LocDisplay(loc)) }); list.entries(entries).finish() }) @@ -538,69 +709,68 @@ impl Debug for Ast { impl Ast { fn new() -> Ast { + let mut tags = AstTables::new(); + let mut datas = AstTables::new(); + let mut source_locs = AstTables::new(); + + tags.other.push(Tag::Root); + datas.other.push(Data::extra_range(0, 0)); + source_locs.other.push(SourceLocation::new(0, 0)); + Self { - tags: vec![Tag::Root], - datas: vec![Data::extra_range(0, 0)], + tags, + datas, extra: vec![], - source_locs: vec![SourceLocation::new(0, 0)], + source_locs, } } - fn reserve_node(&mut self) -> Index { - let i = - unsafe { Index(NonZero::new_unchecked(self.tags.len() as u32)) }; - self.tags.push(Tag::Undefined); - self.datas.push(Data::none()); - self.source_locs.push(SourceLocation::invalid()); + fn reserve_node_other(&mut self) -> Index { + self.reserve_node(Kind::Other) + } + + fn reserve_node(&mut self, kind: index::Kind) -> Index { + let i = self.tags.reserve(kind); + self.datas.reserve(kind); + self.source_locs.reserve(kind); i } fn get_loc(&self, index: Index) -> SourceLocation { - self.source_locs[index.index()] + self.source_locs[index] } fn push_error(&mut self, error: ParseError, loc: SourceLocation) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node(Kind::Error); self.set_tag_data_source_loc(i, Tag::Error, Data::error(error), loc); i } - fn set_file>( - &mut self, - i: Index, - decls: I, - loc: SourceLocation, - ) { + fn set_file>(&mut self, i: Index, decls: I, loc: SourceLocation) { let (extra_start, extra_end) = self.extend_extra_by_indices(decls); - self.set_tag_data_source_loc( - i, - Tag::File, - Data::extra_range(extra_start, extra_end), - loc, - ); + self.set_tag_data_source_loc(i, Tag::File, Data::extra_range(extra_start, extra_end), loc); } - fn push_file>( - &mut self, - decls: I, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); + fn push_file>(&mut self, decls: I, loc: SourceLocation) -> Index { + let i = self.reserve_node(Kind::File); self.set_file(i, decls, loc); i } fn set_root>(&mut self, decls: I) { let (extra_start, extra_end) = self.extend_extra_by_indices(decls); - self.tags[0] = Tag::Root; - self.datas[0] = Data::extra_range(extra_start, extra_end); + self.tags.other[0] = Tag::Root; + self.datas.other[0] = Data::extra_range(extra_start, extra_end); } fn get_root_file_indices<'a>(&'a self) -> impl Iterator + 'a { - let (a, b) = self.datas[0].as_extra_range(); - self.extra[a..b].iter().cloned().map(|i| Index::new(i)) + let (a, b) = self.datas.other[0].as_extra_range(); + self.extra[a..b] + .iter() + .cloned() + .map(|i| Index::from_u32(i).unwrap()) } fn push_global_decl( @@ -610,9 +780,8 @@ impl Ast { expr: Index, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); - let (extra_start, _) = - self.extend_extra([ty.into_u32(), expr.into_u32()]); + let i = self.reserve_node(Kind::GlobalDecl); + let (extra_start, _) = self.extend_extra([ty.into_u32(), expr.into_u32()]); self.set_tag_data_source_loc( i, Tag::GlobalDecl, @@ -623,47 +792,23 @@ impl Ast { i } - fn set_fn_decl( - &mut self, - i: Index, - proto: Index, - body: Index, - loc: SourceLocation, - ) { - self.set_tag_data_source_loc( - i, - Tag::FunctionDecl, - Data::two_indices(proto, body), - loc, - ); + fn set_fn_decl(&mut self, i: Index, proto: Index, body: Index, loc: SourceLocation) { + self.set_tag_data_source_loc(i, Tag::FunctionDecl, Data::two_indices(proto, body), loc); } - fn push_fn_decl( - &mut self, - proto: Index, - body: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); + fn push_fn_decl(&mut self, proto: Index, body: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node(Kind::Function); self.set_fn_decl(i, proto, body, loc); i } fn push_ret(&mut self, expr: Option, loc: SourceLocation) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node(Kind::Other); match expr { - Some(expr) => self.set_tag_data_source_loc( - i, - Tag::ReturnExprStmt, - Data::index(expr), - loc, - ), - None => self.set_tag_data_source_loc( - i, - Tag::ReturnStmt, - Data::none(), - loc, - ), + Some(expr) => { + self.set_tag_data_source_loc(i, Tag::ReturnExprStmt, Data::index(expr), loc) + } + None => self.set_tag_data_source_loc(i, Tag::ReturnStmt, Data::none(), loc), } i @@ -677,7 +822,7 @@ impl Ast { assignment: Option, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); let start = self.extra.len() as u32; self.extra.push(name.into_u32()); @@ -692,12 +837,7 @@ impl Ast { (false, true) => Tag::MutVarDeclAssignment, }; - self.set_tag_data_source_loc( - i, - tag, - Data::extra_range(start, end), - loc, - ); + self.set_tag_data_source_loc(i, tag, Data::extra_range(start, end), loc); i } @@ -709,9 +849,9 @@ impl Ast { parameter_list: Index, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); - let (extra_start, _) = self - .extend_extra([return_type.into_u32(), parameter_list.into_u32()]); + let i = self.reserve_node_other(); + let (extra_start, _) = + self.extend_extra([return_type.into_u32(), parameter_list.into_u32()]); self.set_tag_data_source_loc( i, Tag::FunctionProto, @@ -729,9 +869,8 @@ impl Ast { trailing: Option, loc: SourceLocation, ) { - let (extra_start, extra_end) = self.extend_extra_by_indices( - statements.into_iter().chain(trailing.into_iter()), - ); + let (extra_start, extra_end) = + self.extend_extra_by_indices(statements.into_iter().chain(trailing.into_iter())); if trailing.is_some() { self.set_tag_data_source_loc( i, @@ -755,7 +894,7 @@ impl Ast { trailing: Option, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); self.set_block(i, statements, trailing, loc); i } @@ -765,7 +904,7 @@ impl Ast { parameters: I, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); let (extra_start, extra_end) = self.extend_extra_by_indices(parameters); self.set_tag_data_source_loc( i, @@ -778,7 +917,7 @@ impl Ast { } fn push_argument(&mut self, expr: Index, loc: SourceLocation) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); self.set_tag_data_source_loc(i, Tag::Argument, Data::index(expr), loc); i @@ -790,7 +929,7 @@ impl Ast { expr: Index, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); self.set_tag_data_source_loc( i, Tag::NamedArgument, @@ -801,19 +940,9 @@ impl Ast { i } - fn push_parameter( - &mut self, - name: intern::Index, - ty: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); - self.set_tag_data_source_loc( - i, - Tag::Parameter, - Data::index_and_intern(ty, name), - loc, - ); + fn push_parameter(&mut self, name: intern::Index, ty: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); + self.set_tag_data_source_loc(i, Tag::Parameter, Data::index_and_intern(ty, name), loc); i } @@ -823,7 +952,7 @@ impl Ast { args: I, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); let (extra_start, extra_end) = self.extend_extra_by_indices(args); self.set_tag_data_source_loc( i, @@ -835,78 +964,37 @@ impl Ast { i } - fn push_unary( - &mut self, - tag: Tag, - lhs: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); + fn push_unary(&mut self, tag: Tag, lhs: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); self.set_tag_data_source_loc(i, tag, Data::index(lhs), loc); i } - fn push_binary( - &mut self, - tag: Tag, - lhs: Index, - rhs: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); + fn push_binary(&mut self, tag: Tag, lhs: Index, rhs: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); self.set_tag_data_source_loc(i, tag, Data::two_indices(lhs, rhs), loc); i } - fn push_assign( - &mut self, - lhs: Index, - rhs: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); - self.set_tag_data_source_loc( - i, - Tag::Assign, - Data::two_indices(lhs, rhs), - loc, - ); + fn push_assign(&mut self, lhs: Index, rhs: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); + self.set_tag_data_source_loc(i, Tag::Assign, Data::two_indices(lhs, rhs), loc); i } - fn push_cast( - &mut self, - lhs: Index, - ty: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); - self.set_tag_data_source_loc( - i, - Tag::ExplicitCast, - Data::two_indices(lhs, ty), - loc, - ); + fn push_cast(&mut self, lhs: Index, ty: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); + self.set_tag_data_source_loc(i, Tag::ExplicitCast, Data::two_indices(lhs, ty), loc); i } - fn push_if( - &mut self, - cond: Index, - body: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); - self.set_tag_data_source_loc( - i, - Tag::IfExpr, - Data::two_indices(cond, body), - loc, - ); + fn push_if(&mut self, cond: Index, body: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); + self.set_tag_data_source_loc(i, Tag::IfExpr, Data::two_indices(cond, body), loc); i } @@ -918,7 +1006,7 @@ impl Ast { other: Index, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); let (extra_start, _) = self.extend_extra_by_indices([body, other]); self.set_tag_data_source_loc( i, @@ -930,19 +1018,9 @@ impl Ast { i } - fn push_call_expr( - &mut self, - lhs: Index, - args: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); - self.set_tag_data_source_loc( - i, - Tag::CallExpr, - Data::two_indices(lhs, args), - loc, - ); + fn push_call_expr(&mut self, lhs: Index, args: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); + self.set_tag_data_source_loc(i, Tag::CallExpr, Data::two_indices(lhs, args), loc); i } @@ -953,7 +1031,7 @@ impl Ast { ident: intern::Index, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); self.set_tag_data_source_loc( i, Tag::DeclRefUnresolved, @@ -965,8 +1043,8 @@ impl Ast { } fn resolve_decl_ref(&mut self, i: Index, decl: Index) { - self.tags[i.index()] = Tag::DeclRef; - self.datas[i.index()] = Data::index(decl); + self.tags[i] = Tag::DeclRef; + self.datas[i] = Data::index(decl); } fn push_struct_decl>( @@ -976,7 +1054,7 @@ impl Ast { fields: I, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node(Kind::GlobalDecl); self.set_struct_decl(i, name, flags, fields, loc) } @@ -1004,19 +1082,9 @@ impl Ast { i } - fn push_field_decl( - &mut self, - name: intern::Index, - ty: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); - self.set_tag_data_source_loc( - i, - Tag::FieldDecl, - Data::index_and_intern(ty, name), - loc, - ); + fn push_field_decl(&mut self, name: intern::Index, ty: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); + self.set_tag_data_source_loc(i, Tag::FieldDecl, Data::index_and_intern(ty, name), loc); i } @@ -1027,29 +1095,15 @@ impl Ast { name: intern::Index, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); - self.set_tag_data_source_loc( - i, - Tag::FieldAccess, - Data::index_and_intern(expr, name), - loc, - ); + let i = self.reserve_node_other(); + self.set_tag_data_source_loc(i, Tag::FieldAccess, Data::index_and_intern(expr, name), loc); i } - fn push_interend_type( - &mut self, - ty: intern::Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); - self.set_tag_data_source_loc( - i, - Tag::InternedType, - Data::intern(ty), - loc, - ); + fn push_interend_type(&mut self, ty: intern::Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); + self.set_tag_data_source_loc(i, Tag::InternedType, Data::intern(ty), loc); i } @@ -1060,7 +1114,7 @@ impl Ast { pointer_ty: Index, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); self.set_tag_data_source_loc( i, Tag::ArrayType, @@ -1071,13 +1125,8 @@ impl Ast { i } - fn push_pointer_type( - &mut self, - ty: Index, - flags: PointerFlags, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); + fn push_pointer_type(&mut self, ty: Index, flags: PointerFlags, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); self.set_tag_data_source_loc( i, Tag::PointerType, @@ -1094,7 +1143,7 @@ impl Ast { ident: intern::Index, loc: SourceLocation, ) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); self.set_tag_data_source_loc( i, Tag::TypeDeclRefUnresolved, @@ -1106,60 +1155,38 @@ impl Ast { } fn resolve_type_ref(&mut self, i: Index, decl: Index) { - self.tags[i.index()] = Tag::TypeDeclRef; - self.datas[i.index()] = Data::index(decl); + self.tags[i] = Tag::TypeDeclRef; + self.datas[i] = Data::index(decl); } fn push_expr_stmt(&mut self, expr: Index) -> Index { - let i = self.reserve_node(); + let i = self.reserve_node_other(); let loc = self.get_loc(expr); self.set_tag_data_source_loc(i, Tag::ExprStmt, Data::index(expr), loc); i } - fn push_constant( - &mut self, - value: intern::Index, - ty: Index, - loc: SourceLocation, - ) -> Index { - let i = self.reserve_node(); - self.set_tag_data_source_loc( - i, - Tag::Constant, - Data::index_and_intern(ty, value), - loc, - ); + fn push_constant(&mut self, value: intern::Index, ty: Index, loc: SourceLocation) -> Index { + let i = self.reserve_node_other(); + self.set_tag_data_source_loc(i, Tag::Constant, Data::index_and_intern(ty, value), loc); i } - fn extend_extra_by_indices>( - &mut self, - indices: I, - ) -> (u32, u32) { - self.extend_extra(indices.into_iter().map(|i| i.0.get())) + fn extend_extra_by_indices>(&mut self, indices: I) -> (u32, u32) { + self.extend_extra(indices.into_iter().map(|i| i.as_u32())) } - fn extend_extra>( - &mut self, - words: I, - ) -> (u32, u32) { + fn extend_extra>(&mut self, words: I) -> (u32, u32) { let i = self.extra.len() as u32; self.extra.extend(words); (i, self.extra.len() as u32) } - fn set_tag_data_source_loc( - &mut self, - index: Index, - tag: Tag, - data: Data, - loc: SourceLocation, - ) { - self.tags[index.index()] = tag; - self.datas[index.index()] = data; - self.source_locs[index.index()] = loc; + fn set_tag_data_source_loc(&mut self, index: Index, tag: Tag, data: Data, loc: SourceLocation) { + self.tags[index] = tag; + self.datas[index] = data; + self.source_locs[index] = loc; } } @@ -1223,8 +1250,8 @@ impl Ast { } let void = ip.get_void_type(); - let tag = self.tags[index.index()]; - let data = self.datas[index.index()]; + let tag = self.tags[index]; + let data = self.datas[index]; let ty = match tag { Tag::ArgumentList @@ -1235,45 +1262,46 @@ impl Ast { | Tag::File => void, Tag::VarDeclAssignment | Tag::MutVarDeclAssignment => { let (_, b) = data.as_extra_range(); - self.get_type_of_node(ip, cache, Index::new(self.extra[b - 1])) + self.get_type_of_node(ip, cache, Index::from_u32(self.extra[b - 1]).unwrap()) } Tag::VarDecl | Tag::MutVarDecl => { - let (a, b) = data.as_extra_range(); - self.get_type_of_node(ip, cache, Index::new(self.extra[a + 1])) + let (a, _b) = data.as_extra_range(); + self.get_type_of_node(ip, cache, Index::from_u32(self.extra[a + 1]).unwrap()) } Tag::GlobalDecl => { let (_, a) = data.as_intern_and_extra_offset(); - self.get_type_of_node(ip, cache, Index::new(self.extra[a])) - } - Tag::FunctionDecl => { - self.get_type_of_node(ip, cache, data.as_two_indices().0) + self.get_type_of_node(ip, cache, Index::from_u32(self.extra[a]).unwrap()) } + Tag::FunctionDecl => self.get_type_of_node(ip, cache, data.as_two_indices().0), Tag::FunctionProto => { let (_, i) = data.as_intern_and_extra_offset(); - let return_type = - { self.datas[self.extra[i] as usize].as_intern() }; + let (return_type, parameter_list) = ( + Index::from_u32(self.extra[i]).unwrap(), + Index::from_u32(self.extra[i + 1]).unwrap(), + ); + let return_type = self.datas[return_type].as_intern(); let parameters = { - let (a, b) = - self.datas[self.extra[i + 1] as usize].as_extra_range(); - self.extra[a..b].iter().map(|&i| { - // i is index to a parameter, a parameter is (index, intern) - let ty = self.datas[i as usize].as_index_intern().0; - self.datas[ty.index()].as_intern() - }) + let (a, b) = self.datas[parameter_list].as_extra_range(); + self.extra[a..b] + .iter() + .map(|&i| Index::from_u32(i).unwrap()) + .map(|i| { + // i is index to a parameter, a parameter is (index, intern) + let ty = self.datas[i].as_index_intern().0; + self.datas[ty].as_intern() + }) }; ip.try_get_function_type(return_type, parameters).unwrap() } Tag::BlockTrailingExpr => { - let (a, b) = data.as_extra_range(); - self.get_type_of_node(ip, cache, Index::new(self.extra[b - 1])) + let (_a, b) = data.as_extra_range(); + self.get_type_of_node(ip, cache, Index::from_u32(self.extra[b - 1]).unwrap()) } Tag::CallExpr => { let (expr, _args) = data.as_two_indices(); let fn_ty = self.get_type_of_node(ip, cache, expr); - if let intern::Key::FunctionType { return_type, .. } = - ip.get_key(fn_ty) - { + if let intern::Key::FunctionType { return_type, .. } = ip.get_key(fn_ty) { return_type } else { eprintln!( @@ -1297,8 +1325,7 @@ impl Ast { let ty = self.get_type_of_node(ip, cache, ty_expr); match ip.get_key(ty) { intern::Key::PointerType { pointee, .. } - if let intern::Key::StructType { fields, .. } = - ip.get_key(pointee) => + if let intern::Key::StructType { fields, .. } = ip.get_key(pointee) => { fields .iter() @@ -1320,8 +1347,7 @@ impl Ast { } Tag::Deref => { let ty = self.get_type_of_node(ip, cache, data.as_index()); - if let intern::Key::PointerType { pointee, .. } = ip.get_key(ty) - { + if let intern::Key::PointerType { pointee, .. } = ip.get_key(ty) { pointee } else { eprintln!("lhs of deref is not a pointer!"); @@ -1329,15 +1355,12 @@ impl Ast { } } Tag::SubscriptExpr => { - let ty = - self.get_type_of_node(ip, cache, data.as_two_indices().0); + let ty = self.get_type_of_node(ip, cache, data.as_two_indices().0); match ip.get_key(ty) { intern::Key::PointerType { pointee, .. } | intern::Key::ArrayType { pointee, .. } => pointee, _ => { - eprintln!( - "lhs of subscript is not an array or pointer!" - ); + eprintln!("lhs of subscript is not an array or pointer!"); void } } @@ -1347,9 +1370,7 @@ impl Ast { // TODO: find out of the expression is const, volatile for flags ip.try_get_pointer_type(ty, None).unwrap() } - Tag::Not | Tag::Negate => { - self.get_type_of_node(ip, cache, data.as_index()) - } + Tag::Not | Tag::Negate => self.get_type_of_node(ip, cache, data.as_index()), Tag::Or | Tag::And | Tag::BitOr @@ -1367,13 +1388,11 @@ impl Ast { | Tag::Sub | Tag::Mul | Tag::Div - | Tag::Rem => { - self.get_type_of_node(ip, cache, data.as_two_indices().0) - } + | Tag::Rem => self.get_type_of_node(ip, cache, data.as_two_indices().0), Tag::IfExpr => ip.get_bool_type(), // really? Tag::IfElseExpr => { let (_, b) = data.as_index_and_extra_offset(); - let if_ = Index::new(self.extra[b]); + let if_ = Index::from_u32(self.extra[b]).unwrap(); self.get_type_of_node(ip, cache, if_) } Tag::Constant | Tag::Parameter => { @@ -1390,14 +1409,11 @@ impl Ast { | Tag::Error | Tag::Undefined | Tag::ReturnStmt => void, - Tag::FieldDecl => { - self.get_type_of_node(ip, cache, data.as_index_intern().0) - } + Tag::FieldDecl => self.get_type_of_node(ip, cache, data.as_index_intern().0), Tag::InternedType => data.as_intern(), - Tag::TypeDeclRef - | Tag::TypeDeclRefUnresolved - | Tag::PointerType - | Tag::ArrayType => ip.get_void_type(), + Tag::TypeDeclRef | Tag::TypeDeclRefUnresolved | Tag::PointerType | Tag::ArrayType => { + ip.get_void_type() + } }; cache.insert(index, ty); @@ -1405,19 +1421,22 @@ impl Ast { } fn get_node_children(&self, index: Index) -> Vec { - let tag = self.tags[index.index()]; - let data = self.datas[index.index()]; + let tag = self.tags[index]; + let data = self.datas[index]; match tag { Tag::File => { let (a, b) = data.as_extra_range(); - self.extra[a..b].iter().map(|&i| Index::new(i)).collect() + self.extra[a..b] + .iter() + .map(|&i| Index::from_u32(i).unwrap()) + .collect() } Tag::FunctionProto => { let (_, i) = data.as_intern_and_extra_offset(); self.extra[i..=i + 1] .iter() - .map(|&i| Index::new(i)) + .map(|&i| Index::from_u32(i).unwrap()) .collect() } Tag::FunctionDecl => { @@ -1426,11 +1445,17 @@ impl Ast { } Tag::ParameterList => { let (a, b) = data.as_extra_range(); - self.extra[a..b].iter().map(|&i| Index::new(i)).collect() + self.extra[a..b] + .iter() + .map(|&i| Index::from_u32(i).unwrap()) + .collect() } Tag::Block | Tag::BlockTrailingExpr => { let (a, b) = data.as_extra_range(); - self.extra[a..b].iter().map(|&i| Index::new(i)).collect() + self.extra[a..b] + .iter() + .map(|&i| Index::from_u32(i).unwrap()) + .collect() } Tag::ExprStmt | Tag::ReturnExprStmt => { let a = data.as_index(); @@ -1440,14 +1465,14 @@ impl Ast { let (a, b) = data.as_extra_range(); self.extra[a + 1..b] .iter() - .map(|&i| Index::new(i)) + .map(|&i| Index::from_u32(i).unwrap()) .collect() } Tag::GlobalDecl => { let (_, offset) = data.as_intern_and_extra_offset(); self.extra[offset..=offset + 1] .iter() - .map(|&i| Index::new(i)) + .map(|&i| Index::from_u32(i).unwrap()) .collect() } Tag::CallExpr | Tag::ExplicitCast => { @@ -1456,7 +1481,10 @@ impl Ast { } Tag::ArgumentList => { let (a, b) = data.as_extra_range(); - self.extra[a..b].iter().map(|&i| Index::new(i)).collect() + self.extra[a..b] + .iter() + .map(|&i| Index::from_u32(i).unwrap()) + .collect() } Tag::Argument => { let a = data.as_index(); @@ -1497,8 +1525,8 @@ impl Ast { } Tag::IfElseExpr => { let (a, b) = data.as_index_and_extra_offset(); - let if_ = Index::new(self.extra[b]); - let else_ = Index::new(self.extra[b + 1]); + let if_ = Index::from_u32(self.extra[b]).unwrap(); + let else_ = Index::from_u32(self.extra[b + 1]).unwrap(); vec![a, if_, else_] } Tag::PointerType => { @@ -1506,11 +1534,11 @@ impl Ast { vec![a] } Tag::StructDecl => { - let (a, offset) = data.as_intern_and_extra_offset(); + let (_a, offset) = data.as_intern_and_extra_offset(); let flags = StructFlags::unpack(self.extra[offset]); self.extra[offset + 1..(offset + 1 + flags.num_fields as usize)] .iter() - .map(|&i| Index::new(i)) + .map(|&i| Index::from_u32(i).unwrap()) .collect() } Tag::InternedType @@ -1529,30 +1557,25 @@ impl Ast { Tag::VarDecl | Tag::MutVarDecl => { let (a, _) = data.as_extra_range(); - vec![Index::new(self.extra[a + 1])] + vec![Index::from_u32(self.extra[a + 1]).unwrap()] } } } - fn is_node_comptime_evaluable( - &self, - cache: &mut ComptimeCache, - index: Index, - ) -> bool { + fn is_node_comptime_evaluable(&self, cache: &mut ComptimeCache, index: Index) -> bool { if let Some(a) = cache.get(&index) { a } else { - let tag = self.tags[index.index()]; - let data = self.datas[index.index()]; + let tag = self.tags[index]; + let data = self.datas[index]; let children = self.get_node_children(index); - let are_children_comptime = - |this: &Self, cache: &mut ComptimeCache| { - children - .iter() - .all(|&i| this.is_node_comptime_evaluable(cache, i)) - }; + let are_children_comptime = |this: &Self, cache: &mut ComptimeCache| { + children + .iter() + .all(|&i| this.is_node_comptime_evaluable(cache, i)) + }; let is_comptime = match tag { Tag::Parameter => false, @@ -1569,13 +1592,8 @@ impl Ast { Tag::GlobalDecl => true, Tag::StructDecl => true, Tag::FieldDecl => true, - Tag::DeclRef => { - self.tags[data.as_index().index()] == Tag::GlobalDecl - } - Tag::InternedType - | Tag::PointerType - | Tag::ArrayType - | Tag::TypeDeclRef => true, + Tag::DeclRef => self.tags[data.as_index()] == Tag::GlobalDecl, + Tag::InternedType | Tag::PointerType | Tag::ArrayType | Tag::TypeDeclRef => true, // Tag::CallExpr => are_children_comptime(self, cache), // Tag::FieldAccess => { // let parent = data.as_index_intern().0; @@ -1583,15 +1601,13 @@ impl Ast { // self.is_node_comptime_evaluable(cache, parent) // } Tag::ArgumentList => are_children_comptime(self, cache), - Tag::Argument => { - self.is_node_comptime_evaluable(cache, data.as_index()) + Tag::Argument => self.is_node_comptime_evaluable(cache, data.as_index()), + Tag::NamedArgument => { + self.is_node_comptime_evaluable(cache, data.as_index_intern().0) + } + Tag::ExplicitCast => { + self.is_node_comptime_evaluable(cache, data.as_two_indices().0) } - Tag::NamedArgument => self.is_node_comptime_evaluable( - cache, - data.as_index_intern().0, - ), - Tag::ExplicitCast => self - .is_node_comptime_evaluable(cache, data.as_two_indices().0), Tag::Deref | Tag::AddressOf => false, Tag::Not | Tag::Negate @@ -1644,8 +1660,8 @@ impl Ast { cache: &mut TypeCache, index: Index, ) -> Option { - let tag = self.tags[index.index()]; - let data = self.datas[index.index()]; + let tag = self.tags[index]; + let data = self.datas[index]; match tag { Tag::Constant => { @@ -1664,7 +1680,7 @@ impl Ast { ip, pointer_bits, cache, - Index::new(self.extra[offset + 1]), + Index::from_u32(self.extra[offset + 1]).unwrap(), ) } Tag::VarDeclAssignment => { @@ -1673,23 +1689,14 @@ impl Ast { ip, pointer_bits, cache, - Index::new(self.extra[a + 1]), + Index::from_u32(self.extra[a + 1]).unwrap(), ) } - Tag::DeclRef => self.comptime_value_of_node( - ip, - pointer_bits, - cache, - data.as_index(), - ), + Tag::DeclRef => self.comptime_value_of_node(ip, pointer_bits, cache, data.as_index()), Tag::ExplicitCast => { let (expr, ty) = data.as_two_indices(); - let ty = ip.as_ast1_type( - intern::AMD64_POINTER_BITS, - self.datas[ty.index()].as_intern(), - ); - let val = - self.comptime_value_of_node(ip, pointer_bits, cache, expr); + let ty = ip.as_ast1_type(intern::AMD64_POINTER_BITS, self.datas[ty].as_intern()); + let val = self.comptime_value_of_node(ip, pointer_bits, cache, expr); val.and_then(|i| i.explicit_cast(ty).ok()) } Tag::Add => { @@ -1939,45 +1946,30 @@ pub fn interned_type_and_value_to_comptime_number( let ty_key = ip.get_key(ty); let signed = ip.is_type_signed(ty, AMD64_POINTER_TYPE_INFO); match ty_key { - intern::Key::SIntType { bit_width: bits } - | intern::Key::UIntType { bit_width: bits } => { + intern::Key::SIntType { bit_width: bits } | intern::Key::UIntType { bit_width: bits } => { let ty = IntegralType::new(signed, bits); match ip.get_key(val) { - intern::Key::SIntSmall { bits } => { - ComptimeNumber::Integral(ComptimeInt::Native { - bits: bits as _, - ty, - }) - } - intern::Key::UIntSmall { bits } => { - ComptimeNumber::Integral(ComptimeInt::Native { - bits: bits as _, - ty, - }) - } - intern::Key::SInt64 { bits } => { - ComptimeNumber::Integral(ComptimeInt::Native { - bits: bits as _, - ty, - }) - } - intern::Key::UInt64 { bits } => { - ComptimeNumber::Integral(ComptimeInt::Native { - bits: bits as _, - ty, - }) - } + intern::Key::SIntSmall { bits } => ComptimeNumber::Integral(ComptimeInt::Native { + bits: bits as _, + ty, + }), + intern::Key::UIntSmall { bits } => ComptimeNumber::Integral(ComptimeInt::Native { + bits: bits as _, + ty, + }), + intern::Key::SInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native { + bits: bits as _, + ty, + }), + intern::Key::UInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native { + bits: bits as _, + ty, + }), intern::Key::PositiveInt { bigint } => { - ComptimeNumber::Integral(ComptimeInt::BigInt { - bits: bigint, - ty, - }) + ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty }) } intern::Key::NegativeInt { bigint } => { - ComptimeNumber::Integral(ComptimeInt::BigInt { - bits: bigint, - ty, - }) + ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty }) } _ => { unreachable!() @@ -2031,29 +2023,19 @@ pub fn interned_type_and_value_to_comptime_number( ty, }) } - intern::Key::SInt64 { bits } => { - ComptimeNumber::Integral(ComptimeInt::Native { - bits: bits as _, - ty, - }) - } - intern::Key::UInt64 { bits } => { - ComptimeNumber::Integral(ComptimeInt::Native { - bits: bits as _, - ty, - }) - } + intern::Key::SInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native { + bits: bits as _, + ty, + }), + intern::Key::UInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native { + bits: bits as _, + ty, + }), intern::Key::PositiveInt { bigint } => { - ComptimeNumber::Integral(ComptimeInt::BigInt { - bits: bigint, - ty, - }) + ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty }) } intern::Key::NegativeInt { bigint } => { - ComptimeNumber::Integral(ComptimeInt::BigInt { - bits: bigint, - ty, - }) + ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty }) } _ => { unreachable!() @@ -2074,8 +2056,9 @@ pub fn interned_type_and_value_to_comptime_number( intern::Key::UInt64 { bits } => { BigInt::from_signed_bytes_le(&bits.to_le_bytes()) } - intern::Key::PositiveInt { bigint } - | intern::Key::NegativeInt { bigint } => bigint, + intern::Key::PositiveInt { bigint } | intern::Key::NegativeInt { bigint } => { + bigint + } _ => { unreachable!() } @@ -2141,7 +2124,7 @@ pub mod visitor { } fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data) { - (self.tags[node.index()], self.datas[node.index()]) + (self.tags[node], self.datas[node]) } } impl AstExt for &mut Ast { @@ -2150,7 +2133,7 @@ pub mod visitor { } fn get_node_tag_and_data(&self, node: Index) -> (Tag, Data) { - (self.tags[node.index()], self.datas[node.index()]) + (self.tags[node], self.datas[node]) } } @@ -2224,10 +2207,7 @@ pub mod visitor { } } } - pub fn visit_pre( - &mut self, - mut cb: F, - ) { + pub fn visit_pre(&mut self, mut cb: F) { while let Some(node) = self.nodes.pop() { match node { A::PushChildren(i) => { @@ -2277,10 +2257,7 @@ pub mod visitor { } } } - pub fn visit_post( - &mut self, - mut cb: F, - ) { + pub fn visit_post(&mut self, mut cb: F) { while let Some(node) = self.nodes.pop() { match node { A::PushChildren(i) => { @@ -2354,13 +2331,13 @@ pub struct NodeDisplay<'a> { impl<'a> Display for NodeDisplay<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let node = self.node; - let tag = self.ast.tags[node.index()]; - let loc = self.ast.source_locs[node.index()]; + let tag = self.ast.tags[node]; + let loc = self.ast.source_locs[node]; let children = Children(self.ast.get_node_children(node)); - let ty = - self.ast - .get_type_of_node(self.ip, &mut TypeCache::new(), node); + let ty = self + .ast + .get_type_of_node(self.ip, &mut TypeCache::new(), node); let is_comptime = self .ast @@ -2392,12 +2369,11 @@ impl<'a> AstRenderer<'a> { fn render(&mut self, w: &mut W) -> core::fmt::Result { self.ast.visitor().visit_pre(|ast, scopes, node, tag, _| { - let loc = ast.source_locs[node.index()]; + let loc = ast.source_locs[node]; let children = Children(ast.get_node_children(node)); let ty = self.ast.get_type_of_node(self.ip, &mut self.cache, node); - let is_comptime = - ast.is_node_comptime_evaluable(&mut self.comptime_cache, node); + let is_comptime = ast.is_node_comptime_evaluable(&mut self.comptime_cache, node); _ = writeln_indented!( scopes.len() as u32 * 2, w, @@ -2476,8 +2452,7 @@ pub mod ast_gen { pub fn create_comptime_folding_graph(&mut self, pointer_bits: u16) { let mut type_cache = TypeCache::new(); let mut cache = ComptimeCache::default(); - let mut nodes = - self.ast.get_root_file_indices().collect::>(); + let mut nodes = self.ast.get_root_file_indices().collect::>(); while let Some(node) = nodes.pop() { if !self.ast.is_node_comptime_evaluable(&mut cache, node) { nodes.extend(self.ast.get_node_children(node)); @@ -2489,25 +2464,19 @@ pub mod ast_gen { .inner .iter() .filter(|(_, b)| **b) - .map(|(e, _)| { - self.ast.get_node_children(*e).into_iter().map(|d| (*e, d)) - }) + .map(|(e, _)| self.ast.get_node_children(*e).into_iter().map(|d| (*e, d))) .flatten() // .map(|(a, b)| (a.into_u32(), b.into_u32())) .map(|(a, b)| { ( - node_map.iter().position(|&i| i == a).unwrap_or_else( - || { - node_map.push(a); - node_map.len() - 1 - }, - ) as u32, - node_map.iter().position(|&i| i == b).unwrap_or_else( - || { - node_map.push(b); - node_map.len() - 1 - }, - ) as u32, + node_map.iter().position(|&i| i == a).unwrap_or_else(|| { + node_map.push(a); + node_map.len() - 1 + }) as u32, + node_map.iter().position(|&i| i == b).unwrap_or_else(|| { + node_map.push(b); + node_map.len() - 1 + }) as u32, ) }) .collect::>(); @@ -2516,19 +2485,14 @@ pub mod ast_gen { .inner .iter() .filter(|(_, b)| **b) - .filter_map(|(i, _)| { - (!node_map.contains(i)).then(|| node_map.push(*i)) - }) + .filter_map(|(i, _)| (!node_map.contains(i)).then(|| node_map.push(*i))) .count(); eprintln!("cache: {cache:?}"); eprintln!("node_map: {node_map:?}"); eprintln!("edges: {edges:?}"); - let mut graph = - petgraph::stable_graph::StableDiGraph::<(), ()>::from_edges( - edges, - ); + let mut graph = petgraph::stable_graph::StableDiGraph::<(), ()>::from_edges(edges); for _ in 0..extra_nodes { graph.add_node(()); } @@ -2539,44 +2503,31 @@ pub mod ast_gen { petgraph::dot::Dot::with_attr_getters( &graph, &[], - &|graph, edgeref| { "".to_string() }, - &|graph, noderef| { - format!( - "label = \"{}\"", - node_map[noderef.0.index()] - ) + &|_graph, _edgeref| { "".to_string() }, + &|_graph, noderef| { + format!("label = \"{}\"", node_map[noderef.0.index()]) } ) ), ) .expect("writing comptime graph repr"); - while let Some(external) = - graph.externals(petgraph::Direction::Outgoing).next() - { + while let Some(external) = graph.externals(petgraph::Direction::Outgoing).next() { let node = node_map[external.index()]; - if !(self.ast.tags[node.index()] == Tag::Constant - || self.ast.tags[node.index()].is_type()) - && self.ast.tags[node.index()].is_expr() + if !(self.ast.tags[node] == Tag::Constant || self.ast.tags[node].is_type()) + && self.ast.tags[node].is_expr() { eprintln!("folding {node}:\n{}", self.node_display(node)); let value = self .ast - .comptime_value_of_node( - &self.intern, - pointer_bits, - &mut type_cache, - node, - ) + .comptime_value_of_node(&self.intern, pointer_bits, &mut type_cache, node) .expect(&format!("{node} has value of None?")); - let (value, ty) = - comptime_number_to_interned_type_and_value( - &mut self.intern, - pointer_bits, - value, - ); - let ty = - self.ast.push_interend_type(ty, self.ast.get_loc(node)); + let (value, ty) = comptime_number_to_interned_type_and_value( + &mut self.intern, + pointer_bits, + value, + ); + let ty = self.ast.push_interend_type(ty, self.ast.get_loc(node)); self.ast.set_tag_data_source_loc( node, Tag::Constant, @@ -2594,23 +2545,22 @@ pub mod ast_gen { /// folds more AST-patterns into structures that are easier to build the IR with pub fn fold_more_patterns(&mut self) { use visitor::AstExt; - self.ast.visitor_mut().visit_post(|ast, _, i, tag, data| { + self.ast.visitor_mut().visit_post(|ast, _, _i, tag, data| { match tag { // normalise functions with block-with-trailing-expr into block Tag::FunctionDecl => { let (_, block) = data.as_two_indices(); - let (block_tag, block_data) = - ast.get_node_tag_and_data(block); + let (block_tag, block_data) = ast.get_node_tag_and_data(block); if block_tag == Tag::BlockTrailingExpr { let (_, end) = block_data.as_extra_range(); let end = end - 1; - let expr = Index::new(ast.extra[end]); + let expr = Index::from_u32(ast.extra[end]).unwrap(); let loc = ast.get_loc(expr); let ret = ast.push_ret(Some(expr), loc); // modify last element in place to be a return instruction - ast.extra[end] = *ret.as_u32(); - ast.tags[block.index()] = Tag::Block; + ast.extra[end] = ret.as_u32(); + ast.tags[block] = Tag::Block; eprintln!("folding ({block}): {block_tag:?} into Tag::Block"); eprintln!("expr: {expr:?}"); } @@ -2626,12 +2576,12 @@ pub mod ast_gen { Tag::ArrayType => { let (length, pointee) = data.as_two_indices(); let pointee = - ast.datas[pointee.index()].as_intern(); + ast.datas[pointee].as_intern(); variant!( self.intern.get_key(pointee) => intern::Key::PointerType { pointee, flags }); // get interened value from constant node let length = { - let value = ast.datas[length.index()] + let value = ast.datas[length] .as_index_intern() .1; @@ -2664,48 +2614,54 @@ pub mod ast_gen { Some(flags), length, ); - ast.tags[i.index()] = Tag::InternedType; - ast.datas[i.index()] = Data::intern(ty); + ast.tags[i] = Tag::InternedType; + ast.datas[i] = Data::intern(ty); } Tag::PointerType => { let (pointee, flags) = data.as_index_and_extra_offset(); let pointee = - ast.datas[pointee.index()].as_intern(); + ast.datas[pointee].as_intern(); let ty = self.intern.get_pointer_type( pointee, Some(PointerFlags::unpack(flags as u8)), ); - ast.tags[i.index()] = Tag::InternedType; - ast.datas[i.index()] = Data::intern(ty); + ast.tags[i] = Tag::InternedType; + ast.datas[i] = Data::intern(ty); } Tag::TypeDeclRef => { let decl = data.as_index(); - let (name, _) = ast.datas[decl.index()] + let (name, _) = ast.datas[decl] .as_intern_and_extra_offset(); let ty = self.intern.get_struct_type(name, decl); - ast.tags[i.index()] = Tag::InternedType; - ast.datas[i.index()] = Data::intern(ty); + ast.tags[i] = Tag::InternedType; + ast.datas[i] = Data::intern(ty); } Tag::FunctionProto => { let (_, i) = data.as_intern_and_extra_offset(); + let (return_type, parameter_list) = ( + Index::from_u32(ast.extra[i]).unwrap(), + Index::from_u32(ast.extra[i + 1]).unwrap(), + ); let return_type = ast.get_type_of_node( &self.intern, &mut TypeCache::new(), - Index::new(ast.extra[i]), + return_type ); let parameters = { let (a, b) = ast.datas - [ast.extra[i + 1] as usize] + [parameter_list] .as_extra_range(); - ast.extra[a..b].iter().map(|&i| { + ast.extra[a..b].iter() + .map(|&i| Index::from_u32(i).unwrap()) + .map(|i| { // i is index to a parameter, a parameter is (index, intern) - let ty = ast.datas[i as usize] + let ty = ast.datas[i] .as_index_intern() .0; - ast.datas[ty.index()].as_intern() + ast.datas[ty].as_intern() }) }; @@ -2728,9 +2684,9 @@ pub mod ast_gen { let types = ast.extra[types] .iter() - .map(|&i| Index::new(i)) + .map(|&i| Index::from_u32(i).unwrap()) .map(|i| { - ast.datas[i.index()].as_intern() + ast.datas[i].as_intern() }); let names = ast.extra[names] .iter() @@ -2755,27 +2711,22 @@ pub mod ast_gen { .visit_post(|ast, _, node, tag, _| { match tag { Tag::TypeDeclRefUnresolved => { - let (scope, name) = - ast.datas[node.index()].as_index_intern(); + let (scope, name) = ast.datas[node].as_index_intern(); // look in my_scope - if let Some(decl) = self.syms.find_type_symbol( - scope, - name, - ast.source_locs[node.index()], - ) { + if let Some(decl) = + self.syms + .find_type_symbol(scope, name, ast.source_locs[node]) + { ast.resolve_type_ref(node, decl) }; } Tag::DeclRefUnresolved => { - let (scope, name) = - ast.datas[node.index()].as_index_intern(); + let (scope, name) = ast.datas[node].as_index_intern(); // look in my_scope - if let Some(decl) = self.syms.find_symbol( - scope, - name, - ast.source_locs[node.index()], - ) { + if let Some(decl) = + self.syms.find_symbol(scope, name, ast.source_locs[node]) + { ast.resolve_decl_ref(node, decl) }; } @@ -2788,15 +2739,11 @@ pub mod ast_gen { self.scopes.last().cloned().unwrap() } - fn parse_ident( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { - let ident = - tokens.expect_token(Token::Ident).map_err(|_| ErrorInfo { - error: ParseError::ExpectedIdent, - loc: tokens.current_source_location(), - })?; + fn parse_ident(&mut self, tokens: &mut TokenIterator) -> Result { + let ident = tokens.expect_token(Token::Ident).map_err(|_| ErrorInfo { + error: ParseError::ExpectedIdent, + loc: tokens.current_source_location(), + })?; let name = self.intern.get_or_insert(intern::Key::String { str: ident.lexeme(), @@ -2805,110 +2752,83 @@ pub mod ast_gen { Ok(name) } - fn parse_pointer( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_pointer(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); tokens.eat_token(Token::Star).ok_or(ErrorInfo { error: ParseError::ExpectedToken(Token::Star), loc: tokens.current_source_location(), })?; - let &[cnst, vol, noalias] = &tokens.eat_all_zero_or_once(&[ - Token::Const, - Token::Volatile, - Token::Noalias, - ])[..3] else { + let &[cnst, vol, noalias] = + &tokens.eat_all_zero_or_once(&[Token::Const, Token::Volatile, Token::Noalias])[..3] + else { unreachable!() }; let pointee = self.parse_type(tokens)?; - Ok(self.ast.push_pointer_type( - pointee, - PointerFlags::new(cnst, vol, noalias), - loc, - )) + Ok(self + .ast + .push_pointer_type(pointee, PointerFlags::new(cnst, vol, noalias), loc)) } /// [LENGTH]const? volatile? noalias? TYPE - fn parse_array_type( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_array_type(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); - let length_expr = - self.parse_bracketed(tokens, |this, tokens| { - this.parse_expr(tokens) - // let next = tokens.peek_token().ok_or(ErrorInfo { - // error: ParseError::UnexpectedEndOfTokens, - // loc: tokens.current_source_location(), - // })?; - // match next.token() { - // Token::IntegerBinConstant - // | Token::IntegerHexConstant - // | Token::IntegerOctConstant - // | Token::IntegerConstant => { - // _ = tokens.next(); - // Ok(this.parse_integral_constant(&next, next.source_location())) - // } - // _ => Err(ErrorInfo { - // error: ParseError::ExpectedConstantLiteral, - // loc: tokens.current_source_location(), - // }), - // } - })?; + let length_expr = self.parse_bracketed(tokens, |this, tokens| { + this.parse_expr(tokens) + // let next = tokens.peek_token().ok_or(ErrorInfo { + // error: ParseError::UnexpectedEndOfTokens, + // loc: tokens.current_source_location(), + // })?; + // match next.token() { + // Token::IntegerBinConstant + // | Token::IntegerHexConstant + // | Token::IntegerOctConstant + // | Token::IntegerConstant => { + // _ = tokens.next(); + // Ok(this.parse_integral_constant(&next, next.source_location())) + // } + // _ => Err(ErrorInfo { + // error: ParseError::ExpectedConstantLiteral, + // loc: tokens.current_source_location(), + // }), + // } + })?; - let &[cnst, vol, noalias] = &tokens.eat_all_zero_or_once(&[ - Token::Const, - Token::Volatile, - Token::Noalias, - ])[..3] else { + let &[cnst, vol, noalias] = + &tokens.eat_all_zero_or_once(&[Token::Const, Token::Volatile, Token::Noalias])[..3] + else { unreachable!() }; let pointee = self.parse_type(tokens)?; - let pointer = self.ast.push_pointer_type( - pointee, - PointerFlags::new(cnst, vol, noalias), - loc, - ); + let pointer = + self.ast + .push_pointer_type(pointee, PointerFlags::new(cnst, vol, noalias), loc); Ok(self.ast.push_array_type(length_expr, pointer, loc)) } fn parse_simple_type(&mut self, token: Token) -> Option { match token { - Token::Void => Some(self.intern.get_assume_present( - &intern::Key::SimpleType { - ty: SimpleType::Void, - }, - )), - Token::Bool => Some(self.intern.get_assume_present( - &intern::Key::SimpleType { - ty: SimpleType::Bool, - }, - )), - Token::F32 => Some(self.intern.get_assume_present( - &intern::Key::SimpleType { - ty: SimpleType::F32, - }, - )), - Token::F64 => Some(self.intern.get_assume_present( - &intern::Key::SimpleType { - ty: SimpleType::F64, - }, - )), - Token::USize => Some(self.intern.get_assume_present( - &intern::Key::SimpleType { - ty: SimpleType::USize, - }, - )), - Token::ISize => Some(self.intern.get_assume_present( - &intern::Key::SimpleType { - ty: SimpleType::ISize, - }, - )), + Token::Void => Some(self.intern.get_assume_present(&intern::Key::SimpleType { + ty: SimpleType::Void, + })), + Token::Bool => Some(self.intern.get_assume_present(&intern::Key::SimpleType { + ty: SimpleType::Bool, + })), + Token::F32 => Some(self.intern.get_assume_present(&intern::Key::SimpleType { + ty: SimpleType::F32, + })), + Token::F64 => Some(self.intern.get_assume_present(&intern::Key::SimpleType { + ty: SimpleType::F64, + })), + Token::USize => Some(self.intern.get_assume_present(&intern::Key::SimpleType { + ty: SimpleType::USize, + })), + Token::ISize => Some(self.intern.get_assume_present(&intern::Key::SimpleType { + ty: SimpleType::ISize, + })), _ => None, } } @@ -2984,8 +2904,7 @@ pub mod ast_gen { .map(|(_, c)| c) .collect::>(); - let value = - comptime::bigint::parse_bigint(digits.into_iter(), radix); + let value = comptime::bigint::parse_bigint(digits.into_iter(), radix); let ty = match chars.clone().next() { Some((i, 'u')) | Some((i, 'i')) => self @@ -3006,10 +2925,7 @@ pub mod ast_gen { self.intern.get_or_insert(intern::Key::UInt64 { bits }) } _ => { - let bigint = BigInt::from_biguint( - num_bigint::Sign::Plus, - BigUint::new(value), - ); + let bigint = BigInt::from_biguint(num_bigint::Sign::Plus, BigUint::new(value)); self.intern .get_or_insert(intern::Key::PositiveInt { bigint }) } @@ -3019,21 +2935,13 @@ pub mod ast_gen { (interned, ty) } - fn parse_integral_constant( - &mut self, - item: &TokenItem, - loc: SourceLocation, - ) -> Index { + fn parse_integral_constant(&mut self, item: &TokenItem, loc: SourceLocation) -> Index { let (interned, ty) = self.parse_integral_constant_inner(item); let ty = self.ast.push_interend_type(ty, loc); return self.ast.push_constant(interned, ty, loc); } - fn parse_floating_constant( - &mut self, - item: &TokenItem, - loc: SourceLocation, - ) -> Index { + fn parse_floating_constant(&mut self, item: &TokenItem, loc: SourceLocation) -> Index { let lexeme = item.lexeme(); let lexeme = lexeme .strip_suffix("f32") @@ -3065,10 +2973,7 @@ pub mod ast_gen { /// SIMPLE_TYPE /// [ TYPE ; CONSTANT_EXPR ] /// INTEGRAL_TYPE // u[0..65535] | i[0..65535] - fn parse_type( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_type(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); match tokens .peek_token() @@ -3082,35 +2987,30 @@ pub mod ast_gen { Token::OpenSquareBracket => self.parse_array_type(tokens), Token::Ident => { let token = tokens.next().unwrap(); - match self.try_parse_integral_type(token.lexeme()).map_err( - |error| ErrorInfo { + match self + .try_parse_integral_type(token.lexeme()) + .map_err(|error| ErrorInfo { error, loc: token.source_location(), - }, - )? { + })? { Some(int) => Ok(self.ast.push_interend_type(int, loc)), None => { - let name = self.intern.get_or_insert( - intern::Key::String { - str: token.lexeme(), - }, - ); + let name = self.intern.get_or_insert(intern::Key::String { + str: token.lexeme(), + }); // TODO: this will cause issues with redefinitions of types with the same name // and actually, make type into a proper node of the ast - Ok(self.ast.push_type_ref_unresolved( - self.current_scope(), - name, - loc, - )) + Ok(self + .ast + .push_type_ref_unresolved(self.current_scope(), name, loc)) } } } token => { - let ty = - self.parse_simple_type(token).ok_or(ErrorInfo { - error: ParseError::ExpectedTypeName, - loc: tokens.current_source_location(), - })?; + let ty = self.parse_simple_type(token).ok_or(ErrorInfo { + error: ParseError::ExpectedTypeName, + loc: tokens.current_source_location(), + })?; _ = tokens.next(); Ok(self.ast.push_interend_type(ty, loc)) @@ -3120,10 +3020,7 @@ pub mod ast_gen { /// GLOBAL_DECL <- /// const IDENTIFIER: TYPENAME = EXPR; - fn parse_const_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_const_decl(&mut self, tokens: &mut TokenIterator) -> ParseResult { let err = 'blk: { let loc = tokens.current_source_location(); let Some(_) = tokens.eat_token(Token::Const) else { @@ -3175,14 +3072,9 @@ pub mod ast_gen { }; }; - let decl = - self.ast.push_global_decl(ident, typename, expr, loc); - self.syms.insert_symbol( - self.current_scope(), - ident, - SymbolKind::Const, - decl, - ); + let decl = self.ast.push_global_decl(ident, typename, expr, loc); + self.syms + .insert_symbol(self.current_scope(), ident, SymbolKind::Const, decl); return Ok(decl); }; @@ -3212,37 +3104,31 @@ pub mod ast_gen { let ident = self.parse_ident(tokens)?; - let parameters = - self.parse_parenthesised(tokens, |this, tokens| { - if tokens.is_next_token(Token::CloseParens) { - Ok(this.ast.push_parameter_list([], loc)) - } else { - this.parse_parameter_list(tokens) - } - })?; - - let return_type = - if let Some(_) = tokens.eat_token(Token::MinusGreater) { - self.parse_type(tokens)? + let parameters = self.parse_parenthesised(tokens, |this, tokens| { + if tokens.is_next_token(Token::CloseParens) { + Ok(this.ast.push_parameter_list([], loc)) } else { - self.ast.push_interend_type( - self.intern.get_void_type(), - tokens.current_source_location(), - ) - }; + this.parse_parameter_list(tokens) + } + })?; - let decl = - self.ast.push_fn_proto(ident, return_type, parameters, loc); + let return_type = if let Some(_) = tokens.eat_token(Token::MinusGreater) { + self.parse_type(tokens)? + } else { + self.ast.push_interend_type( + self.intern.get_void_type(), + tokens.current_source_location(), + ) + }; + + let decl = self.ast.push_fn_proto(ident, return_type, parameters, loc); Ok((decl, ident)) } - fn parse_fn_inner( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_fn_inner(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); - let func = self.ast.reserve_node(); + let func = self.ast.reserve_node(Kind::Function); self.push_scope(func, intern::Index::invalid()); @@ -3259,12 +3145,8 @@ pub mod ast_gen { self.ast.set_fn_decl(func, proto, body, loc); - self.syms.insert_symbol( - self.current_scope(), - ident, - SymbolKind::Function, - func, - ); + self.syms + .insert_symbol(self.current_scope(), ident, SymbolKind::Function, func); Ok(func) } @@ -3283,10 +3165,7 @@ pub mod ast_gen { /// RETURN_STATEMENT <- /// return EXPRESSION? ; - fn parse_return_stmt( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_return_stmt(&mut self, tokens: &mut TokenIterator) -> ParseResult { // SAFETY: function invariance let ret = tokens.next().unwrap(); let loc = ret.source_location(); @@ -3318,10 +3197,7 @@ pub mod ast_gen { /// VAR_DECL <- /// (let | var) IDENTIFIER (: TYPENAME)? ; /// (let | var) IDENTIFIER (: TYPENAME)? = EXPRESSION ; - fn parse_var_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_var_decl(&mut self, tokens: &mut TokenIterator) -> ParseResult { match self.parse_var_decl_inner(tokens) { Ok(i) => { _ = tokens.eat_token(Token::Semi).ok_or(ErrorInfo { @@ -3340,10 +3216,7 @@ pub mod ast_gen { } } - fn parse_var_decl_inner( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_var_decl_inner(&mut self, tokens: &mut TokenIterator) -> ParseResult { // SAFETY: function invariance let let_or_var = tokens.next().unwrap(); let loc = let_or_var.source_location(); @@ -3364,8 +3237,7 @@ pub mod ast_gen { None }; - let decl = - self.ast.push_var_decl(is_let, name, ty, assignment, loc); + let decl = self.ast.push_var_decl(is_let, name, ty, assignment, loc); self.syms.insert_symbol( self.current_scope(), name, @@ -3406,10 +3278,10 @@ pub mod ast_gen { _ => { if self.is_statement(tokens) { // expr -> statements - let expr = self.parse_with_trailing_semi( - tokens, - |this, tokens| this.parse_expr(tokens), - )?; + let expr = self + .parse_with_trailing_semi(tokens, |this, tokens| { + this.parse_expr(tokens) + })?; statements.push(expr); } else { @@ -3435,12 +3307,9 @@ pub mod ast_gen { /// BLOCK <- /// { STATEMENT* EXPRESSION? } - fn parse_block( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_block(&mut self, tokens: &mut TokenIterator) -> ParseResult { let block = self.parse_braced(tokens, |this, tokens| { - let block = this.ast.reserve_node(); + let block = this.ast.reserve_node_other(); this.push_scope(block, intern::Index::invalid()); let block_result = this.parse_block_inner(block, tokens); this.pop_scope(); @@ -3454,10 +3323,7 @@ pub mod ast_gen { /// PARAMETER_LIST <- /// PARAMETER /// PARAMETER_LIST , ARGUMENT - fn parse_parameter_list( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_parameter_list(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); let mut params = Vec::new(); @@ -3479,10 +3345,7 @@ pub mod ast_gen { /// PARAMETER <- /// IDENT : TYPENAME - fn parse_parameter( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_parameter(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); let name = self.parse_ident(tokens)?; let Some(_) = tokens.eat_token(Token::Colon) else { @@ -3494,12 +3357,8 @@ pub mod ast_gen { let ty = self.parse_type(tokens)?; let param = self.ast.push_parameter(name, ty, loc); - self.syms.insert_symbol( - self.current_scope(), - name, - SymbolKind::Local(loc), - param, - ); + self.syms + .insert_symbol(self.current_scope(), name, SymbolKind::Local(loc), param); return Ok(param); } @@ -3507,13 +3366,9 @@ pub mod ast_gen { /// ARGUMENT <- /// IDENT : EXPR /// EXPR - fn parse_argument( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_argument(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); - let name = if tokens.is_next_token2(Token::Colon) - && tokens.is_next_token(Token::Ident) + let name = if tokens.is_next_token2(Token::Colon) && tokens.is_next_token(Token::Ident) { let name = self.parse_ident(tokens)?; // we checked `is_next_token2` @@ -3535,10 +3390,7 @@ pub mod ast_gen { /// ARGUMENT_LIST <- /// ARGUMENT /// ARGUMENT_LIST , ARGUMENT - fn parse_argument_list( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_argument_list(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); let mut args = Vec::new(); loop { @@ -3562,10 +3414,7 @@ pub mod ast_gen { /// FLOATING_CONSTANT /// ( EXPRESSION ) /// BLOCK - fn parse_primary_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_primary_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); let Some(next) = tokens.peek_token() else { @@ -3581,27 +3430,19 @@ pub mod ast_gen { | Token::IntegerOctConstant | Token::IntegerConstant => { _ = tokens.next(); - return Ok(self.parse_integral_constant( - &next, - next.source_location(), - )); + return Ok(self.parse_integral_constant(&next, next.source_location())); } Token::FloatingConstant | Token::FloatingExpConstant | Token::DotFloatingConstant | Token::DotFloatingExpConstant => { _ = tokens.next(); - return Ok(self.parse_floating_constant( - &next, - next.source_location(), - )); + return Ok(self.parse_floating_constant(&next, next.source_location())); } Token::OpenParens => { - let expr = self - .parse_parenthesised(tokens, |this, tokens| { - this.parse_expr(tokens) - })?; + let expr = + self.parse_parenthesised(tokens, |this, tokens| this.parse_expr(tokens))?; return Ok(expr); } @@ -3614,11 +3455,9 @@ pub mod ast_gen { let ident = self .intern .get_or_insert(intern::Key::String { str: ident }); - return Ok(self.ast.push_decl_ref_unresolved( - self.current_scope(), - ident, - loc, - )); + return Ok(self + .ast + .push_decl_ref_unresolved(self.current_scope(), ident, loc)); } // TODO: eventually handle paths _ => { @@ -3636,14 +3475,9 @@ pub mod ast_gen { /// PRIMARY_EXPR ( ARGUMENT_LIST ) /// PRIMARY_EXPR [ EXPR ] /// POSTFIX_EXPR . IDENTIFIER - fn parse_postfix_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_postfix_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult { let mut lhs = self.parse_primary_expr(tokens)?; - while let Some(postfix) = - self.try_parse_postfix_expr_inner(tokens, lhs)? - { + while let Some(postfix) = self.try_parse_postfix_expr_inner(tokens, lhs)? { lhs = postfix; } @@ -3659,31 +3493,24 @@ pub mod ast_gen { let loc = next.source_location(); match next.token() { Token::OpenParens => { - let arguments = self.parse_parenthesised( - tokens, - |this, tokens| { - if tokens.is_next_token(Token::CloseParens) { - Ok(this.ast.push_argument_list([], loc)) - } else { - this.parse_argument_list(tokens) - } - }, - )?; + let arguments = self.parse_parenthesised(tokens, |this, tokens| { + if tokens.is_next_token(Token::CloseParens) { + Ok(this.ast.push_argument_list([], loc)) + } else { + this.parse_argument_list(tokens) + } + })?; Some(self.ast.push_call_expr(lhs, arguments, loc)) } Token::OpenSquareBracket => { - let subscript = self - .parse_bracketed(tokens, |this, tokens| { - this.parse_expr(tokens) - })?; + let subscript = + self.parse_bracketed(tokens, |this, tokens| this.parse_expr(tokens))?; - Some(self.ast.push_binary( - Tag::SubscriptExpr, - lhs, - subscript, - loc, - )) + Some( + self.ast + .push_binary(Tag::SubscriptExpr, lhs, subscript, loc), + ) } Token::Dot if tokens.is_next_token2(Token::Ident) => { _ = tokens.next(); @@ -3701,11 +3528,7 @@ pub mod ast_gen { Ok(lhs) } - fn push_error( - &mut self, - error: ParseError, - loc: SourceLocation, - ) -> Index { + fn push_error(&mut self, error: ParseError, loc: SourceLocation) -> Index { self.errors.push(ErrorInfo { error, loc }); self.ast.push_error(error, loc) } @@ -3716,10 +3539,7 @@ pub mod ast_gen { /// - POSTFIX_EXPR /// & POSTFIX_EXPR /// * POSTFIX_EXPR - fn parse_prefix_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_prefix_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult { let next = tokens.peek_token().ok_or(ErrorInfo { error: ParseError::ExpectedPrefixExpression, loc: tokens.current_source_location(), @@ -3757,10 +3577,7 @@ pub mod ast_gen { /// AS_EXPR <- /// PREFIX_EXPR /// PREFIX_EXPR as TYPENAME - fn parse_as_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_as_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); let expr = self.parse_prefix_expr(tokens)?; @@ -3805,8 +3622,7 @@ pub mod ast_gen { break; }; let loc = tok.source_location(); - let Some(prec) = PRECEDENCE_MAP.get(&tok.token()).cloned() - else { + let Some(prec) = PRECEDENCE_MAP.get(&tok.token()).cloned() else { break; }; @@ -3853,10 +3669,7 @@ pub mod ast_gen { /// BINARY_EXPRESSION ASSIGNMENT_OP EXPRESSION /// ASSIGNMENT_OP <- /// = += -= *= /= %= ... - fn parse_assignment_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_assignment_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult { let lhs = self.parse_binary_expr(tokens, 0)?; if tokens @@ -3898,10 +3711,7 @@ pub mod ast_gen { /// ELSE_EXPR <- /// 'else' (IF_EXPR | EXPR_OR_STATEMENT_OR_BLOCK) - fn parse_else_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_else_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult { // SAFETY: function invariance let _else_ = tokens.eat_token(Token::Else).unwrap(); @@ -3914,17 +3724,12 @@ pub mod ast_gen { /// IF_EXPR <- /// 'if' ( EXPR ) EXPR_OR_STATEMENT_OR_BLOCK ELSE_EXPR? - fn parse_if_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_if_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult { // SAFETY: function invariance let iff = tokens.eat_token(Token::If).unwrap(); let loc = iff.source_location(); - let cond = self.parse_parenthesised(tokens, |this, tokens| { - this.parse_expr(tokens) - })?; + let cond = self.parse_parenthesised(tokens, |this, tokens| this.parse_expr(tokens))?; let body = self.parse_expr_or_block_as_block(tokens)?; @@ -3957,10 +3762,7 @@ pub mod ast_gen { } } - fn parse_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_expr(&mut self, tokens: &mut TokenIterator) -> ParseResult { let loc = tokens.current_source_location(); let Some(next) = tokens.peek_token() else { return Err(ErrorInfo { @@ -3981,10 +3783,7 @@ pub mod ast_gen { /// type IDENTIFIER = extern? union { (IDENTIFIER: TYPE,)* } /// type IDENTIFIER = extern? packed? enum { (IDENTIFIER (= EXPRESSION),)* } /// type IDENTIFIER = extern? packed? struct { (IDENTIFIER: TYPE,)* } - fn parse_type_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_type_decl(&mut self, tokens: &mut TokenIterator) -> ParseResult { _ = tokens.eat_token(Token::Type).ok_or(ErrorInfo { error: ParseError::ExpectedToken(Token::Type), loc: tokens.current_source_location(), @@ -3999,8 +3798,7 @@ pub mod ast_gen { }); let (has_attributes, c_like, packed) = { - let vec = tokens - .eat_all_zero_or_once(&[Token::Extern, Token::Packed]); + let vec = tokens.eat_all_zero_or_once(&[Token::Extern, Token::Packed]); (vec[0] || vec[1], vec[0], vec[1]) }; @@ -4012,9 +3810,7 @@ pub mod ast_gen { }; let decl = match next.token() { - Token::Struct => { - self.parse_struct_decl(tokens, name, c_like, packed, loc) - } + Token::Struct => self.parse_struct_decl(tokens, name, c_like, packed, loc), Token::Union => { unimplemented!() } @@ -4047,12 +3843,8 @@ pub mod ast_gen { } }?; - self.syms.insert_symbol( - self.current_scope(), - name, - SymbolKind::Type, - decl, - ); + self.syms + .insert_symbol(self.current_scope(), name, SymbolKind::Type, decl); Ok(decl) } @@ -4062,37 +3854,25 @@ pub mod ast_gen { /// TYPE_UNION <- /// TYPE (| TYPE_UNION)? /// IDENTIFIER: TYPE (| TYPE_UNION)? - fn parse_sumtype_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_sumtype_decl(&mut self, _tokens: &mut TokenIterator) -> ParseResult { todo!() } /// TUPLE_DECL <- /// type IDENTIFIER = (TYPE,* ) - fn parse_tuple_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_tuple_decl(&mut self, _tokens: &mut TokenIterator) -> ParseResult { todo!() } /// UNION_DECL <- /// type IDENTIFIER = union { IDENTIFIER: TYPE,* } - fn parse_union_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_union_decl(&mut self, _tokens: &mut TokenIterator) -> ParseResult { todo!() } /// ENUM_DECL <- /// type IDENTIFIER = packed? enum { IDENTIFIER (= EXPRESSION),* } - fn parse_enum_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> ParseResult { + fn parse_enum_decl(&mut self, _tokens: &mut TokenIterator) -> ParseResult { todo!() } @@ -4113,12 +3893,11 @@ pub mod ast_gen { loc: tokens.current_source_location(), })?; - let decl = self.ast.reserve_node(); + let decl = self.ast.reserve_node(Kind::GlobalDecl); let decl = self.parse_braced(tokens, |this, tokens| { this.parse_struct_fields(tokens).map(|fields| { _ = tokens.eat_token(Token::Comma); - let flags = - StructFlags::new(packed, c_like, fields.len() as u32); + let flags = StructFlags::new(packed, c_like, fields.len() as u32); this.intern.insert_or_replace_struct_type( name, @@ -4172,12 +3951,7 @@ pub mod ast_gen { ) -> ParseResult where F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, - E: FnOnce( - &mut Self, - &mut TokenIterator, - ErrorInfo, - TokenItem, - ) -> ParseResult, + E: FnOnce(&mut Self, &mut TokenIterator, ErrorInfo, TokenItem) -> ParseResult, { let Some(start) = tokens.eat_token(open) else { return Err(ErrorInfo { @@ -4190,20 +3964,14 @@ pub mod ast_gen { Ok(i) => { _ = tokens.eat_token(close).ok_or(ErrorInfo { error: match open { - Token::OpenBrace => ParseError::UnmatchedBrace( - start.token_pos().start, - ), - Token::OpenParens => ParseError::UnmatchedParens( - start.token_pos().start, - ), - Token::OpenSquareBracket => { - ParseError::UnmatchedSquareBracket( - start.token_pos().start, - ) + Token::OpenBrace => ParseError::UnmatchedBrace(start.token_pos().start), + Token::OpenParens => { + ParseError::UnmatchedParens(start.token_pos().start) } - _ => ParseError::UnmatchedDelimiter( - start.token_pos().start, - ), + Token::OpenSquareBracket => { + ParseError::UnmatchedSquareBracket(start.token_pos().start) + } + _ => ParseError::UnmatchedDelimiter(start.token_pos().start), }, loc: tokens.current_source_location(), })?; @@ -4224,61 +3992,39 @@ pub mod ast_gen { where F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, { - self.parse_inner( - tokens, - open, - close, - parse, - |this, tokens, err, start| { - match close { - Token::CloseBrace => { - tokens.advance_past_end_of_braced().ok_or( - ErrorInfo { - error: ParseError::UnmatchedBrace( - start.token_pos().start, - ), - loc: tokens.current_source_location(), - }, - )?; - } - Token::CloseParens => { - tokens.advance_past_end_of_parens().ok_or( - ErrorInfo { - error: ParseError::UnmatchedParens( - start.token_pos().start, - ), - loc: tokens.current_source_location(), - }, - )?; - } - Token::CloseSquareBracket => { - tokens.advance_past_end_of_bracketed().ok_or( - ErrorInfo { - error: ParseError::UnmatchedSquareBracket( - start.token_pos().start, - ), - loc: tokens.current_source_location(), - }, - )?; - } - Token::Semi => { - tokens.advance_past_semi().ok_or(ErrorInfo { - error: ParseError::ExpectedToken(Token::Semi), - loc: tokens.current_source_location(), - })?; - } - _ => unimplemented!(), + self.parse_inner(tokens, open, close, parse, |this, tokens, err, start| { + match close { + Token::CloseBrace => { + tokens.advance_past_end_of_braced().ok_or(ErrorInfo { + error: ParseError::UnmatchedBrace(start.token_pos().start), + loc: tokens.current_source_location(), + })?; } - Ok(this.push_error(err.error, err.loc)) - }, - ) + Token::CloseParens => { + tokens.advance_past_end_of_parens().ok_or(ErrorInfo { + error: ParseError::UnmatchedParens(start.token_pos().start), + loc: tokens.current_source_location(), + })?; + } + Token::CloseSquareBracket => { + tokens.advance_past_end_of_bracketed().ok_or(ErrorInfo { + error: ParseError::UnmatchedSquareBracket(start.token_pos().start), + loc: tokens.current_source_location(), + })?; + } + Token::Semi => { + tokens.advance_past_semi().ok_or(ErrorInfo { + error: ParseError::ExpectedToken(Token::Semi), + loc: tokens.current_source_location(), + })?; + } + _ => unimplemented!(), + } + Ok(this.push_error(err.error, err.loc)) + }) } - fn parse_bracketed( - &mut self, - tokens: &mut TokenIterator, - parse: F, - ) -> ParseResult + fn parse_bracketed(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult where F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, { @@ -4290,20 +4036,11 @@ pub mod ast_gen { ) } - fn parse_braced( - &mut self, - tokens: &mut TokenIterator, - parse: F, - ) -> ParseResult + fn parse_braced(&mut self, tokens: &mut TokenIterator, parse: F) -> ParseResult where F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, { - self.parse_inner2( - tokens, - Token::OpenBrace, - Token::CloseBrace, - parse, - ) + self.parse_inner2(tokens, Token::OpenBrace, Token::CloseBrace, parse) } fn parse_parenthesised( @@ -4314,12 +4051,7 @@ pub mod ast_gen { where F: FnOnce(&mut Self, &mut TokenIterator) -> ParseResult, { - self.parse_inner2( - tokens, - Token::OpenParens, - Token::CloseParens, - parse, - ) + self.parse_inner2(tokens, Token::OpenParens, Token::CloseParens, parse) } fn parse_struct_fields( @@ -4387,24 +4119,22 @@ pub mod ast_gen { fn parse_file(&mut self, tokens: &mut TokenIterator) -> Index { let start = tokens.current_source_location(); let mut decls = Vec::new(); - let file = self.ast.reserve_node(); + let file = self.ast.reserve_node(Kind::File); self.push_scope(file, intern::Index::invalid()); while let Some(next) = tokens.peek_token() { let loc = next.source_location(); - let decl = match self.parse_constant_decls(tokens).and_then( - |i| match i { - Some(i) => Ok(i), - None => { - let error = ParseError::UnexpectedTokenAtFileScope; - let node = self.push_error(error, loc); + let decl = match self.parse_constant_decls(tokens).and_then(|i| match i { + Some(i) => Ok(i), + None => { + let error = ParseError::UnexpectedTokenAtFileScope; + let node = self.push_error(error, loc); - self.find_next_fn_or_const(tokens); + self.find_next_fn_or_const(tokens); - Ok(node) - } - }, - ) { + Ok(node) + } + }) { Ok(i) => i, Err(err) => self.push_error(err.error, err.loc), }; @@ -4487,16 +4217,9 @@ pub mod ast_gen { false } - fn find_next_fn_or_const( - &mut self, - tokens: &mut TokenIterator, - ) -> Option<()> { + fn find_next_fn_or_const(&mut self, tokens: &mut TokenIterator) -> Option<()> { tokens - .advance_until_before_one_of(&[ - Token::Const, - Token::Fn, - Token::Type, - ]) + .advance_until_before_one_of(&[Token::Const, Token::Fn, Token::Type]) .map(|_| ()) } } @@ -4504,12 +4227,8 @@ pub mod ast_gen { pub mod irgen { - use super::visitor::AstExt; use super::*; - use crate::{ - symbol_table::syms2::Symbols, - triples::{self, *}, - }; + use crate::{symbol_table::syms2::Symbols, triples::*}; use std::collections::HashMap; struct IRGen { @@ -4524,6 +4243,7 @@ pub mod irgen { let mut mapping = HashMap::::new(); self.ast.visitor().visit( |ast, scopes, i, tag, data| { + _ = (&mapping, ast, scopes, i, tag, data); // pre match tag { Tag::Root => todo!(), @@ -4589,6 +4309,7 @@ pub mod irgen { } }, |ast, scopes, i, tag, data| { + _ = (&mapping, ast, scopes, i, tag, data); // post match tag { Tag::Root => todo!(), diff --git a/src/bin/main.rs b/src/bin/main.rs index b745648..b46523b 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,8 +1,7 @@ -use std::{io::Read, path::PathBuf, sync::Arc}; +use std::{io::Read, path::PathBuf}; use clap::Command; use compiler::{ - ast2::intern::InternPool, lexer::Tokenizer, parser::Tree, triples::{MirBuilder, IR}, @@ -29,8 +28,7 @@ fn main() { .subcommands([ Command::new("ast").about("output AST."), Command::new("ast2").about("output AST."), - Command::new("mir") - .about("output machine-level intermediate representation."), + Command::new("mir").about("output machine-level intermediate representation."), Command::new("ir").about("output intermediate representation."), Command::new("asm").about("output x86-64 assembly (intel syntax)."), ]); @@ -85,11 +83,7 @@ fn main() { } = mir; for (name, mir) in functions { - println!( - "{}:\n{}", - strings.get_str(name), - mir.display(&strings) - ); + println!("{}:\n{}", strings.get_str(name), mir.display(&strings)); } } "asm" => { diff --git a/src/lib.rs b/src/lib.rs index 5517302..6cd1907 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,10 +31,7 @@ pub mod triples; pub fn tokenize<'a>( bytes: &'a [u8], -) -> Result< - lexer::Tokenizer<'a>, - (lexer::Tokenizer<'a>, Vec), -> { +) -> Result, (lexer::Tokenizer<'a>, Vec)> { lexer::Tokenizer::new_with_errors(bytes) } diff --git a/src/mir.rs b/src/mir.rs index 018a6d1..83f5c44 100644 --- a/src/mir.rs +++ b/src/mir.rs @@ -11,7 +11,6 @@ use std::u32; use itertools::Itertools; use crate::asm::amd64::Register; -use crate::ast::IntegralType; use crate::ast2::intern; #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] @@ -104,9 +103,7 @@ impl Type { Type::Byte => Inst::ConstantByte, Type::Word => Inst::ConstantWord, Type::SinglePrecision | Type::DWord => Inst::ConstantDWord, - Type::Function | Type::DoublePrecision | Type::QWord => { - Inst::ConstantQWord - } + Type::Function | Type::DoublePrecision | Type::QWord => Inst::ConstantQWord, } } @@ -521,16 +518,12 @@ impl OperandKinds { reg.union(mem).union(imm) } const fn to_lhs_binop(self) -> BinaryOperandFlags { - let reg = if self - .intersects(Self::RegReg.union(Self::RegImm).union(Self::RegMem)) - { + let reg = if self.intersects(Self::RegReg.union(Self::RegImm).union(Self::RegMem)) { BinaryOperandFlags::LhsReg } else { BinaryOperandFlags::empty() }; - let mem = if self - .intersects(Self::MemReg.union(Self::MemMem).union(Self::MemImm)) - { + let mem = if self.intersects(Self::MemReg.union(Self::MemMem).union(Self::MemImm)) { BinaryOperandFlags::LhsMem } else { BinaryOperandFlags::empty() @@ -602,13 +595,7 @@ struct BinaryOperandsRunner<'a> { impl<'a> BinaryOperandsRunner<'a> { #[allow(dead_code)] - fn new( - inner: BinaryOperands<'a>, - lhs: u32, - lhs_type: Type, - rhs: u32, - rhs_type: Type, - ) -> Self { + fn new(inner: BinaryOperands<'a>, lhs: u32, lhs_type: Type, rhs: u32, rhs_type: Type) -> Self { Self { inner, lhs: (lhs, lhs_type), @@ -659,9 +646,7 @@ impl<'a> BinaryOperandsRunner<'a> { let l_kind = self.mir().as_operand_kind(lhs).as_lhs(); let r_kind = self.mir().as_operand_kind(rhs).as_rhs(); - if self.inner.commutative - && (!l_legal.contains(l_kind) && l_legal.contains(r_kind)) - { + if self.inner.commutative && (!l_legal.contains(l_kind) && l_legal.contains(r_kind)) { core::mem::swap(&mut self.lhs, &mut self.rhs); } } @@ -722,13 +707,7 @@ impl<'a> BinaryOperands<'a> { Self::new(mir, false, OperandKinds::shift()) } - fn wrangle( - self, - lhs: u32, - lhs_type: Type, - rhs: u32, - rhs_type: Type, - ) -> (u32, u32) { + fn wrangle(self, lhs: u32, lhs_type: Type, rhs: u32, rhs_type: Type) -> (u32, u32) { let mut runner = BinaryOperandsRunner { inner: self, lhs: (lhs, lhs_type), @@ -805,10 +784,7 @@ impl Mir { self.data[node.index()] = data; } - fn indices( - &self, - ) -> impl Iterator + DoubleEndedIterator + FusedIterator - { + fn indices(&self) -> impl Iterator + DoubleEndedIterator + FusedIterator { (0..self.nodes.len() as u32).map(|n| NodeRef::from(n)) } } @@ -868,12 +844,7 @@ impl Mir { node } - pub fn push_const( - &mut self, - ip: &intern::InternPool, - value: intern::Index, - ty: Type, - ) -> u32 { + pub fn push_const(&mut self, ip: &intern::InternPool, value: intern::Index, ty: Type) -> u32 { let inst = match ty { Type::Byte => Inst::ConstantByte, Type::Word => Inst::ConstantWord, @@ -974,63 +945,27 @@ impl Mir { } } - pub fn gen_is_eq( - &mut self, - ty: Type, - signed: bool, - lhs: u32, - rhs: u32, - ) -> u32 { + pub fn gen_is_eq(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 { let cmp = self.gen_cmp(ty, lhs, rhs); self.push(Inst::IsEq(signed), Data::node(cmp)) } - pub fn gen_is_neq( - &mut self, - ty: Type, - signed: bool, - lhs: u32, - rhs: u32, - ) -> u32 { + pub fn gen_is_neq(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 { let cmp = self.gen_cmp(ty, lhs, rhs); self.push(Inst::IsNeq(signed), Data::node(cmp)) } - pub fn gen_is_gt( - &mut self, - ty: Type, - signed: bool, - lhs: u32, - rhs: u32, - ) -> u32 { + pub fn gen_is_gt(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 { let cmp = self.gen_cmp(ty, lhs, rhs); self.push(Inst::IsGt(signed), Data::node(cmp)) } - pub fn gen_is_lt( - &mut self, - ty: Type, - signed: bool, - lhs: u32, - rhs: u32, - ) -> u32 { + pub fn gen_is_lt(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 { let cmp = self.gen_cmp(ty, lhs, rhs); self.push(Inst::IsLt(signed), Data::node(cmp)) } - pub fn gen_is_ge( - &mut self, - ty: Type, - signed: bool, - lhs: u32, - rhs: u32, - ) -> u32 { + pub fn gen_is_ge(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 { let cmp = self.gen_cmp(ty, lhs, rhs); self.push(Inst::IsGe(signed), Data::node(cmp)) } - pub fn gen_is_le( - &mut self, - ty: Type, - signed: bool, - lhs: u32, - rhs: u32, - ) -> u32 { + pub fn gen_is_le(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 { let cmp = self.gen_cmp(ty, lhs, rhs); self.push(Inst::IsLe(signed), Data::node(cmp)) } @@ -1057,12 +992,7 @@ impl Mir { pub fn gen_load(&mut self, ty: Type, src: u32) -> u32 { self.push(Inst::Load(ty), Data::node(src)) } - pub fn gen_get_element_ptr( - &mut self, - ty: Type, - src: u32, - index: u32, - ) -> u32 { + pub fn gen_get_element_ptr(&mut self, ty: Type, src: u32, index: u32) -> u32 { self.push(Inst::GetElementPtr(ty), Data::binary(src, index)) } pub fn gen_store(&mut self, ty: Type, src: u32, dst: u32) -> u32 { @@ -1100,13 +1030,7 @@ impl Mir { } /// truncates a value `src` of `mir::Type` `ty` to `bits` bits, while preserving the sign - pub fn gen_truncate_integer( - &mut self, - src: u32, - ty: Type, - signed: bool, - bits: u16, - ) -> u32 { + pub fn gen_truncate_integer(&mut self, src: u32, ty: Type, signed: bool, bits: u16) -> u32 { // example: u4 -> (byte, false, 4) // 1111_1111 << 4 = 1111_0000 // mask = 0000_1111; @@ -1118,9 +1042,7 @@ impl Mir { Type::Byte => self.gen_u8(mask as u8), Type::Word => self.gen_u16(mask as u16), Type::SinglePrecision | Type::DWord => self.gen_u32(mask as u32), - Type::Function | Type::DoublePrecision | Type::QWord => { - self.gen_u64(mask as u64) - } + Type::Function | Type::DoublePrecision | Type::QWord => self.gen_u64(mask as u64), }; let masked = self.gen_bitand(ty, src, mask); @@ -1151,12 +1073,7 @@ impl Mir { // mask = 0000_1111; // shift = 8 - 4; let src_ty = Type::from_bitsize_int(from.bitsize); - let truncated = self.gen_truncate_integer( - src, - src_ty, - from.signed, - from.bitsize as u16, - ); + let truncated = self.gen_truncate_integer(src, src_ty, from.signed, from.bitsize as u16); let dst_ty = Type::from_bitsize_int(to.bitsize); if to.signed { @@ -1179,8 +1096,7 @@ impl Mir { let (lhs, rhs) = if ty.is_floating() { BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty) } else { - BinaryOperands::new_add_or_and_xor_adc(self) - .wrangle(lhs, ty, rhs, ty) + BinaryOperands::new_add_or_and_xor_adc(self).wrangle(lhs, ty, rhs, ty) }; self.push(Inst::Add(ty), Data::binary(lhs, rhs)) } @@ -1192,13 +1108,7 @@ impl Mir { }; self.push(Inst::Sub(ty), Data::binary(lhs, rhs)) } - pub fn gen_mul( - &mut self, - ty: Type, - signed: bool, - lhs: u32, - rhs: u32, - ) -> u32 { + pub fn gen_mul(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 { if ty.is_floating() { self.gen_mul_sse(ty, lhs, rhs) } else if signed { @@ -1208,27 +1118,18 @@ impl Mir { } } pub fn gen_mul_sse(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = - BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::MulSSE(ty), Data::binary(lhs, rhs)) } pub fn gen_mul_unsigned(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = - BinaryOperands::new_mul(self).wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_mul(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::Mul(ty), Data::binary(lhs, rhs)) } pub fn gen_mul_signed(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = - BinaryOperands::new_imul(self).wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_imul(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::MulSigned(ty), Data::binary(lhs, rhs)) } - pub fn gen_div( - &mut self, - ty: Type, - signed: bool, - lhs: u32, - rhs: u32, - ) -> u32 { + pub fn gen_div(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 { if ty.is_floating() { self.gen_div_sse(ty, lhs, rhs) } else if signed { @@ -1238,27 +1139,18 @@ impl Mir { } } pub fn gen_div_sse(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = - BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_sse(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::DivSSE(ty), Data::binary(lhs, rhs)) } pub fn gen_div_unsigned(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self) - .wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::Div(ty), Data::binary(lhs, rhs)) } pub fn gen_div_signed(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self) - .wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::DivSigned(ty), Data::binary(lhs, rhs)) } - pub fn gen_rem( - &mut self, - ty: Type, - signed: bool, - lhs: u32, - rhs: u32, - ) -> u32 { + pub fn gen_rem(&mut self, ty: Type, signed: bool, lhs: u32, rhs: u32) -> u32 { if ty.is_floating() { self.gen_rem_fp(ty, lhs, rhs) } else if signed { @@ -1269,34 +1161,28 @@ impl Mir { } pub fn gen_rem_fp(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { let (lhs, rhs) = - BinaryOperands::new(self, false, OperandKinds::any_mem_reg()) - .wrangle(lhs, ty, rhs, ty); + BinaryOperands::new(self, false, OperandKinds::any_mem_reg()).wrangle(lhs, ty, rhs, ty); self.push(Inst::RemFP(ty), Data::binary(lhs, rhs)) } pub fn gen_rem_unsigned(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self) - .wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::Rem(ty), Data::binary(lhs, rhs)) } pub fn gen_rem_signed(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self) - .wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_div_idiv_rem_irem(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::RemSigned(ty), Data::binary(lhs, rhs)) } pub fn gen_bitand(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self) - .wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::BitAnd(ty), Data::binary(lhs, rhs)) } pub fn gen_bitor(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self) - .wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::BitOr(ty), Data::binary(lhs, rhs)) } pub fn gen_bitxor(&mut self, ty: Type, lhs: u32, rhs: u32) -> u32 { - let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self) - .wrangle(lhs, ty, rhs, ty); + let (lhs, rhs) = BinaryOperands::new_add_or_and_xor_adc(self).wrangle(lhs, ty, rhs, ty); self.push(Inst::BitXOr(ty), Data::binary(lhs, rhs)) } pub fn gen_negate(&mut self, ty: Type, src: u32) -> u32 { @@ -1310,20 +1196,17 @@ impl Mir { #[doc(alias = "gen_shift_left")] pub fn gen_shl(&mut self, ty: Type, src: u32, shift: u32) -> u32 { - let (src, shift) = - BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte); + let (src, shift) = BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte); self.push(Inst::ShiftLeft(ty), Data::binary(src, shift)) } #[doc(alias = "gen_shift_right")] pub fn gen_shr(&mut self, ty: Type, src: u32, shift: u32) -> u32 { - let (src, shift) = - BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte); + let (src, shift) = BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte); self.push(Inst::ShiftRightUnsigned(ty), Data::binary(src, shift)) } #[doc(alias = "gen_shift_right_signed")] pub fn gen_sar(&mut self, ty: Type, src: u32, shift: u32) -> u32 { - let (src, shift) = - BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte); + let (src, shift) = BinaryOperands::new_shift(self).wrangle(src, ty, shift, Type::Byte); self.push(Inst::ShiftRightSigned(ty), Data::binary(src, shift)) } pub fn gen_ret_val(&mut self, ty: Type, val: u32) -> u32 { @@ -1354,11 +1237,9 @@ impl Mir { Inst::Label => { writeln!(w, "%{node} = label {}", ip.get_str(data.as_index())) } - Inst::ConstantBytes => writeln!( - w, - "%{node} = bytes({:x?})", - ip.get_bytes(data.as_index()) - ), + Inst::ConstantBytes => { + writeln!(w, "%{node} = bytes({:x?})", ip.get_bytes(data.as_index())) + } Inst::ConstantByte => { writeln!(w, "%{node} = imm8({:x?})", data.as_imm8()) } @@ -1398,10 +1279,7 @@ impl Mir { } Inst::GetElementPtr(ty) => { let (ptr, idx) = data.as_binary(); - writeln!( - w, - "%{node} = get element ptr {ty}, ptr %{ptr}, idx {idx}" - ) + writeln!(w, "%{node} = get element ptr {ty}, ptr %{ptr}, idx {idx}") } Inst::Load(ty) => { writeln!(w, "%{node} = load {ty}, ptr %{}", data.as_node()) @@ -1538,10 +1416,7 @@ impl Mir { } Inst::ShiftRightSigned(ty) => { let (lhs, rhs) = data.as_binary(); - writeln!( - w, - "%{node} = signed shift right {ty} %{lhs}, {ty} %{rhs}" - ) + writeln!(w, "%{node} = signed shift right {ty} %{lhs}, {ty} %{rhs}") } Inst::ReturnValue(ty) => { let lhs = data.as_node(); @@ -1577,10 +1452,7 @@ impl Mir { Ok(()) } - pub fn display<'a, 'b>( - &'a self, - ip: &'b intern::InternPool, - ) -> DisplayMir<'a, 'b> { + pub fn display<'a, 'b>(&'a self, ip: &'b intern::InternPool) -> DisplayMir<'a, 'b> { DisplayMir { mir: self, ip } } } @@ -1627,9 +1499,9 @@ pub mod liveness { let dirty = self .interference_graph_for_node(node) .map(|graph| { - graph.neighbors(node.0.into()).filter_map(|n| { - register_map.get(&NodeRef(n.index() as u32)).cloned() - }) + graph + .neighbors(node.0.into()) + .filter_map(|n| register_map.get(&NodeRef(n.index() as u32)).cloned()) }) .into_iter() .flatten() @@ -1686,10 +1558,7 @@ pub mod liveness { } } - pub fn new( - mir: &Mir, - references: &BTreeSet<(NodeRef, NodeRef)>, - ) -> Self { + pub fn new(mir: &Mir, references: &BTreeSet<(NodeRef, NodeRef)>) -> Self { let mut sorted_branches = Vec::new(); let mut branch_graph_edges = Vec::new(); @@ -1785,9 +1654,7 @@ pub mod liveness { .map(|(range, edges)| { ( range, - InterferenceGraph::from_edges( - edges.into_iter().map(|(a, b)| (a.0, b.0)), - ), + InterferenceGraph::from_edges(edges.into_iter().map(|(a, b)| (a.0, b.0))), ) }) .collect::>(); @@ -1814,16 +1681,11 @@ pub mod liveness { fn branch_index_for_node(&self, node: NodeRef) -> Option { self.branches - .binary_search_by(|(range, _)| { - range.partial_cmp(&node).unwrap() - }) + .binary_search_by(|(range, _)| range.partial_cmp(&node).unwrap()) .ok() } - pub fn interference_graph_for_node( - &self, - node: NodeRef, - ) -> Option<&InterferenceGraph> { + pub fn interference_graph_for_node(&self, node: NodeRef) -> Option<&InterferenceGraph> { if let Some(index) = self.branch_index_for_node(node) { Some(&self.branches[index].1) } else { @@ -1907,8 +1769,7 @@ pub mod liveness { use Register::*; let mut in_colors = [r9, r8, rcx, rdx, rdi, rsi].to_vec(); - let mut in_colors_sse = - [xmm7, xmm6, xmm5, xmm4, xmm3, xmm2, xmm1, xmm0].to_vec(); + let mut in_colors_sse = [xmm7, xmm6, xmm5, xmm4, xmm3, xmm2, xmm1, xmm0].to_vec(); for node in self.mir.indices() { let want_color = match self.mir.get_node(node).0 { @@ -1922,9 +1783,7 @@ pub mod liveness { Inst::ShiftLeft(_) | Inst::ShiftRightSigned(_) | Inst::ShiftRightUnsigned(_) => Some(rcx), - Inst::Mul(_) | Inst::Div(_) | Inst::DivSigned(_) => { - Some(rax) - } + Inst::Mul(_) | Inst::Div(_) | Inst::DivSigned(_) => Some(rax), Inst::Rem(_) | Inst::RemSigned(_) => Some(rdx), Inst::ReturnValue(ty) => { if ty.is_floating() { @@ -1983,15 +1842,10 @@ pub mod liveness { pub fn get_register(&self, node: NodeRef) -> Option { self.register_map.get(&node).cloned() } - pub fn dirty_registers( - &self, - ) -> std::collections::btree_map::Values { + pub fn dirty_registers(&self) -> std::collections::btree_map::Values { self.register_map.values() } - pub fn get_scratch_register_at_node( - &self, - node: NodeRef, - ) -> Option { + pub fn get_scratch_register_at_node(&self, node: NodeRef) -> Option { let dirty = self .branches .dirty_registers_at_node(&self.register_map, node); @@ -2002,11 +1856,7 @@ pub mod liveness { .next() } - pub fn is_register_in_use_at_node( - &self, - node: NodeRef, - reg: Register, - ) -> bool { + pub fn is_register_in_use_at_node(&self, node: NodeRef, reg: Register) -> bool { self.branches .dirty_registers_at_node(&self.register_map, node) .contains(®) @@ -2078,11 +1928,7 @@ pub mod liveness { .map(|graph| { graph .neighbors(node) - .filter_map(|n| { - self.colors - .get(&NodeRef(n.index() as u32)) - .cloned() - }) + .filter_map(|n| self.colors.get(&NodeRef(n.index() as u32)).cloned()) .find(|color| color.color() == preferred_color) }) .flatten(); @@ -2116,9 +1962,7 @@ pub mod liveness { .map(|graph| { graph .neighbors(node) - .filter_map(|n| { - self.colors.get(&NodeRef(n.index() as u32)).cloned() - }) + .filter_map(|n| self.colors.get(&NodeRef(n.index() as u32)).cloned()) .collect::>() }) .unwrap_or_default(); @@ -2140,9 +1984,7 @@ pub mod liveness { // here we want to first check clique_colors with tentative coloring. let color = colors .into_iter() - .find_or_first(|&c| { - !clique_colors.contains(&Color::Tentative(c)) - }) + .find_or_first(|&c| !clique_colors.contains(&Color::Tentative(c))) .expect("ran out of registers :("); v.insert(Color::Final(color)); color @@ -2497,20 +2339,14 @@ impl Function { } } - pub fn finish_as_function( - self, - ip: &intern::InternPool, - ) -> Result { + pub fn finish_as_function(self, ip: &intern::InternPool) -> Result { let mut buf = String::new(); self.finish(&mut buf, ip)?; Ok(buf) } - pub fn finish_constants( - self, - ip: &intern::InternPool, - ) -> Result { + pub fn finish_constants(self, ip: &intern::InternPool) -> Result { use core::fmt::Write; let mut buf = String::new(); let w = &mut buf; @@ -2674,9 +2510,7 @@ impl Mir { let label = func.get_constant_label(node as usize); ImmRegMem::Rip(RipRelative::Label(Type::QWord, label)) } - Inst::GetElementPtr(ty) => { - liveness.get_register(node.into()).unwrap().into() - } + Inst::GetElementPtr(ty) => liveness.get_register(node.into()).unwrap().into(), Inst::Parameter(ty) | Inst::Call(ty) | Inst::Phi2(ty) @@ -2723,12 +2557,10 @@ impl Mir { Inst::ExternRef(ty) => { // let ty = ty.unwrap_or(Type::QWord); match ty { - None | Some(Type::Function) => { - ImmRegMem::Rip(RipRelative::Reference(format!( - "{}", - strings.get_str(data.as_index()) - ))) - } + None | Some(Type::Function) => ImmRegMem::Rip(RipRelative::Reference(format!( + "{}", + strings.get_str(data.as_index()) + ))), Some(ty) => ImmRegMem::Rip(RipRelative::Label( ty, format!("{}", strings.get_str(data.as_index())), @@ -2741,10 +2573,7 @@ impl Mir { } } - pub fn assemble( - &self, - strings: &intern::InternPool, - ) -> Result { + pub fn assemble(&self, strings: &intern::InternPool) -> Result { use core::fmt::Write; // mapping if (i, (stack_offset, bytes)) for local stack variables let mut mapping = BTreeMap::::new(); @@ -2770,9 +2599,7 @@ impl Mir { | Inst::ConstantWord | Inst::ConstantDWord | Inst::ConstantQWord => { - func.add_constant_from_inst_and_data( - i, inst, data, strings, - ); + func.add_constant_from_inst_and_data(i, inst, data, strings); } Inst::ConstantSinglePrecision => { let bits = data.as_imm32(); @@ -2784,12 +2611,8 @@ impl Mir { } Inst::LoadRegister(ty) => { let src = data.as_node(); - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); - let src = self.node_as_operand( - &liveness, &mapping, &mut func, strings, src, - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); + let src = self.node_as_operand(&liveness, &mapping, &mut func, strings, src); if ty.is_floating() { match src { ImmRegMem::Byte(_) @@ -2805,10 +2628,7 @@ impl Mir { }); if spill_rax { - writeln!( - func.current_branch(), - "push rax" - )?; + writeln!(func.current_branch(), "push rax")?; } writeln!( @@ -2827,16 +2647,10 @@ impl Mir { } } ImmRegMem::Mem(_) | ImmRegMem::Rip(_) => { - writeln!( - func.current_branch(), - "movss {dst}, {src}", - )?; + writeln!(func.current_branch(), "movss {dst}, {src}",)?; } ImmRegMem::Reg(_) => { - writeln!( - func.current_branch(), - "movd {dst}, {src}", - )?; + writeln!(func.current_branch(), "movd {dst}, {src}",)?; } } } else { @@ -2850,21 +2664,12 @@ impl Mir { mapping.insert(i, (offset, size)); } Inst::Load(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let src = data.as_node(); - let src = self.node_as_operand( - &liveness, &mapping, &mut func, strings, src, - ); + let src = self.node_as_operand(&liveness, &mapping, &mut func, strings, src); match src { ImmRegMem::Reg(_) => { - writeln!( - func.current_branch(), - "mov {}, {ty} ptr [{}]", - dst, - src, - )?; + writeln!(func.current_branch(), "mov {}, {ty} ptr [{}]", dst, src,)?; } ImmRegMem::Mem(ref mem) => { let mut spill_rax = false; @@ -2878,18 +2683,8 @@ impl Mir { if spill_rax { writeln!(func.current_branch(), "push rax")?; } - writeln!( - func.current_branch(), - "mov {}, {}", - scratch, - src - )?; - writeln!( - func.current_branch(), - "mov {}, [{}]", - dst, - scratch - )?; + writeln!(func.current_branch(), "mov {}, {}", scratch, src)?; + writeln!(func.current_branch(), "mov {}, [{}]", dst, scratch)?; if spill_rax { writeln!(func.current_branch(), "pop rax")?; } @@ -2901,12 +2696,8 @@ impl Mir { } Inst::Store(ty) => { let (src, dst) = data.as_binary(); - let src = self.node_as_operand( - &liveness, &mapping, &mut func, strings, src, - ); - let dst = self.node_as_operand( - &liveness, &mapping, &mut func, strings, dst, - ); + let src = self.node_as_operand(&liveness, &mapping, &mut func, strings, src); + let dst = self.node_as_operand(&liveness, &mapping, &mut func, strings, dst); if src.is_floating() { writeln!(func.current_branch(), "movss {dst}, {src}")?; } else { @@ -2916,9 +2707,7 @@ impl Mir { Inst::GetElementPtr(ty) => { let dst = liveness.get_register(node.into()).unwrap(); let (src, idx) = data.as_binary(); - let src = self.node_as_operand( - &liveness, &mapping, &mut func, strings, src, - ); + let src = self.node_as_operand(&liveness, &mapping, &mut func, strings, src); if let ImmRegMem::Mem(_) = &src { writeln!(func.current_branch(), "lea {dst}, {src}",)?; @@ -2926,10 +2715,7 @@ impl Mir { let offset = idx * ty.bytes(); if offset != 0 { - writeln!( - func.current_branch(), - "lea {dst}, [{dst} + {offset}]", - )?; + writeln!(func.current_branch(), "lea {dst}, [{dst} + {offset}]",)?; } } Inst::Parameter(ty) => { @@ -2952,19 +2738,10 @@ impl Mir { let mut spilled_registers = vec![]; - let mut gprs = Register::SYSV_ARG_GPR - .into_iter() - .rev() - .collect::>(); - let mut sses = Register::SYSV_ARG_SSE - .into_iter() - .rev() - .collect::>(); + let mut gprs = Register::SYSV_ARG_GPR.into_iter().rev().collect::>(); + let mut sses = Register::SYSV_ARG_SSE.into_iter().rev().collect::>(); - if liveness.is_register_in_use_at_node( - NodeRef(node), - Register::rax, - ) { + if liveness.is_register_in_use_at_node(NodeRef(node), Register::rax) { writeln!(func.current_branch(), "push rax")?; spilled_registers.push(Register::rax); } @@ -2972,56 +2749,38 @@ impl Mir { for arg in (start + 1)..end { variant!(self.nodes[arg as usize] => Inst::Argument(ty)); let arg = self.data[arg as usize].as_node(); - let src = self.node_as_operand( - &liveness, &mapping, &mut func, strings, arg, - ); + let src = + self.node_as_operand(&liveness, &mapping, &mut func, strings, arg); if ty.is_floating() { let reg = sses.pop().unwrap(); - if liveness - .is_register_in_use_at_node(NodeRef(node), reg) - { + if liveness.is_register_in_use_at_node(NodeRef(node), reg) { writeln!(func.current_branch(), "push {reg}")?; spilled_registers.push(reg); } - writeln!( - func.current_branch(), - "movss {reg}, {src}" - )?; + writeln!(func.current_branch(), "movss {reg}, {src}")?; } else { let reg = gprs.pop().unwrap(); - if liveness - .is_register_in_use_at_node(NodeRef(node), reg) - { + if liveness.is_register_in_use_at_node(NodeRef(node), reg) { writeln!(func.current_branch(), "push {reg}")?; spilled_registers.push(reg); } let reg = ty.register_width(reg); - writeln!( - func.current_branch(), - "mov {reg}, {src}" - )?; + writeln!(func.current_branch(), "mov {reg}, {src}")?; } } let f = self.data[start as usize].as_node(); - let f = self.node_as_operand( - &liveness, &mapping, &mut func, strings, f, - ); + let f = self.node_as_operand(&liveness, &mapping, &mut func, strings, f); writeln!(func.current_branch(), "test rax, rax")?; writeln!(func.current_branch(), "call {f}")?; - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); if ty.is_floating() { if dst.parent_reg() != Register::xmm0 { - writeln!( - func.current_branch(), - "movss {dst}, xmm0" - )?; + writeln!(func.current_branch(), "movss {dst}, xmm0")?; } } else { if dst.parent_reg() != Register::rax { @@ -3041,83 +2800,51 @@ impl Mir { } } Inst::Add(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); if ty.is_floating() { writeln!(func.current_branch(), "addss {lhs}, {rhs}")?; if !lhs.occupy_same_register(dst) { - writeln!( - func.current_branch(), - "movss {dst}, {lhs}" - )?; + writeln!(func.current_branch(), "movss {dst}, {lhs}")?; } } else { writeln!(func.current_branch(), "add {lhs}, {rhs}")?; if !lhs.occupy_same_register(dst) { - writeln!( - func.current_branch(), - "mov {dst}, {lhs}" - )?; + writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } } } Inst::Sub(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); if ty.is_floating() { writeln!(func.current_branch(), "subss {lhs}, {rhs}")?; if !lhs.occupy_same_register(dst) { - writeln!( - func.current_branch(), - "movss {dst}, {lhs}" - )?; + writeln!(func.current_branch(), "movss {dst}, {lhs}")?; } } else { writeln!(func.current_branch(), "sub {lhs}, {rhs}")?; if !lhs.occupy_same_register(dst) { - writeln!( - func.current_branch(), - "mov {dst}, {lhs}" - )?; + writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } } } Inst::Mul(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); - let spill_rax = liveness - .is_register_in_use_at_node(node.into(), Register::rax) + let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax) && !(lhs.occupy_same_register(Register::rax) || rhs.occupy_same_register(Register::rax) || dst.parent_reg() == Register::rax); - let spill_rdx = liveness - .is_register_in_use_at_node(node.into(), Register::rdx) + let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx) && !(lhs.occupy_same_register(Register::rdx) || rhs.occupy_same_register(Register::rdx) || dst.parent_reg() == Register::rdx); @@ -3155,24 +2882,16 @@ impl Mir { } } Inst::MulSigned(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); - let spill_rax = liveness - .is_register_in_use_at_node(node.into(), Register::rax) + let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax) && !(lhs.occupy_same_register(Register::rax) || rhs.occupy_same_register(Register::rax) || dst.parent_reg() == Register::rax); - let spill_rdx = liveness - .is_register_in_use_at_node(node.into(), Register::rdx) + let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx) && !(lhs.occupy_same_register(Register::rdx) || rhs.occupy_same_register(Register::rdx) || dst.parent_reg() == Register::rdx); @@ -3198,24 +2917,16 @@ impl Mir { } } Inst::Div(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); - let spill_rax = liveness - .is_register_in_use_at_node(node.into(), Register::rax) + let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax) && !(lhs.occupy_same_register(Register::rax) || rhs.occupy_same_register(Register::rax) || dst.parent_reg() == Register::rax); - let spill_rdx = liveness - .is_register_in_use_at_node(node.into(), Register::rdx) + let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx) && !(lhs.occupy_same_register(Register::rdx) || rhs.occupy_same_register(Register::rdx) || dst.parent_reg() == Register::rdx); @@ -3253,24 +2964,16 @@ impl Mir { } } Inst::DivSigned(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); - let spill_rax = liveness - .is_register_in_use_at_node(node.into(), Register::rax) + let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax) && !(lhs.occupy_same_register(Register::rax) || rhs.occupy_same_register(Register::rax) || dst.parent_reg() == Register::rax); - let spill_rdx = liveness - .is_register_in_use_at_node(node.into(), Register::rdx) + let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx) && !(lhs.occupy_same_register(Register::rdx) || rhs.occupy_same_register(Register::rdx) || dst.parent_reg() == Register::rdx); @@ -3308,24 +3011,16 @@ impl Mir { } } Inst::Rem(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); - let spill_rax = liveness - .is_register_in_use_at_node(node.into(), Register::rax) + let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax) && !(lhs.occupy_same_register(Register::rax) || rhs.occupy_same_register(Register::rax) || dst.parent_reg() == Register::rax); - let spill_rdx = liveness - .is_register_in_use_at_node(node.into(), Register::rdx) + let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx) && !(lhs.occupy_same_register(Register::rdx) || rhs.occupy_same_register(Register::rdx) || dst.parent_reg() == Register::rdx); @@ -3363,24 +3058,16 @@ impl Mir { } } Inst::RemSigned(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); - let spill_rax = liveness - .is_register_in_use_at_node(node.into(), Register::rax) + let spill_rax = liveness.is_register_in_use_at_node(node.into(), Register::rax) && !(lhs.occupy_same_register(Register::rax) || rhs.occupy_same_register(Register::rax) || dst.parent_reg() == Register::rax); - let spill_rdx = liveness - .is_register_in_use_at_node(node.into(), Register::rdx) + let spill_rdx = liveness.is_register_in_use_at_node(node.into(), Register::rdx) && !(lhs.occupy_same_register(Register::rdx) || rhs.occupy_same_register(Register::rdx) || dst.parent_reg() == Register::rdx); @@ -3418,16 +3105,10 @@ impl Mir { } } Inst::MulSSE(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); writeln!(func.current_branch(), "mulss {lhs}, {rhs}")?; if !lhs.occupy_same_register(dst) { @@ -3435,16 +3116,10 @@ impl Mir { } } Inst::DivSSE(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); writeln!(func.current_branch(), "divss {lhs}, {rhs}")?; if !lhs.occupy_same_register(dst) { @@ -3452,108 +3127,61 @@ impl Mir { } } Inst::RemFP(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); let ty = ty.int_repr(); let size = ty.bytes(); - writeln!( - func.current_branch(), - "sub rsp, 0x{:x}", - size * 2 - )?; - writeln!( - func.current_branch(), - "movss {ty} ptr [rsp], {lhs}" - )?; + writeln!(func.current_branch(), "sub rsp, 0x{:x}", size * 2)?; + writeln!(func.current_branch(), "movss {ty} ptr [rsp], {lhs}")?; writeln!( func.current_branch(), "movss {ty} ptr [rsp + {size}], {rhs}" )?; - writeln!( - func.current_branch(), - "fld {ty} ptr [rsp + {size}]" - )?; + writeln!(func.current_branch(), "fld {ty} ptr [rsp + {size}]")?; writeln!(func.current_branch(), "fld {ty} ptr [rsp]")?; writeln!(func.current_branch(), "fprem")?; writeln!(func.current_branch(), "fst {ty} ptr [rsp]")?; - writeln!( - func.current_branch(), - "movss {dst}, {ty} ptr [rsp]" - )?; - writeln!( - func.current_branch(), - "add rsp, 0x{:x}", - size * 2 - )?; + writeln!(func.current_branch(), "movss {dst}, {ty} ptr [rsp]")?; + writeln!(func.current_branch(), "add rsp, 0x{:x}", size * 2)?; } Inst::BitAnd(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); writeln!(func.current_branch(), "and {lhs}, {rhs}")?; if !lhs.occupy_same_register(dst) { writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } } Inst::BitOr(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); writeln!(func.current_branch(), "or {lhs}, {rhs}")?; if !lhs.occupy_same_register(dst) { writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } } Inst::BitXOr(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); writeln!(func.current_branch(), "xor {lhs}, {rhs}")?; if !lhs.occupy_same_register(dst) { writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } } Inst::ShiftLeft(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); let lhs_is_rcx = lhs.occupy_same_register(Register::rcx); let rhs_is_rcx = rhs.occupy_same_register(Register::rcx); @@ -3561,43 +3189,25 @@ impl Mir { match rhs { ImmRegMem::Byte(v) => { - writeln!( - func.current_branch(), - "shl {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "shl {lhs}, {}", v as u8)?; } ImmRegMem::DWord(v) => { - writeln!( - func.current_branch(), - "shl {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "shl {lhs}, {}", v as u8)?; } ImmRegMem::QWord(v) => { - writeln!( - func.current_branch(), - "shl {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "shl {lhs}, {}", v as u8)?; } ImmRegMem::Word(v) => { - writeln!( - func.current_branch(), - "shl {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "shl {lhs}, {}", v as u8)?; } ImmRegMem::Reg(reg) => { // reg needs to be moved to CL // if lhs is in rcx, lhs needs to move to rax and we spill rax temporarily // if neither lhs nor rhx nor dst are rcx, spill rcx temporarily - let spill_rcx = - liveness.is_register_in_use_at_node( - node.into(), - Register::rcx, - ) && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx); + let spill_rcx = liveness + .is_register_in_use_at_node(node.into(), Register::rcx) + && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx); if spill_rcx { writeln!(func.current_branch(), "push rcx")?; @@ -3613,20 +3223,11 @@ impl Mir { } if lhs_is_rcx { - if liveness.is_register_in_use_at_node( - node.into(), - Register::rax, - ) { - writeln!( - func.current_branch(), - "push rax" - )?; + if liveness.is_register_in_use_at_node(node.into(), Register::rax) { + writeln!(func.current_branch(), "push rax")?; } - writeln!( - func.current_branch(), - "test rax,rax" - )?; + writeln!(func.current_branch(), "test rax,rax")?; writeln!( func.current_branch(), "mov {}, {lhs}", @@ -3634,27 +3235,15 @@ impl Mir { .register_width(Register::rax) )?; writeln!(func.current_branch(), "shl rax, cl")?; - writeln!( - func.current_branch(), - "mov {dst}, rax" - )?; + writeln!(func.current_branch(), "mov {dst}, rax")?; - if liveness.is_register_in_use_at_node( - node.into(), - Register::rax, - ) { + if liveness.is_register_in_use_at_node(node.into(), Register::rax) { writeln!(func.current_branch(), "pop rax")?; } } else { - writeln!( - func.current_branch(), - "shl {lhs}, cl" - )?; + writeln!(func.current_branch(), "shl {lhs}, cl")?; if lhs.occupy_same_register(dst) { - writeln!( - func.current_branch(), - "mov {dst}, {lhs}" - )?; + writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } } @@ -3669,16 +3258,10 @@ impl Mir { } } Inst::ShiftRightSigned(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); let lhs_is_rcx = lhs.occupy_same_register(Register::rcx); let rhs_is_rcx = rhs.occupy_same_register(Register::rcx); @@ -3686,43 +3269,25 @@ impl Mir { match rhs { ImmRegMem::Byte(v) => { - writeln!( - func.current_branch(), - "sar {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "sar {lhs}, {}", v as u8)?; } ImmRegMem::DWord(v) => { - writeln!( - func.current_branch(), - "sar {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "sar {lhs}, {}", v as u8)?; } ImmRegMem::QWord(v) => { - writeln!( - func.current_branch(), - "sar {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "sar {lhs}, {}", v as u8)?; } ImmRegMem::Word(v) => { - writeln!( - func.current_branch(), - "sar {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "sar {lhs}, {}", v as u8)?; } ImmRegMem::Reg(reg) => { // reg needs to be moved to CL // if lhs is in rcx, lhs needs to move to rax and we spill rax temporarily // if neither lhs nor rhx nor dst are rcx, spill rcx temporarily - let spill_rcx = - liveness.is_register_in_use_at_node( - node.into(), - Register::rcx, - ) && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx); + let spill_rcx = liveness + .is_register_in_use_at_node(node.into(), Register::rcx) + && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx); if spill_rcx { writeln!(func.current_branch(), "push rcx")?; @@ -3738,19 +3303,10 @@ impl Mir { } if lhs_is_rcx { - if liveness.is_register_in_use_at_node( - node.into(), - Register::rax, - ) { - writeln!( - func.current_branch(), - "push rax" - )?; + if liveness.is_register_in_use_at_node(node.into(), Register::rax) { + writeln!(func.current_branch(), "push rax")?; } - writeln!( - func.current_branch(), - "test rax,rax" - )?; + writeln!(func.current_branch(), "test rax,rax")?; writeln!( func.current_branch(), "mov {}, {lhs}", @@ -3758,27 +3314,15 @@ impl Mir { .register_width(Register::rax) )?; writeln!(func.current_branch(), "sar rax, cl")?; - writeln!( - func.current_branch(), - "mov {dst}, rax" - )?; + writeln!(func.current_branch(), "mov {dst}, rax")?; - if liveness.is_register_in_use_at_node( - node.into(), - Register::rax, - ) { + if liveness.is_register_in_use_at_node(node.into(), Register::rax) { writeln!(func.current_branch(), "pop rax")?; } } else { - writeln!( - func.current_branch(), - "sar {lhs}, cl" - )?; + writeln!(func.current_branch(), "sar {lhs}, cl")?; if lhs.occupy_same_register(dst) { - writeln!( - func.current_branch(), - "mov {dst}, {lhs}" - )?; + writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } } @@ -3793,16 +3337,10 @@ impl Mir { } } Inst::ShiftRightUnsigned(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); let lhs_is_rcx = lhs.occupy_same_register(Register::rcx); let rhs_is_rcx = rhs.occupy_same_register(Register::rcx); @@ -3810,43 +3348,25 @@ impl Mir { match rhs { ImmRegMem::Byte(v) => { - writeln!( - func.current_branch(), - "shr {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "shr {lhs}, {}", v as u8)?; } ImmRegMem::DWord(v) => { - writeln!( - func.current_branch(), - "shr {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "shr {lhs}, {}", v as u8)?; } ImmRegMem::QWord(v) => { - writeln!( - func.current_branch(), - "shr {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "shr {lhs}, {}", v as u8)?; } ImmRegMem::Word(v) => { - writeln!( - func.current_branch(), - "shr {lhs}, {}", - v as u8 - )?; + writeln!(func.current_branch(), "shr {lhs}, {}", v as u8)?; } ImmRegMem::Reg(reg) => { // reg needs to be moved to CL // if lhs is in rcx, lhs needs to move to rax and we spill rax temporarily // if neither lhs nor rhx nor dst are rcx, spill rcx temporarily - let spill_rcx = - liveness.is_register_in_use_at_node( - node.into(), - Register::rcx, - ) && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx); + let spill_rcx = liveness + .is_register_in_use_at_node(node.into(), Register::rcx) + && !(lhs_is_rcx || rhs_is_rcx || dst_is_rcx); if spill_rcx { writeln!(func.current_branch(), "push rcx")?; @@ -3862,20 +3382,11 @@ impl Mir { } if lhs_is_rcx { - if liveness.is_register_in_use_at_node( - node.into(), - Register::rax, - ) { - writeln!( - func.current_branch(), - "push rax" - )?; + if liveness.is_register_in_use_at_node(node.into(), Register::rax) { + writeln!(func.current_branch(), "push rax")?; } - writeln!( - func.current_branch(), - "test rax,rax" - )?; + writeln!(func.current_branch(), "test rax,rax")?; writeln!( func.current_branch(), "mov {}, {lhs}", @@ -3883,27 +3394,15 @@ impl Mir { .register_width(Register::rax) )?; writeln!(func.current_branch(), "shr rax, cl")?; - writeln!( - func.current_branch(), - "mov {dst}, rax" - )?; + writeln!(func.current_branch(), "mov {dst}, rax")?; - if liveness.is_register_in_use_at_node( - node.into(), - Register::rax, - ) { + if liveness.is_register_in_use_at_node(node.into(), Register::rax) { writeln!(func.current_branch(), "pop rax")?; } } else { - writeln!( - func.current_branch(), - "shr {lhs}, cl" - )?; + writeln!(func.current_branch(), "shr {lhs}, cl")?; if lhs.occupy_same_register(dst) { - writeln!( - func.current_branch(), - "mov {dst}, {lhs}" - )?; + writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } } @@ -3918,13 +3417,9 @@ impl Mir { } } Inst::Not(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let lhs = data.as_node(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); writeln!(func.current_branch(), "not {lhs}")?; if !lhs.occupy_same_register(dst) { @@ -3932,44 +3427,27 @@ impl Mir { } } Inst::Negate(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let lhs = data.as_node(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); if ty.is_floating() { - writeln!( - func.current_branch(), - "mulss {lhs}, [rip + .NEG1F32]" - )?; + writeln!(func.current_branch(), "mulss {lhs}, [rip + .NEG1F32]")?; if lhs != ImmRegMem::Reg(dst) { - writeln!( - func.current_branch(), - "movss {dst}, {lhs}" - )?; + writeln!(func.current_branch(), "movss {dst}, {lhs}")?; } } else { writeln!(func.current_branch(), "neg {lhs}")?; if lhs != ImmRegMem::Reg(dst) { - writeln!( - func.current_branch(), - "mov {dst}, {lhs}" - )?; + writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } } } Inst::SignExtend(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let lhs = data.as_node(); let lhs_ty = self.type_of_node(lhs).unwrap(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); if ty == lhs_ty { writeln!(func.current_branch(), "test {dst}, {dst}")?; @@ -3977,11 +3455,7 @@ impl Mir { } else { match lhs { ImmRegMem::Byte(v) => { - writeln!( - func.current_branch(), - "mov {}, {v}", - dst.into_byte() - )?; + writeln!(func.current_branch(), "mov {}, {v}", dst.into_byte())?; writeln!( func.current_branch(), "movsx {dst}, {}", @@ -3989,11 +3463,7 @@ impl Mir { )?; } ImmRegMem::Word(v) => { - writeln!( - func.current_branch(), - "mov {},{v}", - dst.into_word() - )?; + writeln!(func.current_branch(), "mov {},{v}", dst.into_word())?; writeln!( func.current_branch(), "movsx {dst}, {}", @@ -4001,11 +3471,7 @@ impl Mir { )?; } ImmRegMem::DWord(v) => { - writeln!( - func.current_branch(), - "mov {},{v}", - dst.into_dword() - )?; + writeln!(func.current_branch(), "mov {},{v}", dst.into_dword())?; writeln!( func.current_branch(), "movsxd {dst}, {}", @@ -4013,30 +3479,17 @@ impl Mir { )?; } ImmRegMem::QWord(v) => { - writeln!( - func.current_branch(), - "mov {},{v}", - dst.into_qword() - )?; + writeln!(func.current_branch(), "mov {},{v}", dst.into_qword())?; } ImmRegMem::Mem(mem) => match lhs_ty { Type::Byte | Type::Word => { - writeln!( - func.current_branch(), - "movsx {dst}, {mem}" - )?; + writeln!(func.current_branch(), "movsx {dst}, {mem}")?; } Type::DWord => { - writeln!( - func.current_branch(), - "movsxd {dst}, {mem}" - )?; + writeln!(func.current_branch(), "movsxd {dst}, {mem}")?; } Type::QWord => { - writeln!( - func.current_branch(), - "movs {dst}, {mem}" - )?; + writeln!(func.current_branch(), "movs {dst}, {mem}")?; } _ => { panic!("cannot sign-extend a floating register") @@ -4044,22 +3497,13 @@ impl Mir { }, ImmRegMem::Reg(reg) => match lhs_ty { Type::Byte | Type::Word => { - writeln!( - func.current_branch(), - "movsx {dst}, {reg}" - )?; + writeln!(func.current_branch(), "movsx {dst}, {reg}")?; } Type::DWord => { - writeln!( - func.current_branch(), - "movsxd {dst}, {reg}" - )?; + writeln!(func.current_branch(), "movsxd {dst}, {reg}")?; } Type::QWord => { - writeln!( - func.current_branch(), - "mov {dst}, {reg}" - )?; + writeln!(func.current_branch(), "mov {dst}, {reg}")?; } _ => { panic!("cannot sign-extend a floating register") @@ -4070,52 +3514,28 @@ impl Mir { } } Inst::ZeroExtend(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let lhs = data.as_node(); let lhs_ty = self.type_of_node(lhs).unwrap(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); if ty == lhs_ty { writeln!(func.current_branch(), "test {dst}, {dst}")?; writeln!(func.current_branch(), "mov {dst}, {lhs}")?; } else { - writeln!( - func.current_branch(), - "test {0}, {0}", - dst.parent_reg() - )?; + writeln!(func.current_branch(), "test {0}, {0}", dst.parent_reg())?; match lhs { ImmRegMem::Byte(v) => { - writeln!( - func.current_branch(), - "mov {}, {v}", - dst.into_byte() - )?; + writeln!(func.current_branch(), "mov {}, {v}", dst.into_byte())?; } ImmRegMem::Word(v) => { - writeln!( - func.current_branch(), - "mov {}, {v}", - dst.into_word() - )?; + writeln!(func.current_branch(), "mov {}, {v}", dst.into_word())?; } ImmRegMem::DWord(v) => { - writeln!( - func.current_branch(), - "mov {}, {v}", - dst.into_dword() - )?; + writeln!(func.current_branch(), "mov {}, {v}", dst.into_dword())?; } ImmRegMem::QWord(v) => { - writeln!( - func.current_branch(), - "mov {}, {v}", - dst.into_qword() - )?; + writeln!(func.current_branch(), "mov {}, {v}", dst.into_qword())?; } ImmRegMem::Mem(mem) => { writeln!( @@ -4137,12 +3557,8 @@ impl Mir { } Inst::Cmp(ty) => { let (lhs, rhs) = data.as_binary(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); - let rhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, rhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); + let rhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, rhs); if ty.is_floating() { writeln!(func.current_branch(), "comiss {lhs}, {rhs}")?; @@ -4156,8 +3572,7 @@ impl Mir { | Inst::IsLt(signed) | Inst::IsGe(signed) | Inst::IsLe(signed) => { - let dst = - liveness.get_register(node.into()).unwrap().into_byte(); + let dst = liveness.get_register(node.into()).unwrap().into_byte(); #[cfg_attr(rustfmt, rustfmt::skip)] let mnemonic = match inst { @@ -4173,32 +3588,19 @@ impl Mir { writeln!(func.current_branch(), "{mnemonic} {dst}")?; } Inst::IsZero(ty) => { - let dst = ty.register_width( - liveness.get_register(node.into()).unwrap(), - ); + let dst = ty.register_width(liveness.get_register(node.into()).unwrap()); let lhs = data.as_node(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); writeln!(func.current_branch(), "mov {dst}, {lhs}")?; writeln!(func.current_branch(), "test {dst}, {dst}")?; - writeln!( - func.current_branch(), - "setz {}", - dst.into_byte() - )?; + writeln!(func.current_branch(), "setz {}", dst.into_byte())?; } Inst::ReturnValue(ty) => { let lhs = data.as_node(); - let lhs = self.node_as_operand( - &liveness, &mapping, &mut func, strings, lhs, - ); + let lhs = self.node_as_operand(&liveness, &mapping, &mut func, strings, lhs); if ty.is_floating() { if !lhs.occupy_same_register(Register::xmm0) { - writeln!( - func.current_branch(), - "movss xmm0, {lhs}", - )?; + writeln!(func.current_branch(), "movss xmm0, {lhs}",)?; } } else { if !lhs.occupy_same_register(Register::rax) { @@ -4221,34 +3623,21 @@ impl Mir { } } Inst::Branch(condition) => { - let cond = self.node_as_operand( - &liveness, &mapping, &mut func, strings, condition, - ); + let cond = + self.node_as_operand(&liveness, &mapping, &mut func, strings, condition); let (lhs, rhs) = data.as_binary(); writeln!(func.current_branch(), "test {cond}, {cond}")?; match (lhs, rhs) { _ if lhs == node + 1 => { - writeln!( - func.current_branch(), - "jz .{name}__L{rhs}" - )?; + writeln!(func.current_branch(), "jz .{name}__L{rhs}")?; } _ if rhs == node + 1 => { - writeln!( - func.current_branch(), - "jnz .{name}__L{lhs}" - )?; + writeln!(func.current_branch(), "jnz .{name}__L{lhs}")?; } _ => { - writeln!( - func.current_branch(), - "jnz .{name}__L{lhs}" - )?; - writeln!( - func.current_branch(), - "jz .{name}__L{rhs}" - )?; + writeln!(func.current_branch(), "jnz .{name}__L{lhs}")?; + writeln!(func.current_branch(), "jz .{name}__L{rhs}")?; } } } diff --git a/src/parser.rs b/src/parser.rs index 51ea59a..f1f502e 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -2,10 +2,7 @@ use itertools::Itertools; use num_bigint::{BigInt, BigUint}; use crate::{ - ast::{ - self, FloatingType, IntegralType, LetOrVar, Node, PrimitiveType, Tag, - Type, - }, + ast::{self, FloatingType, IntegralType, LetOrVar, Node, Tag, Type}, ast2::intern::{self, AMD64_POINTER_BITS}, common::NextIf, comptime::{self, ComptimeNumber}, @@ -147,17 +144,13 @@ impl Tree { .map(|decl| { let name = match self.nodes.get_node(*decl) { Tag::FunctionDecl { proto, .. } => { - let Tag::FunctionProto { name, .. } = - self.nodes.get_node(*proto) - else { + let Tag::FunctionProto { name, .. } = self.nodes.get_node(*proto) else { unreachable!() }; self.get_ident_str(*name).unwrap().to_owned() } - Tag::GlobalDecl { name, .. } => { - self.get_ident_str(*name).unwrap().to_owned() - } + Tag::GlobalDecl { name, .. } => self.get_ident_str(*name).unwrap().to_owned(), _ => { unreachable!() } @@ -243,10 +236,7 @@ impl Tree { IntegralType { signed, bits } } - fn parse_integral_constant( - token: Token, - lexeme: &str, - ) -> (BigInt, Option) { + fn parse_integral_constant(token: Token, lexeme: &str) -> (BigInt, Option) { let radix = Radix::from_token(token).unwrap(); // TODO: figure out how to do this safely for bigger types, whether to @@ -269,9 +259,9 @@ impl Tree { let value = comptime::bigint::parse_bigint(digits.into_iter(), radix); let ty = match iter.clone().next() { - Some((_, 'u')) | Some((_, 'i')) => Some(Self::parse_integral_type( - &lexeme[iter.next().unwrap().0..], - )), + Some((_, 'u')) | Some((_, 'i')) => { + Some(Self::parse_integral_type(&lexeme[iter.next().unwrap().0..])) + } _ => None, }; @@ -281,10 +271,7 @@ impl Tree { ) } - fn parse_floating_constant( - _token: Token, - lexeme: &str, - ) -> (u64, FloatingType) { + fn parse_floating_constant(_token: Token, lexeme: &str) -> (u64, FloatingType) { // let (dot, exp) = match token { // Token::DotFloatingExpConstant => (true, true), // Token::DotFloatingConstant => (true, false), @@ -304,12 +291,8 @@ impl Tree { ); let bits = match lexeme.1 { - FloatingType::Binary32 => { - lexeme.0.parse::().unwrap().to_bits() as u64 - } - FloatingType::Binary64 => { - lexeme.0.parse::().unwrap().to_bits() as u64 - } + FloatingType::Binary32 => lexeme.0.parse::().unwrap().to_bits() as u64, + FloatingType::Binary64 => lexeme.0.parse::().unwrap().to_bits() as u64, }; (bits, lexeme.1) @@ -328,10 +311,7 @@ impl Tree { } } - pub fn parse_primitive_type( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_primitive_type(&mut self, tokens: &mut TokenIterator) -> Result { let token = tokens.next().ok_or(Error::UnexpectedEndOfTokens)?; let prim = match token.token() { Token::Void => intern::Index::VOID, @@ -346,10 +326,7 @@ impl Tree { Ok(self.nodes.push_tag(Tag::PrimitiveType(prim))) } - pub fn parse_pointer( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_pointer(&mut self, tokens: &mut TokenIterator) -> Result { tokens.expect_token(Token::Star)?; let _constness = tokens.eat_token(Token::Const); let typename = self.parse_typename(tokens)?; @@ -357,24 +334,19 @@ impl Tree { Ok(self.nodes.push_tag(Tag::Pointer { pointee: typename })) } - pub fn parse_typename( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_typename(&mut self, tokens: &mut TokenIterator) -> Result { match tokens.peek_token_or_err()?.token() { Token::Star => self.parse_pointer(tokens), Token::Ident => { let token = tokens.next().unwrap(); match Self::try_parse_integral_type(token.lexeme())? { Some(int) => { - let ty = - self.intern_pool.get_int_type(int.signed, int.bits); + let ty = self.intern_pool.get_int_type(int.signed, int.bits); Ok(self.nodes.push_tag(Tag::IntegralType(ty))) } None => { - let name = - self.intern_pool.insert_string(token.lexeme()); + let name = self.intern_pool.insert_string(token.lexeme()); Ok(self.nodes.push_tag(Tag::Ident { name })) } } @@ -383,10 +355,7 @@ impl Tree { } } - pub fn parse_var_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_var_decl(&mut self, tokens: &mut TokenIterator) -> Result { let let_or_var = match tokens .eat_token(Token::Let) .or_else(|| tokens.eat_token(Token::Var)) @@ -406,8 +375,7 @@ impl Tree { None }; - let name_str = - self.intern_pool.get_str(self.ident_index(name)).to_owned(); + let name_str = self.intern_pool.get_str(self.ident_index(name)).to_owned(); let decl = self.nodes.reserve_node(); let assignment = if tokens.eat_token(Token::Equal).is_some() { @@ -435,10 +403,7 @@ impl Tree { /// GLOBAL_DECL <- /// const IDENTIFIER (: TYPENAME)? = EXPR; - pub fn parse_global_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_global_decl(&mut self, tokens: &mut TokenIterator) -> Result { _ = tokens.expect_token(Token::Const)?; let name = self.parse_ident(tokens)?; @@ -483,10 +448,7 @@ impl Tree { /// PARAMETER <- /// IDENTIFIER : TYPENAME - pub fn parse_parameter( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_parameter(&mut self, tokens: &mut TokenIterator) -> Result { let name = self.parse_ident(tokens)?; tokens.expect_token(Token::Colon)?; let ty = self.parse_typename(tokens)?; @@ -505,10 +467,7 @@ impl Tree { /// PARAMETER_LIST <- /// PARAMETER /// PARAMETER_LIST , PARAMETER - pub fn parse_parameter_list( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_parameter_list(&mut self, tokens: &mut TokenIterator) -> Result { let mut parameters = Vec::new(); loop { @@ -533,10 +492,7 @@ impl Tree { /// fn IDENTIFIER () -> TYPENAME /// fn IDENTIFIER ( PARAMETER_LIST ,? ) /// fn IDENTIFIER ( PARAMETER_LIST ,? ) -> TYPENAME - pub fn parse_fn_proto( - &mut self, - tokens: &mut TokenIterator, - ) -> Result<(Node, Node)> { + pub fn parse_fn_proto(&mut self, tokens: &mut TokenIterator) -> Result<(Node, Node)> { tokens.expect_token(Token::Fn)?; let name = self.parse_ident(tokens)?; tokens.expect_token(Token::OpenParens)?; @@ -567,10 +523,7 @@ impl Tree { /// FUNCTION_DECL <- /// FUNCTION_PROTO BLOCK - pub fn parse_fn_decl( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_fn_decl(&mut self, tokens: &mut TokenIterator) -> Result { let (proto, name) = self.parse_fn_proto(tokens)?; let decl = match self @@ -580,10 +533,8 @@ impl Tree { Some(record) => record.node(), None => { let decl = self.nodes.reserve_node(); - self.st.insert_orderless_symbol( - &self.get_ident_str(name).unwrap().to_owned(), - decl, - ); + self.st + .insert_orderless_symbol(&self.get_ident_str(name).unwrap().to_owned(), decl); decl } }; @@ -593,9 +544,7 @@ impl Tree { let body = self.parse_block(tokens, Some(block))?; let unresolved = self .st - .extract_orderless_if(|_, v| { - self.nodes.get_node(v.node()) == &Tag::Undefined - }) + .extract_orderless_if(|_, v| self.nodes.get_node(v.node()) == &Tag::Undefined) .collect::>(); self.st.into_parent(); self.st.extend_orderless(unresolved); @@ -669,10 +618,7 @@ impl Tree { /// ASSIGNMENT_EXPR <- /// BINARY_EXPRESSION /// BINARY_EXPRESSION ASSIGNMENT_OP EXPRESSION - pub fn parse_assignment_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_assignment_expr(&mut self, tokens: &mut TokenIterator) -> Result { let lhs = self.parse_binary_expr(tokens, 0)?; Ok(self.try_parse_assignment(lhs, tokens)?.unwrap_or(lhs)) @@ -700,24 +646,12 @@ impl Tree { Token::MinusEqual => self.nodes.push_tag(Tag::Sub { lhs, rhs }), Token::StarEqual => self.nodes.push_tag(Tag::Mul { lhs, rhs }), Token::SlashEqual => self.nodes.push_tag(Tag::Sub { lhs, rhs }), - Token::PercentEqual => { - self.nodes.push_tag(Tag::Rem { lhs, rhs }) - } - Token::PipeEqual => { - self.nodes.push_tag(Tag::BitOr { lhs, rhs }) - } - Token::CaretEqual => { - self.nodes.push_tag(Tag::BitXOr { lhs, rhs }) - } - Token::AmpersandEqual => { - self.nodes.push_tag(Tag::BitAnd { lhs, rhs }) - } - Token::LessLessEqual => { - self.nodes.push_tag(Tag::Shl { lhs, rhs }) - } - Token::GreaterGreaterEqual => { - self.nodes.push_tag(Tag::Shr { lhs, rhs }) - } + Token::PercentEqual => self.nodes.push_tag(Tag::Rem { lhs, rhs }), + Token::PipeEqual => self.nodes.push_tag(Tag::BitOr { lhs, rhs }), + Token::CaretEqual => self.nodes.push_tag(Tag::BitXOr { lhs, rhs }), + Token::AmpersandEqual => self.nodes.push_tag(Tag::BitAnd { lhs, rhs }), + Token::LessLessEqual => self.nodes.push_tag(Tag::Shl { lhs, rhs }), + Token::GreaterGreaterEqual => self.nodes.push_tag(Tag::Shr { lhs, rhs }), Token::Equal => rhs, _ => { unreachable!() @@ -731,10 +665,7 @@ impl Tree { /// RETURN_STATEMENT <- /// return EXPRESSION? ; - pub fn try_parse_return_stmt( - &mut self, - tokens: &mut TokenIterator, - ) -> Result> { + pub fn try_parse_return_stmt(&mut self, tokens: &mut TokenIterator) -> Result> { if tokens.eat_token(Token::Return).is_some() { let expr = if !tokens.is_next_token(Token::Semi) { let expr = Some(self.parse_expr(tokens)?); @@ -755,10 +686,7 @@ impl Tree { /// RETURN_EXPRESSION /// VAR_DECL ; /// EXPRESSION ; - pub fn parse_statement( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_statement(&mut self, tokens: &mut TokenIterator) -> Result { match tokens.peek_token_or_err()?.token() { Token::Return => Ok(self.try_parse_return_stmt(tokens)?.unwrap()), Token::Var | Token::Let => { @@ -854,10 +782,7 @@ impl Tree { /// - POSTFIX_EXPR /// & POSTFIX_EXPR /// * POSTFIX_EXPR - pub fn parse_prefix_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_prefix_expr(&mut self, tokens: &mut TokenIterator) -> Result { match tokens.peek_token_or_err()?.token() { Token::Bang => { _ = tokens.next(); @@ -886,10 +811,7 @@ impl Tree { /// AS_EXPR <- /// PREFIX_EXPR /// PREFIX_EXPR as TYPENAME - pub fn parse_as_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_as_expr(&mut self, tokens: &mut TokenIterator) -> Result { let expr = self.parse_prefix_expr(tokens)?; if tokens.eat_token(Token::As).is_some() { @@ -906,10 +828,7 @@ impl Tree { /// ARGUMENT <- /// IDENT : EXPR /// EXPR - pub fn parse_argument( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_argument(&mut self, tokens: &mut TokenIterator) -> Result { if tokens.is_next_token2(Token::Colon) { let name = self.parse_ident(tokens)?; _ = tokens.expect_token(Token::Colon)?; @@ -927,10 +846,7 @@ impl Tree { /// ARGUMENT_LIST <- /// ARGUMENT /// ARGUMENT_LIST , ARGUMENT - pub fn parse_argument_list( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_argument_list(&mut self, tokens: &mut TokenIterator) -> Result { let mut arguments = Vec::new(); loop { @@ -954,10 +870,7 @@ impl Tree { /// PRIMARY_EXPR /// PRIMARY_EXPR ( ) /// PRIMARY_EXPR ( ARGUMENT_LIST ) - pub fn parse_postfix_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_postfix_expr(&mut self, tokens: &mut TokenIterator) -> Result { let lhs = self.parse_primary_expr(tokens)?; if tokens.eat_token(Token::OpenParens).is_some() { @@ -983,10 +896,7 @@ impl Tree { /// FLOATING_CONSTANT /// ( EXPRESSION ) /// { STATEMENT* EXPRESSION? } - pub fn parse_primary_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_primary_expr(&mut self, tokens: &mut TokenIterator) -> Result { let token = tokens.peek_token_or_err()?; match token.token() { Token::Ident => { @@ -995,16 +905,12 @@ impl Tree { let name = ident.lexeme(); if let Some(record) = self.st.find_ordered_symbol(name) { Ok(self.nodes.push_tag(Tag::DeclRef(record.node()))) - } else if let Some(record) = self.st.find_orderless_symbol(name) - { + } else if let Some(record) = self.st.find_orderless_symbol(name) { Ok(self.nodes.push_tag(Tag::GlobalRef(record.node()))) } else { let node = self .st - .insert_orderless_symbol( - name, - self.nodes.reserve_node(), - ) + .insert_orderless_symbol(name, self.nodes.reserve_node()) .node(); Ok(self.nodes.push_tag(Tag::GlobalRef(node))) @@ -1015,10 +921,7 @@ impl Tree { | Token::IntegerOctConstant | Token::IntegerConstant => { _ = tokens.next(); - let (bits, ty) = Self::parse_integral_constant( - token.token(), - token.lexeme(), - ); + let (bits, ty) = Self::parse_integral_constant(token.token(), token.lexeme()); let (_, bytes) = bits.to_bytes_le(); const BUF_SIZE: usize = core::mem::size_of::(); @@ -1027,18 +930,15 @@ impl Tree { .copy_from_slice(&bytes[..bytes.len().min(BUF_SIZE)]); let bytes = match bytes.len() { 0..2 => { - let (buf, _) = - buf.split_at(core::mem::size_of::()); + let (buf, _) = buf.split_at(core::mem::size_of::()); self.intern_pool.get_unsigned_integer( u32::from_le_bytes(buf.try_into().unwrap()) as u64, ) } 0..4 => { - let (buf, _) = - buf.split_at(core::mem::size_of::()); - self.intern_pool.get_unsigned_integer( - u64::from_le_bytes(buf.try_into().unwrap()), - ) + let (buf, _) = buf.split_at(core::mem::size_of::()); + self.intern_pool + .get_unsigned_integer(u64::from_le_bytes(buf.try_into().unwrap())) } 0.. => self.intern_pool.insert_bytes(&bytes), }; @@ -1055,22 +955,15 @@ impl Tree { | Token::DotFloatingConstant | Token::DotFloatingExpConstant => { _ = tokens.next(); - let (bits, ty) = Self::parse_floating_constant( - token.token(), - token.lexeme(), - ); + let (bits, ty) = Self::parse_floating_constant(token.token(), token.lexeme()); let bytes = match ty { - FloatingType::Binary32 => { - self.intern_pool.get_or_insert(intern::Key::F32 { - bits: f32::from_bits(bits as u32), - }) - } - FloatingType::Binary64 => { - self.intern_pool.get_or_insert(intern::Key::F64 { - bits: f64::from_bits(bits), - }) - } + FloatingType::Binary32 => self.intern_pool.get_or_insert(intern::Key::F32 { + bits: f32::from_bits(bits as u32), + }), + FloatingType::Binary64 => self.intern_pool.get_or_insert(intern::Key::F64 { + bits: f64::from_bits(bits), + }), }; Ok(self.nodes.push_tag(Tag::Constant { @@ -1096,10 +989,7 @@ impl Tree { /// BLOCK /// EXPR /// EXPR ; - pub fn parse_expr_or_stmt_or_block( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_expr_or_stmt_or_block(&mut self, tokens: &mut TokenIterator) -> Result { let peek = tokens.peek_token_or_err()?; let body = match peek.token() { // block @@ -1130,10 +1020,7 @@ impl Tree { /// ELSE_EXPR <- /// 'else' (IF_EXPR | EXPR_OR_STATEMENT_OR_BLOCK) - pub fn try_parse_else_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> Result> { + pub fn try_parse_else_expr(&mut self, tokens: &mut TokenIterator) -> Result> { if tokens.eat_token(Token::Else).is_none() { return Ok(None); } @@ -1148,10 +1035,7 @@ impl Tree { /// IF_EXPR <- /// 'if' ( EXPR ) EXPR_OR_STATEMENT_OR_BLOCK ELSE_EXPR? - pub fn try_parse_if_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> Result> { + pub fn try_parse_if_expr(&mut self, tokens: &mut TokenIterator) -> Result> { if tokens.eat_token(Token::If).is_none() { return Ok(None); } @@ -1175,10 +1059,7 @@ impl Tree { /// IF_EXPR <- /// 'if' ( EXPR ) EXPR_OR_STATEMENT_OR_BLOCK ELSE_EXPR? - pub fn parse_if_expr( - &mut self, - tokens: &mut TokenIterator, - ) -> Result { + pub fn parse_if_expr(&mut self, tokens: &mut TokenIterator) -> Result { self.try_parse_if_expr(tokens)? .ok_or(Error::ExpectedTokenNotFound(Token::If)) } @@ -1228,9 +1109,7 @@ impl Tree { fn get_typename_str(&self, node: Node) -> Option { match self.nodes.get_node(node) { Tag::IntegralType(i) => Some(i.to_string()), - Tag::Ident { name } => { - Some(self.intern_pool.get_str(*name).to_owned()) - } + Tag::Ident { name } => Some(self.intern_pool.get_str(*name).to_owned()), Tag::Pointer { pointee } => self.get_typename_str(*pointee), Tag::PrimitiveType(prim) => Some(prim.to_string()), _ => None, @@ -1272,9 +1151,7 @@ impl Tree { } children } - Tag::ReturnStmt { expr } => { - expr.into_iter().cloned().collect::>() - } + Tag::ReturnStmt { expr } => expr.into_iter().cloned().collect::>(), &Tag::ExprStmt { expr } => { vec![expr] } @@ -1321,10 +1198,7 @@ impl Tree { &Tag::ExplicitCast { lhs, typename } => { vec![lhs, typename] } - Tag::Deref { lhs } - | Tag::Ref { lhs } - | Tag::Not { lhs } - | Tag::Negate { lhs } => { + Tag::Deref { lhs } | Tag::Ref { lhs } | Tag::Not { lhs } | Tag::Negate { lhs } => { vec![*lhs] } Tag::Or { lhs, rhs } @@ -1371,17 +1245,8 @@ impl Tree { if let Some(parameters) = parameters { self.render_node(writer, parameters, indent)?; } - write_indented!( - indent, - writer, - "%{} = function_proto: {{", - node.get() - )?; - write!( - writer, - "name: \"{}\"", - self.get_ident_str(name).unwrap() - )?; + write_indented!(indent, writer, "%{} = function_proto: {{", node.get())?; + write!(writer, "name: \"{}\"", self.get_ident_str(name).unwrap())?; if let Some(parameters) = parameters { write!(writer, ", parameters: %{}", parameters.get())?; } @@ -1389,12 +1254,7 @@ impl Tree { writeln!(writer, "}}") } Tag::ParameterList { parameters } => { - writeln_indented!( - indent, - writer, - "%{} = ParameterList [", - node.get() - )?; + writeln_indented!(indent, writer, "%{} = ParameterList [", node.get())?; for param in parameters { self.render_node(writer, param, indent + 1)?; } @@ -1410,9 +1270,7 @@ impl Tree { self.get_typename_str(ty).unwrap() ) } - Tag::Pointer { .. } - | Tag::IntegralType(_) - | Tag::PrimitiveType(_) => { + Tag::Pointer { .. } | Tag::IntegralType(_) | Tag::PrimitiveType(_) => { writeln_indented!( indent, writer, @@ -1469,20 +1327,9 @@ impl Tree { Tag::ReturnStmt { expr } => { if let Some(expr) = expr { self.render_node(writer, expr, indent)?; - writeln_indented!( - indent, - writer, - "%{} = return %{};", - node.get(), - expr.get() - ) + writeln_indented!(indent, writer, "%{} = return %{};", node.get(), expr.get()) } else { - writeln_indented!( - indent, - writer, - "%{} = return;", - node.get() - ) + writeln_indented!(indent, writer, "%{} = return;", node.get()) } } Tag::ExprStmt { expr } => self.render_node(writer, expr, indent), @@ -1493,8 +1340,7 @@ impl Tree { assignment, } => { self.render_node(writer, name, indent)?; - explicit_type - .map(|node| self.render_node(writer, node, indent)); + explicit_type.map(|node| self.render_node(writer, node, indent)); assignment.map(|node| self.render_node(writer, node, indent)); write_indented!( @@ -1513,11 +1359,7 @@ impl Tree { self.get_ident_str(name).unwrap() )?; if let Some(ty) = explicit_type { - write!( - writer, - ", ty: {}", - self.get_typename_str(ty).unwrap() - )?; + write!(writer, ", ty: {}", self.get_typename_str(ty).unwrap())?; } if let Some(assignment) = assignment { write!(writer, ", value: %{assignment}")?; @@ -1541,11 +1383,7 @@ impl Tree { self.get_ident_str(name).unwrap() )?; if let Some(ty) = explicit_type { - write!( - writer, - ", ty: {}", - self.get_typename_str(ty).unwrap() - )?; + write!(writer, ", ty: {}", self.get_typename_str(ty).unwrap())?; } write!(writer, ", value: %{assignment}")?; writeln!(writer, ");")?; @@ -1555,26 +1393,13 @@ impl Tree { self.render_node(writer, lhs, indent)?; if let Some(rhs) = rhs { self.render_node(writer, rhs, indent)?; - writeln_indented!( - indent, - writer, - "%{node} = call (%{lhs})(%{rhs})" - ) + writeln_indented!(indent, writer, "%{node} = call (%{lhs})(%{rhs})") } else { - writeln_indented!( - indent, - writer, - "%{node} = call (%{lhs})()" - ) + writeln_indented!(indent, writer, "%{node} = call (%{lhs})()") } } Tag::ArgumentList { arguments } => { - writeln_indented!( - indent, - writer, - "%{} = ArgumentList [", - node.get() - )?; + writeln_indented!(indent, writer, "%{} = ArgumentList [", node.get())?; for args in arguments { self.render_node(writer, args, indent + 1)?; } @@ -1590,12 +1415,7 @@ impl Tree { self.get_ident_str(name).unwrap(), ) } else { - writeln_indented!( - indent, - writer, - "%{} = %{expr},", - node.get(), - ) + writeln_indented!(indent, writer, "%{} = %{expr},", node.get(),) } } @@ -1612,13 +1432,7 @@ impl Tree { } Tag::Deref { lhs } => { self.render_node(writer, lhs, indent)?; - writeln_indented!( - indent, - writer, - "%{} = deref(%{})", - node.get(), - lhs.get() - ) + writeln_indented!(indent, writer, "%{} = deref(%{})", node.get(), lhs.get()) } Tag::Ref { lhs } => { self.render_node(writer, lhs, indent)?; @@ -1636,13 +1450,7 @@ impl Tree { } Tag::Negate { lhs } => { self.render_node(writer, lhs, indent)?; - writeln_indented!( - indent, - writer, - "%{} = not(%{})", - node.get(), - lhs.get() - ) + writeln_indented!(indent, writer, "%{} = not(%{})", node.get(), lhs.get()) } Tag::Or { lhs, rhs } => { self.render_node(writer, lhs, indent)?; @@ -1950,10 +1758,7 @@ impl Tree { } } - pub fn render( - &mut self, - writer: &mut W, - ) -> core::fmt::Result { + pub fn render(&mut self, writer: &mut W) -> core::fmt::Result { for decl in &self.global_decls.clone() { self.render_node(writer, *decl, 0)?; } @@ -1961,16 +1766,6 @@ impl Tree { Ok(()) } - fn render2(&mut self, w: &mut W) { - for decl in self.global_decls.clone().iter() { - ast::tree_visitor::Visitor::new( - *decl, - |_: &mut Tree, _: Node| {}, - |_: &mut Tree, _: Node| {}, - ); - } - } - pub fn peer_type_of_nodes_unwrap(&self, lhs: Node, rhs: Node) -> Type { self.peer_type_of_nodes(lhs, rhs).expect({ let at = self.type_of_node(lhs); @@ -2031,9 +1826,7 @@ impl Tree { pointee: Box::new(self.type_of_node(*pointee)), }, Tag::Constant { ty, .. } => ty.clone(), - Tag::IntegralType(t) => { - self.intern_pool.as_ast1_type(AMD64_POINTER_BITS, *t) - } + Tag::IntegralType(t) => self.intern_pool.as_ast1_type(AMD64_POINTER_BITS, *t), Tag::PrimitiveType(t) => match *t { intern::Index::F32 => Type::Floating(FloatingType::Binary32), intern::Index::F64 => Type::Floating(FloatingType::Binary64), @@ -2054,9 +1847,7 @@ impl Tree { (Some(a), b) => self.peer_type_of_nodes(*a, *b).expect({ let at = self.type_of_node(*a); let bt = self.type_of_node(*b); - &format!( - "incompatible types for %{a}({at}) and %{b}({bt})" - ) + &format!("incompatible types for %{a}({at}) and %{b}({bt})") }), }; @@ -2081,9 +1872,7 @@ impl Tree { ty } - Tag::CallExpr { lhs, .. } => { - self.type_of_node(*lhs).return_type().unwrap().clone() - } + Tag::CallExpr { lhs, .. } => self.type_of_node(*lhs).return_type().unwrap().clone(), Tag::ExplicitCast { typename, .. } => self.type_of_node(*typename), Tag::Deref { lhs } => self.type_of_node(*lhs).remove_ptr().unwrap(), Tag::Ref { lhs } => self.type_of_node(*lhs).into_ptr(), @@ -2099,15 +1888,11 @@ impl Tree { | Tag::And { lhs, rhs } | Tag::BitOr { lhs, rhs } | Tag::BitAnd { lhs, rhs } - | Tag::BitXOr { lhs, rhs } => { - self.peer_type_of_nodes(*lhs, *rhs).expect({ - let at = self.type_of_node(*lhs); - let bt = self.type_of_node(*rhs); - &format!( - "incompatible types for %{lhs}({at}) and %{rhs}({bt})" - ) - }) - } + | Tag::BitXOr { lhs, rhs } => self.peer_type_of_nodes(*lhs, *rhs).expect({ + let at = self.type_of_node(*lhs); + let bt = self.type_of_node(*rhs); + &format!("incompatible types for %{lhs}({at}) and %{rhs}({bt})") + }), Tag::Shl { lhs, .. } => self.type_of_node(*lhs), Tag::Shr { lhs, .. } => self.type_of_node(*lhs), Tag::Eq { .. } => Type::bool(), @@ -2181,9 +1966,7 @@ impl Tree { is_comptime } - Tag::Not { lhs } | Tag::Negate { lhs } => { - self.is_node_comptime(*lhs, true) - } + Tag::Not { lhs } | Tag::Negate { lhs } => self.is_node_comptime(*lhs, true), Tag::Or { lhs, rhs } | Tag::And { lhs, rhs } | Tag::BitOr { lhs, rhs } @@ -2202,8 +1985,7 @@ impl Tree { | Tag::Mul { lhs, rhs } | Tag::Rem { lhs, rhs } | Tag::Div { lhs, rhs } => { - self.is_node_comptime(*lhs, true) - && self.is_node_comptime(*rhs, true) + self.is_node_comptime(*lhs, true) && self.is_node_comptime(*rhs, true) } _ => false, } @@ -2212,15 +1994,13 @@ impl Tree { pub fn value_of_comptime_node(&self, node: Node) -> Option { match self.nodes.get_node(node) { Tag::Constant { bytes, ty } => { - let ty = - self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty); - let number = - crate::ast2::interned_type_and_value_to_comptime_number( - &self.intern_pool, - AMD64_POINTER_BITS, - ty, - *bytes, - ); + let ty = self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty); + let number = crate::ast2::interned_type_and_value_to_comptime_number( + &self.intern_pool, + AMD64_POINTER_BITS, + ty, + *bytes, + ); Some(number) } @@ -2258,17 +2038,14 @@ impl Tree { |_: &mut Tree, _| {}, |tree: &mut Tree, node| { if let Ok(value) = tree.fold_comptime_inner(node, false) { - let (value, ty) = - crate::ast2::comptime_number_to_interned_type_and_value( - &mut tree.intern_pool, - AMD64_POINTER_BITS, - value, - ); - let ty = - tree.intern_pool.as_ast1_type(AMD64_POINTER_BITS, ty); + let (value, ty) = crate::ast2::comptime_number_to_interned_type_and_value( + &mut tree.intern_pool, + AMD64_POINTER_BITS, + value, + ); + let ty = tree.intern_pool.as_ast1_type(AMD64_POINTER_BITS, ty); - *tree.nodes.get_node_mut(node) = - Tag::Constant { bytes: value, ty }; + *tree.nodes.get_node_mut(node) = Tag::Constant { bytes: value, ty }; } }, ) @@ -2283,15 +2060,13 @@ impl Tree { if self.is_node_comptime(decl, check_declrefs) { match self.nodes.get_node(decl) { Tag::Constant { bytes, ty } => { - let ty = - self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty); - let number = - crate::ast2::interned_type_and_value_to_comptime_number( - &self.intern_pool, - AMD64_POINTER_BITS, - ty, - *bytes, - ); + let ty = self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, ty); + let number = crate::ast2::interned_type_and_value_to_comptime_number( + &self.intern_pool, + AMD64_POINTER_BITS, + ty, + *bytes, + ); return Ok(number); } @@ -2523,8 +2298,7 @@ impl Tree { match self.nodes[node].clone() { Tag::FunctionProto { .. } => {} Tag::FunctionDecl { proto, body } => { - let Tag::FunctionProto { return_type, .. } = self.nodes[proto] - else { + let Tag::FunctionProto { return_type, .. } = self.nodes[proto] else { unreachable!() }; @@ -2533,25 +2307,19 @@ impl Tree { if let Some(peer_t) = body_t.equal_type(&ret_t) { if body_t == Type::comptime_number() { - let Tag::Block { trailing_expr, .. } = self.nodes[body] - else { + let Tag::Block { trailing_expr, .. } = self.nodes[body] else { unreachable!() }; if let Some(expr) = trailing_expr { let ty = self.nodes.push_tag(Tag::PrimitiveType( - self.intern_pool.from_ast1_type( - AMD64_POINTER_BITS, - &peer_t, - ), + self.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &peer_t), )); let expr = self.nodes.push_tag(Tag::ExplicitCast { lhs: expr, typename: ty, }); - let Tag::Block { trailing_expr, .. } = - &mut self.nodes[body] - else { + let Tag::Block { trailing_expr, .. } = &mut self.nodes[body] else { unreachable!() }; *trailing_expr = Some(expr) @@ -2576,10 +2344,7 @@ impl Tree { }; if bits < ty.bit_width() as u32 { errors.push(AnalysisError::new( - AnalysisErrorTag::InsufficientBitsInTypeForConstant( - bits, - ty.clone(), - ), + AnalysisErrorTag::InsufficientBitsInTypeForConstant(bits, ty.clone()), )); } } diff --git a/src/triples.rs b/src/triples.rs index afb6cea..9d90e05 100644 --- a/src/triples.rs +++ b/src/triples.rs @@ -6,12 +6,9 @@ use std::{ }; use crate::{ - ast::{IntegralType, Node as AstNode, Tag, Type}, - ast2::intern::{ - self, InternPool, AMD64_POINTER_BITS, AMD64_POINTER_TYPE_INFO, - }, + ast::{Node as AstNode, Tag, Type}, + ast2::intern::{self, InternPool, AMD64_POINTER_BITS, AMD64_POINTER_TYPE_INFO}, parser::Tree, - string_table::{ImmOrIndex, Index as StringsIndex, StringTable}, variant, write_indented, writeln_indented, }; @@ -48,9 +45,7 @@ fn mir_unalignment(signed: bool, bits: u32) -> Option<(bool, u16)> { impl Type2 { fn mir_type(self) -> mir::Type { match self { - Type2::Integral(_, bits) => { - mir::Type::from_bitsize_int(bits as u32) - } + Type2::Integral(_, bits) => mir::Type::from_bitsize_int(bits as u32), Type2::Binary32 => mir::Type::SinglePrecision, Type2::Binary64 => mir::Type::DoublePrecision, Type2::Bool => mir::Type::from_bitsize_int(1), @@ -135,9 +130,7 @@ impl From<&Type> for Type2 { Type::Pointer { .. } => Type2::Pointer, Type::Fn { .. } => Type2::Pointer, _ => { - unimplemented!( - "conversion from {value:?} to triples type not implemented" - ) + unimplemented!("conversion from {value:?} to triples type not implemented") } } } @@ -284,15 +277,15 @@ impl From for Data { } } -impl From for Data { - fn from(value: crate::string_table::ImmOrIndex) -> Self { - match value { - ImmOrIndex::U64(v) => v.into(), - ImmOrIndex::U32(v) => v.into(), - ImmOrIndex::Index(v) => v.into(), - } - } -} +// impl From for Data { +// fn from(value: crate::string_table::ImmOrIndex) -> Self { +// match value { +// ImmOrIndex::U64(v) => v.into(), +// ImmOrIndex::U32(v) => v.into(), +// ImmOrIndex::Index(v) => v.into(), +// } +// } +// } impl From for Data { fn from(value: intern::Index) -> Self { @@ -397,33 +390,24 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { ); self.ir.push(Inst::FunctionStart, { - variant!( - Tag::Ident { name } = self.tree.nodes.get_node(*name) - ); + variant!(Tag::Ident { name } = self.tree.nodes.get_node(*name)); Some((*name).into()) }); if let Some(parameters) = parameters { variant!( - Tag::ParameterList { parameters } = - self.tree.nodes.get_node(*parameters) + Tag::ParameterList { parameters } = self.tree.nodes.get_node(*parameters) ); for param in parameters { - variant!( - Tag::Parameter { ty, .. } = - self.tree.nodes.get_node(*param) - ); + variant!(Tag::Parameter { ty, .. } = self.tree.nodes.get_node(*param)); let ty = self.tree.type_of_node(*ty); let size = ty.size_of(); let align = ty.align_of(); - let ty = self - .intern_pool() - .from_ast1_type(AMD64_POINTER_BITS, &ty); - let ir = self.ir.push( - Inst::Parameter(ty), - Some(Data::new(size, align)), - ); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ir = self + .ir + .push(Inst::Parameter(ty), Some(Data::new(size, align))); self.lookup.insert(*param, NodeOrList::Node(ir)); } @@ -434,53 +418,43 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { self.tree.st.into_parent(); if value != !0 { let ty = self.tree.type_of_node(*body); - let ty = self - .intern_pool() - .from_ast1_type(AMD64_POINTER_BITS, &ty); - self.ir.push( - Inst::ReturnValue(ty.into()), - Some(Data::lhs(value)), - ); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + self.ir + .push(Inst::ReturnValue(ty.into()), Some(Data::lhs(value))); } self.ir.push(Inst::FunctionEnd, None) } Tag::CallExpr { lhs, rhs } => { - let ty = - self.tree.type_of_node(*lhs).return_type().unwrap().clone(); - let args = if let Some(args) = *rhs { - variant!( - self.tree.nodes.get_node(args) => Tag::ArgumentList { arguments } - ); + let ty = self.tree.type_of_node(*lhs).return_type().unwrap().clone(); + let args = + if let Some(args) = *rhs { + variant!( + self.tree.nodes.get_node(args) => Tag::ArgumentList { arguments } + ); - let args = arguments.clone().iter().map(|arg| { + let args = arguments.clone().iter().map(|arg| { variant!(*self.tree.nodes.get_node(*arg) => Tag::Argument { expr ,..}); (self.visit(expr), self.tree.type_of_node(expr)) }).collect::>(); - let start = self.ir.nodes.len(); - for (arg, ty) in args { - let ty = self - .intern_pool() - .from_ast1_type(AMD64_POINTER_BITS, &ty); - _ = self.ir.push( - Inst::Argument(ty.into()), - Some(Data::lhs(arg)), - ); - } - let end = self.ir.nodes.len(); + let start = self.ir.nodes.len(); + for (arg, ty) in args { + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + _ = self + .ir + .push(Inst::Argument(ty.into()), Some(Data::lhs(arg))); + } + let end = self.ir.nodes.len(); - Some((start as u32, end as u32)) - } else { - None - }; - let (start, end) = args.unwrap_or(( - self.ir.nodes.len() as u32, - self.ir.nodes.len() as u32, - )); + Some((start as u32, end as u32)) + } else { + None + }; + let (start, end) = + args.unwrap_or((self.ir.nodes.len() as u32, self.ir.nodes.len() as u32)); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir.push(Inst::InlineType(ty.into()), None); let func = self.visit(*lhs); @@ -504,20 +478,17 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { } Tag::VarDecl { assignment, .. } => { let ty = self.tree.type_of_node(node); - let alloca = self.ir.push( - Inst::Alloca, - Some(Data::new(ty.size_of(), ty.align_of())), - ); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let alloca = self + .ir + .push(Inst::Alloca, Some(Data::new(ty.size_of(), ty.align_of()))); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); if let Some(assignment) = assignment { let value = self.visit(*assignment); // discard store - let _ = self.ir.push( - Inst::Store(ty.into()), - Some(Data::new(value, alloca)), - ); + let _ = self + .ir + .push(Inst::Store(ty.into()), Some(Data::new(value, alloca))); } self.lookup.insert(node, NodeOrList::Node(alloca)); alloca @@ -531,8 +502,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { variant!(self.tree.nodes.get_node(*name) => Tag::Ident { name }); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); let global = self.ir.push( Inst::GlobalConstant(*name, ty.into()), Some(Data::lhs(value)), @@ -544,12 +514,10 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { } Tag::GlobalRef(decl) => { let ty = self.tree.type_of_node(*decl); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); - let node = self.ir.push( - Inst::ExternRef(ty.into()), - Some(Data::lhs(decl.get())), - ); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let node = self + .ir + .push(Inst::ExternRef(ty.into()), Some(Data::lhs(decl.get()))); self.fixup.push(node); node } @@ -566,41 +534,33 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { let dest = self.visit(*lhs); let source = self.visit(*rhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::Store(ty.into()), Some(Data::new(source, dest))) } Tag::ReturnStmt { expr } => { if let Some(expr) = expr { let ty = self.tree.type_of_node(*expr); - let ty = self - .intern_pool() - .from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); let expr = self.visit(*expr); - self.ir.push( - Inst::ReturnValue(ty.into()), - Some(Data::lhs(expr)), - ) + self.ir + .push(Inst::ReturnValue(ty.into()), Some(Data::lhs(expr))) } else { self.ir.push(Inst::Return, None) } } Tag::ExprStmt { expr } => self.visit(*expr), Tag::Deref { lhs } => { - let ty = - self.tree.type_of_node(*lhs).pointee().unwrap().clone(); + let ty = self.tree.type_of_node(*lhs).pointee().unwrap().clone(); let lhs = self.visit(*lhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs))) } Tag::Add { lhs, rhs } => { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::Add(ty.into()), Some(Data::new(lhs, rhs))) } @@ -608,8 +568,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::Sub(ty.into()), Some(Data::new(lhs, rhs))) } @@ -617,8 +576,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::BitAnd(ty.into()), Some(Data::new(lhs, rhs))) } @@ -626,8 +584,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::BitOr(ty.into()), Some(Data::new(lhs, rhs))) } @@ -635,8 +592,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::BitXOr(ty.into()), Some(Data::new(lhs, rhs))) } @@ -656,8 +612,7 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { }) .into(); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); let inst = match tag { Tag::Eq { .. } => Inst::Eq(ty), Tag::NEq { .. } => Inst::Neq(ty), @@ -676,31 +631,27 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::Mul(ty.into()), Some(Data::new(lhs, rhs))) } Tag::Negate { lhs } => { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir.push(Inst::Negate(ty.into()), Some(Data::lhs(lhs))) } Tag::Not { lhs } => { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir.push(Inst::Not(ty.into()), Some(Data::lhs(lhs))) } Tag::Shl { lhs, rhs } => { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::ShiftLeft(ty.into()), Some(Data::new(lhs, rhs))) } @@ -708,28 +659,21 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); - self.ir.push( - Inst::ShiftRight(ty.into()), - Some(Data::new(lhs, rhs)), - ) + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + self.ir + .push(Inst::ShiftRight(ty.into()), Some(Data::new(lhs, rhs))) } Tag::Ref { lhs } => { let ty = self.tree.type_of_node(*lhs); let lhs = self.visit(*lhs); // self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs))) // nothing happens here because lhs is of type pointer - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); - self.ir.push( - Inst::GetElementPtr(ty.into()), - Some(Data::new(lhs, 0)), - ) + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + self.ir + .push(Inst::GetElementPtr(ty.into()), Some(Data::new(lhs, 0))) } Tag::Constant { bytes, ty } => { - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, ty); self.ir.push(Inst::Constant, Some((ty, *bytes).into())) } Tag::ExplicitCast { lhs, typename } => { @@ -742,12 +686,8 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { //noop? lhs } else { - let l_ty = self - .intern_pool() - .from_ast1_type(AMD64_POINTER_BITS, &l_ty); - let r_ty = self - .intern_pool() - .from_ast1_type(AMD64_POINTER_BITS, &r_ty); + let l_ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &l_ty); + let r_ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &r_ty); self.ir.push( Inst::ExplicitCast(l_ty.into(), r_ty.into()), Some(Data::lhs(lhs)), @@ -760,16 +700,14 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { let condition = self.visit(*condition); let br = self.ir.push(Inst::Branch(condition), None); - let label_lhs = self.ir.push( - Inst::Label, - Some(intern::Index::EMPTY_STRING.into()), - ); + let label_lhs = self + .ir + .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into())); let _ = self.visit(*body); let jmp = self.ir.push(Inst::Jump, None); - let nojump = self.ir.push( - Inst::Label, - Some(intern::Index::EMPTY_STRING.into()), - ); + let nojump = self + .ir + .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into())); self.ir.data[br as usize] = Some(Data::new(label_lhs, nojump)); self.ir.data[jmp as usize] = Some(Data::lhs(nojump)); @@ -782,37 +720,32 @@ impl<'tree, 'ir> IRBuilder<'tree, 'ir> { } => { assert_eq!(self.tree.type_of_node(*condition), Type::Bool); let ty = self.tree.peer_type_of_nodes_unwrap(*body, *else_expr); - let ty = - self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); + let ty = self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); let condition = self.visit(*condition); let br = self.ir.push(Inst::Branch(condition), None); - let label_lhs = self.ir.push( - Inst::Label, - Some(intern::Index::EMPTY_STRING.into()), - ); + let label_lhs = self + .ir + .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into())); let lhs = self.visit(*body); let ljmp = self.ir.push(Inst::Jump, None); - let label_rhs = self.ir.push( - Inst::Label, - Some(intern::Index::EMPTY_STRING.into()), - ); + let label_rhs = self + .ir + .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into())); let rhs = self.visit(*else_expr); let rjmp = self.ir.push(Inst::Jump, None); - let nojump = self.ir.push( - Inst::Label, - Some(intern::Index::EMPTY_STRING.into()), - ); + let nojump = self + .ir + .push(Inst::Label, Some(intern::Index::EMPTY_STRING.into())); let phi = if ty != intern::Index::VOID { self.ir.push(Inst::Phi2(ty), Some(Data::new(lhs, rhs))) } else { br }; - self.ir.data[br as usize] = - Some(Data::new(label_lhs, label_rhs)); + self.ir.data[br as usize] = Some(Data::new(label_lhs, label_rhs)); self.ir.data[ljmp as usize] = Some(Data::lhs(nojump)); self.ir.data[rjmp as usize] = Some(Data::lhs(nojump)); phi @@ -845,10 +778,7 @@ impl IR { node } - pub fn build<'b, 'tree>( - &'b mut self, - tree: &'tree mut Tree, - ) -> IRBuilder<'tree, 'b> { + pub fn build<'b, 'tree>(&'b mut self, tree: &'tree mut Tree) -> IRBuilder<'tree, 'b> { let global_decls = tree.global_decls.clone(); let mut builder = IRBuilder::new(self, tree); @@ -859,11 +789,7 @@ impl IR { for &fix in builder.fixup.iter() { let ast_node = builder.ir.data[fix as usize].unwrap().lhs; - let idx = match builder - .tree - .nodes - .get_node(AstNode::new(ast_node).unwrap()) - { + let idx = match builder.tree.nodes.get_node(AstNode::new(ast_node).unwrap()) { Tag::FunctionDecl { proto, .. } => { variant!(builder.tree.nodes.get_node(*proto) => Tag::FunctionProto { name,..}); variant!(builder.tree.nodes.get_node(*name) => Tag::Ident { name }); @@ -898,12 +824,7 @@ impl IRBuilder<'_, '_> { match inst { Inst::Label => { let label = self.intern_pool().get_str(data.as_index()); - writeln_indented!( - indent - 1, - w, - "%{} = label \"{label}\":", - node - )?; + writeln_indented!(indent - 1, w, "%{} = label \"{label}\":", node)?; } Inst::FunctionStart => { let label = self.intern_pool().get_str(data.as_index()); @@ -955,129 +876,48 @@ impl IRBuilder<'_, '_> { } Inst::Add(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = add_{ty}(%{} + %{})", - node, - lhs, - rhs - )?; + writeln_indented!(indent, w, "%{} = add_{ty}(%{} + %{})", node, lhs, rhs)?; } Inst::Sub(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = sub_{ty}(%{} - %{})", - node, - lhs, - rhs - )?; + writeln_indented!(indent, w, "%{} = sub_{ty}(%{} - %{})", node, lhs, rhs)?; } Inst::Eq(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = eq_{ty}(%{} == %{})", - node, - lhs, - rhs - )?; + writeln_indented!(indent, w, "%{} = eq_{ty}(%{} == %{})", node, lhs, rhs)?; } Inst::Neq(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = neq_{ty}(%{} != %{})", - node, - lhs, - rhs - )?; + writeln_indented!(indent, w, "%{} = neq_{ty}(%{} != %{})", node, lhs, rhs)?; } Inst::Gt(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = gt_{ty}(%{} > %{})", - node, - lhs, - rhs - )?; + writeln_indented!(indent, w, "%{} = gt_{ty}(%{} > %{})", node, lhs, rhs)?; } Inst::Lt(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = lt_{ty}(%{} < %{})", - node, - lhs, - rhs - )?; + writeln_indented!(indent, w, "%{} = lt_{ty}(%{} < %{})", node, lhs, rhs)?; } Inst::Ge(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = ge_{ty}(%{} >= %{})", - node, - lhs, - rhs - )?; + writeln_indented!(indent, w, "%{} = ge_{ty}(%{} >= %{})", node, lhs, rhs)?; } Inst::Le(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = le_{ty}(%{} <= %{})", - node, - lhs, - rhs - )?; + writeln_indented!(indent, w, "%{} = le_{ty}(%{} <= %{})", node, lhs, rhs)?; } Inst::Mul(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = mul_{ty}(%{} * %{})", - node, - lhs, - rhs - )?; + writeln_indented!(indent, w, "%{} = mul_{ty}(%{} * %{})", node, lhs, rhs)?; } Inst::Negate(ty) => { - writeln_indented!( - indent, - w, - "%{} = negate_{ty}(%{})", - node, - data.lhs - )?; + writeln_indented!(indent, w, "%{} = negate_{ty}(%{})", node, data.lhs)?; } Inst::Not(ty) => { - writeln_indented!( - indent, - w, - "%{} = bitwise_not_{ty}(%{})", - node, - data.lhs - )?; + writeln_indented!(indent, w, "%{} = bitwise_not_{ty}(%{})", node, data.lhs)?; } Inst::ExplicitCast(from, to) => { - writeln_indented!( - indent, - w, - "%{} = cast_{from}_to_{to}(%{})", - node, - data.lhs - )?; + writeln_indented!(indent, w, "%{} = cast_{from}_to_{to}(%{})", node, data.lhs)?; } Inst::ShiftLeft(ty) => { writeln_indented!( @@ -1100,25 +940,14 @@ impl IRBuilder<'_, '_> { )?; } Inst::ReturnValue(ty) => { - writeln_indented!( - indent, - w, - "%{} = return {ty} %{}", - node, - data.lhs - )?; + writeln_indented!(indent, w, "%{} = return {ty} %{}", node, data.lhs)?; } Inst::Return => { writeln_indented!(indent, w, "%{} = return", node)?; } Inst::Alloca => { let (size, align) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = alloca {size} (align: {align})", - node - )?; + writeln_indented!(indent, w, "%{} = alloca {size} (align: {align})", node)?; } Inst::GetElementPtr(ty) => { let (ptr, idx) = data.as_lhs_rhs(); @@ -1132,21 +961,11 @@ impl IRBuilder<'_, '_> { } Inst::Load(ty) => { let source = data.lhs; - writeln_indented!( - indent, - w, - "%{} = load {ty}, %{source}", - node - )?; + writeln_indented!(indent, w, "%{} = load {ty}, %{source}", node)?; } Inst::Store(ty) => { let (src, dst) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{} = store {ty}, ptr %{dst}, %{src}", - node - )?; + writeln_indented!(indent, w, "%{} = store {ty}, ptr %{dst}, %{src}", node)?; } Inst::ExternRef(ty) => { let idx = data.as_index(); @@ -1172,20 +991,12 @@ impl IRBuilder<'_, '_> { } Inst::Phi2(ty) => { let (lhs, rhs) = data.as_lhs_rhs(); - writeln_indented!( - indent, - w, - "%{node} = phi [{ty} %{lhs}, {ty} %{rhs}]" - )?; + writeln_indented!(indent, w, "%{node} = phi [{ty} %{lhs}, {ty} %{rhs}]")?; } Inst::GlobalConstant(name, ty) => { let label = self.intern_pool().get_str(name); let value = data.lhs; - writeln_indented!( - indent, - w, - "%{node} = global const '{label}' {ty} %{value}" - )?; + writeln_indented!(indent, w, "%{node} = global const '{label}' {ty} %{value}")?; } _ => { unimplemented!("{inst:?} rendering unimplemented") @@ -1259,9 +1070,7 @@ impl<'a> IrToMirMapping<'a> { match self.ir.nodes[ir as usize] { Inst::GlobalConstant(name, ty) => { - eprintln!( - "does this even get hit anymore???????????????????//" - ); + eprintln!("does this even get hit anymore???????????????????//"); let ty = self.ip.to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let ext = mir::NodeRef(mir.gen_extern(Some(ty), name)); self.insert(ir, ext); @@ -1311,8 +1120,7 @@ impl<'a> MirBuilder<'a> { } } } - let mut unresolved_jumps_branches = - BTreeSet::<(Node, LeftRight)>::new(); + let mut unresolved_jumps_branches = BTreeSet::<(Node, LeftRight)>::new(); loop { let ir_node = self.ir.node(); @@ -1332,18 +1140,14 @@ impl<'a> MirBuilder<'a> { let range = unresolved_jumps_branches .range( (ir_node, LeftRight::Left(mir::NodeRef::MIN)) - ..=( - ir_node, - LeftRight::Right(mir::NodeRef::MAX), - ), + ..=(ir_node, LeftRight::Right(mir::NodeRef::MAX)), ) .map(|(_, n)| n) .cloned() .collect::>(); for unresolved in range { - unresolved_jumps_branches - .remove(&(ir_node, unresolved)); + unresolved_jumps_branches.remove(&(ir_node, unresolved)); let mir_node = unresolved.noderef(); let (inst, data) = mir.get_node_mut(mir_node); @@ -1356,12 +1160,8 @@ impl<'a> MirBuilder<'a> { let (lhs, rhs) = data.as_binary_noderefs(); *data = match unresolved { - LeftRight::Left(_) => { - mir::Data::binary(label, rhs.0) - } - LeftRight::Right(_) => { - mir::Data::binary(lhs.0, label) - } + LeftRight::Left(_) => mir::Data::binary(label, rhs.0), + LeftRight::Right(_) => mir::Data::binary(lhs.0, label), }; } _ => { @@ -1374,9 +1174,7 @@ impl<'a> MirBuilder<'a> { } Inst::Constant => { let (ty, val) = data.unwrap().as_index_index(); - let mir_ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let mir_ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.push_const(self.intern_pool(), val, mir_ty) } Inst::Alloca => { @@ -1384,37 +1182,26 @@ impl<'a> MirBuilder<'a> { mir.gen_alloca(l, r) } Inst::Load(ty) => { - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let src = mapping - .get(&mut mir, data.unwrap().as_u32()) - .unwrap() - .0; + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let src = mapping.get(&mut mir, data.unwrap().as_u32()).unwrap().0; mir.gen_load(ty, src) } Inst::Store(ty) => { - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let (src, dst) = data.unwrap().as_lhs_rhs(); let src = mapping.get(&mut mir, src).unwrap().0; let dst = mapping.get(&mut mir, dst).unwrap().0; mir.gen_store(ty, src, dst) } Inst::GetElementPtr(ty) => { - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let (ptr, idx) = data.unwrap().as_lhs_rhs(); let src = mapping.get(&mut mir, ptr).unwrap().0; mir.gen_get_element_ptr(ty, src, idx) } Inst::Parameter(ty) => { // let (size, _) = data.unwrap().as_lhs_rhs(); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_param(ty.into()) } Inst::Eq(ty) @@ -1441,9 +1228,7 @@ impl<'a> MirBuilder<'a> { let signed = self .intern_pool() .is_type_signed(ty, AMD64_POINTER_TYPE_INFO); - let mir_ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let mir_ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_cmp_byte(mir_ty, signed, ord, invert, lhs, rhs) } Inst::Add(ty) => { @@ -1451,26 +1236,17 @@ impl<'a> MirBuilder<'a> { let lhs = mapping.get(&mut mir, src).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0; - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); match info.bitsize { 8 | 16 | 32 | 64 => mir.gen_add(ty, lhs, rhs), 64.. => { unimplemented!() } - bits => { + _ => { let sum = mir.gen_add(ty, lhs, rhs); - mir.gen_truncate_integer( - sum, - ty, - info.signed, - info.bitsize as u16, - ) + mir.gen_truncate_integer(sum, ty, info.signed, info.bitsize as u16) } } } @@ -1479,14 +1255,9 @@ impl<'a> MirBuilder<'a> { let lhs = mapping.get(&mut mir, src).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0; - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); let sum = mir.gen_sub(ty, lhs, rhs); if let Some((signed, bits)) = unalignment { @@ -1498,14 +1269,9 @@ impl<'a> MirBuilder<'a> { Inst::Mul(ty) => { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); let lhs = mapping.get(&mut mir, lhs).unwrap().0; let rhs = mapping.get(&mut mir, rhs).unwrap().0; @@ -1520,14 +1286,9 @@ impl<'a> MirBuilder<'a> { Inst::Div(ty) => { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); let lhs = mapping.get(&mut mir, lhs).unwrap().0; let rhs = mapping.get(&mut mir, rhs).unwrap().0; @@ -1542,14 +1303,9 @@ impl<'a> MirBuilder<'a> { Inst::Rem(ty) => { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); let lhs = mapping.get(&mut mir, lhs).unwrap().0; let rhs = mapping.get(&mut mir, rhs).unwrap().0; @@ -1564,21 +1320,15 @@ impl<'a> MirBuilder<'a> { Inst::BitAnd(ty) => { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); - let (lhs, rhs) = - if self.ir.ir.nodes[lhs as usize].is_constant() { - (rhs, lhs) - } else { - (lhs, rhs) - }; + let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() { + (rhs, lhs) + } else { + (lhs, rhs) + }; let lhs = mapping.get(&mut mir, lhs).unwrap().0; let rhs = mapping.get(&mut mir, rhs).unwrap().0; @@ -1593,21 +1343,15 @@ impl<'a> MirBuilder<'a> { Inst::BitOr(ty) => { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); - let (lhs, rhs) = - if self.ir.ir.nodes[lhs as usize].is_constant() { - (rhs, lhs) - } else { - (lhs, rhs) - }; + let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() { + (rhs, lhs) + } else { + (lhs, rhs) + }; let lhs = mapping.get(&mut mir, lhs).unwrap().0; let rhs = mapping.get(&mut mir, rhs).unwrap().0; @@ -1622,24 +1366,18 @@ impl<'a> MirBuilder<'a> { Inst::BitXOr(ty) => { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); - let (lhs, rhs) = - if self.ir.ir.nodes[lhs as usize].is_constant() { - (rhs, lhs) - } else { - (lhs, rhs) - }; + let (lhs, rhs) = if self.ir.ir.nodes[lhs as usize].is_constant() { + (rhs, lhs) + } else { + (lhs, rhs) + }; let lhs = mapping.get(&mut mir, lhs).unwrap().0; let rhs = mapping.get(&mut mir, rhs).unwrap().0; - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); let sum = mir.gen_bitxor(ty, lhs, rhs); if let Some((signed, bits)) = unalignment { @@ -1653,18 +1391,12 @@ impl<'a> MirBuilder<'a> { let lhs = mapping.get(&mut mir, src).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0; - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); // TODO: check rhs type and pass it to gen_sh{l,r}? - let rhs = - mir.gen_truncate_integer(rhs, ty.into(), false, 8); + let rhs = mir.gen_truncate_integer(rhs, ty.into(), false, 8); let sum = mir.gen_shl(ty, lhs, rhs); if let Some((signed, bits)) = unalignment { @@ -1678,18 +1410,12 @@ impl<'a> MirBuilder<'a> { let lhs = mapping.get(&mut mir, src).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0; - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); // TODO: check rhs type and pass it to gen_sh{l,r}? - let rhs = - mir.gen_truncate_integer(rhs, ty.into(), false, 8); + let rhs = mir.gen_truncate_integer(rhs, ty.into(), false, 8); let sum = mir.gen_shr(ty, lhs, rhs); if let Some((signed, bits)) = unalignment { @@ -1702,14 +1428,9 @@ impl<'a> MirBuilder<'a> { let lhs = data.unwrap().as_u32(); let lhs = mapping.get(&mut mir, lhs).unwrap().0; - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); let sum = mir.gen_not(ty, lhs); if let Some((signed, bits)) = unalignment { @@ -1722,14 +1443,9 @@ impl<'a> MirBuilder<'a> { let lhs = data.unwrap().as_u32(); let lhs = mapping.get(&mut mir, lhs).unwrap().0; - let info = self - .intern_pool() - .size_of_type(ty, AMD64_POINTER_TYPE_INFO); - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); - let unalignment = - mir_unalignment(info.signed, info.bitsize); + let info = self.intern_pool().size_of_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let unalignment = mir_unalignment(info.signed, info.bitsize); let sum = mir.gen_negate(ty, lhs); if let Some((signed, bits)) = unalignment { @@ -1742,23 +1458,17 @@ impl<'a> MirBuilder<'a> { let lhs = data.unwrap().as_u32(); let lhs = mapping.get(&mut mir, lhs).unwrap().0; - let to_info = self - .intern_pool() - .size_of_type(to, AMD64_POINTER_TYPE_INFO); - let to_ty = self - .intern_pool() - .to_mir_type(to, AMD64_POINTER_TYPE_INFO); - let to_unalignment = - mir_unalignment(to_info.signed, to_info.bitsize); + let to_info = self.intern_pool().size_of_type(to, AMD64_POINTER_TYPE_INFO); + let to_ty = self.intern_pool().to_mir_type(to, AMD64_POINTER_TYPE_INFO); + let _to_unalignment = mir_unalignment(to_info.signed, to_info.bitsize); let from_info = self .intern_pool() .size_of_type(from, AMD64_POINTER_TYPE_INFO); - let from_ty = self + let _from_ty = self .intern_pool() .to_mir_type(from, AMD64_POINTER_TYPE_INFO); - let from_unalignment = - mir_unalignment(from_info.signed, from_info.bitsize); + let _from_unalignment = mir_unalignment(from_info.signed, from_info.bitsize); if from == to { lhs @@ -1776,12 +1486,7 @@ impl<'a> MirBuilder<'a> { let one = mir.gen_u8(0b1); mir.gen_bitand(mir::Type::Byte, lhs, one) } else if from_info.bitsize > to_info.bitsize { - mir.gen_truncate_integer( - lhs, - to_ty, - to_info.signed, - to_info.bitsize as u16, - ) + mir.gen_truncate_integer(lhs, to_ty, to_info.signed, to_info.bitsize as u16) } else if from_info.bitsize < to_info.bitsize { mir.gen_extend_integer(lhs, from_info, to_info) } else { @@ -1793,9 +1498,7 @@ impl<'a> MirBuilder<'a> { let src = data.unwrap().as_u32(); let src = mapping.get(&mut mir, src).unwrap().0; - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_ret_val(ty, src) } @@ -1808,18 +1511,13 @@ impl<'a> MirBuilder<'a> { let label = match mapping.get(&mut mir, label) { Some(label) => label.0, None => { - unresolved_jumps_branches.insert(( - label, - LeftRight::Left(mir::NodeRef(jmp)), - )); + unresolved_jumps_branches + .insert((label, LeftRight::Left(mir::NodeRef(jmp)))); 0 } }; - mir.set_node_data( - mir::NodeRef(jmp), - mir::Data::node(label), - ); + mir.set_node_data(mir::NodeRef(jmp), mir::Data::node(label)); jmp } @@ -1832,28 +1530,21 @@ impl<'a> MirBuilder<'a> { let lhs = match mapping.get(&mut mir, lhs) { Some(n) => n.0, None => { - unresolved_jumps_branches.insert(( - lhs, - LeftRight::Left(mir::NodeRef(br)), - )); + unresolved_jumps_branches + .insert((lhs, LeftRight::Left(mir::NodeRef(br)))); 0 } }; let rhs = match mapping.get(&mut mir, rhs) { Some(n) => n.0, None => { - unresolved_jumps_branches.insert(( - rhs, - LeftRight::Right(mir::NodeRef(br)), - )); + unresolved_jumps_branches + .insert((rhs, LeftRight::Right(mir::NodeRef(br)))); 0 } }; - mir.set_node_data( - mir::NodeRef(br), - mir::Data::binary(lhs, rhs), - ); + mir.set_node_data(mir::NodeRef(br), mir::Data::binary(lhs, rhs)); br } @@ -1864,16 +1555,12 @@ impl<'a> MirBuilder<'a> { let (start, end) = data.unwrap().as_lhs_rhs(); variant!(&ir.nodes[end as usize -1] => Inst::InlineType(ty)); - let ty = self - .intern_pool() - .to_mir_type(*ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(*ty, AMD64_POINTER_TYPE_INFO); let args = (start..(end - 1)) .map(|arg| { variant!(&ir.nodes[arg as usize] => Inst::Argument(ty)); - let ty = self - .intern_pool() - .to_mir_type(*ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(*ty, AMD64_POINTER_TYPE_INFO); let arg = ir.data[arg as usize].unwrap().lhs; let arg = mapping.get(&mut mir, arg).unwrap().0; (ty, arg) @@ -1886,16 +1573,12 @@ impl<'a> MirBuilder<'a> { let (src, dst) = data.unwrap().as_lhs_rhs(); let lhs = mapping.get(&mut mir, src).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0; - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_phi2(ty, lhs, rhs) } Inst::GlobalConstant(name, ty) => { - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let ext = mir.gen_extern(Some(ty), name); ext @@ -1904,16 +1587,12 @@ impl<'a> MirBuilder<'a> { continue; } Inst::ExternRef(ty) => { - let ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let ty = self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_extern(Some(ty), data.unwrap().as_index()) } #[allow(unreachable_patterns)] _ => { - eprintln!( - "ir inst {inst:?} not supported in mir translation" - ); + eprintln!("ir inst {inst:?} not supported in mir translation"); unimplemented!() } }; @@ -1930,9 +1609,7 @@ impl<'a> MirBuilder<'a> { break; }; match inst { - Inst::FunctionStart => { - self.build_function(data.unwrap().as_index()) - } + Inst::FunctionStart => self.build_function(data.unwrap().as_index()), Inst::GlobalConstant(name, ..) => { let mut mir = mir::Mir::new(name); let value = data.unwrap().lhs; @@ -1941,9 +1618,8 @@ impl<'a> MirBuilder<'a> { let _value = match inst { Inst::Constant => { let (ty, val) = data.unwrap().as_index_index(); - let mir_ty = self - .intern_pool() - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + let mir_ty = + self.intern_pool().to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.push_const(self.intern_pool(), val, mir_ty) } _ => { @@ -1982,7 +1658,7 @@ fn u10(x: i10) -> i10 { tree.render(&mut buf).unwrap(); println!("AST:\n{buf}"); - let mut intern = InternPool::new(); + let mut _intern = InternPool::new(); let mut ir = IR::new(); { let builder = ir.build(&mut tree);