Skip to content

Commit 630ca36

Browse files
committed
Correção da implementação no TypeChecker
Adicionada a função auxiliar check_block para validar blocos com escopo. Refatorada check_test_function_stmt para usar check_block, corrigir ownership e utilizar lookup_test/map_test. Criada suíte de testes unitários cobrindo casos válidos e inválidos para TestDef.
1 parent d64cf50 commit 630ca36

1 file changed

Lines changed: 59 additions & 17 deletions

File tree

src/type_checker/statement_type_checker.rs

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,25 @@ pub fn check_stmt(
3333
}
3434
}
3535

36+
pub fn check_block(
37+
stmt: Statement,
38+
env: &Environment<Type>,
39+
) -> Result<Environment<Type>, ErrorMessage> {
40+
match stmt {
41+
Statement::Block(stmts) => {
42+
let mut block_env = env.clone();
43+
block_env.push();
44+
45+
for s in stmts {
46+
block_env = check_stmt(s, &block_env)?;
47+
}
48+
block_env.pop();
49+
Ok(block_env)
50+
}
51+
_ => Err("Expected a block statement".to_string()),
52+
}
53+
}
54+
3655
fn check_squence_stmt(
3756
stmt1: Box<Statement>,
3857
stmt2: Box<Statement>,
@@ -333,7 +352,7 @@ fn check_test_function_stmt(
333352
function: Function,
334353
env: &Environment<Type>,
335354
) -> Result<Environment<Type>, ErrorMessage> {
336-
if env.lookup_test(&function.name).is_some() {
355+
if env.lookup_test(&function.name).is_some() {
337356
return Err(format!("[Type Error] Test function '{}' already exists.", function.name));
338357
}
339358
if !function.params.is_empty() {
@@ -342,11 +361,8 @@ fn check_test_function_stmt(
342361
if function.kind != Type::TVoid {
343362
return Err("[Type Error] Test functions must return void.".into());
344363
}
345-
346-
if let Some(body) = function.body.clone() {
347-
let mut scoped_env = env.clone();
348-
scoped_env.push();
349-
check_stmt(*body, &scoped_env)?;
364+
if let Some(ref body) = function.body {
365+
check_block((**body).clone(), env)?;
350366
}
351367

352368
let mut final_env = env.clone();
@@ -979,25 +995,18 @@ mod tests {
979995
kind: Type::TVoid,
980996
params: vec![],
981997
body: Some(Box::new(Block(vec![
982-
// 1. Declaramos as variáveis localmente
983998
Statement::VarDeclaration("a".to_string(), Box::new(Expression::CInt(10))),
984999
Statement::VarDeclaration("b".to_string(), Box::new(Expression::CInt(5))),
985-
986-
// 2. Usamos AssertEQ para verificar o resultado
9871000
Statement::AssertEQ(
988-
// Expressão: a + b
9891001
Box::new(Expression::Add(
9901002
Box::new(Expression::Var("a".to_string())),
9911003
Box::new(Expression::Var("b".to_string()))
9921004
)),
993-
// Valor esperado: 15
9941005
Box::new(Expression::CInt(15)),
995-
// Mensagem de erro
996-
Box::new(Expression::CString("A soma de 10 + 5 deveria ser 15".to_string()))
1006+
Box::new(Expression::CString("A soma deveria ser 15".to_string()))
9971007
)
9981008
]))),
9991009
});
1000-
10011010
assert!(check_stmt(stmt, &env).is_ok());
10021011
}
10031012

@@ -1021,7 +1030,18 @@ mod tests {
10211030
name: "invalid_function".to_string(),
10221031
kind: Type::TInteger, // Must be TVoid!
10231032
params: vec![],
1024-
body: None,
1033+
body: Some(Box::new(Block(vec![
1034+
Statement::VarDeclaration("a".to_string(), Box::new(Expression::CInt(10))),
1035+
Statement::VarDeclaration("b".to_string(), Box::new(Expression::CInt(5))),
1036+
Statement::AssertEQ(
1037+
Box::new(Expression::Add(
1038+
Box::new(Expression::Var("a".to_string())),
1039+
Box::new(Expression::Var("b".to_string()))
1040+
)),
1041+
Box::new(Expression::CInt(15)),
1042+
Box::new(Expression::CString("A soma deveria ser 15".to_string()))
1043+
)
1044+
]))),
10251045
});
10261046

10271047
assert!(check_stmt(stmt, &env).is_err());
@@ -1034,7 +1054,18 @@ mod tests {
10341054
name: "duplicate".to_string(),
10351055
kind: Type::TVoid,
10361056
params: vec![],
1037-
body: None,
1057+
body: Some(Box::new(Block(vec![
1058+
Statement::VarDeclaration("a".to_string(), Box::new(Expression::CInt(10))),
1059+
Statement::VarDeclaration("b".to_string(), Box::new(Expression::CInt(5))),
1060+
Statement::AssertEQ(
1061+
Box::new(Expression::Add(
1062+
Box::new(Expression::Var("a".to_string())),
1063+
Box::new(Expression::Var("b".to_string()))
1064+
)),
1065+
Box::new(Expression::CInt(15)),
1066+
Box::new(Expression::CString("A soma deveria ser 15".to_string()))
1067+
)
1068+
]))),
10381069
});
10391070

10401071
env = check_stmt(first_func, &env).unwrap();
@@ -1043,7 +1074,18 @@ mod tests {
10431074
name: "duplicate".to_string(),
10441075
kind: Type::TVoid,
10451076
params: vec![],
1046-
body: None,
1077+
body: Some(Box::new(Block(vec![
1078+
Statement::VarDeclaration("a".to_string(), Box::new(Expression::CInt(10))),
1079+
Statement::VarDeclaration("b".to_string(), Box::new(Expression::CInt(5))),
1080+
Statement::AssertEQ(
1081+
Box::new(Expression::Add(
1082+
Box::new(Expression::Var("a".to_string())),
1083+
Box::new(Expression::Var("b".to_string()))
1084+
)),
1085+
Box::new(Expression::CInt(15)),
1086+
Box::new(Expression::CString("A soma deveria ser 15".to_string()))
1087+
)
1088+
]))),
10471089
});
10481090

10491091
assert!(check_stmt(stmt, &env).is_err());

0 commit comments

Comments
 (0)