diff options
Diffstat (limited to 'src/semantic')
| -rw-r--r-- | src/semantic/analysis.rs | 26 | ||||
| -rw-r--r-- | src/semantic/translate.rs | 23 | 
2 files changed, 28 insertions, 21 deletions
diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs index c7acfc9..b7462a0 100644 --- a/src/semantic/analysis.rs +++ b/src/semantic/analysis.rs @@ -3,11 +3,13 @@  // License, v. 2.0. If a copy of the MPL was not distributed with this  // file, You can obtain one at http://mozilla.org/MPL/2.0/. +use std::rc::Rc; +  use ::ast::{self, WithLocation};  use super::environment;  use super::frame;  use super::ir; -use super::translate::{self, Expression, Level, Translate}; +use super::translate::{self, Expression, LevelRef, Translate};  use super::types::{self, Ty};  #[derive(Debug)] @@ -33,9 +35,9 @@ type VarEnvironment<'a> = environment::Environment<'a, String, VarValue>;  type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>;  pub type Result<T> = ::std::result::Result<T, WithLocation<TypeError>>; -pub fn translate<'a, F: frame::Frame>( +pub fn translate<F: frame::Frame>(      translate: &mut Translate<F>, -    level: &mut Level<'a, F>, +    level: LevelRef<F>,      program: &ast::Program)      -> Result<(translate::Expression, Ty)> {      let mut venv = VarEnvironment::new(None); @@ -76,9 +78,9 @@ fn trans_ty<'a>(      }  } -fn trans_decl<'a, 'b, F: frame::Frame>( +fn trans_decl<'a, F: frame::Frame>(      tr: &mut Translate<F>, -    level: &mut Level<'b, F>, +    level: LevelRef<F>,      venv: &mut VarEnvironment<'a>,      tenv: &mut TypeEnvironment<'a>,      decl: &WithLocation<ast::Declaration>) -> Result<(translate::Expression, Ty)> { @@ -119,7 +121,7 @@ fn trans_decl<'a, 'b, F: frame::Frame>(          }          ast::DeclarationBody::Var { ref ty, ref value } => {              let (var_exp, actual_ty) = -                trans_exp(tr, level, venv, tenv, &value)?; +                trans_exp(tr, level.clone(), venv, tenv, &value)?;              if let &Some(ref ty) = ty {                  let decl_ty = trans_ty(venv, tenv, &ty)?;                  if decl_ty != actual_ty { @@ -129,14 +131,14 @@ fn trans_decl<'a, 'b, F: frame::Frame>(                      });                  }              } -            Ok((tr.alloc_local(level, frame::Escape::Yes), actual_ty)) +            Ok((tr.alloc_local(&mut level.borrow_mut(), frame::Escape::Yes), actual_ty))          }      }  } -fn trans_exp<'a, 'b, F: frame::Frame>( +fn trans_exp<'a, F: frame::Frame>(      tr: &mut Translate<F>, -    level: &mut Level<'b, F>, +    level: LevelRef<F>,      venv: &mut VarEnvironment<'a>,      tenv: &mut TypeEnvironment<'a>,      exp: &WithLocation<ast::Expression>) @@ -148,7 +150,7 @@ fn trans_exp<'a, 'b, F: frame::Frame>(              let mut new_venv = VarEnvironment::new(Some(venv));              let mut new_tenv = TypeEnvironment::new(Some(tenv));              for decl in decls.iter() { -                let (decl_exp, decl_ty) = trans_decl(tr, level, &mut new_venv, &mut new_tenv, decl)?; +                let (decl_exp, decl_ty) = trans_decl(tr, level.clone(), &mut new_venv, &mut new_tenv, decl)?;                  match decl.declaration {                      ast::DeclarationBody::Fun { .. } | ast::DeclarationBody::Var { .. } => {                          new_venv.add_binding(decl.name.clone(), VarValue::Variable(decl_exp, decl_ty)); @@ -163,7 +165,7 @@ fn trans_exp<'a, 'b, F: frame::Frame>(          &Call(ref name, ref args) => {              let mut arg_types = vec![];              for arg in args { -                arg_types.push(trans_exp(tr, level, venv, tenv, arg)?); +                arg_types.push(trans_exp(tr, level.clone(), venv, tenv, arg)?);              }              let value = venv.lookup(name) @@ -234,7 +236,7 @@ fn trans_exp<'a, 'b, F: frame::Frame>(          },          &BinOp(ref op, ref left, ref right) => {              use ast::BinOp::*; -            let (left_exp, left_ty) = trans_exp(tr, level, venv, tenv, left)?; +            let (left_exp, left_ty) = trans_exp(tr, level.clone(), venv, tenv, left)?;              let (right_exp, right_ty) = trans_exp(tr, level, venv, tenv, right)?;              match op {                  &Add => { diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs index f802c3f..08e600f 100644 --- a/src/semantic/translate.rs +++ b/src/semantic/translate.rs @@ -1,3 +1,6 @@ +use std::cell::RefCell; +use std::rc::Rc; +  use super::frame;  use super::ir;  use super::temp; @@ -14,16 +17,18 @@ pub struct Translate<F> {      _frametype: ::std::marker::PhantomData<F>,  } -pub enum Level<'a, F> -    where F: 'a + frame::Frame { +pub enum Level<F> +    where F: frame::Frame {      Top,      Level { -        parent: &'a Level<'a, F>, +        parent: LevelRef<F>,          frame: F,          unique_id: usize,      },  } +pub type LevelRef<F> = Rc<RefCell<Level<F>>>; +  impl<F: frame::Frame> Translate<F> {      pub fn new() -> Translate<F> {          Translate { @@ -33,17 +38,17 @@ impl<F: frame::Frame> Translate<F> {          }      } -    pub fn make_level<'a>( +    pub fn make_level(          &mut self, -        parent: &'a Level<F>, -        formals: Vec<frame::Escape>) -> Level<'a, F> { +        parent: LevelRef<F>, +        formals: Vec<frame::Escape>) -> LevelRef<F> {          let id = self.level_counter;          self.level_counter += 1; -        Level::Level { +        Rc::new(RefCell::new(Level::Level {              parent: parent,              frame: F::new(self.temp.next_label(), formals),              unique_id: id, -        } +        }))      }      pub fn make_num(&mut self, num: u64) -> Expression { @@ -61,7 +66,7 @@ impl<F: frame::Frame> Translate<F> {      }      pub fn alloc_local<'a>(&mut self, -                           level: &mut Level<'a, F>, +                           level: &mut Level<F>,                             escapes: frame::Escape) -> Expression {          match level {              &mut Level::Top => {  | 
