diff --git a/src/ast.rs b/src/ast.rs index 1cbbd8e..76b10cd 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1,6 +1,9 @@ use std::num::NonZero; -use crate::string_table::{self, ImmOrIndex}; +use crate::{ + ast2::intern, + string_table::{self, ImmOrIndex}, +}; pub type Node = NonZero; @@ -33,8 +36,8 @@ pub enum Tag { PointerQualifier { constness: bool, }, - IntegralType(IntegralType), - PrimitiveType(PrimitiveType), + IntegralType(intern::Index), + PrimitiveType(intern::Index), FunctionDecl { /// FunctionProto proto: Node, @@ -42,10 +45,11 @@ pub enum Tag { body: Node, }, Ident { - name: string_table::Index, + name: intern::Index, }, + /// bytes might be an integer, float, double, or Bytes Constant { - bytes: ImmOrIndex, + bytes: intern::Index, ty: Type, }, Block { diff --git a/src/ast2/mod.rs b/src/ast2/mod.rs index 9a73f2f..45bd398 100644 --- a/src/ast2/mod.rs +++ b/src/ast2/mod.rs @@ -6,7 +6,7 @@ use std::{ num::NonZero, }; -use intern::{InternPool, PointerFlags, StructFlags}; +use intern::{InternPool, PointerFlags, StructFlags, AMD64_POINTER_TYPE_INFO}; use num_bigint::BigInt; use crate::{ @@ -66,7 +66,7 @@ enum Tag { TypeDeclRef, /// `data` is an inlined key into the symbol table (scope: index, name: intern) TypeDeclRefUnresolved, - /// `data` is an index to a Type and u32 PointerFlags + /// `data` is an index to a Type and u32 PointerFlags (extra offset) PointerType, /// `data` is an index to a length expression, and an underlying pointer type ArrayType, @@ -263,6 +263,7 @@ union Data { two_interns: (intern::Index, intern::Index), intern_and_extra_offset: (intern::Index, u32), index_and_extra_offset: (Index, u32), + index_and_opaque: (Index, u32), } #[derive(Debug)] @@ -279,6 +280,7 @@ enum ExpandedData { TwoInterns(intern::Index, intern::Index), InternAndExtraOffset(intern::Index, usize), IndexAndExtraOffset(Index, usize), + IndexAndOpaque(Index, u32), } impl ExpandedData { @@ -324,6 +326,10 @@ impl ExpandedData { let data = data.as_index_and_extra_offset(); Self::IndexAndExtraOffset(data.0, data.1) } + fn from_index_and_opaque(data: Data) -> Self { + let data = data.as_index_and_opaque(); + Self::IndexAndExtraOffset(data.0, data.1) + } } impl From<(Tag, Data)> for ExpandedData { @@ -428,6 +434,10 @@ impl Data { let (i, e) = unsafe { self.intern_and_extra_offset }; (i, e as usize) } + fn as_index_and_opaque(self) -> (Index, usize) { + let (i, e) = unsafe { self.index_and_opaque }; + (i, e as usize) + } } impl Data { @@ -476,6 +486,11 @@ impl Data { index_and_extra_offset: (index, offset), } } + fn index_and_opaque(index: Index, value: u32) -> Self { + Self { + index_and_opaque: (index, value), + } + } } pub struct Ast { @@ -1822,7 +1837,7 @@ impl Ast { } } -fn comptime_number_to_interned_type_and_value( +pub fn comptime_number_to_interned_type_and_value( ip: &mut InternPool, pointer_bits: u16, comptime: ComptimeNumber, @@ -1898,7 +1913,7 @@ fn comptime_number_to_interned_type_and_value( (value, ty) } -fn interned_type_and_value_to_comptime_number( +pub fn interned_type_and_value_to_comptime_number( ip: &InternPool, pointer_bits: u16, ty: intern::Index, @@ -1908,10 +1923,11 @@ fn interned_type_and_value_to_comptime_number( use crate::comptime::*; 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 } => { - let ty = IntegralType::new(false, bits); + let ty = IntegralType::new(signed, bits); match ip.get_key(val) { intern::Key::SIntSmall { bits } => { ComptimeNumber::Integral(ComptimeInt::Native { @@ -2467,7 +2483,7 @@ pub mod ast_gen { }); let names = self.ast.extra[names] .iter() - .map(|&i| intern::Index(i)); + .map(|&i| intern::Index::from_u32(i)); self.intern.insert_or_replace_struct_type( name, @@ -4248,17 +4264,16 @@ pub mod ast_gen { } pub mod ir_gen { - use intern::InternPool; use super::*; use crate::{symbol_table::syms2::Symbols, triples::*}; - struct IRGen<'a> { + struct IRGen { ast: Ast, syms: Symbols, - intern: InternPool, - ir: IR<'a>, + ir: IR, + ip: intern::InternPool, } - impl IRGen<'_> {} + impl IRGen {} } diff --git a/src/bin/main.rs b/src/bin/main.rs index 15602bf..b745648 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -12,6 +12,7 @@ fn ast_tree(tokens: &Tokenizer) -> Tree { let mut tree = Tree::new(); tree.parse(tokens.iter()).unwrap(); tree.fold_comptime(); + tree.intern_types(); tree } @@ -63,8 +64,7 @@ fn main() { } "ir" => { let mut tree = ast_tree(&tokens); - let mut intern = InternPool::new(); - let mut ir = IR::new(&mut intern); + let mut ir = IR::new(); let builder = ir.build(&mut tree); let mut buf = String::new(); builder.render(&mut buf).unwrap(); @@ -72,15 +72,16 @@ fn main() { } "mir" => { let mut tree = ast_tree(&tokens); - let mut intern = InternPool::new(); - let mut ir = IR::new(&mut intern); + let mut ir = IR::new(); ir.build(&mut tree); - let mut mir = MirBuilder::new(&ir, tree.strings); + let mut mir = MirBuilder::new(&ir, tree.intern_pool); mir.build(); let MirBuilder { - strings, functions, .. + intern_pool: strings, + functions, + .. } = mir; for (name, mir) in functions { @@ -93,16 +94,15 @@ fn main() { } "asm" => { let mut tree = ast_tree(&tokens); - let mut intern = InternPool::new(); - let mut ir = IR::new(&mut intern); + let mut ir = IR::new(); _ = ir.build(&mut tree); - let mut mir = MirBuilder::new(&ir, tree.strings); + let mut mir = MirBuilder::new(&ir, tree.intern_pool); mir.build(); let MirBuilder { globals, - strings, + intern_pool: strings, functions, .. } = mir; diff --git a/src/parser.rs b/src/parser.rs index 905514c..51ea59a 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use itertools::Itertools; use num_bigint::{BigInt, BigUint}; @@ -8,13 +6,14 @@ use crate::{ self, FloatingType, IntegralType, LetOrVar, Node, PrimitiveType, Tag, Type, }, + ast2::intern::{self, AMD64_POINTER_BITS}, common::NextIf, comptime::{self, ComptimeNumber}, error::{AnalysisError, AnalysisErrorTag}, lexer::{Radix, TokenIterator}, - string_table::{ImmOrIndex, Index, StringTable}, symbol_table::{SymbolKind, SymbolTable}, tokens::{Token, PRECEDENCE_MAP}, + BitSize, }; #[derive(Debug, thiserror::Error)] @@ -98,7 +97,7 @@ impl Nodes { pub struct Tree { pub nodes: Nodes, pub st: SymbolTable, - pub strings: StringTable, + pub intern_pool: intern::InternPool, pub global_decls: Vec, } @@ -137,7 +136,7 @@ impl Tree { Self { nodes: Nodes::new(), st: SymbolTable::new(), - strings: StringTable::new(), + intern_pool: intern::InternPool::new(), global_decls: Vec::new(), } } @@ -318,14 +317,14 @@ impl Tree { fn parse_ident(&mut self, tokens: &mut TokenIterator) -> Result { let ident = tokens.expect_token(Token::Ident)?; - let name = self.strings.insert(ident.lexeme().as_bytes()); + let name = self.intern_pool.insert_string(ident.lexeme()); Ok(self.nodes.push_tag(Tag::Ident { name })) } - fn ident_index(&self, node: Node) -> Index { + fn ident_index(&self, node: Node) -> intern::Index { match &self.nodes[node] { Tag::Ident { name } => *name, - _ => Index::new(0, 0), + _ => intern::Index::EMPTY_STRING, } } @@ -335,10 +334,10 @@ impl Tree { ) -> Result { let token = tokens.next().ok_or(Error::UnexpectedEndOfTokens)?; let prim = match token.token() { - Token::Void => PrimitiveType::Void, - Token::Bool => PrimitiveType::Bool, - Token::F32 => PrimitiveType::FloatingType(FloatingType::Binary32), - Token::F64 => PrimitiveType::FloatingType(FloatingType::Binary64), + Token::Void => intern::Index::VOID, + Token::Bool => intern::Index::BOOL, + Token::F32 => intern::Index::F32, + Token::F64 => intern::Index::F64, _ => { return Err(Error::ExpectedPrimitiveType); } @@ -368,11 +367,14 @@ impl Tree { let token = tokens.next().unwrap(); match Self::try_parse_integral_type(token.lexeme())? { Some(int) => { - Ok(self.nodes.push_tag(Tag::IntegralType(int))) + let ty = + self.intern_pool.get_int_type(int.signed, int.bits); + + Ok(self.nodes.push_tag(Tag::IntegralType(ty))) } None => { let name = - self.strings.insert(token.lexeme().as_bytes()); + self.intern_pool.insert_string(token.lexeme()); Ok(self.nodes.push_tag(Tag::Ident { name })) } } @@ -404,7 +406,8 @@ impl Tree { None }; - let name_str = self.strings.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() { @@ -550,7 +553,7 @@ impl Tree { let return_type = if tokens.eat_token(Token::MinusGreater).is_some() { self.parse_typename(tokens)? } else { - self.nodes.push_tag(Tag::PrimitiveType(PrimitiveType::Void)) + self.nodes.push_tag(Tag::PrimitiveType(intern::Index::VOID)) }; let proto = self.nodes.push_tag(Tag::FunctionProto { @@ -1026,19 +1029,18 @@ impl Tree { 0..2 => { let (buf, _) = buf.split_at(core::mem::size_of::()); - let dw = u32::from_le_bytes(buf.try_into().unwrap()); - ImmOrIndex::U32(dw) + 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::()); - let qw = u64::from_le_bytes(buf.try_into().unwrap()); - ImmOrIndex::U64(qw) - } - 0.. => { - let idx = self.strings.insert(bytes); - ImmOrIndex::Index(idx) + self.intern_pool.get_unsigned_integer( + u64::from_le_bytes(buf.try_into().unwrap()), + ) } + 0.. => self.intern_pool.insert_bytes(&bytes), }; let ty = match ty { @@ -1059,8 +1061,16 @@ impl Tree { ); let bytes = match ty { - FloatingType::Binary32 => ImmOrIndex::U32(bits as u32), - FloatingType::Binary64 => ImmOrIndex::U64(bits as u64), + 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 { @@ -1210,7 +1220,7 @@ impl Tree { pub fn get_ident_str(&self, node: Node) -> Option<&str> { match &self.nodes[node] { - Tag::Ident { name } => Some(self.strings.get_str(*name)), + Tag::Ident { name } => Some(self.intern_pool.get_str(*name)), _ => None, } } @@ -1218,7 +1228,9 @@ 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.strings.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, @@ -1429,7 +1441,7 @@ impl Tree { writer, "%{} = identifier(\"{}\")", node.get(), - self.strings.get_str(name) + self.intern_pool.get_str(name) ) } Tag::Block { @@ -1898,10 +1910,10 @@ impl Tree { writeln_indented!( indent, writer, - "%{} = constant{{ ty: {}, bytes: {}}}", + "%{} = constant{{ ty: {}, bytes: {:?}}}", node.get(), ty, - self.strings.display_idx(bytes) + self.intern_pool.get_key(bytes) ) } Tag::ExprStatement { expr } => { @@ -2019,12 +2031,15 @@ impl Tree { pointee: Box::new(self.type_of_node(*pointee)), }, Tag::Constant { ty, .. } => ty.clone(), - Tag::IntegralType(t) => Type::Integer(*t), - Tag::PrimitiveType(t) => match t { - PrimitiveType::FloatingType(t) => Type::Floating(*t), - PrimitiveType::IntegralType(t) => Type::Integer(*t), - PrimitiveType::Bool => Type::bool(), - PrimitiveType::Void => Type::void(), + 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), + intern::Index::BOOL => Type::Bool, + intern::Index::VOID => Type::Void, + _ => self.intern_pool.as_ast1_type(AMD64_POINTER_BITS, *t), }, Tag::Block { trailing_expr, .. } => trailing_expr .map(|n| self.type_of_node(n)) @@ -2197,45 +2212,16 @@ impl Tree { pub fn value_of_comptime_node(&self, node: Node) -> Option { match self.nodes.get_node(node) { Tag::Constant { bytes, ty } => { - let bytes = match bytes { - ImmOrIndex::U64(v) => &v.to_le_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, + ); - ImmOrIndex::U32(v) => &v.to_le_bytes()[..], - ImmOrIndex::Index(idx) => self.strings.get_bytes(*idx), - }; - - let number: ComptimeNumber = match ty { - Type::Bool => (bytes[0] != 0).into(), - Type::ComptimeNumber => { - BigInt::from_bytes_le(num_bigint::Sign::Plus, bytes) - .into() - } - Type::Integer(ty) => { - if bytes.len() > core::mem::size_of::() { - let bits = BigInt::from_bytes_le( - num_bigint::Sign::Plus, - bytes, - ); - (bits, *ty).into() - } else { - let mut buf = [0u8; core::mem::size_of::()]; - buf[..bytes.len()].copy_from_slice(bytes); - let bits = u128::from_le_bytes(buf); - (bits, *ty).into() - } - } - Type::Floating(ty) => match ty { - FloatingType::Binary32 => (f32::from_le_bytes( - (&bytes[..4]).try_into().unwrap(), - )) - .into(), - FloatingType::Binary64 => (f64::from_le_bytes( - (&bytes[..8]).try_into().unwrap(), - )) - .into(), - }, - _ => unimplemented!(), - }; Some(number) } Tag::Block { .. } => todo!(), @@ -2272,13 +2258,17 @@ impl Tree { |_: &mut Tree, _| {}, |tree: &mut Tree, node| { if let Ok(value) = tree.fold_comptime_inner(node, false) { - let (bytes, ty) = value.into_bytes_and_type(); - let idx = tree.strings.insert(bytes); + 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: ImmOrIndex::Index(idx), - ty, - }; + *tree.nodes.get_node_mut(node) = + Tag::Constant { bytes: value, ty }; } }, ) @@ -2293,46 +2283,16 @@ impl Tree { if self.is_node_comptime(decl, check_declrefs) { match self.nodes.get_node(decl) { Tag::Constant { bytes, ty } => { - let bytes = match bytes { - ImmOrIndex::U64(v) => &v.to_le_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, + ); - ImmOrIndex::U32(v) => &v.to_le_bytes()[..], - ImmOrIndex::Index(idx) => self.strings.get_bytes(*idx), - }; - - let number: ComptimeNumber = match ty { - Type::Bool => (bytes[0] != 0).into(), - Type::ComptimeNumber => { - BigInt::from_bytes_le(num_bigint::Sign::Plus, bytes) - .into() - } - Type::Integer(ty) => { - if bytes.len() > core::mem::size_of::() { - let bits = BigInt::from_bytes_le( - num_bigint::Sign::Plus, - bytes, - ); - (bits, *ty).into() - } else { - let mut buf = - [0u8; core::mem::size_of::()]; - buf[..bytes.len()].copy_from_slice(bytes); - let bits = u128::from_le_bytes(buf); - (bits, *ty).into() - } - } - Type::Floating(ty) => match ty { - FloatingType::Binary32 => (f32::from_le_bytes( - (&bytes[..4]).try_into().unwrap(), - )) - .into(), - FloatingType::Binary64 => (f64::from_le_bytes( - (&bytes[..8]).try_into().unwrap(), - )) - .into(), - }, - _ => unimplemented!(), - }; return Ok(number); } Tag::Negate { lhs } => { @@ -2515,6 +2475,20 @@ impl Tree { } } + pub fn intern_types(&mut self) { + for decl in self.global_decls.clone() { + ast::tree_visitor::Visitor::new( + decl, + |_: &mut Tree, _| {}, + |tree: &mut Tree, node| { + let ty = tree.type_of_node(node); + tree.intern_pool.insert_ast1_type(AMD64_POINTER_BITS, &ty); + }, + ) + .visit_mut(self); + } + } + pub fn fold_comptime(&mut self) { for decl in self.global_decls.clone() { match self.nodes.get_node(decl) { @@ -2565,9 +2539,10 @@ impl Tree { }; if let Some(expr) = trailing_expr { let ty = self.nodes.push_tag(Tag::PrimitiveType( - peer_t - .as_primitive_type() - .expect("comptime cannot be cast into a non-primitive type"), + self.intern_pool.from_ast1_type( + AMD64_POINTER_BITS, + &peer_t, + ), )); let expr = self.nodes.push_tag(Tag::ExplicitCast { lhs: expr, @@ -2589,7 +2564,16 @@ impl Tree { } } Tag::Constant { bytes, ty } => { - let bits = self.strings.count_bits(bytes); + let bits = match self.intern_pool.get_key(bytes) { + intern::Key::F32 { .. } => 32, + intern::Key::F64 { .. } => 64, + intern::Key::UInt64 { bits } => bits.bits(), + intern::Key::UIntSmall { bits } => bits.bits(), + intern::Key::Bytes { bytes } => bytes.bits(), + _ => { + unreachable!() + } + }; if bits < ty.bit_width() as u32 { errors.push(AnalysisError::new( AnalysisErrorTag::InsufficientBitsInTypeForConstant( diff --git a/src/triples.rs b/src/triples.rs index f2a44e5..3e7d635 100644 --- a/src/triples.rs +++ b/src/triples.rs @@ -159,15 +159,17 @@ pub enum Inst { /// list of arguments /// start, (inlinetype)end Call(Node), - /// Value - /// lhs - GlobalConstant(StringsIndex, intern::Index), + /// (name: intern, ty: intern) + /// lhs: value node + GlobalConstant(intern::Index, intern::Index), /// u32 ConstantU32, /// lo, hi ConstantU64, /// index ConstantMultiByte, + /// type, value + Constant, /// size, align Alloca, /// src @@ -233,9 +235,10 @@ pub enum Inst { impl Inst { fn is_constant(self) -> bool { match self { - Inst::ConstantU32 | Inst::ConstantU64 | Inst::ConstantMultiByte => { - true - } + Inst::ConstantU32 + | Inst::ConstantU64 + | Inst::ConstantMultiByte + | Inst::Constant => true, _ => false, } @@ -263,11 +266,14 @@ impl Data { fn as_u64(&self) -> u64 { self.lhs as u64 | (self.rhs as u64) << u32::BITS as u64 } - fn as_index(&self) -> StringsIndex { - crate::string_table::Index { - start: self.lhs, - end: self.rhs, - } + fn as_index(&self) -> intern::Index { + intern::Index::from_u32(self.lhs) + } + fn as_index_index(&self) -> (intern::Index, intern::Index) { + ( + intern::Index::from_u32(self.lhs), + intern::Index::from_u32(self.rhs), + ) } fn as_lhs_rhs(&self) -> (u32, u32) { (self.lhs, self.rhs) @@ -297,6 +303,24 @@ impl From for Data { } } +impl From for Data { + fn from(value: intern::Index) -> Self { + Self { + lhs: value.into_u32(), + rhs: 0, + } + } +} + +impl From<(intern::Index, intern::Index)> for Data { + fn from(value: (intern::Index, intern::Index)) -> Self { + Self { + lhs: value.0.into_u32(), + rhs: value.1.into_u32(), + } + } +} + impl From for Data { fn from(value: crate::string_table::Index) -> Self { Self { @@ -306,15 +330,15 @@ impl From for Data { } } -pub struct IRBuilder<'tree, 'ir, 'intern> { - ir: &'ir mut IR<'intern>, +pub struct IRBuilder<'tree, 'ir> { + ir: &'ir mut IR, tree: &'tree mut Tree, type_map: HashMap, lookup: HashMap, fixup: Vec, } -impl core::ops::Index for IR<'_> { +impl core::ops::Index for IR { type Output = Inst; fn index(&self, index: Node) -> &Self::Output { @@ -322,8 +346,8 @@ impl core::ops::Index for IR<'_> { } } -impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { - fn new(ir: &'ir mut IR<'intern>, tree: &'tree mut Tree) -> Self { +impl<'tree, 'ir> IRBuilder<'tree, 'ir> { + fn new(ir: &'ir mut IR, tree: &'tree mut Tree) -> Self { Self { ir, tree, @@ -333,6 +357,13 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { } } + fn intern_pool_mut(&mut self) -> &mut InternPool { + &mut self.tree.intern_pool + } + fn intern_pool(&self) -> &InternPool { + &self.tree.intern_pool + } + fn peer_type_of_nodes(&self, lhs: AstNode, rhs: AstNode) -> Option { let lty = self.tree.type_of_node(lhs); let rty = self.tree.type_of_node(rhs); @@ -396,8 +427,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let size = ty.size_of(); let align = ty.align_of(); let ty = self - .ir - .intern_pool + .intern_pool() .from_ast1_type(AMD64_POINTER_BITS, &ty); let ir = self.ir.push( Inst::Parameter(ty), @@ -414,8 +444,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { if value != !0 { let ty = self.tree.type_of_node(*body); let ty = self - .ir - .intern_pool + .intern_pool() .from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir.push( Inst::ReturnValue(ty.into()), @@ -441,8 +470,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let start = self.ir.nodes.len(); for (arg, ty) in args { let ty = self - .ir - .intern_pool + .intern_pool() .from_ast1_type(AMD64_POINTER_BITS, &ty); _ = self.ir.push( Inst::Argument(ty.into()), @@ -461,7 +489,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { )); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir.push(Inst::InlineType(ty.into()), None); let func = self.visit(*lhs); @@ -490,7 +518,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { Some(Data::new(ty.size_of(), ty.align_of())), ); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); if let Some(assignment) = assignment { let value = self.visit(*assignment); @@ -513,7 +541,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { variant!(self.tree.nodes.get_node(*name) => Tag::Ident { name }); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &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)), @@ -526,7 +554,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { Tag::GlobalRef(decl) => { let ty = self.tree.type_of_node(*decl); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &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())), @@ -548,7 +576,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let source = self.visit(*rhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::Store(ty.into()), Some(Data::new(source, dest))) } @@ -556,8 +584,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { if let Some(expr) = expr { let ty = self.tree.type_of_node(*expr); let ty = self - .ir - .intern_pool + .intern_pool() .from_ast1_type(AMD64_POINTER_BITS, &ty); let expr = self.visit(*expr); self.ir.push( @@ -574,7 +601,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { self.tree.type_of_node(*lhs).pointee().unwrap().clone(); let lhs = self.visit(*lhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &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 } => { @@ -582,7 +609,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::Add(ty.into()), Some(Data::new(lhs, rhs))) } @@ -591,7 +618,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::Sub(ty.into()), Some(Data::new(lhs, rhs))) } @@ -600,7 +627,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::BitAnd(ty.into()), Some(Data::new(lhs, rhs))) } @@ -609,7 +636,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::BitOr(ty.into()), Some(Data::new(lhs, rhs))) } @@ -618,7 +645,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::BitXOr(ty.into()), Some(Data::new(lhs, rhs))) } @@ -639,7 +666,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { .into(); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &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), @@ -659,7 +686,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::Mul(ty.into()), Some(Data::new(lhs, rhs))) } @@ -667,14 +694,14 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let ty = self.tree.type_of_node(node); let lhs = self.visit(*lhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &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.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &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 } => { @@ -682,7 +709,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir .push(Inst::ShiftLeft(ty.into()), Some(Data::new(lhs, rhs))) } @@ -691,7 +718,7 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let lhs = self.visit(*lhs); let rhs = self.visit(*rhs); let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &ty); + self.intern_pool().from_ast1_type(AMD64_POINTER_BITS, &ty); self.ir.push( Inst::ShiftRight(ty.into()), Some(Data::new(lhs, rhs)), @@ -703,23 +730,17 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { // self.ir.push(Inst::Load(ty.into()), Some(Data::lhs(lhs))) // nothing happens here because lhs is of type pointer let ty = - self.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &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, .. } => match bytes { - ImmOrIndex::U64(v) => { - self.ir.push(Inst::ConstantU64, Some((*v).into())) - } - ImmOrIndex::U32(v) => { - self.ir.push(Inst::ConstantU32, Some((*v).into())) - } - ImmOrIndex::Index(idx) => { - self.ir.push(Inst::ConstantMultiByte, Some((*idx).into())) - } - }, + Tag::Constant { bytes, 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 } => { let l_ty = self.tree.type_of_node(*lhs).clone(); let r_ty = self.tree.type_of_node(*typename).clone(); @@ -731,12 +752,10 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { lhs } else { let l_ty = self - .ir - .intern_pool + .intern_pool() .from_ast1_type(AMD64_POINTER_BITS, &l_ty); let r_ty = self - .ir - .intern_pool + .intern_pool() .from_ast1_type(AMD64_POINTER_BITS, &r_ty); self.ir.push( Inst::ExplicitCast(l_ty.into(), r_ty.into()), @@ -750,14 +769,16 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { let condition = self.visit(*condition); let br = self.ir.push(Inst::Branch(condition), None); - let label_lhs = self - .ir - .push(Inst::Label, Some(StringsIndex::none().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(StringsIndex::none().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)); @@ -771,26 +792,29 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { 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.ir.intern_pool.from_ast1_type(AMD64_POINTER_BITS, &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(StringsIndex::none().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(StringsIndex::none().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(StringsIndex::none().into())); - let phi = if ty != self.ir.intern_pool.get_void_type() { + 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 @@ -810,16 +834,15 @@ impl<'tree, 'ir, 'intern> IRBuilder<'tree, 'ir, 'intern> { } } -pub struct IR<'a> { +pub struct IR { nodes: Vec, data: Vec>, - intern_pool: &'a mut InternPool, + // intern_pool: &'a mut InternPool, } -impl<'a> IR<'a> { - pub fn new(intern_pool: &'a mut InternPool) -> Self { +impl IR { + pub fn new() -> Self { Self { - intern_pool, nodes: Vec::new(), data: Vec::new(), } @@ -834,10 +857,7 @@ impl<'a> IR<'a> { pub fn build<'b, 'tree>( &'b mut self, tree: &'tree mut Tree, - ) -> IRBuilder<'tree, 'b, 'a> - where - 'a: 'b, - { + ) -> IRBuilder<'tree, 'b> { let global_decls = tree.global_decls.clone(); let mut builder = IRBuilder::new(self, tree); @@ -873,7 +893,7 @@ impl<'a> IR<'a> { } } -impl IRBuilder<'_, '_, '_> { +impl IRBuilder<'_, '_> { fn render_node( &self, w: &mut W, @@ -886,7 +906,7 @@ impl IRBuilder<'_, '_, '_> { let inst = self.ir.nodes[node as usize]; match inst { Inst::Label => { - let label = self.tree.strings.get_str(data.as_index()); + let label = self.intern_pool().get_str(data.as_index()); writeln_indented!( indent - 1, w, @@ -895,7 +915,7 @@ impl IRBuilder<'_, '_, '_> { )?; } Inst::FunctionStart => { - let label = self.tree.strings.get_str(data.as_index()); + let label = self.intern_pool().get_str(data.as_index()); writeln_indented!(indent - 1, w, "%{} = func {label}:", node)?; } Inst::FunctionEnd => { @@ -931,6 +951,17 @@ impl IRBuilder<'_, '_, '_> { } writeln_indented!(indent, w, ")")?; } + Inst::Constant => { + let (ty, val) = data.as_index_index(); + writeln_indented!( + indent, + w, + "%{} = const {} {}", + node, + self.intern_pool().display_key(ty), + self.intern_pool().display_key(val), + )?; + } Inst::ConstantU32 => { writeln_indented!( indent, @@ -950,7 +981,7 @@ impl IRBuilder<'_, '_, '_> { )?; } Inst::ConstantMultiByte => { - let value = self.tree.strings.get_bytes(data.as_index()); + let value = self.intern_pool().get_bytes(data.as_index()); writeln_indented!( indent, w, @@ -1159,8 +1190,9 @@ impl IRBuilder<'_, '_, '_> { writeln_indented!( indent, w, - "%{node} = extern reference {ty} '{}'", - self.tree.strings.get_str(idx) + "%{node} = extern ref {} '{}'", + self.intern_pool().display_key(ty), + self.intern_pool().get_str(idx) )?; } Inst::Branch(condition) => { @@ -1184,7 +1216,7 @@ impl IRBuilder<'_, '_, '_> { )?; } Inst::GlobalConstant(name, ty) => { - let label = self.tree.strings.get_str(name); + let label = self.intern_pool().get_str(name); let value = data.lhs; writeln_indented!( indent, @@ -1207,18 +1239,18 @@ impl IRBuilder<'_, '_, '_> { } } -struct IRIter<'a, 'b> { - ir: &'a IR<'b>, +struct IRIter<'a> { + ir: &'a IR, offset: usize, item: Option<(Inst, Option)>, } -impl IRIter<'_, '_> { +impl IRIter<'_> { fn node(&self) -> u32 { self.offset as Node } } -impl Iterator for IRIter<'_, '_> { +impl Iterator for IRIter<'_> { type Item = (Inst, Option); fn next(&mut self) -> Option { @@ -1232,23 +1264,25 @@ impl Iterator for IRIter<'_, '_> { use crate::mir; -pub struct MirBuilder<'a, 'b> { - ir: IRIter<'a, 'b>, - pub strings: StringTable, - pub functions: HashMap, - pub globals: HashMap, +pub struct MirBuilder<'a> { + ir: IRIter<'a>, + pub intern_pool: intern::InternPool, + pub functions: HashMap, + pub globals: HashMap, } struct IrToMirMapping<'a> { - ir: &'a IR<'a>, + ir: &'a IR, mapping: BTreeMap, + ip: &'a intern::InternPool, } impl<'a> IrToMirMapping<'a> { - fn new(ir: &'a IR) -> Self { + fn new(ir: &'a IR, ip: &'a intern::InternPool) -> Self { Self { ir, mapping: BTreeMap::new(), + ip, } } fn insert(&mut self, ir: Node, mir: mir::NodeRef) { @@ -1265,10 +1299,7 @@ impl<'a> IrToMirMapping<'a> { eprintln!( "does this even get hit anymore???????????????????//" ); - let ty = self - .ir - .intern_pool - .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + 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); Some(ext) @@ -1278,23 +1309,30 @@ impl<'a> IrToMirMapping<'a> { } } -impl<'a, 'b> MirBuilder<'a, 'b> { - pub fn new(ir: &'a IR<'b>, strings: StringTable) -> MirBuilder<'a, 'b> { +impl<'a> MirBuilder<'a> { + pub fn new(ir: &'a IR, intern_pool: intern::InternPool) -> MirBuilder<'a> { Self { ir: IRIter { ir, offset: 0, item: None, }, - strings, + intern_pool, functions: HashMap::new(), globals: HashMap::new(), } } - fn build_function(&mut self, name: StringsIndex) { + fn intern_pool(&self) -> &intern::InternPool { + &self.intern_pool + } + fn intern_pool_mut(&mut self) -> &mut intern::InternPool { + &mut self.intern_pool + } + + fn build_function(&mut self, name: intern::Index) { let mut mir = mir::Mir::new(name); - let mut mapping = IrToMirMapping::new(&self.ir.ir); + let mut mapping = IrToMirMapping::new(&self.ir.ir, &self.intern_pool); // map of label -> unresolved mir jump or branch instruction // stored as a tree of (label, unresolved) #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)] @@ -1371,6 +1409,13 @@ impl<'a, 'b> MirBuilder<'a, 'b> { label } + Inst::Constant => { + let (ty, val) = data.unwrap().as_index_index(); + let mir_ty = self + .intern_pool() + .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); + mir.push_const(val, mir_ty) + } Inst::ConstantU32 => mir.push( mir::Inst::ConstantDWord, mir::Data::imm32(data.unwrap().as_u32()), @@ -1381,7 +1426,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> { ), Inst::ConstantMultiByte => { let bytes = - self.strings.get_bytes(data.unwrap().as_index()); + self.intern_pool().get_bytes(data.unwrap().as_index()); let mut buf = [0u8; 8]; match bytes.len() { 1 => mir.gen_u8(bytes[0]), @@ -1413,9 +1458,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> { } Inst::Load(ty) => { let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let src = mapping .get(&mut mir, data.unwrap().as_u32()) @@ -1425,9 +1468,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> { } Inst::Store(ty) => { let ty = self - .ir - .ir - .intern_pool + .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; @@ -1436,9 +1477,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> { } Inst::GetElementPtr(ty) => { let ty = self - .ir - .ir - .intern_pool + .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; @@ -1447,9 +1486,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> { Inst::Parameter(ty) => { // let (size, _) = data.unwrap().as_lhs_rhs(); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_param(ty.into()) } @@ -1475,14 +1512,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { }; let signed = self - .ir - .ir - .intern_pool + .intern_pool() .is_type_signed(ty, AMD64_POINTER_TYPE_INFO); let mir_ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_cmp_byte(mir_ty, signed, ord, invert, lhs, rhs) } @@ -1492,14 +1525,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let rhs = mapping.get(&mut mir, dst).unwrap().0; let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); match info.bitsize { @@ -1524,14 +1553,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let rhs = mapping.get(&mut mir, dst).unwrap().0; let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1547,14 +1572,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1573,14 +1594,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1599,14 +1616,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1625,14 +1638,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1658,14 +1667,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let (lhs, rhs) = data.unwrap().as_lhs_rhs(); let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1701,14 +1706,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let rhs = mapping.get(&mut mir, rhs).unwrap().0; let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1726,14 +1727,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let rhs = mapping.get(&mut mir, dst).unwrap().0; let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1755,14 +1752,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let rhs = mapping.get(&mut mir, dst).unwrap().0; let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1783,14 +1776,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let lhs = mapping.get(&mut mir, lhs).unwrap().0; let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1807,14 +1796,10 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let lhs = mapping.get(&mut mir, lhs).unwrap().0; let info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(ty, AMD64_POINTER_TYPE_INFO); let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let unalignment = mir_unalignment(info.signed, info.bitsize); @@ -1831,27 +1816,19 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let lhs = mapping.get(&mut mir, lhs).unwrap().0; let to_info = self - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(to, AMD64_POINTER_TYPE_INFO); let to_ty = self - .ir - .ir - .intern_pool + .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 - .ir - .ir - .intern_pool + .intern_pool() .size_of_type(from, AMD64_POINTER_TYPE_INFO); let from_ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(from, AMD64_POINTER_TYPE_INFO); let from_unalignment = mir_unalignment(from_info.signed, from_info.bitsize); @@ -1890,9 +1867,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let src = mapping.get(&mut mir, src).unwrap().0; let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_ret_val(ty, src) @@ -1963,18 +1938,14 @@ impl<'a, 'b> MirBuilder<'a, 'b> { variant!(&ir.nodes[end as usize -1] => Inst::InlineType(ty)); let ty = self - .ir - .ir - .intern_pool + .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 - .ir - .ir - .intern_pool + .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; @@ -1989,18 +1960,14 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let lhs = mapping.get(&mut mir, src).unwrap().0; let rhs = mapping.get(&mut mir, dst).unwrap().0; let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_phi2(ty, lhs, rhs) } Inst::GlobalConstant(name, ty) => { let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); let ext = mir.gen_extern(Some(ty), name); @@ -2011,9 +1978,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> { } Inst::ExternRef(ty) => { let ty = self - .ir - .ir - .intern_pool + .intern_pool() .to_mir_type(ty, AMD64_POINTER_TYPE_INFO); mir.gen_extern(Some(ty), data.unwrap().as_index()) } @@ -2047,6 +2012,13 @@ impl<'a, 'b> MirBuilder<'a, 'b> { let data = self.ir.ir.data[value as usize]; let inst = self.ir.ir.nodes[value as usize]; 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); + mir.push_const(val, mir_ty) + } Inst::ConstantU32 => mir.push( mir::Inst::ConstantDWord, mir::Data::imm32(data.unwrap().as_u32()), @@ -2057,7 +2029,7 @@ impl<'a, 'b> MirBuilder<'a, 'b> { ), Inst::ConstantMultiByte => { let bytes = self - .strings + .intern_pool() .get_bytes(data.unwrap().as_index()); let mut buf = [0u8; 8]; match bytes.len() { @@ -2121,7 +2093,7 @@ fn u10(x: i10) -> i10 { println!("AST:\n{buf}"); let mut intern = InternPool::new(); - let mut ir = IR::new(&mut intern); + let mut ir = IR::new(); { let builder = ir.build(&mut tree); let mut buf = String::new(); @@ -2129,7 +2101,7 @@ fn u10(x: i10) -> i10 { println!("IR:\n{buf}"); } - let mut mir = MirBuilder::new(&ir, tree.strings); + let mut mir = MirBuilder::new(&ir, tree.intern_pool); mir.build(); } } diff --git a/tests/legal/global_var.sea b/tests/legal/global_var.sea index 1016bb2..b4e53a5 100644 --- a/tests/legal/global_var.sea +++ b/tests/legal/global_var.sea @@ -2,4 +2,4 @@ fn main() -> i32 { return RANDOM; } -const RANDOM: i32 = 4 + (1 << 3); +const RANDOM: i32 = 4i32 + (1i32 << 3i32);