Repository: DesignLiquido/delegua
Pull request #328 (2023-04-23 19:40:17)

As/birl

github-actions[bot]: <!-- jest coverage report action for options with hash 781087021f8e6c43aac1e668f4520603 -->

## Coverage report 



| <div title="Status of coverage:&#10; 🟢 - ok&#10; 🟡 - slightly more than threshold&#10; 🔴 - under the threshold">St.<sup>:grey_question:</sup></div> | Category   | Percentage                                                     | Covered / Total |
| :----------------------------------------------------------------------------------------------------------------------------------------------------: | :--------- | :------------------------------------------------------------- | :-------------: |
|                                                                           🟡                                                                           | Statements | <div title="Base coverage is: 73.31%">73.56% (+0.24% 🔼)</div> |    5366/7295    |
|                                                                           🟡                                                                           | Branches   | <div title="Base coverage is: 61.79%">61.92% (+0.14% 🔼)</div> |    1675/2705    |
|                                                                           🟡                                                                           | Functions  | <div title="Base coverage is: 74.53%">74.67% (+0.14% 🔼)</div> |     793/1062    |
|                                                                           🟡                                                                           | Lines      | <div title="Base coverage is: 73.75%">74% (+0.25% 🔼)</div>    |    5221/7055    |


## Test suite run success
386 tests passing in 35 suites.

<p align="right">Report generated by <a href="https://github.com/ArtiomTr/jest-coverage-report-action">🧪jest coverage report action</a> from c136fc956e8b31d5ead01cf8f51072d6a2c52edc</p>
<!-- Sticky Pull Request Comment -->

Patch:
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
index 74a9ceb6..20da0fd7 100644
--- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
@@ -4,7 +4,6 @@ import {
     Agrupamento,
     AtribuicaoSobrescrita,
     Atribuir,
-    Construto,
     DefinirValor,
     FuncaoConstruto,
     Literal,
@@ -27,10 +26,49 @@ import {
 import { RetornoAvaliadorSintatico, RetornoLexador } from '../../interfaces/retornos';
 import { AvaliadorSintaticoBase } from '../avaliador-sintatico-base';
 
-import { SimboloInterface } from '../../interfaces';
+import { InterpretadorInterface, SimboloInterface } from '../../interfaces';
 import tiposDeSimbolos from '../../tipos-de-simbolos/birl';
+import { Construto } from '../../construtos/construto';
 
 export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
+    tratarSimbolos(simbolos: Array<SimboloInterface>): string | void {
+        let identificador = 0,
+            adicao = 0,
+            subtracao = 0;
+
+        for (const simbolo of simbolos) {
+            if (simbolo.tipo === tiposDeSimbolos.IDENTIFICADOR) {
+                identificador++;
+            } else if (simbolo.tipo === tiposDeSimbolos.ADICAO) {
+                adicao++;
+            } else if (simbolo.tipo === tiposDeSimbolos.SUBTRACAO) {
+                subtracao++;
+            }
+        }
+
+        if (identificador !== 1 || (adicao > 0 && subtracao > 0)) {
+            this.erros.push({
+                message: 'Erro: Combinação desconhecida de símbolos.',
+                name: 'ErroSintatico',
+                simbolo: simbolos[0],
+            });
+            return;
+        }
+
+        if (adicao === 2) {
+            return 'ADICAO';
+        } else if (subtracao === 2) {
+            return 'SUBTRACAO';
+        }
+
+        this.erros.push({
+            message: 'Erro: Combinação desconhecida de símbolos.',
+            name: 'ErroSintatico',
+            simbolo: simbolos[0],
+        });
+        return;
+    }
+
     validarSegmentoHoraDoShow(): void {
         this.consumir(tiposDeSimbolos.HORA, 'Esperado expressão `HORA DO SHOW` para iniciar o programa');
         this.consumir(tiposDeSimbolos.DO, 'Esperado expressão `HORA DO SHOW` para iniciar o programa');
@@ -144,8 +182,8 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
         return new Expressao(expressao);
     }
 
-    declaracaoPara(): Para {
-        const simboloPara: SimboloInterface = this.consumir(
+    declaracaoPara(): any {
+        const primeiroSimbolo = this.consumir(
             tiposDeSimbolos.MAIS,
             'Esperado expressão `MAIS` para iniciar o bloco `PARA`.'
         );
@@ -156,39 +194,48 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
             'Esperado expressão `(` após `MAIS` para iniciar o bloco `PARA`.'
         );
 
-        let inicializador: Var | Expressao;
-        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO_E_VIRGULA)) {
-            inicializador = null;
-        } else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.MONSTRO)) {
-            inicializador = this.declaracaoDeVariavel();
-        } else {
-            inicializador = this.declaracaoExpressao();
-        }
+        const declaracaoInicial = this.declaracao(); // inicialização da variável de controle
 
-        let condicao = null;
-        if (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PONTO_E_VIRGULA)) {
-            condicao = this.expressao();
-        }
+        this.consumir(tiposDeSimbolos.PONTO_E_VIRGULA, 'Esperado expressão `;` após a inicialização do `PARA`.');
 
