Skip to content
Snippets Groups Projects
Commit 54da96ec authored by Per Lindgren's avatar Per Lindgren
Browse files

check call

parent 88413cd2
No related branches found
No related tags found
No related merge requests found
......@@ -47,7 +47,6 @@ pub struct Param {
pub id: Id,
pub ty: Type,
}
// pub bool, pub Id, pub Type);
#[derive(Debug, PartialEq)]
pub enum TypeDecl {
......
......@@ -98,43 +98,44 @@ fn expr_type(
// Err(format!("op {} rt {}", opt, rt))
// }
// }
// Call(s, args) => {
// trace!("call {} with {}", s, args);
// let argt: Vec<Type> = args
// .clone()
// .0
// .into_iter()
// .map(|e| expr_type(&*e, fn_env, type_env, var_env))
// .collect::<Result<_, _>>()?;
// trace!("arg types {:?}", argt);
// let f = match fn_env.get(s.as_str()) {
// Some(f) => f,
// None => Err(format!("{} not found", s))?,
// };
// let part: Vec<Type> = (f.params.0.clone())
// .into_iter()
// .map(|p| From::from(&p))
// .collect();
// trace!(
// "fn to call {} with params {} and types {:?}",
// f,
// f.params,
// part
// );
// if argt == part {
// Ok((false, f.result.clone()))
// } else {
// Err(format!(
// "arguments types {:?} does not match parameter types {:?}",
// argt, part
// ))
// }
// }
Call(s, args) => {
trace!("call {} with {}", s, args);
let arg_t: Vec<Type> = args
.clone()
.0
.into_iter()
.map(|e| expr_type(&*e, fn_env, type_env, var_env))
.collect::<Result<_, _>>()?;
trace!("arg types {:?}", arg_t);
let f = match fn_env.get(s.as_str()) {
Some(f) => f,
None => Err(format!("{} not found", s))?,
};
let par_t: Vec<Type> = (f.params.0.clone())
.into_iter()
.map(|p| From::from(&p))
.collect();
trace!(
"fn to call {} with params {} and types {:?}",
f,
f.params,
par_t
);
if arg_t == par_t {
Ok(f.result.clone())
} else {
Err(format!(
"arguments types {:?} does not match parameter types {:?}",
arg_t, par_t
))
}
}
Id(id) => match var_env.get(id.to_string()) {
Some(t) => Ok(t.clone()),
None => Err(format!("variable not found {}", id)),
......@@ -341,18 +342,27 @@ pub fn check(p: &Program) -> Result<(), Error> {
// build a scope for the arguments
let mut arg_ty = IdType::new();
for Param { is_mut, id, ty } in fd.params.0.iter() {
// TODO move is_mut to Type in parser
arg_ty.insert(id.to_owned(), ty.clone());
let ty = match *is_mut {
true => Type::Mut(Box::new(ty.clone())),
_ => ty.clone(),
};
arg_ty.insert(id.to_owned(), ty);
}
var_env.push_param_scope(arg_ty);
let stmt_type = check_stmts(&fd.body, &fn_env, &type_env, &mut var_env);
trace!("function id {}: {:?}", fd.id, stmt_type);
trace!("function id {}: {:?}", fd.id, &stmt_type);
if stmt_type? != fd.result {
Err(format!("return value does not match statements"))?;
let stmt_type = stmt_type?;
if stmt_type != fd.result {
Err(format!(
"return type {} does not match statements type {}",
fd.result, stmt_type
))?;
}
}
Ok(())
......
......@@ -53,7 +53,6 @@ impl VarEnv {
}
pub fn update(&mut self, id: String, ty: Type) -> Result<(), Error> {
use Type::*;
match self.get_mut(id.clone()) {
Some(ot) => match ot {
Type::Unknown => {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment