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(-)
(limited to 'src')
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