diff options
author | David Li <li.davidm96@gmail.com> | 2017-11-26 19:33:36 -0500 |
---|---|---|
committer | David Li <li.davidm96@gmail.com> | 2017-11-26 19:33:36 -0500 |
commit | c8f4b4d23a55b73cc7d1aa7e4db4a37100c4116d (patch) | |
tree | f311d25e328914fa12531309d0b93f259bf222f8 /src/semantic | |
parent | 376a1217a63291fb6714430b1a4dfd64909906c9 (diff) |
Thread the current level through the program
Diffstat (limited to 'src/semantic')
-rw-r--r-- | src/semantic/analysis.rs | 30 | ||||
-rw-r--r-- | src/semantic/translate.rs | 5 |
2 files changed, 20 insertions, 15 deletions
diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs index 09832c4..4c936f3 100644 --- a/src/semantic/analysis.rs +++ b/src/semantic/analysis.rs @@ -6,7 +6,8 @@ use ::ast::{self, WithLocation}; use super::environment; use super::frame; -use super::translate::{self, Translate}; +use super::ir; +use super::translate::{self, Level, Translate}; use super::types::{self, Ty}; #[derive(Debug)] @@ -26,15 +27,16 @@ pub enum TypeError { type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>; pub type Result<T> = ::std::result::Result<T, WithLocation<TypeError>>; -pub fn translate<F: frame::Frame>( +pub fn translate<'a, F: frame::Frame>( translate: &mut Translate<F>, + level: &mut Level<'a, F>, program: &ast::Program) -> Result<(translate::Expression, Ty)> { let mut venv = TypeEnvironment::new(None); let mut tenv = TypeEnvironment::new(None); tenv.add_binding("int".into(), Ty::Int); tenv.add_binding("string".into(), Ty::String); - trans_exp(translate, &mut venv, &mut tenv, &*program.0) + trans_exp(translate, level, &mut venv, &mut tenv, &*program.0) } macro_rules! err { @@ -68,8 +70,9 @@ fn trans_ty<'a>( } } -fn trans_decl<'a, F: frame::Frame>( +fn trans_decl<'a, 'b, F: frame::Frame>( tr: &mut Translate<F>, + level: &mut Level<'b, F>, venv: &mut TypeEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, decl: &WithLocation<ast::Declaration>) -> Result<Ty> { @@ -89,7 +92,7 @@ fn trans_decl<'a, F: frame::Frame>( } let (body_exp, body_ty) = - trans_exp(tr, &mut new_venv, &mut new_tenv, &*body)?; + trans_exp(tr, level, &mut new_venv, &mut new_tenv, &*body)?; if let Some(decl_ty) = declared_ty { if &decl_ty.value != &body_ty { @@ -107,7 +110,7 @@ fn trans_decl<'a, F: frame::Frame>( } ast::DeclarationBody::Var { ref ty, ref value } => { let (var_exp, actual_ty) = - trans_exp(tr, venv, tenv, &value)?; + trans_exp(tr, level, venv, tenv, &value)?; if let &Some(ref ty) = ty { let decl_ty = trans_ty(venv, tenv, &ty)?; if decl_ty != actual_ty { @@ -122,8 +125,9 @@ fn trans_decl<'a, F: frame::Frame>( } } -fn trans_exp<'a, F: frame::Frame>( +fn trans_exp<'a, 'b, F: frame::Frame>( tr: &mut Translate<F>, + level: &mut Level<'b, F>, venv: &mut TypeEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, exp: &WithLocation<ast::Expression>) @@ -135,7 +139,7 @@ fn trans_exp<'a, 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, &mut new_venv, &mut new_tenv, decl)?; + let 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); @@ -145,12 +149,12 @@ fn trans_exp<'a, F: frame::Frame>( } } } - trans_exp(tr, &mut new_venv, &mut new_tenv, &*body) + trans_exp(tr, level, &mut new_venv, &mut new_tenv, &*body) }, &Call(ref name, ref args) => { let mut arg_types = vec![]; for arg in args { - arg_types.push(trans_exp(tr, venv, tenv, arg)?); + arg_types.push(trans_exp(tr, level, venv, tenv, arg)?); } let fun_ty = venv.lookup(name) @@ -189,7 +193,7 @@ fn trans_exp<'a, F: frame::Frame>( }, &UnaryOp(ref op, ref operand) => { use ast::UnaryOp::*; - let (operand_exp, operand_ty) = trans_exp(tr, venv, tenv, operand)?; + let (operand_exp, operand_ty) = trans_exp(tr, level, venv, tenv, operand)?; match op { &Neg | &Pos => { match operand_ty { @@ -212,8 +216,8 @@ fn trans_exp<'a, F: frame::Frame>( }, &BinOp(ref op, ref left, ref right) => { use ast::BinOp::*; - let (left_exp, left_ty) = trans_exp(tr, venv, tenv, left)?; - let (right_exp, right_ty) = trans_exp(tr, venv, tenv, right)?; + let (left_exp, left_ty) = trans_exp(tr, level, venv, tenv, left)?; + let (right_exp, right_ty) = trans_exp(tr, level, venv, tenv, right)?; match op { &Add => { match (left_ty, right_ty) { diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs index bcbad3a..4a2b6c5 100644 --- a/src/semantic/translate.rs +++ b/src/semantic/translate.rs @@ -9,6 +9,7 @@ pub enum Expression { } pub struct Translate<F> { + pub temp: temp::Temp, level_counter: usize, _frametype: ::std::marker::PhantomData<F>, } @@ -26,6 +27,7 @@ pub enum Level<'a, F> impl<F: frame::Frame> Translate<F> { pub fn new() -> Translate<F> { Translate { + temp: temp::Temp::new(), level_counter: 0, _frametype: ::std::marker::PhantomData, } @@ -34,13 +36,12 @@ impl<F: frame::Frame> Translate<F> { pub fn make_level<'a>( &mut self, parent: &'a Level<F>, - name: temp::TempLabel, formals: Vec<frame::Escape>) -> Level<'a, F> { let id = self.level_counter; self.level_counter += 1; Level::Level { parent: parent, - frame: F::new(name, formals), + frame: F::new(self.temp.next_label(), formals), unique_id: id, } } |