diff options
-rw-r--r-- | src/semantic/analysis.rs | 89 |
1 files changed, 48 insertions, 41 deletions
diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs index b7462a0..8335719 100644 --- a/src/semantic/analysis.rs +++ b/src/semantic/analysis.rs @@ -26,12 +26,17 @@ pub enum TypeError { UnboundName, } -enum VarValue { - Function, +enum VarValue<F: frame::Frame> { + Function { + level: LevelRef<F>, + label: Expression, + body: Expression, + ty: Ty, + }, Variable(Expression, Ty), } -type VarEnvironment<'a> = environment::Environment<'a, String, VarValue>; +type VarEnvironment<'a, F> = environment::Environment<'a, String, VarValue<F>>; type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>; pub type Result<T> = ::std::result::Result<T, WithLocation<TypeError>>; @@ -53,8 +58,8 @@ macro_rules! err { } } -fn trans_ty<'a>( - venv: &mut VarEnvironment<'a>, +fn trans_ty<'a, F: frame::Frame>( + venv: &mut VarEnvironment<'a, F>, tenv: &mut TypeEnvironment<'a>, ty: &WithLocation<ast::Ty>) -> Result<Ty> { match ty.value { @@ -81,7 +86,7 @@ fn trans_ty<'a>( fn trans_decl<'a, F: frame::Frame>( tr: &mut Translate<F>, level: LevelRef<F>, - venv: &mut VarEnvironment<'a>, + venv: &mut VarEnvironment<'a, F>, tenv: &mut TypeEnvironment<'a>, decl: &WithLocation<ast::Declaration>) -> Result<(translate::Expression, Ty)> { match decl.declaration { @@ -139,7 +144,7 @@ fn trans_decl<'a, F: frame::Frame>( fn trans_exp<'a, F: frame::Frame>( tr: &mut Translate<F>, level: LevelRef<F>, - venv: &mut VarEnvironment<'a>, + venv: &mut VarEnvironment<'a, F>, tenv: &mut TypeEnvironment<'a>, exp: &WithLocation<ast::Expression>) -> Result<(translate::Expression, Ty)> { @@ -172,39 +177,41 @@ fn trans_exp<'a, F: frame::Frame>( .ok_or(WithLocation::new(TypeError::UnboundName, exp.start, exp.end))?; match value { - &VarValue::Function => { - // (ref fun_exp, ref fun_ty); - // match fun_ty { - // &Ty::Function(ref expected_args, ref result) => { - // if expected_args.len() != arg_types.len() { - // return err!(exp, TypeError::LengthMismatch { - // expected: expected_args.len(), - // actual: arg_types.len(), - // }); - // } - // for (i, (&(_, ref provided_ty), expected_ty)) in - // arg_types.iter().zip(expected_args).enumerate() { - // if provided_ty != expected_ty { - // return err!(args[i], TypeError::Mismatch { - // expected: expected_ty.clone(), - // actual: provided_ty.clone(), - // }) - // } - // } - // err!(exp, TypeError::Unimplemented) - // // Ok((**result).clone()) - // }, - // otherwise => { - // err!(exp, TypeError::Mismatch { - // // TODO: better way to handle this - // expected: Ty::Function( - // arg_types.into_iter().map(|v| v.1).collect(), - // Box::new(Ty::Nil)), - // actual: otherwise.clone(), - // }) - // } - // } - err!(exp, TypeError::Unimplemented) + &VarValue::Function { + level: ref level, + label: ref label, + body: ref fun_exp, + ty: ref fun_ty, + } => { + match fun_ty { + &Ty::Function(ref expected_args, ref result) => { + if expected_args.len() != arg_types.len() { + return err!(exp, TypeError::LengthMismatch { + expected: expected_args.len(), + actual: arg_types.len(), + }); + } + for (i, (&(_, ref provided_ty), expected_ty)) in + arg_types.iter().zip(expected_args).enumerate() { + if provided_ty != expected_ty { + return err!(args[i], TypeError::Mismatch { + expected: expected_ty.clone(), + actual: provided_ty.clone(), + }) + } + } + Ok((label.clone(), (**result).clone())) + }, + otherwise => { + err!(exp, TypeError::Mismatch { + // TODO: better way to handle this + expected: Ty::Function( + arg_types.into_iter().map(|v| v.1).collect(), + Box::new(Ty::Nil)), + actual: otherwise.clone(), + }) + } + } } &VarValue::Variable(..) => { err!(exp, TypeError::Unimplemented) @@ -280,7 +287,7 @@ fn trans_exp<'a, F: frame::Frame>( // TODO: clone might be expensive, Rc? Ok((exp.clone(), ty.clone())) } - else if let Some(&VarValue::Function) = result { + else if let Some(&VarValue::Function { .. }) = result { err!(exp, TypeError::Unimplemented) } else { |