Skip to content

Commit 31bf3ac

Browse files
Update statement_type_checker.rs
1 parent f5d8110 commit 31bf3ac

1 file changed

Lines changed: 152 additions & 0 deletions

File tree

src/type_checker/statement_type_checker.rs

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ pub fn check_stmt(
2121
Statement::FuncDef(function) => check_func_def_stmt(function, env),
2222
Statement::TypeDeclaration(name, cons) => check_adt_declarations_stmt(name, cons, env),
2323
Statement::Return(exp) => check_return_stmt(exp, env),
24+
25+
Statement::Assert(expr1, expr2) => check_assert(expr1, expr2, env),
26+
Statement::AssertTrue(expr, _) => check_assert_true(expr, env),
27+
Statement::AssertFalse(expr, _) => check_assert_false(expr, env),
28+
Statement::AssertEQ(lhs, rhs, _) => check_assert_eq(lhs, rhs, env),
29+
Statement::AssertNEQ(lhs, rhs, _) => check_assert_neq(lhs, rhs, env),
30+
2431
_ => Err("Not implemented yet".to_string()),
2532
}
2633
}
@@ -230,6 +237,71 @@ fn check_return_stmt(
230237
}
231238
}
232239

240+
241+
fn check_assert(
242+
expr1: Box<Expression>,
243+
expr2: Box<Expression>,
244+
env: &Environment<Type>,
245+
) -> Result<Environment<Type>, ErrorMessage> {
246+
let type1 = check_expr(*expr1, env)?;
247+
let type2 = check_expr(*expr2, env)?;
248+
249+
if type1 != Type::TBool {
250+
Err("[Type Error] First Assert expression must be of type Boolean.".to_string())
251+
} else if type2 != Type::TString {
252+
Err("[Type Error] Second Assert expression must be of type CString.".to_string())
253+
} else {
254+
Ok(env.clone())
255+
}
256+
}
257+
258+
259+
fn check_assert_true(expr: Box<Expression>, env: &Environment<Type>) -> Result<Environment<Type>, ErrorMessage> {
260+
let expr_type = check_expr(*expr, env)?;
261+
if expr_type != Type::TBool {
262+
Err("[Type Error] AssertTrue expression must be of type Boolean.".to_string())
263+
} else {
264+
Ok(env.clone())
265+
}
266+
}
267+
268+
fn check_assert_false(expr: Box<Expression>, env: &Environment<Type>) -> Result<Environment<Type>, ErrorMessage> {
269+
let expr_type = check_expr(*expr, env)?;
270+
if expr_type != Type::TBool {
271+
Err("[Type Error] AssertFalse expression must be of type Boolean.".to_string())
272+
} else {
273+
Ok(env.clone())
274+
}
275+
}
276+
277+
fn check_assert_eq(lhs: Box<Expression>, rhs: Box<Expression>, env: &Environment<Type>) -> Result<Environment<Type>, ErrorMessage> {
278+
let lhs_type = check_expr(*lhs, env)?;
279+
let rhs_type = check_expr(*rhs, env)?;
280+
if lhs_type != rhs_type {
281+
Err(format!(
282+
"[Type Error] AssertEQ expressions must have the same type. Found {:?} and {:?}.",
283+
lhs_type, rhs_type
284+
))
285+
} else {
286+
Ok(env.clone())
287+
}
288+
}
289+
290+
fn check_assert_neq(lhs: Box<Expression>, rhs: Box<Expression>, env: &Environment<Type>) -> Result<Environment<Type>, ErrorMessage> {
291+
let lhs_type = check_expr(*lhs, env)?;
292+
let rhs_type = check_expr(*rhs, env)?;
293+
if lhs_type != rhs_type {
294+
Err(format!(
295+
"[Type Error] AssertNEQ expressions must have the same type. Found {:?} and {:?}.",
296+
lhs_type, rhs_type
297+
))
298+
} else {
299+
Ok(env.clone())
300+
}
301+
}
302+
303+
304+
233305
fn merge_environments(
234306
env1: &Environment<Type>,
235307
env2: &Environment<Type>,
@@ -658,4 +730,84 @@ mod tests {
658730
// TODO: Let discuss this case here next class.
659731
assert!(check_stmt(stmt, &env).is_err());
660732
}
733+
734+
#[test]
735+
fn test_assert_bool_ok() {
736+
let env: Environment<Type> = Environment::new();
737+
let stmt = Statement::Assert(
738+
Box::new(Expression::CTrue),
739+
Box::new(Expression::CString("msg".to_string())),
740+
);
741+
assert!(check_stmt(stmt, &env).is_ok());
742+
}
743+
744+
#[test]
745+
fn test_assert_bool_error() {
746+
let env: Environment<Type> = Environment::new();
747+
let stmt = Statement::Assert(
748+
Box::new(Expression::CInt(1)), // não booleano
749+
Box::new(Expression::CTrue), // segundo argumento pode ser qualquer um válido
750+
);
751+
assert!(check_stmt(stmt, &env).is_err());
752+
}
753+
754+
#[test]
755+
fn test_assert_true_ok() {
756+
let env = Environment::new();
757+
let stmt = Statement::AssertTrue(Box::new(Expression::CTrue), "ok".to_string());
758+
assert!(check_stmt(stmt, &env).is_ok());
759+
}
760+
761+
#[test]
762+
fn test_assert_false_ok() {
763+
let env = Environment::new();
764+
let stmt = Statement::AssertFalse(Box::new(Expression::CFalse), "false".to_string());
765+
assert!(check_stmt(stmt, &env).is_ok());
766+
}
767+
768+
#[test]
769+
fn test_assert_eq_same_type() {
770+
let env = Environment::new();
771+
let stmt = Statement::AssertEQ(
772+
Box::new(Expression::CInt(1)),
773+
Box::new(Expression::CInt(2)),
774+
"eq".to_string(),
775+
);
776+
assert!(check_stmt(stmt, &env).is_ok());
777+
}
778+
779+
#[test]
780+
fn test_assert_eq_mismatch_type() {
781+
let env = Environment::new();
782+
let stmt = Statement::AssertEQ(
783+
Box::new(Expression::CInt(1)),
784+
Box::new(Expression::CString("x".to_string())),
785+
"eq".to_string(),
786+
);
787+
assert!(check_stmt(stmt, &env).is_err());
788+
}
789+
790+
#[test]
791+
fn test_assert_neq_same_type() {
792+
let env = Environment::new();
793+
let stmt = Statement::AssertNEQ(
794+
Box::new(Expression::CInt(1)),
795+
Box::new(Expression::CInt(2)),
796+
"neq".to_string(),
797+
);
798+
assert!(check_stmt(stmt, &env).is_ok());
799+
}
800+
801+
#[test]
802+
fn test_assert_neq_mismatch_type() {
803+
let env = Environment::new();
804+
let stmt = Statement::AssertNEQ(
805+
Box::new(Expression::CTrue),
806+
Box::new(Expression::CString("x".to_string())),
807+
"neq".to_string(),
808+
);
809+
assert!(check_stmt(stmt, &env).is_err());
810+
}
811+
812+
661813
}

0 commit comments

Comments
 (0)