Skip to content

Commit 62295e4

Browse files
committed
[feature] Implementation of the type checker for variables
1 parent e766eb3 commit 62295e4

1 file changed

Lines changed: 68 additions & 32 deletions

File tree

src/tc/type_checker.rs

Lines changed: 68 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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

291267
fn 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

Comments
 (0)