@@ -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+
4386fn 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