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