@@ -141,40 +141,55 @@ fn check_while_stmt(
141141 Ok ( new_env)
142142}
143143
144+ // Função auxiliar para determinar o tipo do elemento iterável
145+ fn get_iterable_element_type ( expr_type : & Type ) -> Result < Type , ErrorMessage > {
146+ match expr_type {
147+ Type :: TList ( base_type) => Ok ( ( * * base_type) . clone ( ) ) ,
148+ Type :: TString => Ok ( Type :: TString ) , // Caracteres como strings
149+ Type :: TTuple ( types) => {
150+ if types. is_empty ( ) {
151+ return Err ( "[Type Error] Cannot iterate over empty tuple type" . to_string ( ) ) ;
152+ }
153+
154+ // Verificar se todos os tipos são iguais (tupla homogênea)
155+ let first_type = & types[ 0 ] ;
156+ if types. iter ( ) . all ( |t| t == first_type) {
157+ Ok ( first_type. clone ( ) )
158+ } else {
159+ Err ( "[Type Error] Can only iterate over homogeneous tuples (all elements same type)" . to_string ( ) )
160+ }
161+ }
162+ _ => Err ( format ! ( "[Type Error] Type {:?} is not iterable" , expr_type) )
163+ }
164+ }
165+
144166fn check_for_stmt (
145167 var : Name ,
146168 expr : Box < Expression > ,
147169 stmt : Box < Statement > ,
148170 env : & Environment < Type > ,
149171) -> Result < Environment < Type > , ErrorMessage > {
150172 let mut new_env = env. clone ( ) ;
151- let _var_type = env. lookup ( & var) ;
173+
174+ // Avaliar o tipo da expressão iterável
152175 let expr_type = check_expr ( * expr, & new_env) ?;
153- match expr_type {
154- Type :: TList ( base_type) => {
155- if let Some ( ( _, t) ) = env. lookup ( & var) {
156- if t == * base_type || * base_type == Type :: TAny {
157- new_env = check_stmt ( * stmt, & new_env) ?;
158- return Ok ( new_env) ;
159- } else {
160- return Err ( format ! (
161- "[TypeError] Type mismatch between {:?} and {:?}" ,
162- t, base_type
163- ) ) ;
164- }
165- } else {
166- new_env. map_variable ( var. clone ( ) , false , * base_type) ;
167- new_env = check_stmt ( * stmt, & new_env) ?;
168- return Ok ( new_env) ;
169- }
170- }
171- _ => {
172- return Err ( format ! (
173- "[TypeError] Expecting a List type, but found a {:?}" ,
174- expr_type
175- ) )
176- }
177- }
176+
177+ // Determinar o tipo do elemento
178+ let element_type = get_iterable_element_type ( & expr_type) ?;
179+
180+ // Criar novo escopo para o loop
181+ new_env. push ( ) ;
182+
183+ // Mapear a variável iteradora no novo escopo
184+ new_env. map_variable ( var. clone ( ) , false , element_type) ;
185+
186+ // Verificar o corpo do loop no novo escopo
187+ new_env = check_stmt ( * stmt, & new_env) ?;
188+
189+ // Remover o escopo do loop
190+ new_env. pop ( ) ;
191+
192+ Ok ( new_env)
178193}
179194
180195fn check_func_def_stmt (
0 commit comments