diff --git a/Cargo.lock b/Cargo.lock index 0c63def..6e6f5d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -574,6 +574,7 @@ name = "uwucc" version = "0.1.0" dependencies = [ "analysis", + "bumpalo", "dbg-pls", "parser", ] diff --git a/Cargo.toml b/Cargo.toml index 248537a..406ada9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +bumpalo = "3.10.0" analysis = { path = "./analysis" } parser = { path = "./parser" } dbg-pls = { version = "0.3.2", features = ["derive", "colors"] } diff --git a/analysis/src/ir.rs b/analysis/src/ir.rs index 7d852d4..df8cafb 100644 --- a/analysis/src/ir.rs +++ b/analysis/src/ir.rs @@ -33,6 +33,8 @@ mod pretty; +use std::fmt::{Debug, Display}; + use parser::{Span, Symbol}; pub use pretty::{func_to_string, ir_to_string}; use rustc_hash::FxHashMap; @@ -43,30 +45,33 @@ use crate::ty::Ty; pub struct DefId(u32); #[derive(Debug, Clone)] -pub struct TyLayout { - pub ty: Ty, - pub layout: Layout, +pub struct TyLayout<'cx> { + pub ty: Ty<'cx>, + pub layout: &'cx Layout, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Layout { pub size: u64, pub align: u64, } -pub struct Ir { - pub funcs: FxHashMap, +pub struct Ir<'cx> { + pub funcs: FxHashMap>, } #[derive(Debug, Clone)] -pub struct Func { - pub regs: Vec, +pub struct Func<'cx> { + pub regs: Vec>, pub bbs: Vec, pub name: Symbol, pub def_span: Span, - pub ret_ty: Ty, + pub ret_ty: Ty<'cx>, } +#[derive(Clone, Copy)] +pub struct BbIdx(pub u32); + #[derive(Debug, Clone)] pub struct BasicBlock { pub statements: Vec, @@ -74,8 +79,8 @@ pub struct BasicBlock { } #[derive(Debug, Clone)] -pub struct RegisterData { - pub tyl: TyLayout, +pub struct RegisterData<'cx> { + pub tyl: TyLayout<'cx>, pub name: Option, } @@ -133,8 +138,12 @@ pub enum Operand { #[derive(Debug, Clone)] pub enum Branch { - Goto(u32), - Switch { cond: Operand, yes: u32, no: u32 }, + Goto(BbIdx), + Switch { + cond: Operand, + yes: BbIdx, + no: BbIdx, + }, Ret(Operand), } @@ -159,6 +168,33 @@ pub enum ConstValue { Int(u128), } +impl Func<'_> { + pub fn bb_mut(&mut self, i: BbIdx) -> &mut BasicBlock { + &mut self.bbs[i.as_usize()] + } +} + +impl BbIdx { + pub fn from_usize(n: usize) -> Self { + Self(n.try_into().unwrap()) + } + pub fn as_usize(self) -> usize { + self.0 as _ + } +} + +impl Debug for BbIdx { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "bb{}", self.0) + } +} + +impl Display for BbIdx { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "bb{}", self.0) + } +} + impl Layout { pub fn size_align(size: u64, align: u64) -> Self { Self { size, align } diff --git a/analysis/src/ir/pretty.rs b/analysis/src/ir/pretty.rs index ba8965d..e4f2700 100644 --- a/analysis/src/ir/pretty.rs +++ b/analysis/src/ir/pretty.rs @@ -1,15 +1,15 @@ use std::fmt::{Display, Formatter, Result, Write}; -use super::{BinKind, Branch, ConstValue, Func, Ir, Operand, StatementKind}; +use super::{BinKind, Branch, ConstValue, Func, Ir, Operand, StatementKind, BbIdx}; use crate::ir::Register; -pub fn ir_to_string(ir: &Ir) -> String { +pub fn ir_to_string(ir: &Ir<'_>) -> String { let mut buf = String::new(); PrettyPrinter { out: &mut buf }.ir(ir).unwrap(); buf } -pub fn func_to_string(func: &Func) -> String { +pub fn func_to_string(func: &Func<'_>) -> String { let mut buf = String::new(); PrettyPrinter { out: &mut buf }.func(func).unwrap(); buf @@ -20,14 +20,14 @@ pub struct PrettyPrinter { } impl PrettyPrinter { - pub fn ir(&mut self, ir: &Ir) -> Result { + pub fn ir(&mut self, ir: &Ir<'_>) -> Result { for (_, func) in &ir.funcs { self.func(func)?; } Ok(()) } - pub fn func(&mut self, func: &Func) -> Result { + pub fn func(&mut self, func: &Func<'_>) -> Result { writeln!(self.out, "def {}() {{", func.name)?; let print_reg = |reg: Register| { @@ -48,7 +48,7 @@ impl PrettyPrinter { if i > 0 { writeln!(self.out)?; } - writeln!(self.out, " {i}:")?; + writeln!(self.out, " {}:", BbIdx::from_usize(i))?; for stmt in &bb.statements { match stmt.kind { @@ -144,9 +144,11 @@ impl PrettyPrinter { match bb.term { Branch::Goto(bbn) => writeln!(self.out, " goto {}", bbn)?, - Branch::Switch { cond, yes, no } => { - writeln!(self.out, " switch {}, {yes}, {no}", print_op(cond))? - } + Branch::Switch { cond, yes, no } => writeln!( + self.out, + " switch {}, then {yes}, else {no}", + print_op(cond) + )?, Branch::Ret(op) => writeln!(self.out, " ret {}", print_op(op))?, } } diff --git a/analysis/src/lower.rs b/analysis/src/lower.rs index a1136ae..78f0e10 100644 --- a/analysis/src/lower.rs +++ b/analysis/src/lower.rs @@ -1,24 +1,104 @@ mod builder; +use std::cell::RefCell; + use parser::{ ast::{self, Atom, DeclAttr, Expr, ExternalDecl, Stmt, TranslationUnit, TypeSpecifier}, Span, Symbol, }; -use rustc_hash::FxHashMap; +use rustc_hash::{FxHashMap, FxHashSet}; use self::builder::FuncBuilder; use crate::{ - ir::{BinKind, ConstValue, Func, Ir, Layout, Operand, Register, TyLayout}, - ty::Ty, + ir::{BinKind, Branch, ConstValue, Func, Ir, Layout, Operand, Register, TyLayout}, + ty::{Ty, TyKind}, Error, }; type Result = std::result::Result; -struct LoweringCx {} +#[derive(Debug)] +struct LoweringCx<'cx> { + tys: RefCell>>, + layouts: RefCell>, + arena: &'cx bumpalo::Bump, +} -pub fn lower_translation_unit(ast: &TranslationUnit) -> Result { - let mut lcx = LoweringCx {}; +impl<'cx> LoweringCx<'cx> { + fn lower_ty(&self, ty: &TypeSpecifier) -> Ty<'cx> { + let kind = match ty { + TypeSpecifier::Void => TyKind::Void, + TypeSpecifier::Char => TyKind::Char, + TypeSpecifier::SChar => TyKind::SChar, + TypeSpecifier::UChar => TyKind::UChar, + TypeSpecifier::Integer(int) => TyKind::Integer(*int), + TypeSpecifier::Float => TyKind::Float, + TypeSpecifier::Double => TyKind::Double, + TypeSpecifier::LongDouble => TyKind::LongDouble, + TypeSpecifier::Bool => TyKind::Bool, + }; + self.intern_ty(kind) + } + + fn intern_ty(&self, kind: TyKind<'cx>) -> Ty<'cx> { + let opt_kind = self.tys.borrow().get(&kind).copied(); + match opt_kind { + Some(ty) => Ty::new_unchecked(ty), + None => { + let kind = self.arena.alloc(kind); + self.tys.borrow_mut().insert(kind); + Ty::new_unchecked(kind) + } + } + } + + fn intern_layout(&self, layout: Layout) -> &'cx Layout { + let opt_layout = self.layouts.borrow().get(&layout).copied(); + match opt_layout { + Some(layout) => layout, + None => { + let layout = self.arena.alloc(layout); + self.layouts.borrow_mut().insert(layout); + layout + } + } + } + + fn layout_of(&self, ty: Ty<'cx>) -> TyLayout<'cx> { + let layout = match *ty { + TyKind::Void => Layout::size_align(0, 1), + TyKind::Char => Layout::size_align(1, 1), + TyKind::SChar => Layout::size_align(1, 1), + TyKind::UChar => Layout::size_align(1, 1), + TyKind::Integer(int) => match int.kind { + parser::ast::IntTyKind::Short => Layout::size_align(2, 2), + parser::ast::IntTyKind::Int => Layout::size_align(4, 4), + parser::ast::IntTyKind::Long => Layout::size_align(8, 8), + parser::ast::IntTyKind::LongLong => Layout::size_align(8, 8), + }, + TyKind::Float => Layout::size_align(4, 4), + TyKind::Double => Layout::size_align(8, 8), + TyKind::LongDouble => Layout::size_align(8, 8), + TyKind::Bool => Layout::size_align(1, 1), + TyKind::Struct(_) => todo!("layout_of struct"), + TyKind::Union(_) => todo!("layout_of union"), + TyKind::Enum(_) => todo!("layout_of enum"), + TyKind::Ptr(_) => Layout::size_align(8, 8), + }; + let layout = self.intern_layout(layout); + TyLayout { ty, layout } + } +} + +pub fn lower_translation_unit<'cx>( + arena: &'cx bumpalo::Bump, + ast: &TranslationUnit, +) -> Result, Error> { + let mut lcx = LoweringCx { + tys: RefCell::default(), + layouts: RefCell::default(), + arena, + }; for (decl, _) in ast { match decl { @@ -26,7 +106,7 @@ pub fn lower_translation_unit(ast: &TranslationUnit) -> Result { ExternalDecl::FunctionDef(def) => { let decl = def.decl.uwnrap_normal(); let body = &def.body; - let ret_ty = lower_ty(&decl.decl_spec.ty); + let ret_ty = lcx.lower_ty(&decl.decl_spec.ty); lower_body( &mut lcx, body, @@ -38,17 +118,18 @@ pub fn lower_translation_unit(ast: &TranslationUnit) -> Result { } } - todo!() + todo!("building is not really") } #[derive(Debug)] -struct FnLoweringCtxt { - scopes: Vec>, - build: FuncBuilder, +struct FnLoweringCtxt<'a, 'cx> { + scopes: Vec>>, + build: FuncBuilder<'a, 'cx>, + lcx: &'a LoweringCx<'cx>, } -impl FnLoweringCtxt { - fn resolve_ident(&self, ident: Symbol) -> Option<&VariableInfo> { +impl<'a, 'cx> FnLoweringCtxt<'a, 'cx> { + fn resolve_ident(&self, ident: Symbol) -> Option<&VariableInfo<'cx>> { self.scopes.iter().rev().find_map(|s| s.get(&ident)) } @@ -63,11 +144,11 @@ impl FnLoweringCtxt { match stmt { Stmt::Decl(decl) => { let decl = decl.uwnrap_normal(); - let ty = lower_ty(&decl.decl_spec.ty); + let ty = self.lcx.lower_ty(&decl.decl_spec.ty); let decl_attr = decl.decl_spec.attrs; for (var, def_span) in &decl.init_declarators { - let tyl = layout_of(ty.clone()); + let tyl = self.lcx.layout_of(ty.clone()); let (name, _) = var.declarator.decl.name(); let ptr_to = self.build.alloca(&tyl.layout, Some(name), stmt_span); @@ -75,18 +156,50 @@ impl FnLoweringCtxt { def_span: *def_span, ptr_to, decl_attr, - tyl, + tyl: tyl.clone(), }; self.scopes.last_mut().unwrap().insert(name, variable_info); + if let Some((init, init_span)) = &var.init { + let init = self.lower_expr(init, *init_span)?; + self.build.store(ptr_to, init, tyl.layout, *init_span); + } } } Stmt::Labeled { .. } => todo!("labels are not implemented"), Stmt::Compound(_) => todo!("blocks are not implemented"), Stmt::If { cond, - then, + then: then_body, otherwise, - } => todo!(), + } => { + let cond = self.lower_expr(&cond.0, cond.1)?; + let pred = self.build.current_bb; + let then = self.build.new_block(); + let els = otherwise + .as_deref() + .map(|oth| (oth, self.build.new_block())); + let cont = self.build.new_block(); + + self.build.current_bb = then; + self.lower_body(&then_body)?; + self.build.cur_bb_mut().term = Branch::Goto(cont); + + let false_branch = match els { + Some((otherwise, els)) => { + self.build.current_bb = els; + self.lower_body(&otherwise)?; + self.build.cur_bb_mut().term = Branch::Goto(cont); + els + } + None => cont, + }; + self.build.bb_mut(pred).term = Branch::Switch { + cond, + yes: then, + no: false_branch, + }; + self.build.current_bb = cont; + } Stmt::Switch => todo!(), Stmt::While { cond, body } => todo!(), Stmt::For { @@ -160,7 +273,13 @@ impl FnLoweringCtxt { ast::BinaryOp::Assign(_) => todo!("no assign"), }; - let reg = self.build.binary(kind, lhs, rhs, span, layout_of(Ty::Void)); + let reg = self.build.binary( + kind, + lhs, + rhs, + span, + self.lcx.layout_of(self.lcx.intern_ty(TyKind::Void)), + ); Ok(Operand::Reg(reg)) } @@ -173,7 +292,12 @@ impl FnLoweringCtxt { .map(|(arg, sp)| self.lower_expr(arg, *sp)) .collect::>()?; - let reg = self.build.call(layout_of(Ty::Void), lhs, args, span); + let reg = self.build.call( + self.lcx.layout_of(self.lcx.intern_ty(TyKind::Void)), + lhs, + args, + span, + ); Ok(Operand::Reg(reg)) } ast::PostfixOp::Member(_) => todo!("member expr"), @@ -189,65 +313,28 @@ impl FnLoweringCtxt { } #[derive(Debug)] -struct VariableInfo { +struct VariableInfo<'cx> { def_span: Span, - tyl: TyLayout, + tyl: TyLayout<'cx>, ptr_to: Register, decl_attr: DeclAttr, } -fn lower_body( +fn lower_body<'cx>( // may be used later - _lcx: &mut LoweringCx, + lcx: &LoweringCx<'cx>, body: &[(Stmt, Span)], def_span: Span, name: Symbol, - ret_ty: Ty, -) -> Result { - let mut cx: FnLoweringCtxt = FnLoweringCtxt { + ret_ty: Ty<'cx>, +) -> Result, Error> { + let mut cx = FnLoweringCtxt { scopes: vec![FxHashMap::default()], - build: FuncBuilder::new(name, def_span, ret_ty), + build: FuncBuilder::new(name, def_span, ret_ty, lcx), + lcx, }; cx.lower_body(body)?; Ok(cx.build.finish()) } - -fn lower_ty(ty: &TypeSpecifier) -> Ty { - match ty { - TypeSpecifier::Void => Ty::Void, - TypeSpecifier::Char => Ty::Char, - TypeSpecifier::SChar => Ty::SChar, - TypeSpecifier::UChar => Ty::UChar, - TypeSpecifier::Integer(int) => Ty::Integer(*int), - TypeSpecifier::Float => Ty::Float, - TypeSpecifier::Double => Ty::Double, - TypeSpecifier::LongDouble => Ty::LongDouble, - TypeSpecifier::Bool => Ty::Bool, - } -} - -fn layout_of(ty: Ty) -> TyLayout { - let layout = match ty { - Ty::Void => Layout::size_align(0, 1), - Ty::Char => Layout::size_align(1, 1), - Ty::SChar => Layout::size_align(1, 1), - Ty::UChar => Layout::size_align(1, 1), - Ty::Integer(int) => match int.kind { - parser::ast::IntTyKind::Short => Layout::size_align(2, 2), - parser::ast::IntTyKind::Int => Layout::size_align(4, 4), - parser::ast::IntTyKind::Long => Layout::size_align(8, 8), - parser::ast::IntTyKind::LongLong => Layout::size_align(8, 8), - }, - Ty::Float => Layout::size_align(4, 4), - Ty::Double => Layout::size_align(8, 8), - Ty::LongDouble => Layout::size_align(8, 8), - Ty::Bool => Layout::size_align(1, 1), - Ty::Struct(_) => todo!("layout_of struct"), - Ty::Union(_) => todo!("layout_of union"), - Ty::Enum(_) => todo!("layout_of enum"), - Ty::Ptr(_) => Layout::size_align(8, 8), - }; - TyLayout { ty, layout } -} diff --git a/analysis/src/lower/builder.rs b/analysis/src/lower/builder.rs index 7d213c5..28e4565 100644 --- a/analysis/src/lower/builder.rs +++ b/analysis/src/lower/builder.rs @@ -1,45 +1,50 @@ use parser::{Span, Symbol}; -use super::layout_of; +use super::LoweringCx; use crate::{ ir::{ - self, BasicBlock, BinKind, Branch, ConstValue, Func, Layout, Operand, Register, + self, BasicBlock, BbIdx, BinKind, Branch, ConstValue, Func, Layout, Operand, Register, RegisterData, Statement, StatementKind, TyLayout, }, - ty::Ty, + ty::{Ty, TyKind}, }; #[derive(Debug)] -pub struct FuncBuilder { - pub ir: Func, - current_bb: u32, +pub(super) struct FuncBuilder<'a, 'cx> { + pub lcx: &'a LoweringCx<'cx>, + pub ir: Func<'cx>, + pub current_bb: BbIdx, } -impl FuncBuilder { - pub fn new(name: Symbol, def_span: Span, ret_ty: Ty) -> Self { +impl<'a, 'cx> FuncBuilder<'a, 'cx> { + pub fn new(name: Symbol, def_span: Span, ret_ty: Ty<'cx>, lcx: &'a LoweringCx<'cx>) -> Self { Self { ir: Func { regs: Vec::new(), bbs: vec![BasicBlock { statements: Vec::new(), - term: Branch::Goto(0), + term: Branch::Goto(BbIdx(0)), }], name, def_span, ret_ty, }, - current_bb: 0, + current_bb: BbIdx(0), + lcx, } } - pub fn new_reg(&mut self, name: Option, tyl: TyLayout) -> Register { + pub fn new_reg(&mut self, name: Option, tyl: TyLayout<'cx>) -> Register { let reg = Register(self.ir.regs.len().try_into().unwrap()); self.ir.regs.push(RegisterData { name, tyl }); reg } pub fn alloca(&mut self, layout: &Layout, name: Option, span: Span) -> Register { - let reg = self.new_reg(name, layout_of(Ty::Ptr(Box::new(Ty::Void)))); + let void_ptr = self + .lcx + .intern_ty(TyKind::Ptr(self.lcx.intern_ty(TyKind::Void))); + let reg = self.new_reg(name, self.lcx.layout_of(void_ptr)); let stmt = Statement { span, kind: StatementKind::Alloca { @@ -48,7 +53,7 @@ impl FuncBuilder { align: Operand::Const(ConstValue::u64(layout.align)), }, }; - self.bb_mut().statements.push(stmt); + self.cur_bb_mut().statements.push(stmt); reg } @@ -58,7 +63,7 @@ impl FuncBuilder { lhs: Operand, rhs: Operand, span: Span, - result_tyl: TyLayout, + result_tyl: TyLayout<'cx>, ) -> Register { let reg = self.new_reg(None, result_tyl); let stmt = StatementKind::BinOp { @@ -67,13 +72,13 @@ impl FuncBuilder { rhs, result: reg, }; - self.bb_mut() + self.cur_bb_mut() .statements .push(Statement { span, kind: stmt }); reg } - pub fn load(&mut self, tyl: TyLayout, ptr_reg: Register, span: Span) -> Register { + pub fn load(&mut self, tyl: TyLayout<'cx>, ptr_reg: Register, span: Span) -> Register { let reg = self.new_reg(None, tyl.clone()); let stmt = StatementKind::Load { result: reg, @@ -81,27 +86,27 @@ impl FuncBuilder { size: Operand::const_u64(tyl.layout.size), align: Operand::const_u64(tyl.layout.align), }; - self.bb_mut() + self.cur_bb_mut() .statements .push(Statement { span, kind: stmt }); reg } - pub fn store(&mut self, ptr_reg: Register, rhs: Operand, layout: Layout, span: Span) { + pub fn store(&mut self, ptr_reg: Register, rhs: Operand, layout: &Layout, span: Span) { let stmt = StatementKind::Store { ptr_reg, value: rhs, size: Operand::const_u64(layout.size), align: Operand::const_u64(layout.align), }; - self.bb_mut() + self.cur_bb_mut() .statements .push(Statement { span, kind: stmt }); } pub fn call( &mut self, - ret_tyl: TyLayout, + ret_tyl: TyLayout<'cx>, func: Operand, args: Vec, span: Span, @@ -112,18 +117,30 @@ impl FuncBuilder { func, args, }; - self.bb_mut() + self.cur_bb_mut() .statements .push(Statement { span, kind: stmt }); reg } - pub fn bb_mut(&mut self) -> &mut BasicBlock { - &mut self.ir.bbs[self.current_bb as usize] + pub fn bb_mut(&mut self, bb: BbIdx) -> &mut BasicBlock { + self.ir.bb_mut(bb) } - pub fn finish(mut self) -> Func { - self.bb_mut().term = Branch::Ret(Operand::Const(ConstValue::Void)); + pub fn cur_bb_mut(&mut self) -> &mut BasicBlock { + &mut self.ir.bbs[self.current_bb.as_usize()] + } + + pub fn new_block(&mut self) -> BbIdx { + self.ir.bbs.push(BasicBlock { + statements: vec![], + term: Branch::Goto(BbIdx(0)), + }); + BbIdx::from_usize(self.ir.bbs.len() - 1) + } + + pub fn finish(mut self) -> Func<'cx> { + self.cur_bb_mut().term = Branch::Ret(Operand::Const(ConstValue::Void)); println!("{}", ir::func_to_string(&self.ir)); diff --git a/analysis/src/ty.rs b/analysis/src/ty.rs index 9e04554..ee6a6b7 100644 --- a/analysis/src/ty.rs +++ b/analysis/src/ty.rs @@ -1,10 +1,18 @@ +use std::{ + hash::{Hash, Hasher}, + ops::Deref, +}; + use indexmap::IndexMap; use parser::{ast::IntTy, Symbol}; use crate::ir::DefId; -#[derive(Debug, Clone)] -pub enum Ty { +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Ty<'cx>(&'cx TyKind<'cx>); + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum TyKind<'cx> { Void, Char, SChar, @@ -14,26 +22,55 @@ pub enum Ty { Double, LongDouble, Bool, - Ptr(Box), - Union(UnionTy), - Struct(StructTy), + Ptr(Ty<'cx>), + Union(UnionTy<'cx>), + Struct(StructTy<'cx>), Enum(EnumTy), } -#[derive(Debug, Clone)] -pub struct UnionTy { +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct UnionTy<'cx> { pub def_id: DefId, - pub variants: IndexMap, + pub variants: IndexMap>, } -#[derive(Debug, Clone)] -pub struct StructTy { +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct StructTy<'cx> { pub def_id: DefId, - pub fields: IndexMap, + pub fields: IndexMap>, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct EnumTy { pub def_id: DefId, pub variants: IndexMap, } + +impl<'cx> Ty<'cx> { + pub fn new_unchecked(kind: &'cx TyKind<'cx>) -> Self { + Self(kind) + } +} + +impl<'cx> Deref for Ty<'cx> { + type Target = &'cx TyKind<'cx>; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl Hash for UnionTy<'_> { + fn hash(&self, state: &mut H) { + self.def_id.hash(state) + } +} +impl Hash for StructTy<'_> { + fn hash(&self, state: &mut H) { + self.def_id.hash(state) + } +} +impl Hash for EnumTy { + fn hash(&self, state: &mut H) { + self.def_id.hash(state) + } +} diff --git a/parser/src/ast.rs b/parser/src/ast.rs index e736cc2..4fc3eff 100644 --- a/parser/src/ast.rs +++ b/parser/src/ast.rs @@ -142,7 +142,7 @@ pub enum Stmt { // --- Types and decls and garbage whatever // -#[derive(Debug, DebugPls, Clone, Copy)] +#[derive(Debug, DebugPls, Clone, Copy, PartialEq, Eq, Hash)] pub enum IntTySignedness { Signed, Unsigned, @@ -155,7 +155,7 @@ impl Default for IntTySignedness { } } -#[derive(Debug, DebugPls, Clone, Copy)] +#[derive(Debug, DebugPls, Clone, Copy, PartialEq, Eq, Hash)] pub enum IntTyKind { Short, Int, @@ -163,7 +163,7 @@ pub enum IntTyKind { LongLong, } -#[derive(Debug, DebugPls, Clone, Copy)] +#[derive(Debug, DebugPls, Clone, Copy, PartialEq, Eq, Hash)] pub struct IntTy { pub sign: IntTySignedness, pub kind: IntTyKind, diff --git a/src/main.rs b/src/main.rs index a512adb..040b87a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,5 +15,7 @@ fn main() { printer.translation_unit(&ast).unwrap(); println!("// END CODE -------------------"); - let _ = analysis::lower_translation_unit(&ast); + let arena = bumpalo::Bump::new(); + + let _ = analysis::lower_translation_unit(&arena, &ast); }