summaryrefslogtreecommitdiff
path: root/src/semantic/analysis.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/semantic/analysis.rs')
-rw-r--r--src/semantic/analysis.rs37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs
index 8335719..0c8dfa3 100644
--- a/src/semantic/analysis.rs
+++ b/src/semantic/analysis.rs
@@ -9,7 +9,7 @@ use ::ast::{self, WithLocation};
use super::environment;
use super::frame;
use super::ir;
-use super::translate::{self, Expression, LevelRef, Translate};
+use super::translate::{self, Expression, Level, LevelRef, Translate};
use super::types::{self, Ty};
#[derive(Debug)]
@@ -88,9 +88,10 @@ fn trans_decl<'a, F: frame::Frame>(
level: LevelRef<F>,
venv: &mut VarEnvironment<'a, F>,
tenv: &mut TypeEnvironment<'a>,
- decl: &WithLocation<ast::Declaration>) -> Result<(translate::Expression, Ty)> {
+ decl: &WithLocation<ast::Declaration>) -> Result<VarValue<F>> {
match decl.declaration {
ast::DeclarationBody::Fun { ref ty, ref params, ref body } => {
+ let new_level = tr.make_level(level, params.iter().map(|_| frame::Escape::Yes));
let declared_ty = if let &Some(ref ty) = ty {
Some(ast::WithLocation::new(trans_ty(venv, tenv, &ty)?, ty.start, ty.end))
} else { None };
@@ -101,12 +102,13 @@ fn trans_decl<'a, F: frame::Frame>(
for param in params.iter() {
let arg_ty = trans_ty(&mut new_venv, &mut new_tenv, &param.ty)?;
arg_types.push(arg_ty.clone());
- // TODO:
- // new_venv.add_binding(param.name.value.clone(), arg_ty);
+ // TODO: don't assume args are in registers
+ new_venv.add_binding(param.name.value.clone(),
+ VarValue::Variable(unimplemented!(), arg_ty));
}
let (body_exp, body_ty) =
- trans_exp(tr, level, &mut new_venv, &mut new_tenv, &*body)?;
+ trans_exp(tr, new_level.clone(), &mut new_venv, &mut new_tenv, &*body)?;
if let Some(decl_ty) = declared_ty {
if &decl_ty.value != &body_ty {
@@ -117,8 +119,13 @@ fn trans_decl<'a, F: frame::Frame>(
}
}
- return err!(decl, TypeError::Unimplemented);
- // Ok(Ty::Function(arg_types, Box::new(body_ty)))
+ let label = new_level.borrow().to_exp();
+ Ok(VarValue::Function {
+ level: new_level,
+ label: label,
+ body: body_exp,
+ ty: Ty::Function(arg_types, Box::new(body_ty)),
+ })
}
ast::DeclarationBody::Ty { ref ty } => {
return err!(decl, TypeError::Unimplemented);
@@ -136,7 +143,9 @@ fn trans_decl<'a, F: frame::Frame>(
});
}
}
- Ok((tr.alloc_local(&mut level.borrow_mut(), frame::Escape::Yes), actual_ty))
+ Ok(VarValue::Variable(
+ tr.alloc_local(&mut level.borrow_mut(), frame::Escape::Yes),
+ actual_ty))
}
}
}
@@ -155,13 +164,14 @@ fn trans_exp<'a, F: frame::Frame>(
let mut new_venv = VarEnvironment::new(Some(venv));
let mut new_tenv = TypeEnvironment::new(Some(tenv));
for decl in decls.iter() {
- let (decl_exp, decl_ty) = trans_decl(tr, level.clone(), &mut new_venv, &mut new_tenv, decl)?;
match decl.declaration {
ast::DeclarationBody::Fun { .. } | ast::DeclarationBody::Var { .. } => {
- new_venv.add_binding(decl.name.clone(), VarValue::Variable(decl_exp, decl_ty));
+ let binding = trans_decl(tr, level.clone(), &mut new_venv, &mut new_tenv, decl)?;
+ new_venv.add_binding(decl.name.clone(), binding);
}
ast::DeclarationBody::Ty { .. } => {
- new_tenv.add_binding(decl.name.clone(), decl_ty);
+ unimplemented!();
+ // new_tenv.add_binding(decl.name.clone(), decl_ty);
}
}
}
@@ -200,7 +210,10 @@ fn trans_exp<'a, F: frame::Frame>(
})
}
}
- Ok((label.clone(), (**result).clone()))
+ Ok((
+ tr.call(label.clone(), arg_types.into_iter().map(|(a, b)| a)),
+ (**result).clone()
+ ))
},
otherwise => {
err!(exp, TypeError::Mismatch {