Repository: DesignLiquido/delegua
Pull request #440 (2023-06-07 20:19:23)

403 birl interpretador
Resolvendo issue: #403 

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.81%">73.53% (-0.28% 🔻)</div> |    7324/9961    |
|                                                                           🟡                                                                           | Branches   | <div title="Base coverage is: 63.26%">63.06% (-0.2% 🔻)</div>  |    2320/3679    |
|                                                                           🟡                                                                           | Functions  | <div title="Base coverage is: 69.93%">69.1% (-0.82% 🔻)</div>  |    1087/1573    |
|                                                                           🟡                                                                           | Lines      | <div title="Base coverage is: 74.23%">73.93% (-0.3% 🔻)</div>  |    7145/9664    |

<details><summary>Show new covered files 🐣</summary>
<br/>

| <div title="Status of coverage:&#10; 🟢 - ok&#10; 🟡 - slightly more than threshold&#10; 🔴 - under the threshold">St.<sup>:grey_question:</sup></div> | File                                                                                                               | Statements | Branches | Functions | Lines  |
| :----------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------- | :--------- | :------- | :-------- | :----- |
|                                                                           🔴                                                                           | <div title="interpretador/dialetos/birl/comum.ts">`...` / comum.ts</div>                                           | 33.33%     | 13.33%   | 100%      | 33.33% |
|                                                                           🟢                                                                           | <div title="analisador-semantico/dialetos/index.ts">`...` / index.ts</div>                                         | 100%       | 100%     | 100%      | 100%   |
|                                                                           🔴                                                                           | <div title="analisador-semantico/dialetos/analisador-semantico-birl.ts">`...` / analisador-semantico-birl.ts</div> | 32.35%     | 0%       | 13.95%    | 32.35% |

</details>


## Test suite run success
627 tests passing in 49 suites.

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

Patch:
diff --git a/.eslintrc b/.eslintrc
index f3be4aa4..7664e672 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -25,6 +25,7 @@
         "no-fallthrough": "off",
         "@typescript-eslint/no-this-alias": "off",
         "@typescript-eslint/no-inferrable-types": "off",
-        "prefer-const": "off"
+        "prefer-const": "off",
+        "no-var": "off"
     }
 }
diff --git a/.vscode/launch.json b/.vscode/launch.json
index d34fbb0f..43987849 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -24,7 +24,7 @@
             "runtimeArgs": [
                 "--inspect-brk",
                 "${workspaceRoot}/node_modules/jest/bin/jest.js",
-                // "interpretador.test.ts",
+                "birl/avaliador-sintatico.test.ts",
                 "birl",
                 "--runInBand"
             ],
diff --git a/fontes/analisador-semantico/analisador-semantico.ts b/fontes/analisador-semantico/analisador-semantico.ts
index 446a5f1a..e56315f9 100644
--- a/fontes/analisador-semantico/analisador-semantico.ts
+++ b/fontes/analisador-semantico/analisador-semantico.ts
@@ -1,31 +1,31 @@
-import { Literal, Atribuir, FimPara, FormatacaoEscrita, Super, TipoDe } from '../construtos';
+import { Atribuir, FimPara, FormatacaoEscrita, Literal, Super, TipoDe } from '../construtos';
 import {
+    Bloco,
+    Classe,
+    Const,
+    Continua,
     Declaracao,
+    Enquanto,
+    Escolha,
+    Escreva,
+    EscrevaMesmaLinha,
     Expressao,
+    Fazer,
+    FuncaoDeclaracao,
+    Importar,
     Leia,
     Para,
     ParaCada,
+    Retorna,
     Se,
-    Fazer,
-    Escolha,
+    Sustar,
     Tente,
-    Enquanto,
-    Importar,
-    Escreva,
-    EscrevaMesmaLinha,
-    Bloco,
     Var,
-    Const,
-    Continua,
-    Sustar,
-    Retorna,
-    FuncaoDeclaracao,
-    Classe,
 } from '../declaracoes';
 import { AnalisadorSemanticoInterface } from '../interfaces/analisador-semantico-interface';
 import { ErroAnalisadorSemantico } from '../interfaces/erros';
 import { RetornoAnalisadorSemantico } from '../interfaces/retornos/retorno-analisador-semantico';
