From 01daee374a299646c595dd245c8e4a4990769002 Mon Sep 17 00:00:00 2001 From: David Li Date: Sun, 26 Nov 2017 19:59:00 -0500 Subject: Translate variable bindings --- src/semantic/analysis.rs | 12 +++++++----- src/semantic/frame.rs | 33 +++++++++++++++++++++++++++++---- src/semantic/translate.rs | 14 ++++++++++++++ 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs index 973e703..152ede9 100644 --- a/src/semantic/analysis.rs +++ b/src/semantic/analysis.rs @@ -75,7 +75,7 @@ fn trans_decl<'a, 'b, F: frame::Frame>( level: &mut Level<'b, F>, venv: &mut TypeEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, - decl: &WithLocation) -> Result { + decl: &WithLocation) -> Result<(translate::Expression, Ty)> { match decl.declaration { ast::DeclarationBody::Fun { ref ty, ref params, ref body } => { let declared_ty = if let &Some(ref ty) = ty { @@ -103,10 +103,12 @@ fn trans_decl<'a, 'b, F: frame::Frame>( } } - Ok(Ty::Function(arg_types, Box::new(body_ty))) + return err!(decl, TypeError::Unimplemented); + // Ok(Ty::Function(arg_types, Box::new(body_ty))) } ast::DeclarationBody::Ty { ref ty } => { - trans_ty(venv, tenv, ty) + return err!(decl, TypeError::Unimplemented); + // trans_ty(venv, tenv, ty) } ast::DeclarationBody::Var { ref ty, ref value } => { let (var_exp, actual_ty) = @@ -120,7 +122,7 @@ fn trans_decl<'a, 'b, F: frame::Frame>( }); } } - Ok(actual_ty) + Ok((tr.alloc_local(level, frame::Escape::Yes), actual_ty)) } } } @@ -139,7 +141,7 @@ fn trans_exp<'a, 'b, F: frame::Frame>( let mut new_venv = TypeEnvironment::new(Some(venv)); let mut new_tenv = TypeEnvironment::new(Some(tenv)); for decl in decls.iter() { - let decl_ty = trans_decl(tr, level, &mut new_venv, &mut new_tenv, decl)?; + let (decl_exp, decl_ty) = trans_decl(tr, level, &mut new_venv, &mut new_tenv, decl)?; match decl.declaration { ast::DeclarationBody::Fun { .. } | ast::DeclarationBody::Var { .. } => { new_venv.add_binding(decl.name.clone(), decl_ty); diff --git a/src/semantic/frame.rs b/src/semantic/frame.rs index ddfc330..95d18a1 100644 --- a/src/semantic/frame.rs +++ b/src/semantic/frame.rs @@ -1,3 +1,4 @@ +use super::ir; use super::temp; pub enum Location { @@ -16,17 +17,20 @@ 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, escapes: Escape) -> 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 { - name, + offset: 0, + name: name, } } @@ -38,7 +42,28 @@ impl Frame for Amd64Frame { unimplemented!(); } - fn alloc_local(&mut self, escapes: Escape) -> 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) + } + } + } } diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs index 57581a4..5e68f36 100644 --- a/src/semantic/translate.rs +++ b/src/semantic/translate.rs @@ -59,4 +59,18 @@ impl Translate { _ => panic!("Can't make binop from Void"), } } + + pub fn alloc_local<'a>(&mut self, + level: &mut Level<'a, F>, + escapes: frame::Escape) -> Expression { + match level { + &mut Level::Top => { + panic!("Can't allocate in toplevel frame") + }, + &mut Level::Level { parent: _, ref mut frame, .. } => { + let access = frame.alloc_local(&mut self.temp, escapes); + Expression::Exp(frame.location_to_exp(access)) + } + } + } } -- cgit v1.2.3