Skip to content

Commit 4827d06

Browse files
Implement type checker for function calls
1 parent 6bff283 commit 4827d06

1 file changed

Lines changed: 44 additions & 1 deletion

File tree

src/type_checker/expression_type_checker.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,54 @@ pub fn check_expr(exp: Expression, env: &Environment<Type>) -> Result<Type, Erro
3535
Expression::Propagate(e) => check_propagate_type(*e, env),
3636
Expression::ListValue(elements) => check_list_value(&elements, env),
3737
Expression::Constructor(name, args) => check_adt_constructor(name, args, env),
38-
38+
Expression::FuncCall(func_name, exp_vec) => check_func_call(func_name.clone(), exp_vec.clone(), env),
39+
3940
_ => Err("not implemented yet.".to_string()),
4041
}
4142
}
4243

44+
45+
fn check_func_call(
46+
func_name: Name,
47+
exp_vector: Vec<Expression>,
48+
env: &Environment<Type>,
49+
) -> Result<Type, ErrorMessage> {
50+
let func = env.lookup_function(&func_name);
51+
if func.is_none() {
52+
return Err(format!(
53+
"Function {} was called but never declared",
54+
func_name
55+
));
56+
}
57+
let func = func.unwrap();
58+
if func.params.len() != exp_vector.len() {
59+
return Err(format!(
60+
"Function {} receives {} arguments, but {} were given",
61+
func_name,
62+
func.params.len(),
63+
exp_vector.len()
64+
));
65+
}
66+
let mut formal_arg_types = Vec::new();
67+
let mut actual_arg_types = Vec::new();
68+
for (param, arg) in func.params.iter().zip(exp_vector.iter()) {
69+
formal_arg_types.push(param.argument_type.clone());
70+
let arg_type = check_expr(arg.clone(), env)?;
71+
actual_arg_types.push(arg_type);
72+
}
73+
for (formal_type, actual_type) in formal_arg_types.iter().zip(actual_arg_types.iter()) {
74+
if formal_type != actual_type {
75+
return Err(format!(
76+
"Mismatched types in function {} call \n
77+
Expected:{:?}\n
78+
Received: {:?}",
79+
func_name, formal_arg_types, actual_arg_types
80+
));
81+
}
82+
}
83+
return Ok(func.kind.clone());
84+
}
85+
4386
fn check_var_name(name: Name, env: &Environment<Type>) -> Result<Type, ErrorMessage> {
4487
match env.lookup(&name) {
4588
Some((_, t)) => Ok(t.clone()),

0 commit comments

Comments
 (0)