summaryrefslogtreecommitdiff
path: root/src/semantic
diff options
context:
space:
mode:
authorDavid Li <li.davidm96@gmail.com>2017-11-28 19:46:49 -0500
committerDavid Li <li.davidm96@gmail.com>2017-11-28 19:46:49 -0500
commit84babea244bb8ef85c6b84fd63eeeedc85781c03 (patch)
treedc3a5c06e93731b4b4350e77d37a97743aa4476d /src/semantic
parent1d5ec57d4ee0695a2a3e2542939b091f51c00036 (diff)
Define how to represent functions in environment
Diffstat (limited to 'src/semantic')
-rw-r--r--src/semantic/analysis.rs89
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 {