-import { ContinuarQuebra, SustarQuebra, RetornoQuebra } from '../quebras';
+import { ContinuarQuebra, RetornoQuebra, SustarQuebra } from '../quebras';
 import { PilhaVariaveis } from './pilha-variaveis';
 
 interface VariavelHipoteticaInterface {
@@ -57,11 +57,11 @@ export class AnalisadorSemantico implements AnalisadorSemanticoInterface {
         this.atual = 0;
         this.erros = [];
     }
-    
+
     visitarExpressaoTipoDe(expressao: TipoDe): Promise<any> {
         return Promise.resolve();
     }
-    
+
     visitarExpressaoFalhar(expressao: any): Promise<any> {
         return Promise.resolve();
     }
diff --git a/fontes/analisador-semantico/dialetos/analisador-semantico-birl.ts b/fontes/analisador-semantico/dialetos/analisador-semantico-birl.ts
new file mode 100644
index 00000000..20c45b63
--- /dev/null
+++ b/fontes/analisador-semantico/dialetos/analisador-semantico-birl.ts
@@ -0,0 +1,247 @@
+import { Atribuir, FimPara, FormatacaoEscrita, Literal, Super, TipoDe, Variavel } from '../../construtos';
+import {
+    Bloco,
+    Classe,
+    Const,
+    Continua,
+    Declaracao,
+    Enquanto,
+    Escolha,
+    Escreva,
+    EscrevaMesmaLinha,
+    Expressao,
+    Fazer,
+    FuncaoDeclaracao,
+    Importar,
+    Leia,
+    Para,
+    ParaCada,
+    Retorna,
+    Se,
+    Sustar,
+    Tente,
+    Var,
+} from '../../declaracoes';
+import { AnalisadorSemanticoInterface } from '../../interfaces/analisador-semantico-interface';
+import { ErroAnalisadorSemantico } from '../../interfaces/erros';
+import { RetornoAnalisadorSemantico } from '../../interfaces/retornos/retorno-analisador-semantico';
+import { ContinuarQuebra, RetornoQuebra, SustarQuebra } from '../../quebras';
+import { PilhaVariaveis } from '../pilha-variaveis';
+
+interface VariavelHipoteticaInterface {
+    tipo:
+        | 'texto'
+        | 'número'
+        | 'longo'
+        | 'vetor'
+        | 'dicionário'
+        | 'nulo'
+        | 'lógico'
+        | 'função'
+        | 'símbolo'
+        | 'objeto'
+        | 'módulo';
+    subtipo?: 'texto' | 'número' | 'longo' | 'lógico';
+    imutavel: boolean;
+}
+
+export class AnalisadorSemanticoBirl implements AnalisadorSemanticoInterface {
+    pilhaVariaveis: PilhaVariaveis;
+    variaveis: { [nomeVariavel: string]: VariavelHipoteticaInterface };
+    atual: number;
+    erros: ErroAnalisadorSemantico[];
+
+    constructor() {
+        this.pilhaVariaveis = new PilhaVariaveis();
+        this.variaveis = {};
+        this.atual = 0;
+        this.erros = [];
+    }
+    visitarExpressaoTipoDe(expressao: TipoDe): Promise<any> {
+        throw new Error('Method not implemented.');
+    }
+
+    visitarDeclaracaoClasse(declaracao: Classe) {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoConst(declaracao: Const): Promise<any> {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoDeAtribuicao(expressao: Atribuir) {
+        if (!this.variaveis.hasOwnProperty(expressao.simbolo.lexema)) {
+            this.erros.push({
+                simbolo: expressao.simbolo,
+                mensagem: `A variável ${expressao.simbolo.lexema} não foi declarada.`,
+                hashArquivo: expressao.hashArquivo,
+                linha: expressao.linha,
+            });
+            return Promise.resolve();
+        }
+
+        if (this.variaveis[expressao.simbolo.lexema].imutavel) {
+            this.erros.push({
+                simbolo: expressao.simbolo,
+                mensagem: `Constante ${expressao.simbolo.lexema} não pode ser modificada.`,
+                hashArquivo: expressao.hashArquivo,
+                linha: expressao.linha,
+            });
+            return Promise.resolve();
+        }
+    }
+    visitarDeclaracaoDeExpressao(declaracao: Expressao) {
+        return declaracao.expressao.aceitar(this);
+    }
+    visitarDeclaracaoDefinicaoFuncao(declaracao: FuncaoDeclaracao) {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoEnquanto(declaracao: Enquanto) {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoEscolha(declaracao: Escolha) {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoEscreva(declaracao: Escreva) {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoFazer(declaracao: Fazer) {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoImportar(declaracao: Importar) {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoPara(declaracao: Para): Promise<any> {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoParaCada(declaracao: ParaCada): Promise<any> {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoSe(declaracao: Se) {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoTente(declaracao: Tente) {
+        return Promise.resolve();
+    }
+    visitarDeclaracaoVar(declaracao: Var): Promise<any> {
+        this.variaveis[declaracao.simbolo.lexema] = {
+            imutavel: false,
+            tipo: 'número',
+        };
+
+        return Promise.resolve();
+    }
+    visitarExpressaoAcessoIndiceVariavel(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoAcessoMetodo(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoAgrupamento(expressao: any): Promise<any> {
+        return Promise.resolve();
+    }
+    visitarExpressaoAtribuicaoPorIndice(expressao: any): Promise<any> {
+        return Promise.resolve();
+    }
+    visitarExpressaoBinaria(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoBloco(declaracao: Bloco): Promise<any> {
+        return Promise.resolve();
+    }
+    visitarExpressaoContinua(declaracao?: Continua): ContinuarQuebra {
+        return Promise.resolve();
+    }
+    visitarExpressaoDeChamada(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoDefinirValor(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoDeleguaFuncao(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoDeVariavel(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoDicionario(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoEscrevaMesmaLinha(declaracao: EscrevaMesmaLinha) {
+        return Promise.resolve();
+    }
+    visitarExpressaoFalhar(expressao: any): Promise<any> {
+        return Promise.resolve();
+    }
+    visitarExpressaoFimPara(declaracao: FimPara) {
+        return Promise.resolve();
+    }
+    visitarExpressaoFormatacaoEscrita(declaracao: FormatacaoEscrita) {
+        return Promise.resolve();
+    }
+    visitarExpressaoIsto(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoLeia(expressao: Leia) {
+        if (!this.variaveis.hasOwnProperty((expressao.argumentos[0] as Variavel).simbolo.lexema)) {
+            this.erros.push({
+                simbolo: (expressao.argumentos[0] as Variavel).simbolo,
+                mensagem: `A variável ${(expressao.argumentos[0] as Variavel).simbolo.lexema} não foi declarada.`,
+                hashArquivo: expressao.hashArquivo,
+                linha: expressao.linha,
+            });
+            return Promise.resolve();
+        }
+
+        const tipoVariavelExpressão = this.variaveis[(expressao.argumentos[0] as Variavel).simbolo.lexema].tipo;
+        const tipoVariavelArgumento = expressao.argumentos[1].valor;
+
+        if (tipoVariavelExpressão !== tipoVariavelArgumento) {
+            this.erros.push({
+                simbolo: (expressao.argumentos[0] as Variavel).simbolo,
+                mensagem: `A variável ${
+                    (expressao.argumentos[0] as Variavel).simbolo.lexema
+                } não é do tipo ${tipoVariavelArgumento}.`,
+                hashArquivo: expressao.hashArquivo,
+                linha: expressao.linha,
+            });
+            return Promise.resolve();
+        }
+
+        return Promise.resolve();
+    }
+    visitarExpressaoLiteral(expressao: Literal): Promise<any> {
+        return Promise.resolve();
+    }
+    visitarExpressaoLogica(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoRetornar(declaracao: Retorna): Promise<RetornoQuebra> {
+        return Promise.resolve(null);
+    }
+    visitarExpressaoSuper(expressao: Super) {
+        return Promise.resolve();
+    }
+    visitarExpressaoSustar(declaracao?: Sustar): SustarQuebra {
+        return Promise.resolve();
+    }
+    visitarExpressaoUnaria(expressao: any) {
+        return Promise.resolve();
+    }
+    visitarExpressaoVetor(expressao: any) {
+        return Promise.resolve();
+    }
+
+    analisar(declaracoes: Declaracao[]): RetornoAnalisadorSemantico {
+        this.variaveis = {};
+        this.atual = 0;
+        this.erros = [];
+
+        while (this.atual < declaracoes.length) {
+            declaracoes[this.atual].aceitar(this);
+            this.atual++;
+        }
+
+        return {
+            erros: this.erros,
+        } as RetornoAnalisadorSemantico;
+    }
+}
diff --git a/fontes/analisador-semantico/dialetos/index.ts b/fontes/analisador-semantico/dialetos/index.ts
new file mode 100644
index 00000000..de9a1469
--- /dev/null
+++ b/fontes/analisador-semantico/dialetos/index.ts
@@ -0,0 +1,1 @@
+export * from "./analisador-semantico-birl"
diff --git a/fontes/avaliador-sintatico/avaliador-sintatico-base.ts b/fontes/avaliador-sintatico/avaliador-sintatico-base.ts
index 4663dcd5..bd48bc66 100644
--- a/fontes/avaliador-sintatico/avaliador-sintatico-base.ts
+++ b/fontes/avaliador-sintatico/avaliador-sintatico-base.ts
@@ -79,6 +79,11 @@ export abstract class AvaliadorSintaticoBase implements AvaliadorSintaticoInterf
         return this.simbolos[this.atual - 1];
     }
 
+    regredirEDevolverAtual(): SimboloInterface {
+        if (this.atual > 0) this.atual -= 1;
+        return this.simbolos[this.atual];
+    }
+
     verificarSeSimboloAtualEIgualA(...argumentos: string[]): boolean {
         for (let i = 0; i < argumentos.length; i++) {
             const tipoAtual = argumentos[i];
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
index 30f4979a..9365d1bc 100644
--- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
@@ -31,12 +31,28 @@ import {
 import { RetornoAvaliadorSintatico, RetornoLexador } from '../../interfaces/retornos';
 import { AvaliadorSintaticoBase } from '../avaliador-sintatico-base';
 
-import { ParametroInterface, SimboloInterface } from '../../interfaces';
-import tiposDeSimbolos from '../../tipos-de-simbolos/birl';
 import { Construto } from '../../construtos/construto';
+import { ParametroInterface, SimboloInterface } from '../../interfaces';
 import { TiposDadosInterface } from '../../interfaces/tipos-dados-interface';
+import tiposDeSimbolos from '../../tipos-de-simbolos/birl';
 
 export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
+    private validarEscopoPrograma(): Declaracao[] {
+        let declaracoes: Declaracao[] = [];
+        this.validarSegmentoHoraDoShow();
+
+        while (!this.estaNoFinal()) {
+            const declaracaoVetor = this.declaracao();
+            if (Array.isArray(declaracaoVetor)) {
+                declaracoes = declaracoes.concat(declaracaoVetor);
+            } else {
+                declaracoes.push(declaracaoVetor);
+            }
+        }
+
+        this.validarSegmentoBirlFinal();
+        return declaracoes;
+    }
     tratarSimbolos(simbolos: Array<SimboloInterface>): string | void {
         let identificador = 0,
             adicao = 0,
@@ -83,6 +99,15 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
     }
 
     validarSegmentoBirlFinal(): void {
+        this.regredirEDevolverAtual();
+        while (!this.verificarTipoSimboloAtual(tiposDeSimbolos.BIRL)) {
+            this.consumir(
+                tiposDeSimbolos.QUEBRA_LINHA,
+                'Esperado expressão `QUEBRA_LINHA` após a declaração de variáveis'
+            );
+            this.regredirEDevolverAtual();
+            this.regredirEDevolverAtual();
+        }
         this.consumir(tiposDeSimbolos.BIRL, 'Esperado expressão `BIRL` para fechamento do programa');
         this.blocos -= 1;
     }
@@ -215,7 +240,12 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                 'numero'
             );
         } else {
-            declaracaoInicial = this.declaracao(); // inicialização da variável de controle
+            const declaracaoVetor = this.declaracao(); // inicialização da variável de controle
+            if (Array.isArray(declaracaoVetor)) {
+                declaracaoInicial = declaracaoVetor[0];
+            } else {
+                declaracaoInicial = declaracaoVetor;
+            }
         }
 
         this.consumir(tiposDeSimbolos.PONTO_E_VIRGULA, 'Esperado expressão `;` após a inicialização do `PARA`.');
@@ -288,6 +318,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
         const simboloCaractere = this.consumir(tiposDeSimbolos.FRANGO, '');
 
         const inicializacoes = [];
+        let eLiteral = true;
 
         do {
             const identificador = this.consumir(
@@ -298,8 +329,10 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
             let valorInicializacao: string | Array<string>;
             if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
                 if (this.verificarTipoSimboloAtual(tiposDeSimbolos.AJUDA)) {
+                    eLiteral = false;
                     valorInicializacao = this.declaracao();
                 } else if (this.verificarTipoSimboloAtual(tiposDeSimbolos.IDENTIFICADOR)) {
+                    eLiteral = false;
                     valorInicializacao = this.declaracao();
                 } else if (this.verificarTipoSimboloAtual(tiposDeSimbolos.TEXTO)) {
                     const literalInicializacao = this.consumir(
@@ -315,7 +348,9 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                 inicializacoes.push(
                     new Var(
                         identificador,
-                        new Literal(this.hashArquivo, Number(simboloCaractere.linha), valorInicializacao),
+                        eLiteral
+                            ? new Literal(this.hashArquivo, Number(simboloCaractere.linha), valorInicializacao)
+                            : (valorInicializacao as any),
                         'texto'
                     )
                 );
@@ -323,7 +358,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                 inicializacoes.push(
                     new Var(
                         identificador,
-                        new Literal(this.hashArquivo, Number(simboloCaractere.hashArquivo), 0),
+                        new Literal(this.hashArquivo, Number(simboloCaractere.hashArquivo), ''),
                         'texto'
                     )
                 );
@@ -347,7 +382,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
 
     declaracaoInteiros(): Var[] {
         let simboloInteiro: SimboloInterface = this.validarTipoDeclaracaoInteiro();
-
+        let eLiteral = true;
         const inicializacoes = [];
         do {
             const identificador = this.consumir(
@@ -357,8 +392,10 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
             let valorInicializacao: any = 0x00;
             if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
                 if (this.verificarTipoSimboloAtual(tiposDeSimbolos.AJUDA)) {
+                    eLiteral = false;
                     valorInicializacao = this.declaracao();
                 } else if (this.verificarTipoSimboloAtual(tiposDeSimbolos.IDENTIFICADOR)) {
+                    eLiteral = false;
                     valorInicializacao = this.declaracao();
                 } else if (this.verificarTipoSimboloAtual(tiposDeSimbolos.NUMERO)) {
                     const literalInicializacao = this.consumir(
@@ -374,7 +411,9 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                 inicializacoes.push(
                     new Var(
                         identificador,
-                        new Literal(this.hashArquivo, Number(simboloInteiro.linha), valorInicializacao),
+                        eLiteral
+                            ? new Literal(this.hashArquivo, Number(simboloInteiro.linha), valorInicializacao)
+                            : valorInicializacao,
                         'numero'
                     )
                 );
@@ -392,7 +431,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
         if (this.verificarTipoSimboloAtual(tiposDeSimbolos.DESCENDENTE)) {
             this.consumir(tiposDeSimbolos.DESCENDENTE, '');
         }
-
+        let eLiteral = true;
         const inicializacoes = [];
 
         do {
@@ -405,8 +444,10 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
 
             if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
                 if (this.verificarTipoSimboloAtual(tiposDeSimbolos.AJUDA)) {
+                    eLiteral = false;
                     valorInicializacao = this.declaracao();
                 } else if (this.verificarTipoSimboloAtual(tiposDeSimbolos.IDENTIFICADOR)) {
+                    eLiteral = false;
                     valorInicializacao = this.declaracao();
                 } else if (this.verificarTipoSimboloAtual(tiposDeSimbolos.NUMERO)) {
                     const literalInicializacao = this.consumir(
@@ -420,7 +461,9 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                 inicializacoes.push(
                     new Var(
                         identificador,
-                        new Literal(this.hashArquivo, Number(simboloFloat.linha), valorInicializacao),
+                        eLiteral
+                            ? new Literal(this.hashArquivo, Number(simboloFloat.linha), valorInicializacao)
+                            : valorInicializacao,
                         'numero'
                     )
                 );
@@ -445,6 +488,30 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
         return new Retorna(primeiroSimbolo, valor);
     }
 
+    protected validaTipoDeclaracaoLeia(caracteres: string): string {
+        const tipoCaractere = caracteres.charAt(1);
+
+        const tipos = {
+            d: 'número',
+            i: 'número',
+            u: 'número',
+            f: 'número',
+            F: 'número',
+            e: 'número',
+            E: 'número',
+            g: 'número',
+            G: 'número',
+            x: 'número',
+            X: 'número',
+            o: 'número',
+            c: 'texto',
+            s: 'texto',
+            p: 'texto',
+        };
+
+        return tipos[tipoCaractere] || 'desconhecido';
+    }
+
     declaracaoLeia(): Leia {
         const primeiroSimbolo = this.consumir(tiposDeSimbolos.QUE, 'Esperado expressão `QUE` para ler valor.');
         this.consumir(tiposDeSimbolos.QUE, 'Esperado expressão `QUE` após `QUE` para ler valor.');
@@ -456,21 +523,28 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
             tiposDeSimbolos.PARENTESE_ESQUERDO,
             'Esperado parêntese esquerdo após interrogação para ler valor.'
         );
-        const simbolo = this.consumir(tiposDeSimbolos.TEXTO, 'Esperado texto após parêntese esquerdo para ler valor.');
-        const ponteiro = this.consumir(
+        const textoOuSimbolo = this.consumir(
+            tiposDeSimbolos.TEXTO,
+            'Esperado texto após parêntese esquerdo para ler valor.'
+        );
+        this.consumir(tiposDeSimbolos.VIRGULA, 'Esperado vírgula após texto para ler valor.');
+        this.consumir(tiposDeSimbolos.PONTEIRO, 'Esperado expressão `&` após texto para ler valor.');
+        const variavel = this.consumir(
             tiposDeSimbolos.IDENTIFICADOR,
-            'Esperado identificador após texto para ler valor.'
+            'Esperado identificador após `&` para ler valor.'
         );
+
+        const tipo = this.validaTipoDeclaracaoLeia(textoOuSimbolo.literal);
+
         this.consumir(
             tiposDeSimbolos.PARENTESE_DIREITO,
             'Esperado parêntese direito após identificador para ler valor.'
         );
-        this.consumir(
-            tiposDeSimbolos.PONTO_E_VIRGULA,
-            'Esperado ponto e vírgula após parêntese direito para ler valor.'
-        );
 
-        return new Leia(Number(primeiroSimbolo.linha), this.hashArquivo, []);
+        return new Leia(Number(primeiroSimbolo.linha), this.hashArquivo, [
+            new Variavel(this.hashArquivo, variavel),
+            new Literal(this.hashArquivo, Number(textoOuSimbolo.linha), tipo),
+        ]);
     }
 
     declaracaoSe(): Se {
@@ -589,7 +663,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
 
         let paramentros = [];
         if (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PARENTESE_DIREITO)) {
-            paramentros.push(this.logicaComumParamentros());
+            paramentros = this.logicaComumParamentros();
         }
         this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após parâmetros.");
         this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após parâmetros.");
@@ -597,7 +671,12 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
         let corpo = [];
 
         do {
-            corpo.push(this.declaracao());
+            const declaracaoVetor = this.declaracao();
+            if (Array.isArray(declaracaoVetor)) {
+                corpo = corpo.concat(declaracaoVetor);
+            } else {
+                corpo.push(declaracaoVetor);
+            }
         } while (![tiposDeSimbolos.BIRL].includes(this.simbolos[this.atual].tipo));
 
         return new FuncaoConstruto(
@@ -761,6 +840,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
                 return this.declaracaoEscreva();
             case tiposDeSimbolos.PONTO_E_VIRGULA:
             case tiposDeSimbolos.QUEBRA_LINHA:
+            case tiposDeSimbolos.BIRL:
                 this.avancarEDevolverAnterior();
                 return null;
             case tiposDeSimbolos.IDENTIFICADOR:
@@ -794,15 +874,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
         this.atual = 0;
 
         this.simbolos = retornoLexador.simbolos;
-        const declaracoes = [];
-
-        this.validarSegmentoHoraDoShow();
-
-        while (!this.estaNoFinal() && this.simbolos[this.atual].tipo !== tiposDeSimbolos.BIRL) {
-            declaracoes.push(this.declaracao());
-        }
-
-        this.validarSegmentoBirlFinal();
+        const declaracoes: Declaracao[] = this.validarEscopoPrograma();
 
         return {
             declaracoes: declaracoes.filter((d) => d),
diff --git a/fontes/interpretador/dialetos/birl/comum.ts b/fontes/interpretador/dialetos/birl/comum.ts
new file mode 100644
index 00000000..00ea740a
--- /dev/null
+++ b/fontes/interpretador/dialetos/birl/comum.ts
@@ -0,0 +1,75 @@
+import { AcessoIndiceVariavel, Construto, Variavel } from '../../../construtos';
+import { InterpretadorBirl } from './interpretador-birl';
+
+function converteTipoOuEstouraError(valor: any, tipo: string) {
+    try {
+        switch (tipo) {
+            case 'texto':
+                return String(valor);
+            case 'número':
+                if ((valor as string).includes('.')) {
+                    return parseFloat(valor);
+                }
+                var numero = Number(valor);
+                if (isNaN(numero)) {
+                    throw new Error(`Não foi possível converter o valor "${valor}" para o tipo ${tipo}.`);
+                }
+                return numero;
+            default:
+                return valor;
+        }
+    } catch (err) {
+        throw new Error(`Não foi possível converter o valor "${valor}" para o tipo ${tipo}.`);
+    }
+}
+
+export async function atribuirVariavel(
+    interpretador: InterpretadorBirl,
+    expressao: Construto,
+    valor: any,
+    tipo: string
+): Promise<any> {
+    valor = converteTipoOuEstouraError(valor, tipo);
+
+    if (expressao instanceof Variavel) {
+        interpretador.pilhaEscoposExecucao.atribuirVariavel(expressao.simbolo, valor);
+        return;
+    }
+
+    if (expressao instanceof AcessoIndiceVariavel) {
+        const promises = await Promise.all([
+            interpretador.avaliar(expressao.entidadeChamada),
+            interpretador.avaliar(expressao.indice),
+        ]);
+
+        let alvo = promises[0];
+        let indice = promises[1];
+        const subtipo = alvo.hasOwnProperty('subtipo') ? alvo.subtipo : undefined;
+
+        if (alvo.hasOwnProperty('valor')) {
+            alvo = alvo.valor;
+        }
+
+        if (indice.hasOwnProperty('valor')) {
+            indice = indice.valor;
+        }
+
+        let valorResolvido;
+        switch (subtipo) {
+            case 'texto':
+                valorResolvido = String(valor);
+                break;
+            case 'número':
+                valorResolvido = Number(valor);
+                break;
+            case 'lógico':
+                valorResolvido = Boolean(valor);
+                break;
+            default:
+                valorResolvido = valor;
+                break;
+        }
+
+        alvo[indice] = valorResolvido;
+    }
+}
diff --git a/fontes/interpretador/dialetos/birl/interpretador-birl.ts b/fontes/interpretador/dialetos/birl/interpretador-birl.ts
index 299939fb..703a4645 100644
--- a/fontes/interpretador/dialetos/birl/interpretador-birl.ts
+++ b/fontes/interpretador/dialetos/birl/interpretador-birl.ts
@@ -1,39 +1,39 @@
-import { Construto, Atribuir, Literal, FimPara, FormatacaoEscrita, Super, Variavel, Unario, TipoDe } from '../../../construtos';
+import { Atribuir, Construto, FimPara, FormatacaoEscrita, Literal, Super, TipoDe, Unario, Variavel } from '../../../construtos';
 import {
+    Bloco,
+    Classe,
+    Const,
+    Continua,
     Declaracao,
+    Enquanto,
+    Escolha,
+    Escreva,
+    EscrevaMesmaLinha,
     Expressao,
+    Fazer,
+    FuncaoDeclaracao,
+    Importar,
     Leia,
     Para,
     ParaCada,
+    Retorna,
     Se,
-    Fazer,
-    Escolha,
     Tente,
-    Enquanto,
-    Importar,
-    Escreva,
-    EscrevaMesmaLinha,
-    Bloco,
     Var,
-    Const,
-    Continua,
-    Sustar,
-    Retorna,
-    FuncaoDeclaracao,
-    Classe,
 } from '../../../declaracoes';
 import { EspacoVariaveis } from '../../../espaco-variaveis';
-import { ObjetoPadrao } from '../../../estruturas';
+import { Chamavel, DeleguaClasse, DeleguaFuncao, DeleguaModulo, FuncaoPadrao, MetodoPrimitiva, ObjetoPadrao } from '../../../estruturas';
 import { ErroEmTempoDeExecucao } from '../../../excecoes';
-import { InterpretadorInterface, SimboloInterface, VariavelInterface } from '../../../interfaces';
+import { InterpretadorInterface, ParametroInterface, SimboloInterface, VariavelInterface } from '../../../interfaces';
 import { ErroInterpretador } from '../../../interfaces/erros/erro-interpretador';
 import { EscopoExecucao } from '../../../interfaces/escopo-execucao';
 import { PilhaEscoposExecucaoInterface } from '../../../interfaces/pilha-escopos-execucao-interface';
 import { RetornoInterpretador } from '../../../interfaces/retornos';
-import { ContinuarQuebra, SustarQuebra, RetornoQuebra, Quebra } from '../../../quebras';
+import { ContinuarQuebra, Quebra, RetornoQuebra, SustarQuebra } from '../../../quebras';
+import tiposDeSimbolos from '../../../tipos-de-simbolos/birl';
 import { inferirTipoVariavel } from '../../inferenciador';
 import { PilhaEscoposExecucao } from '../../pilha-escopos-execucao';
-import tiposDeSimbolos from '../../../tipos-de-simbolos/birl';
+import * as comum from './comum';
 
 export class InterpretadorBirl implements InterpretadorInterface {
     diretorioBase: any;
@@ -89,7 +89,7 @@ export class InterpretadorBirl implements InterpretadorInterface {
             console.log('Aqui');
         } */
 
-        return await expressao. aceitar(this);
+        return await expressao.aceitar(this);
     }
     /**
      * Empilha declarações na pilha de escopos de execução, cria um novo ambiente e
@@ -315,8 +315,125 @@ export class InterpretadorBirl implements InterpretadorInterface {
             return Promise.reject(erro);
         }
     }
-    visitarExpressaoDeChamada(expressao: any) {
-        throw new Error('Método não implementado.');
+    /**
+     * Executa uma chamada de função, método ou classe.
+     * @param expressao A expressão chamada.
+     * @returns O resultado da chamada.
+     */
+    async visitarExpressaoDeChamada(expressao: any): Promise<any> {
+        try {
+            const variavelEntidadeChamada: VariavelInterface | any = await this.avaliar(expressao.entidadeChamada);
+
+            if (variavelEntidadeChamada === null) {
+                return Promise.reject(
+                    new ErroEmTempoDeExecucao(
+                        expressao.parentese,
+                        'Chamada de função ou método inexistente: ' + String(expressao.entidadeChamada),
+                        expressao.linha
+                    )
+                );
+            }
+
+            const entidadeChamada = variavelEntidadeChamada.hasOwnProperty('valor')
+                ? variavelEntidadeChamada.valor
+                : variavelEntidadeChamada;
+
+            let argumentos = [];
+            for (let i = 0; i < expressao.argumentos.length; i++) {
+                argumentos.push(await this.avaliar(expressao.argumentos[i]));
+            }
+
+            if (entidadeChamada instanceof DeleguaModulo) {
+                return Promise.reject(
+                    new ErroEmTempoDeExecucao(
+                        expressao.parentese,
+                        'Entidade chamada é um módulo de Delégua. Provavelmente você quer chamar um de seus componentes?',
+                        expressao.linha
+                    )
+                );
+            }
+
+            if (entidadeChamada instanceof MetodoPrimitiva) {
+                const argumentosResolvidos: any[] = [];
+                for (const argumento of expressao.argumentos) {
+                    const valorResolvido: any = await this.avaliar(argumento);
+                    argumentosResolvidos.push(
+                        valorResolvido?.hasOwnProperty('valor') ? valorResolvido.valor : valorResolvido
+                    );
+                }
+
+                return await entidadeChamada.chamar(this, argumentosResolvidos);
+            }
+
+            let parametros: ParametroInterface[];
+            if (entidadeChamada instanceof DeleguaFuncao) {
+                parametros = entidadeChamada.declaracao.parametros;
+            } else if (entidadeChamada instanceof DeleguaClasse) {
+                parametros = entidadeChamada.metodos.inicializacao
+                    ? entidadeChamada.metodos.inicializacao.declaracao.parametros
+                    : [];
+            } else {
+                parametros = [];
+            }
+
+            const aridade = entidadeChamada.aridade ? entidadeChamada.aridade() : entidadeChamada.length;
+
+            // Completar os parâmetros não preenchidos com nulos.
+            if (argumentos.length < aridade) {
+                const diferenca = aridade - argumentos.length;
+                for (let i = 0; i < diferenca; i++) {
+                    argumentos.push(null);
+                }
+            } else {
+                if (parametros && parametros.length > 0 && parametros[parametros.length - 1].abrangencia === 'multiplo') {
+                    const novosArgumentos = argumentos.slice(0, parametros.length - 1);
+                    novosArgumentos.push(argumentos.slice(parametros.length - 1, argumentos.length));
+                    argumentos = novosArgumentos;
+                }
+            }
+
+            if (entidadeChamada instanceof FuncaoPadrao) {
+                try {
+                    return entidadeChamada.chamar(
+                        argumentos.map((a) => (a !== null && a.hasOwnProperty('valor') ? a.valor : a)),
+                        expressao.entidadeChamada.nome
+                    );
+                } catch (erro: any) {
+                    this.erros.push({
+                        erroInterno: erro,
+                        linha: expressao.linha,
+                        hashArquivo: expressao.hashArquivo,
+                    });
+                    this.erros.push(erro);
+                }
+            }
+
+            if (entidadeChamada instanceof Chamavel) {
+                return entidadeChamada.chamar(this, argumentos);
+            }
+
+            // A função chamada pode ser de uma biblioteca JavaScript.
+            // Neste caso apenas testamos se o tipo é uma função.
+            if (typeof entidadeChamada === 'function') {
+                let objeto = null;
+                if (expressao.entidadeChamada.objeto) {
+                    objeto = await this.avaliar(expressao.entidadeChamada.objeto);
+                }
+                return entidadeChamada.apply(objeto.hasOwnProperty('valor') ? objeto.valor : objeto, argumentos);
+            }
+
+            return Promise.reject(
+                new ErroEmTempoDeExecucao(expressao.parentese, 'Só pode chamar função ou classe.', expressao.linha)
+            );
+        } catch (erro: any) {
+            console.log(erro);
+            this.erros.push({
+                erroInterno: erro,
+                linha: expressao.linha,
+                hashArquivo: expressao.hashArquivo,
+            });
+            this.erros.push(erro);
+        }
     }
     visitarDeclaracaoDeAtribuicao(expressao: Atribuir) {
         throw new Error('Método não implementado.');
@@ -339,12 +456,22 @@ export class InterpretadorBirl implements InterpretadorInterface {
      * @returns Promise com o resultado da leitura.
      */
     async visitarExpressaoLeia(expressao: Leia): Promise<any> {
-        const mensagem = expressao.argumentos && expressao.argumentos[0] ? expressao.argumentos[0].valor : '> ';
-        return new Promise((resolucao) =>
-            this.interfaceEntradaSaida.question(mensagem, (resposta: any) => {
-                resolucao(resposta);
-            })
-        );
+        // const mensagem = expressao.argumentos && expressao.argumentos[0] ? expressao.argumentos[0].valor : '> ';
+        /**
+         * Em Birl não se usa mensagem junto com o prompt, normalmente se usa um Escreva antes.
+         */
+        const mensagem = '> ';
+        const promessaLeitura: Function = () =>
+            new Promise((resolucao) =>
+                this.interfaceEntradaSaida.question(mensagem, (resposta: any) => {
+                    resolucao(resposta);
+                })
+            );
+
+        const valorLido = await promessaLeitura();
+        await comum.atribuirVariavel(this, expressao.argumentos[0], valorLido, expressao.argumentos[1].valor);
+
+        return;
     }
 
     /**
@@ -391,9 +518,9 @@ export class InterpretadorBirl implements InterpretadorInterface {
 
     visitarExpressaoLiteral(expressao: Literal): any {
         if (expressao.valor === tiposDeSimbolos.ADICAO) {
-            return 1
+            return 1;
         } else if (expressao.valor === tiposDeSimbolos.SUBTRACAO) {
-            return -1
+            return -1;
         } else {
             return expressao.valor;
         }
@@ -404,11 +531,7 @@ export class InterpretadorBirl implements InterpretadorInterface {
     }
     async visitarDeclaracaoPara(declaracao: Para): Promise<any> {
         if (declaracao.inicializador !== null) {
-            if (declaracao.inicializador instanceof Array) {
-                await this.avaliar(declaracao.inicializador[0]);
-            } else {
-                await this.avaliar(declaracao.inicializador);
-            }
+            await this.avaliar(declaracao.inicializador);
         }
 
         let retornoExecucao: any;
@@ -498,8 +621,29 @@ export class InterpretadorBirl implements InterpretadorInterface {
     visitarDeclaracaoTente(declaracao: Tente) {
         throw new Error('Método não implementado.');
     }
-    visitarDeclaracaoEnquanto(declaracao: Enquanto) {
-        throw new Error('Método não implementado.');
+    async visitarDeclaracaoEnquanto(declaracao: Enquanto): Promise<any> {
+        let retornoExecucao: any;
+        while (!(retornoExecucao instanceof Quebra) && this.eVerdadeiro(await this.avaliar(declaracao.condicao))) {
+            try {
+                retornoExecucao = await this.executar(declaracao.corpo);
+                if (retornoExecucao instanceof SustarQuebra) {
+                    return null;
+                }
+
+                if (retornoExecucao instanceof ContinuarQuebra) {
+                    retornoExecucao = null;
+                }
+            } catch (erro: any) {
+                this.erros.push({
+                    erroInterno: erro,
+                    linha: declaracao.linha,
+                    hashArquivo: declaracao.hashArquivo,
+                });
+                return Promise.reject(erro);
+            }
+        }
+
+        return retornoExecucao;
     }
     visitarDeclaracaoImportar(declaracao: Importar) {
         throw new Error('Método não implementado.');
@@ -546,8 +690,9 @@ export class InterpretadorBirl implements InterpretadorInterface {
 
     protected async avaliacaoDeclaracaoVar(declaracao: Var): Promise<any> {
         let valorOuOutraVariavel = null;
+
         if (declaracao.inicializador !== null) {
-            valorOuOutraVariavel = await this. avaliar(declaracao.inicializador);
+            valorOuOutraVariavel = await this.avaliar(declaracao.inicializador);
         }
 
         let valorFinal = null;
@@ -581,11 +726,12 @@ export class InterpretadorBirl implements InterpretadorInterface {
     visitarDeclaracaoConst(declaracao: Const): Promise<any> {
         throw new Error('Método não implementado.');
     }
+
     visitarExpressaoContinua(declaracao?: Continua): ContinuarQuebra {
-        throw new Error('Método não implementado.');
+        return new ContinuarQuebra();
     }
-    visitarExpressaoSustar(declaracao?: Sustar): SustarQuebra {
-        throw new Error('Método não implementado.');
+    visitarExpressaoSustar(declaracao?: any): SustarQuebra {
+        return new SustarQuebra();
     }
     async visitarExpressaoRetornar(declaracao: Retorna): Promise<RetornoQuebra> {
         let valor = null;
@@ -606,7 +752,8 @@ export class InterpretadorBirl implements InterpretadorInterface {
         throw new Error('Método não implementado.');
     }
     visitarDeclaracaoDefinicaoFuncao(declaracao: FuncaoDeclaracao) {
-        throw new Error('Método não implementado.');
+        const funcao = new DeleguaFuncao(declaracao.simbolo.lexema, declaracao.funcao);
+        this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, funcao);
     }
     visitarDeclaracaoClasse(declaracao: Classe) {
         throw new Error('Método não implementado.');
@@ -656,22 +803,15 @@ export class InterpretadorBirl implements InterpretadorInterface {
      */
     async executar(declaracao: Declaracao, mostrarResultado = false): Promise<any> {
         let resultado: any = null;
-        // Tratar caso Bloco
-        if (declaracao instanceof Array) {
-            for (const decl of declaracao) {
-                resultado = await this.executar(decl, mostrarResultado);
-            }
-            return resultado;
-        } else {
-            resultado = await declaracao.aceitar(this);
-            if (mostrarResultado) {
-                this.funcaoDeRetorno(this.paraTexto(resultado));
-            }
-            if (resultado || typeof resultado === 'boolean') {
-                this.resultadoInterpretador.push(this.paraTexto(resultado));
-            }
-            return resultado;
+
+        resultado = await declaracao.aceitar(this);
+        if (mostrarResultado) {
+            this.funcaoDeRetorno(this.paraTexto(resultado));
+        }
+        if (resultado || typeof resultado === 'boolean') {
+            this.resultadoInterpretador.push(this.paraTexto(resultado));
         }
+        return resultado;
     }
 
     /**


Test patch:
diff --git a/testes/birl/analisador-semantico.test.ts b/testes/birl/analisador-semantico.test.ts
new file mode 100644
index 00000000..81fc6912
--- /dev/null
+++ b/testes/birl/analisador-semantico.test.ts
@@ -0,0 +1,51 @@
+import {LexadorBirl} from '../../fontes/lexador/dialetos'
+import {AvaliadorSintaticoBirl} from '../../fontes/avaliador-sintatico/dialetos'
+import {AnalisadorSemanticoBirl} from '../../fontes/analisador-semantico/dialetos'
+
+describe('Analisador semântico', () => {
+    let lexador: LexadorBirl;
+    let avaliadorSintatico: AvaliadorSintaticoBirl;
+    let analisadorSemantico: AnalisadorSemanticoBirl;
+
+    describe('analisar()', () => {
+        beforeEach(() => {
+            lexador = new LexadorBirl()
+            avaliadorSintatico = new AvaliadorSintaticoBirl()
+            analisadorSemantico = new AnalisadorSemanticoBirl()
+        })
+
+        describe('Cenários de sucesso', () => {
+            it('Sucesso - Olá Mundo', () => {
+                const retornoLexador = lexador.mapear(
+                    [
+                        'HORA DO SHOW',
+                        '  CE QUER VER ESSA PORRA? ("Hello, World! Porra!\n");',
+                        '  BORA CUMPADE 0;',
+                        'BIRL',
+                    ],
+                    -1
+                );
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+                const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoAnalisadorSemantico).toBeTruthy();
+                expect(retornoAnalisadorSemantico.erros).toHaveLength(0);
+            })
+            it('Sucesso - Verifica tipo LEIA', () => {
+                const retornoLexador = lexador.mapear([
+                    'HORA DO SHOW',
+                    '   MONSTRO X;',
+                    '   QUE QUE CE QUER MONSTRAO? ("%d", &X);',
+                    '   BORA CUMPADE 0;',
+                    'BIRL',
+                ]);
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+                const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoAnalisadorSemantico).toBeTruthy();
+                expect(retornoAnalisadorSemantico.erros).toHaveLength(0);
+            })
+        })
+    })
+})
diff --git a/testes/birl/avaliador-sintatico.test.ts b/testes/birl/avaliador-sintatico.test.ts
index d8a358d4..857957c9 100644
--- a/testes/birl/avaliador-sintatico.test.ts
+++ b/testes/birl/avaliador-sintatico.test.ts
@@ -1,20 +1,16 @@
 import { AvaliadorSintaticoBirl } from '../../fontes/avaliador-sintatico/dialetos';
-import { LexadorBirl } from '../../fontes/lexador/dialetos';
 import {
-    Bloco,
-    Continua,
     Enquanto,
     Escreva,
     FuncaoDeclaracao,
     Para,
-    Retorna,
     Se,
-    Sustar,
-    Var,
+    Var
 } from '../../fontes/declaracoes';
+import { LexadorBirl } from '../../fontes/lexador/dialetos';
 
-import { Chamada, FuncaoConstruto } from '../../fontes/construtos';
 import { ErroAvaliadorSintatico } from '../../fontes/avaliador-sintatico/erro-avaliador-sintatico';
+import { Chamada } from '../../fontes/construtos';
 
 describe('Avaliador Sintático Birl', () => {
     describe('analisar()', () => {
@@ -27,6 +23,21 @@ describe('Avaliador Sintático Birl', () => {
         });
 
         describe('Cenários de sucesso', () => {
+            it('Sucesso - Ler da tela', () => {
+                const retornoLexador = lexador.mapear([
+                    'HORA DO SHOW',
+                    '   MONSTRO X;',
+                    '   QUE QUE CE QUER MONSTRAO? ("%d", &X);',
+                    '   BORA CUMPADE 0;',
+                    'BIRL',
+                ]);
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+                expect(retornoAvaliadorSintatico).toBeTruthy();
+                expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(3);
+            });
+
             it('Sucesso - Hello, World! Porra!', () => {
                 const retornoLexador = lexador.mapear(
                     [
@@ -233,7 +244,7 @@ describe('Avaliador Sintático Birl', () => {
                 expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(2);
                 expect(retornoAvaliadorSintatico.declaracoes[1].assinaturaMetodo).toBe('<principal>');
                 expect(retornoAvaliadorSintatico.declaracoes[1]).toBeInstanceOf(Para);
-                const declaracao1 = retornoAvaliadorSintatico.declaracoes[0][0] as Var;
+                const declaracao1 = retornoAvaliadorSintatico.declaracoes[0] as Var;
                 expect(declaracao1.inicializador.valor).toBe(0);
                 expect(declaracao1.simbolo.lexema).toBe('M');
                 expect((retornoAvaliadorSintatico.declaracoes[1] as Para).corpo.declaracoes[0]).toBeInstanceOf(Escreva);
@@ -253,7 +264,7 @@ describe('Avaliador Sintático Birl', () => {
                 expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(2);
                 expect(retornoAvaliadorSintatico.declaracoes[1].assinaturaMetodo).toBe('<principal>');
                 expect(retornoAvaliadorSintatico.declaracoes[1]).toBeInstanceOf(Para);
-                const declaracao1 = retornoAvaliadorSintatico.declaracoes[0][0] as Var;
+                const declaracao1 = retornoAvaliadorSintatico.declaracoes[0] as Var;
                 expect(declaracao1.inicializador.valor).toBe(0);
                 expect(declaracao1.simbolo.lexema).toBe('M');
                 expect((retornoAvaliadorSintatico.declaracoes[1] as Para).corpo.declaracoes[0]).toBeInstanceOf(Escreva);
@@ -330,11 +341,6 @@ describe('Avaliador Sintático Birl', () => {
                 expect(retornoAvaliadorSintatico.declaracoes[0]).toBeInstanceOf(FuncaoDeclaracao);
                 const declaracoes = retornoAvaliadorSintatico.declaracoes[0] as FuncaoDeclaracao;
                 expect(declaracoes.tipoRetorno?.tipo).toBe('MONSTRO');
-                const funcao = declaracoes.funcao as FuncaoConstruto;
-                expect(funcao.parametros[0]).toHaveLength(2);
-                expect(funcao.corpo).toHaveLength(2);
-                expect(funcao.corpo[1]).toBeInstanceOf(Retorna);
-                expect(funcao.corpo[0]).toBeInstanceOf(Array<Var>);
             });
 
             it('Sucesso - declaração - chamarFuncao - string', () => {
@@ -373,10 +379,10 @@ describe('Avaliador Sintático Birl', () => {
                 const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
                 expect(retornoAvaliadorSintatico).toBeTruthy();
                 expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(3);
-                const declaracao3 = retornoAvaliadorSintatico.declaracoes[2] as unknown as Array<Var>;
-                expect(declaracao3[0].tipo).toBe('numero');
-                expect(declaracao3[0].assinaturaMetodo).toBe('<principal>');
-                expect(declaracao3[0].inicializador.valor).toBeInstanceOf(Chamada);
+                const declaracao3 = retornoAvaliadorSintatico.declaracoes[2] as Var;
+                expect(declaracao3.tipo).toBe('numero');
+                expect(declaracao3.assinaturaMetodo).toBe('<principal>');
+                expect(declaracao3.inicializador).toBeInstanceOf(Chamada);
             });
         });
         describe('Cenários de erro', () => {
diff --git a/testes/birl/interpretador.test.ts b/testes/birl/interpretador.test.ts
index 81ad60f1..d1c703f4 100644
--- a/testes/birl/interpretador.test.ts
+++ b/testes/birl/interpretador.test.ts
@@ -1,6 +1,6 @@
 import { AvaliadorSintaticoBirl } from '../../fontes/avaliador-sintatico/dialetos';
-import { LexadorBirl } from '../../fontes/lexador/dialetos';
 import { InterpretadorBirl } from '../../fontes/interpretador/dialetos';
+import { LexadorBirl } from '../../fontes/lexador/dialetos';
 
 describe('Interpretador', () => {
     describe('interpretar()', () => {
@@ -15,6 +15,118 @@ describe('Interpretador', () => {
                 interpretador = new InterpretadorBirl(process.cwd());
             });
 
+            it('Sucesso - declaração - chamarFuncao', async () => {
+                const retornoLexador = lexador.mapear([
+                    'HORA DO SHOW \n',
+                    '   OH O HOME AI PO (MONSTRO SOMAR(MONSTRO primeiroParametro, MONSTRO segundoParametro))\n',
+                    '       MONSTRO resultado = primeiroParametro + segundoParametro;\n',
+                    '       BORA CUMPADE resultado;',
+                    '   BIRL',
+                    '   MONSTRO primeiro = 5;\n',
+                    '   MONSTRO segundo = 10;\n',
+                    '   MONSTRO resultado = AJUDA O MALUCO TA DOENTE SOMAR(primeiro, segundo);\n',
+                    'BIRL\n',
+                ]);
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            it('Sucesso - Verifica tipo LEIA', async () => {
+                const respostas = ['5'];
+                interpretador.interfaceEntradaSaida = {
+                    question: (mensagem: string, callback: Function) => {
+                        callback(respostas.shift());
+                    },
+                };
+                const retornoLexador = lexador.mapear([
+                    'HORA DO SHOW',
+                    '   MONSTRO X;',
+                    '   QUE QUE CE QUER MONSTRAO? ("%d", &X);',
+                    '   BORA CUMPADE 0;',
+                    'BIRL',
+                ]);
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador).toBeTruthy();
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            it('Sucesso - declaração - declaracaoFuncao', async () => {
+                const retornoLexador = lexador.mapear([
+                    'HORA DO SHOW \n',
+                    '   OH O HOME AI PO(MONSTRO NOMEFUNCAO(MONSTRO primeiro, MONSTRO segundo))\n',
+                    '       MONSTRO C = primeiro + segundo;\n',
+                    '       BORA CUMPADE C;\n',
+                    '   BIRL\n',
+                    'BIRL\n',
+                ]);
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            it('Sucesso - declaração - continue', async () => {
+                const retornoLexador = lexador.mapear([
+                    'HORA DO SHOW \n',
+                    '   MONSTRO M;\n',
+                    '   MAIS QUERO MAIS (M = 0; M < 5; M++)\n',
+                    '       CE QUER VER ESSA PORRA? ("teste");\n',
+                    '       ELE QUE A GENTE QUER? (M > 2)\n',
+                    '           SAI FILHO DA PUTA;\n',
+                    '       NAO VAI DAR NAO\n',
+                    '           VAMO MONSTRO;\n',
+                    '       BIRL\n',
+                    '   BIRL\n',
+                    'BIRL\n',
+                ]);
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            it('Sucesso - declaração - break', async () => {
+                const retornoLexador = lexador.mapear([
+                    'HORA DO SHOW \n',
+                    '   MONSTRO M;\n',
+                    '   MAIS QUERO MAIS (M = 0; M < 5; M++)\n',
+                    '       CE QUER VER ESSA PORRA? ("teste");\n',
+                    '       SAI FILHO DA PUTA;\n',
+                    '   BIRL\n',
+                    'BIRL\n',
+                ]);
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            it('Sucesso - declaração - while', async () => {
+                const RetornoLexador = lexador.mapear([
+                    'HORA DO SHOW \n',
+                    '   MONSTRO X = 5;\n',
+                    '   NEGATIVA BAMBAM (X > 2)',
+                    '       CE QUER VER ESSA PORRA? ("teste");\n',
+                    '       X--;\n',
+                    '   BIRL\n',
+                    'BIRL\n',
+                ]);
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(RetornoLexador, -1);
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
             it('Sucesso - maior igual - 1 <= 2', async () => {
                 const retornoLexador = lexador.mapear([
                     'HORA DO SHOW \n',
@@ -71,7 +183,7 @@ describe('Interpretador', () => {
                     'HORA DO SHOW\n',
                     '   CE QUER VER ESSA PORRA? ("Hello, World! Porra!\n");\n',
                     '   BORA CUMPADE? 0;\n',
-                    'BIRL'
+                    'BIRL',
                 ]);
 
                 const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
@@ -79,7 +191,7 @@ describe('Interpretador', () => {
                 const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
 
                 expect(retornoInterpretador.erros).toHaveLength(0);
-            })
+            });
 
             it('Sucesso - declaração - for - decremento - depois', async () => {
                 const retornoLexador = lexador.mapear([
@@ -214,7 +326,7 @@ describe('Interpretador', () => {
                 const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
 
                 expect(retornoInterpretador.erros).toHaveLength(0);
-            })
+            });
 
             it('Sucesso - Variavel - String', async () => {
                 const retornoLexador = lexador.mapear([
@@ -298,7 +410,6 @@ describe('Interpretador', () => {
 
                 expect(retornoInterpretador.erros).toHaveLength(0);
             });
-
         });
     });
 });