-        let incrementar = null;
-        if (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PARENTESE_DIREITO)) {
-            incrementar = this.expressao();
-        }
+        const condicao = this.declaracao(); // condição de parada
 
-        this.consumir(
-            tiposDeSimbolos.PARENTESE_DIREITO,
-            'Esperado expressão `)` após a condição para iniciar o bloco `PARA`.'
-        );
+        this.consumir(tiposDeSimbolos.PONTO_E_VIRGULA, 'Esperado expressão `;` após a condição do `PARA`.');
+
+        const incremento: Array<any> = [];
+
+        while (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARENTESE_DIREITO)) {
+            incremento.push(this.simbolos[this.atual]);
+            this.avancarEDevolverAnterior();
+        }
 
-        const declaracao = [];
+        const declaracoes = [];
 
         while (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.BIRL)) {
-            declaracao.push(this.declaracao());
+            declaracoes.push(this.declaracao());
         }
 
-        this.consumir(tiposDeSimbolos.BIRL, 'Esperado expressão `BIRL` para fechar o bloco `PARA`.');
+        const incrementoValor = this.tratarSimbolos(incremento);
 
-        return new Para(this.hashArquivo, simboloPara.linha, 0, 0, {} as any, {} as any);
+        const incrementoConstruto: Construto = new Literal(
+            this.hashArquivo,
+            Number(primeiroSimbolo.linha) + 1,
+            incrementoValor as string
+        );
+        const corpo = new Bloco(
+            this.hashArquivo,
+            Number(primeiroSimbolo.linha) + 1,
+            declaracoes.filter((d) => d)
+        );
+
+        return new Para(
+            this.hashArquivo,
+            Number(primeiroSimbolo.linha),
+            declaracaoInicial,
+            condicao,
+            incrementoConstruto,
+            corpo
+        );
     }
 
     declaracaoEscolha(): Escolha {
@@ -235,7 +282,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                 "Esperado identificador após palavra reservada 'FRANGO'."
             );
             inicializacoes.push(
-                new Var(identificador, new Literal(this.hashArquivo, Number(simboloCaractere.hashArquivo), 0))
+                new Var(identificador, new Literal(this.hashArquivo, Number(simboloCaractere.hashArquivo), 0), 'texto')
             );
 
             // Inicialização de variáveis que podem ter valor definido;
@@ -253,7 +300,8 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
             inicializacoes.push(
                 new Var(
                     identificador,
-                    new Literal(this.hashArquivo, Number(simboloCaractere.linha), valorInicializacao)
+                    new Literal(this.hashArquivo, Number(simboloCaractere.linha), valorInicializacao),
+                    'texto'
                 )
             );
         } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
@@ -279,8 +327,6 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                 tiposDeSimbolos.IDENTIFICADOR,
                 `Esperado identificador após palavra reservada '${simboloInteiro.lexema}'.`
             );
-            inicializacoes.push(new Var(identificador, new Literal(this.hashArquivo, Number(simboloInteiro.linha), 0)));
-            // Inicializações de variáveis podem ter valores definidos.
             let valorInicializacao = 0x00;
             if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
                 const literalInicializacao = this.consumir(
@@ -288,10 +334,18 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                     `Esperado literal de ${simboloInteiro.lexema} após símbolo de igual em declaração de variável.`
                 );
                 valorInicializacao = Number(literalInicializacao.literal);
+                inicializacoes.push(
+                    new Var(
+                        identificador,
+                        new Literal(this.hashArquivo, Number(simboloInteiro.linha), valorInicializacao),
+                        'numero'
+                    )
+                );
+            } else {
+                inicializacoes.push(
+                    new Var(identificador, new Literal(this.hashArquivo, Number(simboloInteiro.linha), 0), 'numero')
+                );
             }
-            inicializacoes.push(
-                new Var(identificador, new Literal(this.hashArquivo, Number(simboloInteiro.linha), valorInicializacao))
-            );
         } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
         return inicializacoes;
     }
@@ -310,7 +364,9 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                 "Esperado identificador após palavra reservada 'TRAPEZIO'."
             );
 
-            inicializacoes.push(new Var(identificador, new Literal(this.hashArquivo, Number(simboloFloat.linha), 0)));
+            inicializacoes.push(
+                new Var(identificador, new Literal(this.hashArquivo, Number(simboloFloat.linha), 0), 'numero')
+            );
 
             // Inicializações de variáveis que podem ter valores definidos
             let valorInicializacao = 0x00;
@@ -323,7 +379,11 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
             }
 
             inicializacoes.push(
-                new Var(identificador, new Literal(this.hashArquivo, Number(simboloFloat.linha), valorInicializacao))
+                new Var(
+                    identificador,
+                    new Literal(this.hashArquivo, Number(simboloFloat.linha), valorInicializacao),
+                    'numero'
+                )
             );
         } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
         return inicializacoes;
