From 5a335165bd60c068875d75d313c66e8bccc47a86 Mon Sep 17 00:00:00 2001 From: David Li Date: Tue, 28 Nov 2017 19:28:26 -0500 Subject: Distinguish between functions and values in environment --- src/semantic/analysis.rs | 80 +++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 31 deletions(-) diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs index 829e7c2..c7acfc9 100644 --- a/src/semantic/analysis.rs +++ b/src/semantic/analysis.rs @@ -24,7 +24,12 @@ pub enum TypeError { UnboundName, } -type VarEnvironment<'a> = environment::Environment<'a, String, (Expression, Ty)>; +enum VarValue { + Function, + Variable(Expression, Ty), +} + +type VarEnvironment<'a> = environment::Environment<'a, String, VarValue>; type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>; pub type Result = ::std::result::Result>; @@ -146,7 +151,7 @@ fn trans_exp<'a, 'b, F: frame::Frame>( let (decl_exp, 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_exp, decl_ty)); + new_venv.add_binding(decl.name.clone(), VarValue::Variable(decl_exp, decl_ty)); } ast::DeclarationBody::Ty { .. } => { new_tenv.add_binding(decl.name.clone(), decl_ty); @@ -161,37 +166,46 @@ fn trans_exp<'a, 'b, F: frame::Frame>( arg_types.push(trans_exp(tr, level, venv, tenv, arg)?); } - let &(ref fun_exp, ref fun_ty) = venv.lookup(name) + let value = venv.lookup(name) .ok_or(WithLocation::new(TypeError::UnboundName, exp.start, exp.end))?; - 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(), - }) - } - } + 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::Variable(..) => { 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(), - }) } } }, @@ -259,10 +273,14 @@ fn trans_exp<'a, 'b, F: frame::Frame>( &String(_) => err!(exp, TypeError::Unimplemented), // &String(_) => Ok(Ty::String), &Name(ref name) => { - if let Some(&(ref exp, ref ty)) = venv.lookup(name) { + let result = venv.lookup(name); + if let Some(&VarValue::Variable(ref exp, ref ty)) = result { // TODO: clone might be expensive, Rc? Ok((exp.clone(), ty.clone())) } + else if let Some(&VarValue::Function) = result { + err!(exp, TypeError::Unimplemented) + } else { err!(exp, TypeError::UnboundName) } -- cgit v1.2.3