Repository: DesignLiquido/delegua (ts)

Issue:
Laço para cada só executa apenas uma vez se estiver dentro de outro laço
```js
var numeros = [1, 2, 3, 4]

para cada numero de numeros {
    para cada numero de numeros {
        escreva(numero)
    }
}

```

![Image](https://github.com/user-attachments/assets/94b3ec4d-4b6d-418d-8ace-ebb8e291bba8)

O resultado esperado era pra ser
```js
1
2
3
4
1
2
3
4
1
2
3
4
1
2
3
4
```

Pull request description:
Resolvendo problema de `para cada aninhado` não executando de forma esperada.
Resolve #709 

Patch:
diff --git a/fontes/interpretador/interpretador-base.ts b/fontes/interpretador/interpretador-base.ts
index 03cb02cc..351dc670 100644
--- a/fontes/interpretador/interpretador-base.ts
+++ b/fontes/interpretador/interpretador-base.ts
@@ -927,6 +927,9 @@ export class InterpretadorBase implements InterpretadorInterface {
 
     async visitarDeclaracaoParaCada(declaracao: ParaCada): Promise<any> {
         let retornoExecucao: any;
+        // Posição atual precisa ser reiniciada, pois pode estar dentro de outro
+        // laço de repetição.
+        declaracao.posicaoAtual = 0;
         const vetorResolvido = await this.avaliar(declaracao.vetor);
         const valorVetorResolvido = vetorResolvido.hasOwnProperty('valor') ? vetorResolvido.valor : vetorResolvido;
 


Test patch:
diff --git a/testes/avaliador-sintatico.test.ts b/testes/avaliador-sintatico/avaliador-sintatico.test.ts
similarity index 99%
rename from testes/avaliador-sintatico.test.ts
rename to testes/avaliador-sintatico/avaliador-sintatico.test.ts
index 789fca0a..89183cfa 100644
--- a/testes/avaliador-sintatico.test.ts
+++ b/testes/avaliador-sintatico/avaliador-sintatico.test.ts
@@ -1,7 +1,7 @@
-import { Lexador } from '../fontes/lexador';
-import { AvaliadorSintatico } from '../fontes/avaliador-sintatico';
-import { Bloco, Classe, Const, Escreva, Expressao, FuncaoDeclaracao, Leia, Retorna, TendoComo, Var } from '../fontes/declaracoes';
-import { Binario, Chamada, FuncaoConstruto, Literal, Variavel } from '../fontes/construtos';
+import { Lexador } from '../../fontes/lexador';
+import { AvaliadorSintatico } from '../../fontes/avaliador-sintatico';
+import { Bloco, Classe, Const, Escreva, Expressao, FuncaoDeclaracao, Leia, Retorna, TendoComo, Var } from '../../fontes/declaracoes';
+import { Binario, Chamada, FuncaoConstruto, Literal, Variavel } from '../../fontes/construtos';
 
 describe('Avaliador sintático', () => {
     describe('analisar()', () => {
@@ -773,7 +773,9 @@ describe('Avaliador sintático', () => {
             });
 
             it('Declaração `tente ... pegue com parâmetro`', () => {
-                const retornoLexador = lexador.mapear(['var i = nulo tente { i = i + 1 } pegue (erro) { escreva(erro) }'], -1);
+                const retornoLexador = lexador.mapear([
+                    'var i = nulo tente { i = i + 1 } pegue (erro) { escreva(erro) }'
+                ], -1);
                 const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
 
                 expect(retornoAvaliadorSintatico).toBeTruthy();
diff --git a/testes/micro-avaliador-sintatico.test.ts b/testes/avaliador-sintatico/micro-avaliador-sintatico.test.ts
similarity index 90%
rename from testes/micro-avaliador-sintatico.test.ts
rename to testes/avaliador-sintatico/micro-avaliador-sintatico.test.ts
index 41a6c1f1..dfb67127 100644
--- a/testes/micro-avaliador-sintatico.test.ts
+++ b/testes/avaliador-sintatico/micro-avaliador-sintatico.test.ts
@@ -1,5 +1,5 @@
-import { MicroLexador } from './../fontes/lexador/micro-lexador';
-import { MicroAvaliadorSintatico } from '../fontes/avaliador-sintatico';
+import { MicroLexador } from '../../fontes/lexador/micro-lexador';
+import { MicroAvaliadorSintatico } from '../../fontes/avaliador-sintatico';
 
 describe('Avaliador sintático', () => {
     describe('analisar()', () => {
diff --git a/testes/interpretador/interpretador.test.ts b/testes/interpretador/interpretador.test.ts
index d37c0053..06e2c861 100644
--- a/testes/interpretador/interpretador.test.ts
+++ b/testes/interpretador/interpretador.test.ts
@@ -1082,7 +1082,7 @@ describe('Interpretador', () => {
             });
 
             describe('Laços de repetição', () => {
-                it('Laços de repetição - enquanto', async () => {
+                it('enquanto', async () => {
                     const retornoLexador = lexador.mapear(['var a = 0;\nenquanto (a < 10) { a = a + 1 }'], -1);
                     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
 
@@ -1091,7 +1091,7 @@ describe('Interpretador', () => {
                     expect(retornoInterpretador.erros).toHaveLength(0);
                 });
 
-                it('Laços de repetição - fazer ... enquanto', async () => {
+                it('fazer ... enquanto', async () => {
                     const retornoLexador = lexador.mapear(['var a = 0', 'fazer { a = a + 1 } enquanto (a < 10)'], -1);
                     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
 
@@ -1100,10 +1100,13 @@ describe('Interpretador', () => {
                     expect(retornoInterpretador.erros).toHaveLength(0);
                 });
 
-                it('Laços de repetição - para cada - trivial', async () => {
+                it('para cada - trivial', async () => {
                     const saidasMensagens = ['Valor:  1', 'Valor:  2', 'Valor:  3'];
                     const retornoLexador = lexador.mapear(
-                        ['para cada elemento em [1, 2, 3] {', "   escreva('Valor: ', elemento)", '}'],
+                        [
+                            'para cada elemento em [1, 2, 3] {', 
+                            "   escreva('Valor: ', elemento)", '}'
+                        ],
                         -1
                     );
                     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
@@ -1117,10 +1120,14 @@ describe('Interpretador', () => {
                     expect(retornoInterpretador.erros).toHaveLength(0);
                 });
 
-                it('Laços de repetição - para cada - vetor variável', async () => {
+                it('para cada - vetor variável', async () => {
                     const saidasMensagens = ['Valor:  1', 'Valor:  2', 'Valor:  3'];
                     const retornoLexador = lexador.mapear(
-                        ['var v = [1, 2, 3]', 'para cada elemento em v {', "   escreva('Valor: ', elemento)", '}'],
+                        [
+                            'var v = [1, 2, 3]', 
+                            'para cada elemento em v {', 
+                            "   escreva('Valor: ', elemento)", '}'
+                        ],
                         -1
                     );
                     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
@@ -1134,7 +1141,31 @@ describe('Interpretador', () => {
                     expect(retornoInterpretador.erros).toHaveLength(0);
                 });
 
-                it('Laços de repetição - para', async () => {
+                it('para cada - aninhado', async () => {
+                    let _saidas: string[] = [];
+                    const retornoLexador = lexador.mapear(
+                        [
+                            'var numeros = [1, 2, 3, 4]',
+                            'para cada numero de numeros {',
+                            '    para cada numero de numeros {',
+                            '        escreva(numero)',
+                            '    }',
+                            '}'
+                        ],
+                        -1
+                    );
+                    const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+                    interpretador.funcaoDeRetorno = (saida: any) => {
+                        _saidas.push(saida);
+                    };
+
+                    const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+                    expect(retornoInterpretador.erros).toHaveLength(0);
+                    expect(_saidas).toHaveLength(16);
+                });
+
+                it('para', async () => {
                     const saidasMensagens = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
                     const retornoLexador = lexador.mapear(['para (var i = 0; i < 10; i = i + 1) { escreva(i) }'], -1);
                     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);