Skip to content

Commit d28184c

Browse files
committed
Implementação e Testes de DefTest no TypeChecker
1 parent b6f55e6 commit d28184c

1 file changed

Lines changed: 92 additions & 1 deletion

File tree

src/type_checker/statement_type_checker.rs

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub fn check_stmt(
2727
Statement::AssertFalse(expr1, errmsg) => check_assert_false(expr1, errmsg, env),
2828
Statement::AssertEQ(lhs, rhs, errmsg) => check_assert_eq(lhs, rhs, errmsg, env),
2929
Statement::AssertNEQ(lhs, rhs, errmsg) => check_assert_neq(lhs, rhs, errmsg, env),
30+
Statement::TestDef(function) => check_test_function_stmt(function, env),
3031

3132
_ => Err("Not implemented yet".to_string()),
3233
}
@@ -328,6 +329,34 @@ fn check_assert_neq(
328329
}
329330
}
330331

332+
fn check_test_function_stmt(
333+
function: Function,
334+
env: &Environment<Type>,
335+
) -> Result<Environment<Type>, ErrorMessage> {
336+
if env.lookup_function(&function.name).is_some() {
337+
return Err(format!("[Type Error] Test function '{}' already exists", function.name));
338+
}
339+
if !function.params.is_empty() {
340+
return Err("[Type Error] Test functions must not have parameters".into());
341+
}
342+
if function.kind != Type::TVoid {
343+
return Err("[Type Error] Test functions must return void".into());
344+
}
345+
346+
let mut new_env = env.clone();
347+
new_env.push();
348+
349+
if let Some(body) = function.body.clone() {
350+
new_env = check_stmt(*body, &new_env)?;
351+
}
352+
353+
new_env.pop();
354+
355+
let mut final_env = env.clone();
356+
final_env.map_function(function);
357+
Ok(final_env)
358+
}
359+
331360
fn merge_environments(
332361
env1: &Environment<Type>,
333362
env2: &Environment<Type>,
@@ -365,7 +394,7 @@ fn merge_environments(
365394
}
366395
}
367396
}
368-
397+
369398
//TODO: should we merge ADTs and functions?
370399

371400
Ok(merged)
@@ -944,4 +973,66 @@ mod tests {
944973
);
945974
assert!(check_stmt(stmt, &env).is_ok());
946975
}
976+
977+
#[test]
978+
fn test_check_valid_test_function() {
979+
let env: Environment<Type> = Environment::new();
980+
let stmt = TestDef(Function {
981+
name: "valid_function".to_string(),
982+
kind: Type::TVoid,
983+
params: vec![],
984+
body: None,
985+
});
986+
987+
assert!(check_stmt(stmt, &env).is_ok());
988+
}
989+
990+
#[test]
991+
fn test_check_test_function_with_params() {
992+
let env: Environment<Type> = Environment::new();
993+
let stmt = TestDef(Function {
994+
name: "invalid_function".to_string(),
995+
kind: Type::TVoid,
996+
params: vec![FormalArgument::new("param".to_string(), Type::TString)], // Must have no parameters
997+
body: None,
998+
});
999+
1000+
assert!(check_stmt(stmt, &env).is_err());
1001+
}
1002+
1003+
#[test]
1004+
fn test_check_test_function_with_non_void_return() {
1005+
let env: Environment<Type> = Environment::new();
1006+
let stmt = TestDef(Function {
1007+
name: "invalid_function".to_string(),
1008+
kind: Type::TInteger, // Must be TVoid!
1009+
params: vec![],
1010+
body: None,
1011+
});
1012+
1013+
assert!(check_stmt(stmt, &env).is_err());
1014+
}
1015+
1016+
#[test]
1017+
fn test_check_duplicate_test_function() {
1018+
let mut env: Environment<Type> = Environment::new();
1019+
let first_func = TestDef(Function {
1020+
name: "duplicate".to_string(),
1021+
kind: Type::TVoid,
1022+
params: vec![],
1023+
body: None,
1024+
});
1025+
1026+
env = check_stmt(first_func, &env).unwrap();
1027+
1028+
let stmt = TestDef(Function {
1029+
name: "duplicate".to_string(),
1030+
kind: Type::TVoid,
1031+
params: vec![],
1032+
body: None,
1033+
});
1034+
1035+
assert!(check_stmt(stmt, &env).is_err());
1036+
}
1037+
9471038
}

0 commit comments

Comments
 (0)