diff --git a/src/Ast.hs b/src/Ast.hs index d948e32..7bc2ba1 100644 --- a/src/Ast.hs +++ b/src/Ast.hs @@ -278,7 +278,7 @@ typeCheckStatement (Block statements) symtab classes = If {} -> (accSts ++ [checkedStmt], currentSymtab, if stmtType /= "Void" then types ++ [stmtType] else types) While _ _ -> (accSts ++ [checkedStmt], currentSymtab, if stmtType /= "Void" then types ++ [stmtType] else types) - Return _ -> (accSts ++ [checkedStmt], currentSymtab, if stmtType /= "Void" then types ++ [stmtType]) + Return _ -> (accSts ++ [checkedStmt], currentSymtab, if stmtType /= "Void" then types ++ [stmtType] else types) _ -> (accSts ++ [checkedStmt], currentSymtab, types) -- Initial accumulator: empty statements list, initial symbol table, empty types list @@ -290,8 +290,16 @@ typeCheckStatement (Block statements) symtab classes = in TypedStatement blockType (Block checkedStatements) typeCheckStatement (LocalVariableDeclaration (VariableDeclaration dataType identifier maybeExpr)) symtab classes = - let checkedExpr = fmap (\expr -> typeCheckExpression expr symtab classes) maybeExpr - in TypedStatement dataType (LocalVariableDeclaration (VariableDeclaration dataType identifier checkedExpr)) + -- Check for redefinition in the current scope + if any ((== identifier) . snd) symtab + then error $ "Variable '" ++ identifier ++ "' is redefined in the same scope" + else + -- If there's an initializer expression, type check it + let checkedExpr = fmap (\expr -> typeCheckExpression expr symtab classes) maybeExpr + exprType = fmap getTypeFromExpr checkedExpr + in case exprType of + Just t | t /= dataType -> error $ "Type mismatch in declaration of '" ++ identifier ++ "': expected " ++ dataType ++ ", found " ++ t + _ -> TypedStatement dataType (LocalVariableDeclaration (VariableDeclaration dataType identifier checkedExpr)) typeCheckStatement (Return expr) symtab classes = let expr' = case expr of