use super::ir; use super::temp; pub enum Location { InFrame { offset: usize, }, Register(temp::TempName), } pub enum Escape { No, Yes, } pub trait Frame { fn new(name: temp::TempLabel, formals: Vec) -> Self; fn name(&self) -> temp::TempLabel; fn formals(&self) -> &[Location]; fn alloc_local(&mut self, temp: &mut temp::Temp, escapes: Escape) -> Location; fn location_to_exp(&mut self, location: Location) -> ir::Expression; } pub struct Amd64Frame { offset: u64, name: temp::TempLabel, } impl Frame for Amd64Frame { fn new(name: temp::TempLabel, formals: Vec) -> Self { Amd64Frame { offset: 0, name: name, } } fn name(&self) -> temp::TempLabel { self.name } fn formals(&self) -> &[Location] { unimplemented!(); } fn alloc_local(&mut self, temp: &mut temp::Temp, escapes: Escape) -> Location { // TODO: this is WRONG Location::InFrame { offset: 0 } } fn location_to_exp(&mut self, location: Location) -> ir::Expression { match location { Location::InFrame { offset } => { ir::Expression::Memory( Box::new( ir::Expression::BinOp( ir::BinOp::Plus, Box::new(ir::Expression::Const(self.offset)), Box::new(ir::Expression::Const(offset as u64)), ) ) ) } Location::Register(name) => { ir::Expression::Temp(name) } } } }