Skip to content

Commit 1ee453a

Browse files
committed
loop for implementation
1 parent 829325d commit 1ee453a

3 files changed

Lines changed: 96 additions & 26 deletions

File tree

src/interpreter/statement_execute.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,60 @@ pub fn execute(
7575
}
7676
}
7777

78+
Statement::For(var, expr, stmt) => {
79+
let coll = eval(*expr, &new_env)?;
80+
81+
match coll {
82+
// Lista de valores
83+
Expression::ListValue(items) => {
84+
new_env.push();
85+
for item in items {
86+
new_env.map_variable(var.clone(), true, item);
87+
new_env = execute(*stmt.clone(), &new_env)?;
88+
}
89+
new_env.pop();
90+
Ok(new_env)
91+
}
92+
93+
// String - itera sobre caracteres
94+
Expression::CString(s) => {
95+
new_env.push();
96+
for ch in s.chars() {
97+
let char_value = Expression::CString(ch.to_string());
98+
new_env.map_variable(var.clone(), true, char_value);
99+
new_env = execute(*stmt.clone(), &new_env)?;
100+
}
101+
new_env.pop();
102+
Ok(new_env)
103+
}
104+
105+
// Tupla (assumindo que você tem Expression::Tuple)
106+
Expression::Tuple(items) => {
107+
new_env.push();
108+
for item in items {
109+
new_env.map_variable(var.clone(), true, item);
110+
new_env = execute(*stmt.clone(), &new_env)?;
111+
}
112+
new_env.pop();
113+
Ok(new_env)
114+
}
115+
116+
// Constructor (já existia)
117+
Expression::Constructor(_, items) => {
118+
new_env.push();
119+
for item_expr in items {
120+
let item_value = *item_expr.clone();
121+
new_env.map_variable(var.clone(), true, item_value);
122+
new_env = execute(*stmt.clone(), &new_env)?;
123+
}
124+
new_env.pop();
125+
Ok(new_env)
126+
}
127+
128+
_ => Err((format!("Cannot iterate over {:?}", coll), None)),
129+
}
130+
}
131+
78132
Statement::Sequence(s1, s2) => {
79133
new_env = execute(*s1, &new_env)?;
80134
execute(*s2, &new_env)

src/ir/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,5 @@ pub enum Statement {
134134
FuncDef(Function),
135135
Return(Box<Expression>),
136136
TypeDeclaration(Name, Vec<ValueConstructor>),
137+
Tuple(Vec<Expression>)
137138
}

src/type_checker/statement_type_checker.rs

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
144166
fn 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

180195
fn check_func_def_stmt(

0 commit comments

Comments
 (0)