diff options
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,          }      }  | 