@@ -437,7 +497,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
     declaracao(): any {
         const simboloAtual = this.simbolos[this.atual];
         switch (simboloAtual.tipo) {
-            case tiposDeSimbolos.BORA: // BORA CUMPADE?
+            case tiposDeSimbolos.BORA:
                 return this.declaracaoRetorna();
             case tiposDeSimbolos.QUE:
                 return this.declaracaoLeia();
diff --git a/fontes/declaracoes/para.ts b/fontes/declaracoes/para.ts
index 35beaa21..ca43dff5 100644
--- a/fontes/declaracoes/para.ts
+++ b/fontes/declaracoes/para.ts
@@ -4,7 +4,7 @@ import { Bloco } from './bloco';
 import { Declaracao } from './declaracao';
 
 /**
- * Uma estrutura de repetição `para`, normalmente com um inicializador, 
+ * Uma estrutura de repetição `para`, normalmente com um inicializador,
  * uma condição de continuação e uma instrução de incremento.
  */
 export class Para extends Declaracao {
@@ -15,7 +15,14 @@ export class Para extends Declaracao {
     inicializada: boolean;
     blocoPosExecucao?: Bloco;
 
-    constructor(hashArquivo: number, linha: number, inicializador: any, condicao: any, incrementar: Construto, corpo: Bloco) {
+    constructor(
+        hashArquivo: number,
+        linha: number,
+        inicializador: any,
+        condicao: any,
+        incrementar: Construto,
+        corpo: Bloco
+    ) {
         super(linha, hashArquivo);
         this.inicializador = inicializador;
         this.condicao = condicao;
diff --git a/fontes/declaracoes/var.ts b/fontes/declaracoes/var.ts
index ca2b1c91..49e76e52 100644
--- a/fontes/declaracoes/var.ts
+++ b/fontes/declaracoes/var.ts
@@ -11,7 +11,7 @@ export class Var extends Declaracao {
     tipo: 'texto' | 'numero' | 'longo' | 'lógico' | 'nulo' | 'vetor' | 'módulo' | 'dicionário' | 'função' | 'símbolo' | undefined
 
     constructor(
-        simbolo: SimboloInterface, 
+        simbolo: SimboloInterface,
         inicializador: Construto,
         tipo: 'texto' | 'numero' | 'longo' | 'lógico' | 'nulo' | 'vetor' | 'módulo' | 'dicionário' | 'função' | 'símbolo' | undefined = undefined
     ) {


Test patch:
diff --git a/testes/birl/avaliador-sintatico.test.ts b/testes/birl/avaliador-sintatico.test.ts
index 9318bc12..0dc0bec4 100644
--- a/testes/birl/avaliador-sintatico.test.ts
+++ b/testes/birl/avaliador-sintatico.test.ts
@@ -1,5 +1,5 @@
 import { AvaliadorSintaticoBirl } from '../../fontes/avaliador-sintatico/dialetos';
-import { Se } from '../../fontes/declaracoes';
+import { Para, Se } from '../../fontes/declaracoes';
 import { LexadorBirl } from '../../fontes/lexador/dialetos';
 
 describe('Avaliador Sintático Birl', () => {
@@ -24,25 +24,6 @@ describe('Avaliador Sintático Birl', () => {
             expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(2);
         });
 
-        it.skip('Sucesso - For', () => {
-            //@TODO: @ItaloCobains - Implementar esse teste
-            const retornoLexador = lexador.mapear(
-                [
-                    'HORA DO SHOW',
-                    '  MONSTRO M;',
-                    '  MAIS QUERO MAIS (M = 0; M < 5; M++)',
-                    '    CE QUER VER ESSA PORRA? ("%d", M);',
-                    '  BIRL',
-                    'BIRL',
-                ],
-                -1
-            );
-
-            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
-            expect(retornoAvaliadorSintatico).toBeTruthy();
-            // expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(2);
-        });
-
         it('Sucesso - Variavel - Numero', () => {
             const retornoLexador = lexador.mapear(
                 [
@@ -186,5 +167,22 @@ describe('Avaliador Sintático Birl', () => {
                 expect(retornoAvaliadorSintatico.declaracoes[0]).toBeInstanceOf(Se);
             });
         });
+        describe('Sucesso - Loops', () => {
+            it('Sucesso - declaração - for', () => {
+                const retornoLexador = lexador.mapear([
+                    'HORA DO SHOW \n',
+                    '   MAIS QUERO MAIS (MONSTRO M = 0; M < 5; M++)',
+                    '       CE QUER VER ESSA PORRA? ("teste");\n',
+                    '   BIRL\n',
+                    'BIRL\n',
+                ]);
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+                expect(retornoAvaliadorSintatico).toBeTruthy();
+                expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(1);
+                expect(retornoAvaliadorSintatico.declaracoes[0].assinaturaMetodo).toBe('<principal>');
+                expect(retornoAvaliadorSintatico.declaracoes[0]).toBeInstanceOf(Para);
+            })
+        });
     });
 });