From c8f4b4d23a55b73cc7d1aa7e4db4a37100c4116d Mon Sep 17 00:00:00 2001 From: David Li Date: Sun, 26 Nov 2017 19:33:36 -0500 Subject: Thread the current level through the program --- src/semantic/analysis.rs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src/semantic/analysis.rs') 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 = ::std::result::Result>; -pub fn translate( +pub fn translate<'a, F: frame::Frame>( translate: &mut Translate, + 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, + level: &mut Level<'b, F>, venv: &mut TypeEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, decl: &WithLocation) -> Result { @@ -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, + level: &mut Level<'b, F>, venv: &mut TypeEnvironment<'a>, tenv: &mut TypeEnvironment<'a>, exp: &WithLocation) @@ -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) { -- cgit v1.2.3