@@ -28,7 +28,7 @@ pub fn check_exp(exp: Expression, env: &Environment<Type>) -> Result<Type, Error
2828 Expression :: LT ( l, r) => check_bin_relational_expression ( * l, * r, env) ,
2929 Expression :: GTE ( l, r) => check_bin_relational_expression ( * l, * r, env) ,
3030 Expression :: LTE ( l, r) => check_bin_relational_expression ( * l, * r, env) ,
31- // Expression::Var(name) => check_var_name(name, env, false),
31+ Expression :: Var ( name) => check_var_name ( name, env, false ) ,
3232 Expression :: COk ( e) => check_result_ok ( * e, env) ,
3333 Expression :: CErr ( e) => check_result_err ( * e, env) ,
3434 Expression :: CJust ( e) => check_maybe_just ( * e, env) ,
@@ -256,37 +256,13 @@ pub fn check_stmt(
256256// Ok(())
257257// }
258258
259- // fn check_var_name(name: Name, env: &Environment<Type>, scoped: bool) -> Result<Type, ErrorMessage> {
260- // let mut curr_scope = env.scope_key();
261-
262- // loop {
263- // let frame = env.get_frame(curr_scope.clone());
264-
265- // match frame.variables.get(&name) {
266- // Some(kind) => {
267- // if scoped && curr_scope != env.scope_key() {
268- // return Err(format!(
269- // "[Local Name Error on '{}'] cannot access local variable '{}'.",
270- // env.scope_name(),
271- // name
272- // ));
273- // } else {
274- // return Ok(kind.clone());
275- // }
276- // }
277- // None => match &frame.parent_key {
278- // Some(parent) => curr_scope = parent.clone(),
279- // None => {
280- // return Err(format!(
281- // "[Name Error on '{}'] '{}' is not defined.",
282- // env.scope_name(),
283- // name
284- // ))
285- // }
286- // },
287- // }
288- // }
289- // }
259+ fn check_var_name ( name : Name , env : & Environment < Type > , scoped : bool ) -> Result < Type , ErrorMessage > {
260+ let var_type = env. lookup ( & name) ;
261+ match var_type {
262+ Some ( t) => Ok ( t. clone ( ) ) ,
263+ None => Err ( format ! ( "[Name Error] '{}' is not defined." , name) ) ,
264+ }
265+ }
290266
291267fn check_bin_arithmetic_expression (
292268 left : Expression ,
@@ -872,4 +848,64 @@ mod tests {
872848 // and later used consistently as an integer
873849 assert ! ( check_stmt( stmt, & env) . is_ok( ) ) ;
874850 }
851+
852+ #[ test]
853+ fn test_undefined_variable ( ) {
854+ let env = Environment :: new ( ) ;
855+ let exp = Expression :: Var ( "x" . to_string ( ) ) ;
856+
857+ // Should fail - x is not defined
858+ assert ! ( check_exp( exp, & env) . is_err( ) ) ;
859+ }
860+
861+ #[ test]
862+ fn test_defined_variable ( ) {
863+ let mut env = Environment :: new ( ) ;
864+ env. map_variable ( "x" . to_string ( ) , Type :: TInteger ) ;
865+ let exp = Expression :: Var ( "x" . to_string ( ) ) ;
866+
867+ // Should succeed and return integer type
868+ assert_eq ! ( check_exp( exp, & env) , Ok ( Type :: TInteger ) ) ;
869+ }
870+
871+ #[ test]
872+ fn test_variable_assignment ( ) {
873+ let env = Environment :: new ( ) ;
874+ let stmt = Statement :: Assignment (
875+ "x" . to_string ( ) ,
876+ Box :: new ( Expression :: CInt ( 42 ) )
877+ ) ;
878+
879+ // Should succeed and add x:integer to environment
880+ let new_env = check_stmt ( stmt, & env) . unwrap ( ) ;
881+ assert_eq ! ( new_env. lookup( & "x" . to_string( ) ) , Some ( & Type :: TInteger ) ) ;
882+ }
883+
884+ #[ test]
885+ fn test_variable_reassignment_same_type ( ) {
886+ let mut env = Environment :: new ( ) ;
887+ env. map_variable ( "x" . to_string ( ) , Type :: TInteger ) ;
888+
889+ let stmt = Statement :: Assignment (
890+ "x" . to_string ( ) ,
891+ Box :: new ( Expression :: CInt ( 100 ) )
892+ ) ;
893+
894+ // Should succeed - reassigning same type
895+ assert ! ( check_stmt( stmt, & env) . is_ok( ) ) ;
896+ }
897+
898+ #[ test]
899+ fn test_variable_reassignment_different_type ( ) {
900+ let mut env = Environment :: new ( ) ;
901+ env. map_variable ( "x" . to_string ( ) , Type :: TInteger ) ;
902+
903+ let stmt = Statement :: Assignment (
904+ "x" . to_string ( ) ,
905+ Box :: new ( Expression :: CString ( "hello" . to_string ( ) ) )
906+ ) ;
907+
908+ // Should fail - trying to reassign different type
909+ assert ! ( check_stmt( stmt, & env) . is_err( ) ) ;
910+ }
875911}
0 commit comments