Repository: DesignLiquido/delegua
Pull request #314 (2023-04-07 05:34:23)

Estrutura inicial da Linguagem Mapler
Andamento...

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: 75.39%">72.71% (-2.68% 🔻)</div> |    5202/7154    |
|                                                                           🟡                                                                           | Branches   | <div title="Base coverage is: 63.51%">60.79% (-2.72% 🔻)</div> |    1600/2632    |
|                                                                           🟡                                                                           | Functions  | <div title="Base coverage is: 77.24%">74.49% (-2.75% 🔻)</div> |     774/1039    |
|                                                                           🟡                                                                           | Lines      | <div title="Base coverage is: 75.86%">73.15% (-2.71% 🔻)</div> |    5059/6916    |

<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="avaliador-sintatico/dialetos/avaliador-sintatico-mapler.ts">`...` / avaliador-sintatico-mapler.ts</div>                  | 42.33%     | 46.81%   | 47.06%    | 42.72% |
|                                                                           🟢                                                                           | <div title="tipos-de-simbolos/mapler.ts">`...` / mapler.ts</div>                                                                     | 100%       | 100%     | 100%      | 100%   |
|                                                                           🔴                                                                           | <div title="lexador/dialetos/lexador-mapler.ts">`...` / lexador-mapler.ts</div>                                                      | 48.76%     | 44.9%    | 100%      | 48.31% |
|                                                                           🟢                                                                           | <div title="lexador/dialetos/palavras-reservadas/mapler.ts">`...` / mapler.ts</div>                                                  | 100%       | 100%     | 100%      | 100%   |
|                                                                           🔴                                                                           | <div title="interpretador/dialetos/mapler/interpretador-mapler.ts">`...` / interpretador-mapler.ts</div>                             | 43.59%     | 58.33%   | 27.27%    | 44.74% |
|                                                                           🔴                                                                           | <div title="interpretador/dialetos/mapler/comum.ts">`...` / comum.ts</div>                                                           | 7.81%      | 0%       | 0%        | 8.47%  |
|                                                                           🔴                                                                           | <div title="interpretador/dialetos/mapler/interpretador-mapler-com-depuracao.ts">`...` / interpretador-mapler-com-depuracao.ts</div> | 9.62%      | 0%       | 0%        | 9.62%  |

</details>


## Test suite run success
374 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 052ee5dc46e2ffd7d0373546638175f34538c4b4</p>
<!-- Sticky Pull Request Comment -->

Patch:
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 121ada43..68b0873b 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -678,6 +678,20 @@
             "console": "integratedTerminal",
             "internalConsoleOptions": "neverOpen"
         },
+        {
+            "name": "Testes unitários - Mapler",
+            "type": "node",
+            "request": "launch",
+            "runtimeArgs": [
+                "--inspect-brk",
+                "${workspaceRoot}/node_modules/jest/bin/jest.js",
+                "mapler",
+                "--runInBand"
+            ],
+            "skipFiles": ["<node_internals>/**", "node_modules/**"],
+            "console": "integratedTerminal",
+            "internalConsoleOptions": "neverOpen"
+        },
         {
             "name": "Testes unitários - Portugol IPT",
             "type": "node",
diff --git a/fontes/avaliador-sintatico/avaliador-sintatico-base.ts b/fontes/avaliador-sintatico/avaliador-sintatico-base.ts
index 7ac8f704..14d68bd7 100644
--- a/fontes/avaliador-sintatico/avaliador-sintatico-base.ts
+++ b/fontes/avaliador-sintatico/avaliador-sintatico-base.ts
@@ -37,7 +37,6 @@ export abstract class AvaliadorSintaticoBase implements AvaliadorSintaticoInterf
     atual: number;
     blocos: number;
 
-
     consumir(tipo: string, mensagemDeErro: string): SimboloInterface {
         if (this.verificarTipoSimboloAtual(tipo)) return this.avancarEDevolverAnterior();
         throw this.erro(this.simbolos[this.atual], mensagemDeErro);
diff --git a/fontes/avaliador-sintatico/avaliador-sintatico.ts b/fontes/avaliador-sintatico/avaliador-sintatico.ts
index a61a7431..1c0cccb6 100644
--- a/fontes/avaliador-sintatico/avaliador-sintatico.ts
+++ b/fontes/avaliador-sintatico/avaliador-sintatico.ts
@@ -664,7 +664,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
                 tiposDeSimbolos.FALSO,
                 tiposDeSimbolos.PARENTESE_ESQUERDO,
                 tiposDeSimbolos.SUPER,
-            ]
+            ].includes(this.simbolos[this.atual].tipo)
         ) {
             valor = this.expressao();
         }
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-mapler.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-mapler.ts
new file mode 100644
index 00000000..84252f8b
--- /dev/null
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-mapler.ts
@@ -0,0 +1,780 @@
+import { RetornoLexador, RetornoAvaliadorSintatico } from '../../interfaces/retornos';
+import { AvaliadorSintaticoBase } from '../avaliador-sintatico-base';
+import {
+    Bloco,
+    Declaracao,
+    Enquanto,
+    Escolha,
+    Escreva,
+    EscrevaMesmaLinha,
+    Fazer,
+    FuncaoDeclaracao,
+    Leia,
+    Para,
+    Se,
+    Sustar,
+    Var,
+} from '../../declaracoes';
+import {
+    AcessoIndiceVariavel,
+    Agrupamento,
+    AtribuicaoSobrescrita,
+    Atribuir,
+    Binario,
+    Chamada,
+    Construto,
+    FormatacaoEscrita,
+    FuncaoConstruto,
+    Literal,
+    Logico,
+    Variavel,
+} from '../../construtos';
+import { SimboloInterface } from '../../interfaces';
+import { Simbolo } from '../../lexador';
+
+import tiposDeSimbolos from '../../tipos-de-simbolos/mapler';
+
+export class AvaliadorSintaticoMapler extends AvaliadorSintaticoBase {
+    private criarVetorNDimensional(dimensoes: number[]) {
+        if (dimensoes.length > 0) {
+            const dimensao = dimensoes[0] + 1;
+            const resto = dimensoes.slice(1);
+            const novoArray = Array(dimensao);
+            for (let i = 0; i <= dimensao; i++) {
+                novoArray[i] = this.criarVetorNDimensional(resto);
+            }
+            return novoArray;
+        } else {
+            return undefined;
+        }
+    }
+
+    private validarDimensoesVetor(): number[] {
+        let dimensoes = [];
+        do {
+            const numeroInicial = this.consumir(
+                tiposDeSimbolos.NUMERO,
+                'Esperado índice inicial para inicialização de dimensão de vetor.'
+            );
+            this.consumir(
+                tiposDeSimbolos.PONTO,
+                'Esperado primeiro ponto após índice inicial para inicialização de dimensão de vetor.'
+            );
+            this.consumir(
+                tiposDeSimbolos.PONTO,
+                'Esperado segundo ponto após índice inicial para inicialização de dimensão de vetor.'
+            );
+            const numeroFinal = this.consumir(
+                tiposDeSimbolos.NUMERO,
+                'Esperado índice final para inicialização de dimensão de vetor.'
+            );
+            dimensoes.push(Number(numeroFinal.literal) - Number(numeroInicial.literal));
+        } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
+
+        return dimensoes;
+    }
+
+    private logicaComumParametroMapler(): 
+        { identificadores: SimboloInterface[], tipo: string, simbolo: SimboloInterface }
+    {
+        const identificadores = [];
+        do {
+            identificadores.push(this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome de variável.'));
+        } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
+
+        this.consumir(tiposDeSimbolos.DOIS_PONTOS, 'Esperado dois-pontos após nome de variável.');
+
+        if (
+            !this.verificarSeSimboloAtualEIgualA(
+                tiposDeSimbolos.CADEIA,
+                tiposDeSimbolos.CARACTERE,
+                tiposDeSimbolos.INTEIRO,
+                tiposDeSimbolos.LOGICO,
+                tiposDeSimbolos.REAL,
+                tiposDeSimbolos.VETOR
+            )
+        ) {
+            throw this.erro(this.simbolos[this.atual], 'Tipo de variável não conhecido.');
+        }
+
+        const simboloAnterior = this.simbolos[this.atual - 1];
+        const tipoVariavel: string = simboloAnterior.tipo;
+
+        return {
+            identificadores,
+            tipo: tipoVariavel,
+            simbolo: simboloAnterior
+        };
+    }
+
+    /**
+     * Validação do segmento de declaração de variáveis (opcional).
+     * @returns Vetor de Construtos para inicialização de variáveis.
+     */
+    private validarSegmentoVariaveis(): Construto[] | Declaracao[] {
+        const inicializacoes = [];
+
+        while (!this.verificarTipoSimboloAtual(tiposDeSimbolos.INICIO)) {
+
+            const simboloAtual = this.simbolos[this.atual];
+            
+            switch (simboloAtual.tipo) {
+                // case tiposDeSimbolos.PROCEDIMENTO:
+                //     const dadosProcedimento = this.declaracaoProcedimento();
+                //     inicializacoes.push(dadosProcedimento);
+                //     break;
+                default:
+                    const dadosVariaveis = this.logicaComumParametroMapler();
+                    // Se chegou até aqui, variáveis são válidas.
+                    // Devem ser declaradas com um valor inicial padrão.
+                    for (let identificador of dadosVariaveis.identificadores) {
+                        switch (dadosVariaveis.tipo) {
+                            case tiposDeSimbolos.CADEIA:
+                            case tiposDeSimbolos.CARACTERE:
+                                inicializacoes.push(
+                                    new Var(identificador, new Literal(this.hashArquivo, Number(dadosVariaveis.simbolo.linha), ''))
+                                );
+                                break;
+                            case tiposDeSimbolos.INTEIRO:
+                            case tiposDeSimbolos.REAL:
+                                inicializacoes.push(
+                                    new Var(identificador, new Literal(this.hashArquivo, Number(dadosVariaveis.simbolo.linha), 0))
+                                );
+                                break;
+                            case tiposDeSimbolos.LOGICO:
+                                inicializacoes.push(
+                                    new Var(identificador, new Literal(this.hashArquivo, Number(dadosVariaveis.simbolo.linha), false))
+                                );
+                                break;
+                            case tiposDeSimbolos.VETOR:
+                                // TODO: Validar vetor
+                                this.consumir(
+                                    tiposDeSimbolos.COLCHETE_ESQUERDO,
+                                    'Esperado colchete esquerdo após palavra reservada "vetor".'
+                                );
+                                const dimensoes = this.validarDimensoesVetor();
+                                this.consumir(
+                                    tiposDeSimbolos.COLCHETE_DIREITO,
+                                    'Esperado colchete direito após declaração de dimensões de vetor.'
+                                );
+                                this.consumir(
+                                    tiposDeSimbolos.DE,
+                                    'Esperado palavra reservada "de" após declaração de dimensões de vetor.'
+                                );
+                                if (
+                                    !this.verificarSeSimboloAtualEIgualA(
+                                        tiposDeSimbolos.CARACTERE,
+                                        tiposDeSimbolos.INTEIRO,
+                                        tiposDeSimbolos.LOGICO,
+                                        tiposDeSimbolos.REAL,
+                                        tiposDeSimbolos.VETOR
+                                    )
+                                ) {
+                                    throw this.erro(
+                                        this.simbolos[this.atual],
+                                        'Tipo de variável não conhecido para inicialização de vetor.'
+                                    );
+                                }
+                                inicializacoes.push(
+                                    new Var(
+                                        identificador,
+                                        new Literal(
+                                            this.hashArquivo,
+                                            Number(dadosVariaveis.simbolo.linha),
+                                            this.criarVetorNDimensional(dimensoes)
+                                        )
+                                    )
+                                );
+                                break;
+                        }
+                    }
+                    break;
+            }
+
+            this.consumir(tiposDeSimbolos.PONTO_VIRGULA, 'Esperado \';\' após declaração de variável.');
+        }
+
+        return inicializacoes;
+    }
+
+    estaNoFinal(): boolean {
+        return this.atual === this.simbolos.length;
+    }
+
+    metodoBibliotecaGlobal(): Construto {
+        const simboloAnterior = this.simbolos[this.atual - 1];
+
+        switch (simboloAnterior.lexema) {
+            case 'int':
+                return new Chamada(
+                    this.hashArquivo,
+                    new Variavel(
+                        this.hashArquivo,
+                        new Simbolo(
+                            tiposDeSimbolos.IDENTIFICADOR,
+                            'inteiro',
+                            null,
+                            Number(simboloAnterior.linha),
+                            this.hashArquivo
+                        )
+                    ),
+                    null,
+                    []
+                );
+            default:
+                return null;
+        }
+    }
+
+    primario(): Construto {
+        const simboloAtual = this.simbolos[this.atual];
+
+        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.FALSO))
+            return new Literal(this.hashArquivo, Number(simboloAtual.linha), false);
+        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VERDADEIRO))
+            return new Literal(this.hashArquivo, Number(simboloAtual.linha), true);
+
+        if (
+            this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IDENTIFICADOR)
+        ) {
+            return new Variavel(this.hashArquivo, this.simbolos[this.atual - 1]);
+        }
+
+        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.NUMERO, tiposDeSimbolos.CARACTERE)) {
+            const simboloAnterior: SimboloInterface = this.simbolos[this.atual - 1];
+            return new Literal(this.hashArquivo, Number(simboloAnterior.linha), simboloAnterior.literal);
+        }
+
+        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARENTESE_ESQUERDO)) {
+            const expressao = this.expressao();
+            this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após a expressão.");
+
+            return new Agrupamento(this.hashArquivo, Number(simboloAtual.linha), expressao);
+        }
+
+        //TODO: @Samuel
+        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO_VIRGULA)) {
+            return null;
+        }
+
+        throw this.erro(this.simbolos[this.atual], 'Esperado expressão.');
+    }
+
+    comparacaoIgualdade(): Construto {
+        let expressao = this.comparar();
+
+        while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.DIFERENTE, tiposDeSimbolos.IGUAL)) {
+            const simboloAnterior = this.simbolos[this.atual - 1];
+            const direito = this.comparar();
+            expressao = new Binario(this.hashArquivo, expressao, simboloAnterior, direito);
+        }
+
+        return expressao;
+    }
+
+    ou(): Construto {
+        let expressao = this.e();
+
+        while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.OU/*, tiposDeSimbolos.XOU*/)) {
+            const operador = this.simbolos[this.atual - 1];
+            const direito = this.e();
+            expressao = new Logico(this.hashArquivo, expressao, operador, direito);
+        }
+
+        return expressao;
+    }
+
+    /**
+     * Método que resolve atribuições.
+     * @returns Um construto do tipo `Atribuir`, `Conjunto` ou `AtribuicaoSobrescrita`.
+     */
+    atribuir(): Construto {
+        const expressao = this.ou();
+
+        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.SETA_ATRIBUICAO)) {
+            const setaAtribuicao = this.simbolos[this.atual - 1];
+            const valor = this.atribuir();
+
+            if (expressao instanceof Variavel) {
+                const simbolo = expressao.simbolo;
+                return new Atribuir(this.hashArquivo, simbolo, valor);
+            } else if (expressao instanceof AcessoIndiceVariavel) {
+                return new AtribuicaoSobrescrita(
+                    this.hashArquivo,
+                    expressao.linha,
+                    expressao.entidadeChamada,
+                    expressao.indice,
+                    valor
+                );
+            }
+
+            this.erro(setaAtribuicao, 'Tarefa de atribuição inválida');
+        }
+
+        return expressao;
+    }
+
+    expressao(): Construto {
+        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.LER)) return this.declaracaoLeia();
+        return this.atribuir();
+    }
+
+    blocoEscopo(): any[] {
+        const declaracoes = [];
+
+        // while (![
+        //         tiposDeSimbolos.FIM_FUNCAO, 
+        //         tiposDeSimbolos.FIM_PROCEDIMENTO
+        //     ].includes(this.simbolos[this.atual].tipo) && !this.estaNoFinal()) 
+        // {
+        //     declaracoes.push(this.declaracao());
+        // }
+
+        // Se chegou até aqui, simplesmente consome o símbolo.
+        this.avancarEDevolverAnterior();
+        // this.consumir(tiposDeSimbolos.FIM_FUNCAO, "Esperado palavra-chave 'fimfuncao' após o bloco.");
+        return declaracoes;
+    }
+
+    chamar(): Construto {
+        let expressao = this.primario();
+
+        while (true) {
+            if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARENTESE_ESQUERDO)) {
+                expressao = this.finalizarChamada(expressao);
+            } else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
+                const indices = [];
+                do {
+                    indices.push(this.expressao());
+                } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
+
+                const indice = indices[0];
+                const simboloFechamento = this.consumir(
+                    tiposDeSimbolos.COLCHETE_DIREITO,
+                    "Esperado ']' após escrita do indice."
+                );
+                expressao = new AcessoIndiceVariavel(this.hashArquivo, expressao, indice, simboloFechamento);
+            } else {
+                break;
+            }
+        }
+
+        return expressao;
+    }
+
+    corpoDaFuncao(tipo: any): FuncaoConstruto {
+        const simboloAnterior = this.simbolos[this.atual - 1];
+        this.consumir(tiposDeSimbolos.DOIS_PONTOS, 'Esperado dois-pontos após nome de função.');
+
+        // Tipo retornado pela função.
+        if (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.INTEIRO, tiposDeSimbolos.CARACTERE)) {
+            throw this.erro(this.simbolos[this.atual], 'Esperado um tipo válido para retorno de função');
+        }
+
+        // this.consumir(tiposDeSimbolos.QUEBRA_LINHA, "Esperado quebra de linha após tipo retornado por 'funcao'.");
+
+        this.validarSegmentoVariaveis();
+        // this.validarSegmentoInicio('função');
+
+        const corpo = this.blocoEscopo();
+
+        return new FuncaoConstruto(this.hashArquivo, Number(simboloAnterior.linha), null, corpo);
+    }
+
+    declaracaoEnquanto(): Enquanto {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        const condicao = this.expressao();
+
+        this.consumir(
+            tiposDeSimbolos.FACA,
+            "Esperado paravra reservada 'faca' após condição de continuidade em declaracão 'enquanto'."
+        );
+
+        const declaracoes = [];
+        do {
+            declaracoes.push(this.declaracao());
+        } while (![tiposDeSimbolos.FIM_ENQUANTO].includes(this.simbolos[this.atual].tipo));
+
+        this.consumir(
+            tiposDeSimbolos.FIM_ENQUANTO,
+            "Esperado palavra-chave 'fimenquanto' para fechamento de declaração 'enquanto'."
+        );
+
+        // this.consumir(tiposDeSimbolos.QUEBRA_LINHA, "Esperado quebra de linha após palavra-chave 'fimenquanto'.");
+
+        return new Enquanto(
+            condicao, 
+            new Bloco(
+                simboloAtual.hashArquivo, 
+                Number(simboloAtual.linha), 
+                declaracoes.filter(d => d)
+            )
+        );
+    }
+
+    private logicaCasosEscolha(): any {
+        const literais = [];
+
+        let simboloAtualCaso: SimboloInterface = this.simbolos[this.atual];
+        // while (simboloAtualCaso.tipo !== tiposDeSimbolos.QUEBRA_LINHA) {
+        //     literais.push(this.primario());
+        //     this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA);
+        //     simboloAtualCaso = this.simbolos[this.atual];
+        // }
+
+        return literais;
+    }
+
+    declaracaoEscolha(): Escolha {
+        throw new Error('Method not implemented.');
+    }
+
+    private logicaComumEscreva(): FormatacaoEscrita[] {
+        const simboloAtual = this.simbolos[this.atual];
+        const argumentos: FormatacaoEscrita[] = [];
+
+        do {
+            const valor = this.declaracao();
+
+            argumentos.push(
+                new FormatacaoEscrita(this.hashArquivo, Number(simboloAtual.linha), valor)
+            );
+        } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
+
+        this.consumir(
+            tiposDeSimbolos.PONTO_VIRGULA,
+            "Esperado quebra de linha após fechamento de parênteses pós instrução 'escreva'."
+        );
+
+        return argumentos;
+    }
+
+    declaracaoEscreva(): Escreva {
+        throw new Error('Method not implemented.');
+    }
+
+    declaracaoEscrevaMesmaLinha(): EscrevaMesmaLinha {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        const argumentos = this.logicaComumEscreva();
+
+        return new EscrevaMesmaLinha(Number(simboloAtual.linha), this.hashArquivo, argumentos);
+    }
+
+    /**
+     * Criação de declaração "repita".
+     * @returns Um construto do tipo Fazer
+     */
+    declaracaoFazer(): Fazer {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        // this.consumir(tiposDeSimbolos.QUEBRA_LINHA, "Esperado quebra de linha após instrução 'repita'.");
+
+        const declaracoes = [];
+        do {
+            declaracoes.push(this.declaracao());
+        } while (![tiposDeSimbolos.ATE].includes(this.simbolos[this.atual].tipo));
+
+        this.consumir(
+            tiposDeSimbolos.ATE,
+            "Esperado palavra-chave 'ate' após declaração de bloco em instrução 'repita'."
+        );
+
+        const condicao = this.expressao();
+
+        // this.consumir(
+        //     tiposDeSimbolos.QUEBRA_LINHA,
+        //     "Esperado quebra de linha após condição de continuidade em instrução 'repita'."
+        // );
+
+        return new Fazer(
+            this.hashArquivo,
+            Number(simboloAtual.linha),
+            new Bloco(
+                this.hashArquivo,
+                Number(simboloAtual.linha),
+                declaracoes.filter((d) => d)
+            ),
+            condicao
+        );
+    }
+
+    /**
+     * Criação de declaração "interrompa".
+     * Em Mapler, "sustar" é chamada de "interrompa".
+     * @returns Uma declaração do tipo Sustar.
+     */
+    private declaracaoInterrompa(): Sustar {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        // TODO: Contar blocos para colocar esta condição de erro.
+        /* if (this.blocos < 1) {
+            this.erro(this.simbolos[this.atual - 1], "'interrompa' deve estar dentro de um laço de repetição.");
+        } */
+
+        return new Sustar(simboloAtual);
+    }
+
+    /**
+     * Análise de uma declaração `leia()`. No Mapler, `leia()` aceita 1..N argumentos.
+     * @returns Uma declaração `Leia`.
+     */
+    declaracaoLeia(): Leia {
+        const simboloAtual = this.avancarEDevolverAnterior();
+
+        // this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' antes do argumento em instrução `leia`.");
+
+        const argumentos = [];
+        do {
+            argumentos.push(this.declaracao());
+        } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO_VIRGULA));
+
+        // this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após o argumento em instrução `leia`.");
+
+        // this.consumir(
+        //     tiposDeSimbolos.QUEBRA_LINHA,
+        //     'Esperado quebra de linha após fechamento de parênteses pós instrução `leia`.'
+        // );
+
+        return new Leia(Number(simboloAtual.linha), simboloAtual.hashArquivo, argumentos);
+    }
+
+    declaracaoPara(): Para {
+        throw new Error('Method not implemented.');
+
+        // const simboloPara: SimboloInterface = this.avancarEDevolverAnterior();
+
+        // const variavelIteracao = this.consumir(
+        //     tiposDeSimbolos.IDENTIFICADOR,
+        //     "Esperado identificador de variável após 'para'."
+        // );
+
+        // this.consumir(tiposDeSimbolos.DE, "Esperado palavra reservada 'de' após variáve de controle de 'para'.");
+
+        // const numeroInicio = this.consumir(
+        //     tiposDeSimbolos.NUMERO,
+        //     "Esperado literal ou variável após 'de' em declaração 'para'."
+        // );
+
+        // this.consumir(
+        //     tiposDeSimbolos.ATE,
+        //     "Esperado palavra reservada 'ate' após valor inicial do laço de repetição 'para'."
+        // );
+
+        // const numeroFim = this.consumir(
+        //     tiposDeSimbolos.NUMERO,
+        //     "Esperado literal ou variável após 'de' em declaração 'para'."
+        // );
+
+        // this.consumir(
+        //     tiposDeSimbolos.FACA,
+        //     "Esperado palavra reservada 'faca' após valor final do laço de repetição 'para'."
+        // );
+
+        // this.consumir(
+        //     tiposDeSimbolos.QUEBRA_LINHA,
+        //     "Esperado quebra de linha após palavra reservada 'faca' do laço de repetição 'para'."
+        // );
+
+        // const declaracoesBlocoPara = [];
+        // let simboloAtualBlocoPara: SimboloInterface = this.simbolos[this.atual];
+        // while (simboloAtualBlocoPara.tipo !== tiposDeSimbolos.FIM_PARA) {
+        //     declaracoesBlocoPara.push(this.declaracao());
+        //     simboloAtualBlocoPara = this.simbolos[this.atual];
+        // }
+
+        // this.consumir(tiposDeSimbolos.FIM_PARA, '');
+        // this.consumir(tiposDeSimbolos.QUEBRA_LINHA, "Esperado quebra de linha após palavra reservada 'fimpara'.");
+
+        // const corpo = new Bloco(
+        //     this.hashArquivo,
+        //     Number(simboloPara.linha) + 1,
+        //     declaracoesBlocoPara.filter((d) => d)
+        // );
+
+        // return new Para(
+        //     this.hashArquivo,
+        //     Number(simboloPara.linha),
+        //     new Atribuir(
+        //         this.hashArquivo,
+        //         variavelIteracao,
+        //         new Literal(this.hashArquivo, Number(simboloPara.linha), numeroInicio.literal)
+        //     ),
+        //     new Binario(
+        //         this.hashArquivo,
+        //         new Variavel(this.hashArquivo, variavelIteracao),
+        //         new Simbolo(tiposDeSimbolos.MENOR_IGUAL, '', '', Number(simboloPara.linha), this.hashArquivo),
+        //         new Literal(this.hashArquivo, Number(simboloPara.linha), numeroFim.literal)
+        //     ),
+        //     new Atribuir(
+        //         this.hashArquivo,
+        //         variavelIteracao,
+        //         new Binario(
+        //             this.hashArquivo,
+        //             new Variavel(this.hashArquivo, variavelIteracao),
+        //             new Simbolo(tiposDeSimbolos.ADICAO, '', null, Number(simboloPara.linha), this.hashArquivo),
+        //             new Literal(this.hashArquivo, Number(simboloPara.linha), 1)
+        //         )
+        //     ),
+        //     corpo
+        // );
+    }
+
+    // logicaComumParametros(): ParametroInterface[] {
+    //     const parametros: ParametroInterface[] = [];
+    //     if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARENTESE_ESQUERDO)) {
+    //         while (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PARENTESE_DIREITO)) {
+    //             const dadosParametros = this.logicaComumParametroMapler();
+    //             for (let parametro of dadosParametros.identificadores) {
+    //                 parametros.push({
+    //                     abrangencia: 'padrao',
+    //                     nome: parametro
+    //                 });
+    //             }
+    //         }
+
+    //         // Consumir parêntese direito
+    //         this.consumir(
+    //             tiposDeSimbolos.PARENTESE_DIREITO, 
+    //             "Esperado parêntese direito para finalização da leitura de parâmetros."
+    //         )
+    //     }
+
+    //     return parametros;
+    // }
+
+    /**
+     * Procedimentos nada mais são do que funções que não retornam valor.
+     */
+    // declaracaoProcedimento() {
+    //     const simboloProcedimento: SimboloInterface = this.avancarEDevolverAnterior();
+
+    //     const nomeProcedimento = this.consumir(tiposDeSimbolos.IDENTIFICADOR, 
+    //         "Esperado nome do procedimento após palavra-chave `procedimento`.");
+
+    //     // Parâmetros
+    //     const parametros = this.logicaComumParametros();
+
+    //     this.validarSegmentoVariaveis();
+    //     this.validarSegmentoInicio('procedimento');
+
+    //     const corpo = this.blocoEscopo();
+
+    //     return new FuncaoDeclaracao(
+    //         nomeProcedimento, new FuncaoConstruto(
+    //             this.hashArquivo, 
+    //             Number(simboloProcedimento.linha), 
+    //             parametros, 
+    //             corpo.filter(d => d)
+    //         )
+    //     );
+    // }
+
+    declaracaoSe(): Se {
+        const simboloSe: SimboloInterface = this.avancarEDevolverAnterior();
+
+        const condicao = this.expressao();
+
+        this.consumir(tiposDeSimbolos.ENTAO, "Esperado palavra reservada 'entao' após condição em declaração 'se'.");
+        // this.consumir(
+        //     tiposDeSimbolos.QUEBRA_LINHA,
+        //     "Esperado quebra de linha após palavra reservada 'entao' em declaração 'se'."
+        // );
+
+        const declaracoes = [];
+        do {
+            declaracoes.push(this.declaracao());
+        } while (![tiposDeSimbolos.SENAO, tiposDeSimbolos.FIM_SE].includes(this.simbolos[this.atual].tipo));
+
+        let caminhoSenao = null;
+        if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.SENAO)) {
+            const simboloSenao = this.simbolos[this.atual - 1];
+            const declaracoesSenao = [];
+
+            do {
+                declaracoesSenao.push(this.declaracao());
+            } while (![tiposDeSimbolos.FIM_SE].includes(this.simbolos[this.atual].tipo));
+
+            caminhoSenao = new Bloco(
+                this.hashArquivo,
+                Number(simboloSenao.linha),
+                declaracoesSenao.filter((d) => d)
+            );
+        }
+
+        this.consumir(tiposDeSimbolos.FIM_SE, "Esperado palavra-chave 'fimse' para fechamento de declaração 'se'.");
+
+        // this.consumir(tiposDeSimbolos.QUEBRA_LINHA, "Esperado quebra de linha após palavra-chave 'fimse'.");
+
+        return new Se(
+            condicao,
+            new Bloco(
+                this.hashArquivo,
+                Number(simboloSe.linha),
+                declaracoes.filter((d) => d)
+            ),
+            [],
+            caminhoSenao
+        );
+    }
+
+    declaracao(): Declaracao | Declaracao[] | Construto | Construto[] | any {
+        const simboloAtual = this.simbolos[this.atual];
+        switch (simboloAtual.tipo) {
+            case tiposDeSimbolos.ENQUANTO:
+                return this.declaracaoEnquanto();
+            case tiposDeSimbolos.ESCREVER:
+                return this.declaracaoEscrevaMesmaLinha();
+            // case tiposDeSimbolos.FUNCAO:
+            //     return this.funcao('funcao');
+            // case tiposDeSimbolos.INTERROMPA:
+            //     return this.declaracaoInterrompa();
+            case tiposDeSimbolos.LER:
+                return this.declaracaoLeia();
+            case tiposDeSimbolos.PARA:
+                return this.declaracaoPara();
+            // case tiposDeSimbolos.PARENTESE_DIREITO:
+            //     throw new Error('Não deveria estar caindo aqui.');
+            // case tiposDeSimbolos.PROCEDIMENTO:
+            //     return this.declaracaoProcedimento();
+            // case tiposDeSimbolos.QUEBRA_LINHA:
+            //     this.avancarEDevolverAnterior();
+            //     return null;
+            case tiposDeSimbolos.REPITA:
+                return this.declaracaoFazer();
+            case tiposDeSimbolos.SE:
+                return this.declaracaoSe();
+            default:
+                return this.expressao();
+        }
+    }
+
+    /**
+     * No Mapler, há uma determinada cadência de validação de símbolos.
+     * @param retornoLexador Os símbolos entendidos pelo Lexador.
+     * @param hashArquivo Obrigatório por interface mas não usado aqui.
+     */
+    analisar(retornoLexador: RetornoLexador, hashArquivo?: number): RetornoAvaliadorSintatico {
+        this.erros = [];
+        this.atual = 0;
+        this.blocos = 0;
+
+        this.hashArquivo = hashArquivo || 0;
+        this.simbolos = retornoLexador?.simbolos || [];
+
+        let declaracoes = [];
+        this.consumir(tiposDeSimbolos.VARIAVEIS, "Esperado expressão 'variaveis' para inicializar programa.");
+        declaracoes = declaracoes.concat(this.validarSegmentoVariaveis());
+        this.consumir(tiposDeSimbolos.INICIO, `Esperado expressão 'inicio' para marcar o inicio do programa.`);
+
+        while (!this.estaNoFinal() && this.simbolos[this.atual].tipo !== tiposDeSimbolos.FIM) {
+            declaracoes.push(this.declaracao());
+        }
+
+        return {
+            declaracoes: declaracoes.filter((d) => d),
+            erros: this.erros,
+        } as RetornoAvaliadorSintatico;
+    }
+}
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts
index c30b4840..05da73cb 100644
--- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts
@@ -11,6 +11,7 @@ import {
     FuncaoDeclaracao,
     Leia,
     Para,
+    Retorna,
     Se,
     Sustar,
     Var,
@@ -35,6 +36,13 @@ import { Simbolo } from '../../lexador';
 import tiposDeSimbolos from '../../tipos-de-simbolos/visualg';
 
 export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
+    blocoPrincipalIniciado: boolean;
+
+    constructor() {
+        super();
+        this.blocoPrincipalIniciado = false;
+    }
+
     private validarSegmentoAlgoritmo(): void {
         this.consumir(tiposDeSimbolos.ALGORITMO, "Esperada expressão 'algoritmo' para inicializar programa.");
 
@@ -389,21 +397,30 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
 
     corpoDaFuncao(tipo: any): FuncaoConstruto {
         const simboloAnterior = this.simbolos[this.atual - 1];
+
+        // Parâmetros
+        const parametros = this.logicaComumParametros();
         this.consumir(tiposDeSimbolos.DOIS_PONTOS, 'Esperado dois-pontos após nome de função.');
 
         // Tipo retornado pela função.
-        if (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.INTEIRO, tiposDeSimbolos.CARACTERE)) {
+        if (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.INTEIRO, tiposDeSimbolos.CARACTERE, tiposDeSimbolos.REAL, tiposDeSimbolos.LOGICO)) {
             throw this.erro(this.simbolos[this.atual], 'Esperado um tipo válido para retorno de função');
         }
 
         this.consumir(tiposDeSimbolos.QUEBRA_LINHA, "Esperado quebra de linha após tipo retornado por 'funcao'.");
 
-        this.validarSegmentoVar();
+        const inicializacoes = this.validarSegmentoVar();
         this.validarSegmentoInicio('função');
 
-        const corpo = this.blocoEscopo();
+        const corpo: any[] = (inicializacoes as any[])
+            .concat(this.blocoEscopo());
 
-        return new FuncaoConstruto(this.hashArquivo, Number(simboloAnterior.linha), null, corpo);
+        return new FuncaoConstruto(
+            this.hashArquivo, 
+            Number(simboloAnterior.linha), 
+            parametros, 
+            corpo.filter(d => d)
+        );
     }
 
     declaracaoEnquanto(): Enquanto {
@@ -775,13 +792,15 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
         // Parâmetros
         const parametros = this.logicaComumParametros();
 
-        this.validarSegmentoVar();
+        const inicializacoes = this.validarSegmentoVar();
         this.validarSegmentoInicio('procedimento');
 
-        const corpo = this.blocoEscopo();
+        const corpo: any[] = (inicializacoes as any[])
+            .concat(this.blocoEscopo());
 
         return new FuncaoDeclaracao(
-            nomeProcedimento, new FuncaoConstruto(
+            nomeProcedimento, 
+            new FuncaoConstruto(
                 this.hashArquivo, 
                 Number(simboloProcedimento.linha), 
                 parametros, 
@@ -790,6 +809,28 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
         );
     }
 
+    declaracaoRetorna(): Retorna {
+        const simboloRetorna: SimboloInterface = this.avancarEDevolverAnterior();
+        let valor = null;
+
+        if (
+            [
+                tiposDeSimbolos.CARACTER,
+                tiposDeSimbolos.CARACTERE,
+                tiposDeSimbolos.IDENTIFICADOR,
+                tiposDeSimbolos.NUMERO,
+                tiposDeSimbolos.VERDADEIRO,
+                tiposDeSimbolos.NEGACAO,
+                tiposDeSimbolos.FALSO,
+                tiposDeSimbolos.PARENTESE_ESQUERDO
+            ].includes(this.simbolos[this.atual].tipo)
+        ) {
+            valor = this.expressao();
+        }
+
+        return new Retorna(simboloRetorna, valor);
+    }
+
     declaracaoSe(): Se {
         const simboloSe: SimboloInterface = this.avancarEDevolverAnterior();
 
@@ -839,7 +880,6 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
     }
 
     declaracao(): Declaracao | Declaracao[] | Construto | Construto[] | any {
-        // Refatorar isso no futuro.
         const simboloAtual = this.simbolos[this.atual];
         switch (simboloAtual.tipo) {
             case tiposDeSimbolos.ENQUANTO:
@@ -852,6 +892,9 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
                 return this.declaracaoEscreva();
             case tiposDeSimbolos.FUNCAO:
                 return this.funcao('funcao');
+            case tiposDeSimbolos.INICIO:
+                this.validarSegmentoInicio('algoritmo');
+                return null;
             case tiposDeSimbolos.INTERROMPA:
                 return this.declaracaoInterrompa();
             case tiposDeSimbolos.LEIA:
@@ -867,8 +910,15 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
                 return null;
             case tiposDeSimbolos.REPITA:
                 return this.declaracaoFazer();
+            case tiposDeSimbolos.RETORNE:
+                return this.declaracaoRetorna();
             case tiposDeSimbolos.SE:
                 return this.declaracaoSe();
+            case tiposDeSimbolos.VAR:
+                if (this.blocoPrincipalIniciado) {
+                    throw this.erro(this.simbolos[this.atual], 'Sintaxe incorreta: início do bloco principal já foi declarado.');
+                }
+                return this.validarSegmentoVar();
             default:
                 return this.expressao();
         }
@@ -878,9 +928,12 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
      * No VisuAlg, há uma determinada cadência de validação de símbolos.
      * - O primeiro símbolo é `algoritmo`, seguido por um identificador e
      * uma quebra de linha.
-     * - O segundo símbolo é `var`, que pode ser seguido por uma série de
-     * declarações de variáveis e finalizado por uma quebra de linha.
-     * - O terceiro símbolo é `inicio`, seguido por uma quebra de linha.
+     * - Os próximos símbolo pode `var`, que pode ser seguido por uma série de
+     * declarações de variáveis e finalizado por uma quebra de linha, 
+     * ou ainda `funcao` ou `procedimento`, seguidos dos devidos símbolos que definem 
+     * os blocos.
+     * - O penúltimo símbolo é `inicio`, seguido por uma quebra de linha.
+     * Pode haver ou não declarações dentro do bloco.
      * - O último símbolo deve ser `fimalgoritmo`, que também é usado para
      * definir quando não existem mais construtos a serem adicionados.
      * @param retornoLexador Os símbolos entendidos pelo Lexador.
@@ -890,6 +943,7 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
         this.erros = [];
         this.atual = 0;
         this.blocos = 0;
+        this.blocoPrincipalIniciado = false;
 
         this.hashArquivo = hashArquivo || 0;
         this.simbolos = retornoLexador?.simbolos || [];
@@ -899,12 +953,15 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
         }
 
         let declaracoes = [];
-        this.validarSegmentoAlgoritmo();
-        declaracoes = declaracoes.concat(this.validarSegmentoVar());
-        this.validarSegmentoInicio('algoritmo');
+        this.validarSegmentoAlgoritmo();        
 
         while (!this.estaNoFinal() && this.simbolos[this.atual].tipo !== tiposDeSimbolos.FIM_ALGORITMO) {
-            declaracoes.push(this.declaracao());
+            const declaracao = this.declaracao();
+            if (Array.isArray(declaracao)) {
+                declaracoes = declaracoes.concat(declaracao);
+            } else {
+                declaracoes.push(declaracao);
+            }
         }
 
         return {
diff --git a/fontes/avaliador-sintatico/dialetos/index.ts b/fontes/avaliador-sintatico/dialetos/index.ts
index ac30da9e..454f19e7 100644
--- a/fontes/avaliador-sintatico/dialetos/index.ts
+++ b/fontes/avaliador-sintatico/dialetos/index.ts
@@ -1,6 +1,7 @@
 export * from './avaliador-sintatico-birl';
 export * from './avaliador-sintatico-egua-classico';
 export * from './avaliador-sintatico-eguap';
+export * from './avaliador-sintatico-mapler';
 export * from './avaliador-sintatico-portugol-ipt';
 export * from './avaliador-sintatico-portugol-studio';
 export * from './avaliador-sintatico-visualg';
diff --git a/fontes/interfaces/avaliador-sintatico-interface.ts b/fontes/interfaces/avaliador-sintatico-interface.ts
index 63df6c52..ae40343a 100644
--- a/fontes/interfaces/avaliador-sintatico-interface.ts
+++ b/fontes/interfaces/avaliador-sintatico-interface.ts
@@ -30,7 +30,6 @@ export interface AvaliadorSintaticoInterface {
     atual: number;
     blocos: number;
 
-    // sincronizar(): void;
     consumir(tipo: any, mensagemDeErro: string): any;
     erro(simbolo: SimboloInterface, mensagemDeErro: string): ErroAvaliadorSintatico;
     verificarTipoSimboloAtual(tipo: string): boolean;
diff --git a/fontes/interpretador/dialetos/index.ts b/fontes/interpretador/dialetos/index.ts
index 779cf4ff..d674a9c6 100644
--- a/fontes/interpretador/dialetos/index.ts
+++ b/fontes/interpretador/dialetos/index.ts
@@ -1,4 +1,6 @@
 export * from './egua-classico';
+export * from './mapler/interpretador-mapler';
+export * from './mapler/interpretador-mapler-com-depuracao';
 export * from './portugol-studio/interpretador-portugol-studio';
 export * from './portugol-studio/interpretador-portugol-studio-com-depuracao';
 export * from './visualg/interpretador-visualg';
diff --git a/fontes/interpretador/dialetos/mapler/comum.ts b/fontes/interpretador/dialetos/mapler/comum.ts
new file mode 100644
index 00000000..5fcefd69
--- /dev/null
+++ b/fontes/interpretador/dialetos/mapler/comum.ts
@@ -0,0 +1,165 @@
+import { Binario, Construto, Logico } from "../../../construtos";
+import { InterpretadorInterface, SimboloInterface, VariavelInterface } from "../../../interfaces";
+import { inferirTipoVariavel } from '../../inferenciador';
+
+import tiposDeSimbolos from '../../../tipos-de-simbolos/mapler';
+import { ErroEmTempoDeExecucao } from "../../../excecoes";
+
+async function avaliar(interpretador: InterpretadorInterface, expressao: Construto): Promise<any> {
+    return await expressao.aceitar(interpretador);
+}
+
+function eIgual(esquerda: VariavelInterface | any, direita: VariavelInterface | any): boolean {
+    if (esquerda === null && direita === null) return true;
+    if (esquerda === null) return false;
+    return esquerda === direita;
+}
+
+function eVerdadeiro(objeto: any): boolean {
+    if (objeto === null) return false;
+    if (typeof objeto === 'boolean') return Boolean(objeto);
+    if (objeto.hasOwnProperty('valor')) {
+        return Boolean(objeto.valor);
+    }
+
+    return true;
+}
+
+function verificarOperandosNumeros(
+    operador: SimboloInterface,
+    direita: VariavelInterface | any,
+    esquerda: VariavelInterface | any
+): void {
+    const tipoDireita: string = direita.tipo ? direita.tipo : typeof direita === 'number' ? 'número' : String(NaN);
+    const tipoEsquerda: string = esquerda.tipo
+        ? esquerda.tipo
+        : typeof esquerda === 'number'
+        ? 'número'
+        : String(NaN);
+    if (tipoDireita === 'número' && tipoEsquerda === 'número') return;
+    throw new ErroEmTempoDeExecucao(operador, 'Operadores precisam ser números.', operador.linha);
+}
+
+/**
+ * Método de visita de expressão binária.
+ * Reintroduzido pelas particularidades do VisuAlg.
+ * @param expressao A expressão binária.
+ * @returns O resultado da resolução da expressão.
+ */
+export async function visitarExpressaoBinaria(interpretador: InterpretadorInterface, expressao: Binario | any): Promise<any> {
+    try {
+        const esquerda: VariavelInterface | any = await avaliar(interpretador, expressao.esquerda);
+        const direita: VariavelInterface | any = await avaliar(interpretador, expressao.direita);
+
+        let valorEsquerdo: any = esquerda?.hasOwnProperty('valor') ? esquerda.valor : esquerda;
+        let valorDireito: any = direita?.hasOwnProperty('valor') ? direita.valor : direita;
+
+        // No VisuAlg, uma variável pode resolver para função porque funções não precisam ter parênteses.
+        // Esta parte evita o problema.
+        if (valorEsquerdo && valorEsquerdo.hasOwnProperty('funcao')) {
+            valorEsquerdo = valorEsquerdo.funcao();
+        }
+
+        if (valorDireito && valorDireito.hasOwnProperty('funcao')) {
+            valorDireito = valorDireito.funcao();
+        }
+
+        const tipoEsquerdo: string = esquerda?.hasOwnProperty('tipo')
+            ? esquerda.tipo
+            : inferirTipoVariavel(esquerda);
+        const tipoDireito: string = direita?.hasOwnProperty('tipo') ? direita.tipo : inferirTipoVariavel(direita);
+
+        switch (expressao.operador.tipo) {
+            // case tiposDeSimbolos.EXPONENCIACAO:
+            //     verificarOperandosNumeros(expressao.operador, esquerda, direita);
+            //     return Math.pow(valorEsquerdo, valorDireito);
+
+            case tiposDeSimbolos.MAIOR:
+                verificarOperandosNumeros(expressao.operador, esquerda, direita);
+                return Number(valorEsquerdo) > Number(valorDireito);
+
+            case tiposDeSimbolos.MAIOR_IGUAL:
+                verificarOperandosNumeros(expressao.operador, esquerda, direita);
+                return Number(valorEsquerdo) >= Number(valorDireito);
+
+            case tiposDeSimbolos.MENOR:
+                verificarOperandosNumeros(expressao.operador, esquerda, direita);
+                return Number(valorEsquerdo) < Number(valorDireito);
+
+            case tiposDeSimbolos.MENOR_IGUAL:
+                verificarOperandosNumeros(expressao.operador, esquerda, direita);
+                return Number(valorEsquerdo) <= Number(valorDireito);
+
+            case tiposDeSimbolos.SUBTRACAO:
+                verificarOperandosNumeros(expressao.operador, esquerda, direita);
+                return Number(valorEsquerdo) - Number(valorDireito);
+
+            case tiposDeSimbolos.ADICAO:
+                if (tipoEsquerdo === 'número' && tipoDireito === 'número') {
+                    return Number(valorEsquerdo) + Number(valorDireito);
+                } else {
+                    return String(valorEsquerdo) + String(valorDireito);
+                }
+
+            case tiposDeSimbolos.DIVISAO:
+                verificarOperandosNumeros(expressao.operador, esquerda, direita);
+                return Number(valorEsquerdo) / Number(valorDireito);
+
+            // case tiposDeSimbolos.DIVISAO_INTEIRA:
+            //     verificarOperandosNumeros(expressao.operador, esquerda, direita);
+            //     return Math.floor(Number(valorEsquerdo) / Number(valorDireito));
+
+            case tiposDeSimbolos.MULTIPLICACAO:
+                if (tipoEsquerdo === 'texto' || tipoDireito === 'texto') {
+                    // Sem ambos os valores resolvem como texto, multiplica normal.
+                    // Se apenas um resolve como texto, o outro repete o 
+                    // texto n vezes, sendo n o valor do outro.
+                    if (tipoEsquerdo === 'texto' && tipoDireito === 'texto') {
+                        return Number(valorEsquerdo) * Number(valorDireito);    
+                    } 
+                    
+                    if (tipoEsquerdo === 'texto') {
+                        return valorEsquerdo.repeat(Number(valorDireito));
+                    }
+
+                    return valorDireito.repeat(Number(valorEsquerdo));
+                }
+                
+                return Number(valorEsquerdo) * Number(valorDireito);
+
+            case tiposDeSimbolos.MODULO:
+                verificarOperandosNumeros(expressao.operador, esquerda, direita);
+                return Number(valorEsquerdo) % Number(valorDireito);
+
+            case tiposDeSimbolos.DIFERENTE:
+                return !eIgual(valorEsquerdo, valorDireito);
+
+            case tiposDeSimbolos.IGUAL:
+                return eIgual(valorEsquerdo, valorDireito);
+        }
+    } catch (erro: any) {
+        return Promise.reject(erro);
+    }
+}
+
+export async function visitarExpressaoLogica(interpretador: InterpretadorInterface, expressao: Logico): Promise<any> {
+    const esquerda = await avaliar(interpretador, expressao.esquerda);
+
+    // se um estado for verdadeiro, retorna verdadeiro
+    // if (expressao.operador.tipo === tiposDeSimbolos.OU) {
+    //     if (eVerdadeiro(esquerda)) return esquerda;
+    // }
+
+    // se a primeira variável é verdadeiro, retorna a segunda invertida
+    // if (expressao.operador.tipo === tiposDeSimbolos.XOU) {
+    //     const valorDireito = await avaliar(interpretador, expressao.direita);
+    //     return eVerdadeiro(esquerda) !== eVerdadeiro(valorDireito);
+    // }
+
+    // se um estado for falso, retorna falso
+    // if (expressao.operador.tipo === tiposDeSimbolos.E) {
+    //     if (!eVerdadeiro(esquerda)) return esquerda;
+    // }
+
+    return await avaliar(interpretador, expressao.direita);
+}
\ No newline at end of file
diff --git a/fontes/interpretador/dialetos/mapler/interpretador-mapler-com-depuracao.ts b/fontes/interpretador/dialetos/mapler/interpretador-mapler-com-depuracao.ts
new file mode 100644
index 00000000..332b29c9
--- /dev/null
+++ b/fontes/interpretador/dialetos/mapler/interpretador-mapler-com-depuracao.ts
@@ -0,0 +1,147 @@
+import { AcessoIndiceVariavel, Binario, Construto, Logico, Variavel } from '../../../construtos';
+import { EscrevaMesmaLinha, Escreva, Fazer, Leia } from '../../../declaracoes';
+import { ContinuarQuebra, Quebra } from '../../../quebras';
+import { InterpretadorComDepuracao } from '../../interpretador-com-depuracao';
+
+import * as comum from './comum';
+
+/**
+ * Interpretador com depuração para o dialeto Mapler.
+ */
+export class InterpretadorMaplerComDepuracao extends InterpretadorComDepuracao {
+    mensagemPrompt: string;
+
+    constructor(diretorioBase: string, funcaoDeRetorno: Function = null, funcaoDeRetornoMesmaLinha: Function = null) {
+        super(diretorioBase, funcaoDeRetorno, funcaoDeRetornoMesmaLinha);
+        this.mensagemPrompt = '> ';
+    }
+
+    private async avaliarArgumentosEscrevaMapler(argumentos: Construto[]): Promise<string> {
+        let formatoTexto: string = '';
+
+        for (const argumento of argumentos) {
+            const resultadoAvaliacao = await this.avaliar(argumento);
+            let valor = resultadoAvaliacao?.hasOwnProperty('valor') ? resultadoAvaliacao.valor : resultadoAvaliacao;
+
+            formatoTexto += `${this.paraTexto(valor)}`;
+        }
+
+        return formatoTexto;
+    }
+
+    /**
+     * No Mapler, o bloco executa se a condição for falsa.
+     * Por isso a reimplementação aqui.
+     * @param declaracao A declaração `Fazer`
+     * @returns Só retorna em caso de erro na execução, e neste caso, o erro.
+     */
+    async visitarDeclaracaoFazer(declaracao: Fazer): Promise<any> {
+        let retornoExecucao: any;
+        do {
+            try {
+                retornoExecucao = await this.executar(declaracao.caminhoFazer);
+                if (retornoExecucao instanceof ContinuarQuebra) {
+                    retornoExecucao = null;
+                }
+            } catch (erro: any) {
+                return Promise.reject(erro);
+            }
+        } while (
+            !(retornoExecucao instanceof Quebra) &&
+            !this.eVerdadeiro(await this.avaliar(declaracao.condicaoEnquanto))
+        );
+    }
+
+    /**
+     * Execução de uma escrita na saída padrão, sem quebras de linha.
+     * Implementada para alguns dialetos, como Mapler.
+     *
+     * Como `readline.question` sobrescreve o que foi escrito antes, aqui
+     * definimos `this.mensagemPrompt` para uso com `leia`.
+     * No Mapler é muito comum usar `escreva()` seguido de `leia()` para
+     * gerar um prompt na mesma linha.
+     * @param declaracao A declaração.
+     * @returns Sempre nulo, por convenção de visita.
+     */
+    async visitarExpressaoEscrevaMesmaLinha(declaracao: EscrevaMesmaLinha): Promise<any> {
+        try {
+            const formatoTexto: string = await this.avaliarArgumentosEscrevaMapler(declaracao.argumentos);
+            this.mensagemPrompt = formatoTexto;
+            this.funcaoDeRetornoMesmaLinha(formatoTexto);
+            return null;
+        } catch (erro: any) {
+            this.erros.push(erro);
+        }
+    }
+
+    /**
+     * Execução de uma escrita na saída configurada, que pode ser `console` (padrão) ou
+     * alguma função para escrever numa página Web.
+     * @param declaracao A declaração.
+     * @returns Sempre nulo, por convenção de visita.
+     */
+    async visitarExpressaoEscreva(declaracao: Escreva): Promise<any> {
+        try {
+            const formatoTexto: string = await this.avaliarArgumentosEscrevaMapler(declaracao.argumentos);
+            this.funcaoDeRetorno(formatoTexto);
+            return null;
+        } catch (erro: any) {
+            this.erros.push(erro);
+        }
+    }
+
+    async atribuirVariavel(expressao: Construto, valor: any): Promise<any> {
+        if (expressao instanceof Variavel) {
+            this.pilhaEscoposExecucao.atribuirVariavel(expressao.simbolo, valor);
+            return;
+        }
+
+        if (expressao instanceof AcessoIndiceVariavel) {
+            const promises = await Promise.all([
+                this.avaliar(expressao.entidadeChamada),
+                this.avaliar(expressao.indice)
+            ]);
+
+            let alvo = promises[0];
+            let indice = promises[1];
+            if (alvo.hasOwnProperty('valor')) {
+                alvo = alvo.valor;
+            }
+
+            if (indice.hasOwnProperty('valor')) {
+                indice = indice.valor;
+            }
+
+            alvo[indice] = valor;
+        }
+    }
+
+    /**
+     * Execução da leitura de valores da entrada configurada no
+     * início da aplicação.
+     * @param expressao Expressão do tipo Leia
+     * @returns Promise com o resultado da leitura.
+     */
+    async visitarExpressaoLeia(expressao: Leia): Promise<any> {
+        for (let argumento of expressao.argumentos) {
+            const promessaLeitura: Function = () =>
+                new Promise((resolucao) =>
+                    this.interfaceEntradaSaida.question(this.mensagemPrompt, (resposta: any) => {
+                        this.mensagemPrompt = '> ';
+                        resolucao(resposta);
+                    })
+                );
+
+            const valorLido = await promessaLeitura();
+            await this.atribuirVariavel(argumento, valorLido);
+        }
+    }
+
+    async visitarExpressaoBinaria(expressao: Binario | any): Promise<any> {
+        return comum.visitarExpressaoBinaria(this, expressao);
+    }
+
+    async visitarExpressaoLogica(expressao: Logico): Promise<any> {
+        return comum.visitarExpressaoLogica(this, expressao);
+    }
+}
diff --git a/fontes/interpretador/dialetos/mapler/interpretador-mapler.ts b/fontes/interpretador/dialetos/mapler/interpretador-mapler.ts
new file mode 100644
index 00000000..7d5e8720
--- /dev/null
+++ b/fontes/interpretador/dialetos/mapler/interpretador-mapler.ts
@@ -0,0 +1,122 @@
+import { Binario, Construto, Logico, Variavel } from '../../../construtos';
+import { Escreva, EscrevaMesmaLinha, Fazer, Leia } from '../../../declaracoes';
+import { InterpretadorBase } from '../..';
+import { ContinuarQuebra, Quebra } from '../../../quebras';
+
+import * as comum from './comum';
+
+export class InterpretadorMapler extends InterpretadorBase {
+    mensagemPrompt: string;
+
+    constructor(
+        diretorioBase: string,
+        performance = false,
+        funcaoDeRetorno: Function = null,
+        funcaoDeRetornoMesmaLinha: Function = null
+    ) {
+        super(diretorioBase, performance, funcaoDeRetorno, funcaoDeRetornoMesmaLinha);
+        this.mensagemPrompt = '> ';
+    }
+
+    private async avaliarArgumentosEscrevaMapler(argumentos: Construto[]): Promise<string> {
+        let formatoTexto: string = '';
+
+        for (const argumento of argumentos) {
+            const resultadoAvaliacao = await this.avaliar(argumento);
+            let valor = resultadoAvaliacao?.hasOwnProperty('valor') ? resultadoAvaliacao.valor : resultadoAvaliacao;
+
+            formatoTexto += `${this.paraTexto(valor)}`;
+        }
+
+        return formatoTexto;
+    }
+
+    /**
+     * No Mapler, o bloco de condição executa se falso.
+     * Por isso a reimplementação aqui.
+     * @param declaracao A declaração `Fazer`
+     * @returns Só retorna em caso de erro na execução, e neste caso, o erro.
+     */
+    async visitarDeclaracaoFazer(declaracao: Fazer): Promise<any> {
+        let retornoExecucao: any;
+        do {
+            try {
+                retornoExecucao = await this.executar(declaracao.caminhoFazer);
+                if (retornoExecucao instanceof ContinuarQuebra) {
+                    retornoExecucao = null;
+                }
+            } catch (erro: any) {
+                return Promise.reject(erro);
+            }
+        } while (
+            !(retornoExecucao instanceof Quebra) &&
+            !this.eVerdadeiro(await this.avaliar(declaracao.condicaoEnquanto))
+        );
+    }
+
+    /**
+     * Execução de uma escrita na saída padrão, sem quebras de linha.
+     * Implementada para alguns dialetos, como Mapler.
+     * 
+     * Como `readline.question` sobrescreve o que foi escrito antes, aqui
+     * definimos `this.mensagemPrompt` para uso com `leia`.
+     * No Mapler é muito comum usar `escreva()` seguido de `leia()` para
+     * gerar um prompt na mesma linha.
+     * @param declaracao A declaração.
+     * @returns Sempre nulo, por convenção de visita.
+     */
+    async visitarExpressaoEscrevaMesmaLinha(declaracao: EscrevaMesmaLinha): Promise<any> {
+        try {
+            const formatoTexto: string = await this.avaliarArgumentosEscrevaMapler(declaracao.argumentos);
+            this.mensagemPrompt = formatoTexto;
+            this.funcaoDeRetornoMesmaLinha(formatoTexto);
+            return null;
+        } catch (erro: any) {
+            this.erros.push(erro);
+        }
+    }
+
+    /**
+     * Execução de uma escrita na saída configurada, que pode ser `console` (padrão) ou
+     * alguma função para escrever numa página Web.
+     * @param declaracao A declaração.
+     * @returns Sempre nulo, por convenção de visita.
+     */
+    async visitarDeclaracaoEscreva(declaracao: Escreva): Promise<any> {
+        try {
+            const formatoTexto: string = await this.avaliarArgumentosEscrevaMapler(declaracao.argumentos);
+            this.funcaoDeRetorno(formatoTexto);
+            return null;
+        } catch (erro: any) {
+            this.erros.push(erro);
+        }
+    }
+
+    /**
+     * Execução da leitura de valores da entrada configurada no
+     * início da aplicação.
+     * @param expressao Expressão do tipo Leia
+     * @returns Promise com o resultado da leitura.
+     */
+    async visitarExpressaoLeia(expressao: Leia): Promise<any> {
+        for (let argumento of expressao.argumentos) {
+            const promessaLeitura: Function = () => new Promise((resolucao) =>
+                this.interfaceEntradaSaida.question(this.mensagemPrompt, (resposta: any) => {
+                    this.mensagemPrompt = '> ';
+                    resolucao(resposta);
+                })
+            );
+
+            const valorLido = await promessaLeitura();
+            this.pilhaEscoposExecucao.atribuirVariavel((<Variavel>argumento).simbolo, valorLido);
+        }
+    }
+
+    async visitarExpressaoBinaria(expressao: Binario | any): Promise<any> {
+        return comum.visitarExpressaoBinaria(this, expressao);
+    }
+
+    async visitarExpressaoLogica(expressao: Logico): Promise<any> {
+        return comum.visitarExpressaoLogica(this, expressao);
+    }
+}
diff --git a/fontes/interpretador/interpretador-com-depuracao.ts b/fontes/interpretador/interpretador-com-depuracao.ts
index 1be207eb..e229e7f2 100644
--- a/fontes/interpretador/interpretador-com-depuracao.ts
+++ b/fontes/interpretador/interpretador-com-depuracao.ts
@@ -503,6 +503,8 @@ export class InterpretadorComDepuracao
             }
 
             return retornoExecucao;
+        } catch (erro: any) {
+            this.erros.push(erro);
         } finally {
             if (!this.pontoDeParadaAtivo && this.comando !== 'adentrarEscopo') {
                 this.pilhaEscoposExecucao.removerUltimo();
diff --git a/fontes/lexador/dialetos/index.ts b/fontes/lexador/dialetos/index.ts
index 5088cbeb..7714bc10 100644
--- a/fontes/lexador/dialetos/index.ts
+++ b/fontes/lexador/dialetos/index.ts
@@ -2,6 +2,7 @@ export * from './lexador-birl';
 export * from './lexador-egua-classico';
 export * from './lexador-eguap';
 export * from './lexador-guarani';
+export * from './lexador-mapler';
 export * from './lexador-portugol-ipt';
 export * from './lexador-portugol-studio';
 export * from './lexador-visualg';
diff --git a/fontes/lexador/dialetos/lexador-mapler.ts b/fontes/lexador/dialetos/lexador-mapler.ts
new file mode 100644
index 00000000..9e7171f9
--- /dev/null
+++ b/fontes/lexador/dialetos/lexador-mapler.ts
@@ -0,0 +1,217 @@
+import { RetornoLexador } from '../../interfaces/retornos';
+import { LexadorBaseLinhaUnica } from '../lexador-base-linha-unica';
+import { ErroLexador } from '../erro-lexador';
+
+import tiposDeSimbolos from '../../tipos-de-simbolos/mapler';
+import palavrasReservadas from './palavras-reservadas/mapler';
+
+export class LexadorMapler extends LexadorBaseLinhaUnica {
+    analisarNumero(): void {
+        while (this.eDigito(this.simboloAtual())) {
+            this.avancar();
+        }
+
+        if (this.simboloAtual() == '.' && this.eDigito(this.proximoSimbolo())) {
+            this.avancar();
+
+            while (this.eDigito(this.simboloAtual())) {
+                this.avancar();
+            }
+        }
+
+        const numeroCompleto = this.codigo.substring(this.inicioSimbolo, this.atual);
+        this.adicionarSimbolo(tiposDeSimbolos.NUMERO, parseFloat(numeroCompleto));
+    }
+
+    analisarTexto(delimitador: string): void {
+        while (this.simboloAtual() !== delimitador && !this.eFinalDoCodigo()) {
+            this.avancar();
+        }
+
+        if (this.eFinalDoCodigo()) {
+            this.erros.push({
+                linha: this.linha + 1,
+                caractere: this.simboloAnterior(),
+                mensagem: 'Caractere não finalizado.',
+            } as ErroLexador);
+            return;
+        }
+
+        const valor = this.codigo.substring(this.inicioSimbolo + 1, this.atual);
+        this.adicionarSimbolo(tiposDeSimbolos.CARACTERE, valor);
+    }
+
+    identificarPalavraChave(): void {
+        while (this.eAlfabetoOuDigito(this.simboloAtual())) {
+            this.avancar();
+        }
+
+        const codigo = this.codigo.substring(this.inicioSimbolo, this.atual).toLowerCase();
+        if (codigo in palavrasReservadas) {
+            this.adicionarSimbolo(
+                palavrasReservadas[codigo],
+                codigo
+            );
+        } else {
+            this.adicionarSimbolo(tiposDeSimbolos.IDENTIFICADOR, codigo);
+        }
+    }
+
+    analisarToken(): void {
+        const caractere = this.simboloAtual();
+
+        switch (caractere) {
+            case '(':
+                this.adicionarSimbolo(tiposDeSimbolos.PARENTESE_ESQUERDO);
+                this.avancar();
+                break;
+            case ')':
+                this.adicionarSimbolo(tiposDeSimbolos.PARENTESE_DIREITO);
+                this.avancar();
+                break;
+            case '[':
+                this.adicionarSimbolo(tiposDeSimbolos.COLCHETE_ESQUERDO);
+                this.avancar();
+                break;
+            case ']':
+                this.adicionarSimbolo(tiposDeSimbolos.COLCHETE_DIREITO);
+                this.avancar();
+                break;
+            case ':':
+                this.adicionarSimbolo(tiposDeSimbolos.DOIS_PONTOS);
+                this.avancar();
+                break;
+            case '<':
+                this.avancar();
+                switch (this.simboloAtual()) {
+                    case '-':
+                        this.adicionarSimbolo(tiposDeSimbolos.SETA_ATRIBUICAO);
+                        this.avancar();
+                        break;
+                    case '=':
+                        this.adicionarSimbolo(tiposDeSimbolos.MENOR_IGUAL);
+                        this.avancar();
+                        break;
+                    case '>':
+                        this.adicionarSimbolo(tiposDeSimbolos.DIFERENTE);
+                        this.avancar();
+                        break;
+                    default:
+                        this.adicionarSimbolo(tiposDeSimbolos.MENOR);
+                        break;
+                }
+
+                break;
+            case '>':
+                this.avancar();
+                if (this.simboloAtual() === '=') {
+                    this.adicionarSimbolo(tiposDeSimbolos.MAIOR_IGUAL);
+                    this.avancar();
+                } else {
+                    this.adicionarSimbolo(tiposDeSimbolos.MAIOR);
+                }
+                break;
+            case '=':
+                this.adicionarSimbolo(tiposDeSimbolos.IGUAL);
+                this.avancar();
+                break;
+            case ',':
+                this.adicionarSimbolo(tiposDeSimbolos.VIRGULA);
+                this.avancar();
+                break;
+            case ';':
+                this.adicionarSimbolo(tiposDeSimbolos.PONTO_VIRGULA);
+                this.avancar();
+                break;
+            case '.':
+                this.adicionarSimbolo(tiposDeSimbolos.PONTO);
+                this.avancar();
+                break;
+            case '-':
+                this.adicionarSimbolo(tiposDeSimbolos.SUBTRACAO);
+                this.avancar();
+                break;
+            case '+':
+                this.adicionarSimbolo(tiposDeSimbolos.ADICAO);
+                this.avancar();
+                break;
+            case '%':
+                this.adicionarSimbolo(tiposDeSimbolos.MODULO);
+                this.avancar();
+                break;
+            case '*':
+                this.adicionarSimbolo(tiposDeSimbolos.MULTIPLICACAO);
+                this.avancar();
+                break;
+            case '/':
+                this.avancar();
+                switch (this.simboloAtual()) {
+                    case '/':
+                        while (this.simboloAtual() != '\n' && !this.eFinalDoCodigo()) this.avancar();
+                        break;
+                    default:
+                        this.adicionarSimbolo(tiposDeSimbolos.DIVISAO);
+                        break;
+                }
+
+                break;
+            // Esta sessão ignora espaços em branco na tokenização.
+            // Ponto-e-vírgula é opcional em Delégua, então pode apenas ser ignorado.
+            case ' ':
+            case '\0':
+            case '\r':
+            case '\t':
+                this.avancar();
+                break;
+
+            case '\n':
+                // this.adicionarSimbolo(tiposDeSimbolos.QUEBRA_LINHA);
+                this.linha++;
+                this.avancar();
+                break;
+
+            // case '"':
+            //     this.avancar();
+            //     this.analisarTexto('"');
+            //     this.avancar();
+            //     break;
+            case '"':
+                this.avancar();
+                this.analisarTexto('"');
+                this.avancar();
+                break;
+            default:
+                if (this.eDigito(caractere)) this.analisarNumero();
+                else if (this.eAlfabeto(caractere)) this.identificarPalavraChave();
+                else {
+                    this.erros.push({
+                        linha: this.linha + 1,
+                        caractere: caractere,
+                        mensagem: 'Caractere inesperado.',
+                    } as ErroLexador);
+                    this.avancar();
+                }
+        }
+    }
+
+    mapear(codigo: string[], hashArquivo: number): RetornoLexador {
+        this.erros = [];
+        this.simbolos = [];
+        this.inicioSimbolo = 0;
+        this.atual = 0;
+        this.linha = 0;
+
+        this.codigo = codigo.join('\n') || '';
+        this.hashArquivo = hashArquivo;
+
+        while (!this.eFinalDoCodigo()) {
+            this.inicioSimbolo = this.atual;
+            this.analisarToken();
+        }
+
+        return {
+            simbolos: this.simbolos,
+            erros: this.erros,
+        } as RetornoLexador;
+    }
+}
diff --git a/fontes/lexador/dialetos/palavras-reservadas/mapler.ts b/fontes/lexador/dialetos/palavras-reservadas/mapler.ts
new file mode 100644
index 00000000..6ae994cd
--- /dev/null
+++ b/fontes/lexador/dialetos/palavras-reservadas/mapler.ts
@@ -0,0 +1,32 @@
+import tiposDeSimbolos from '../../../tipos-de-simbolos/mapler';
+
+export default {
+    ate: tiposDeSimbolos.ATE,
+    cadeia: tiposDeSimbolos.CADEIA,
+    caractere: tiposDeSimbolos.CARACTERE,
+    de: tiposDeSimbolos.DE,
+    e: tiposDeSimbolos.E,
+    enquanto: tiposDeSimbolos.ENQUANTO,
+    entao: tiposDeSimbolos.ENTAO,
+    escrever: tiposDeSimbolos.ESCREVER,
+    faca: tiposDeSimbolos.FACA,
+    falso: tiposDeSimbolos.FALSO,
+    fim: tiposDeSimbolos.FIM,
+    fimenquanto: tiposDeSimbolos.FIM_ENQUANTO,
+    fimpara: tiposDeSimbolos.FIM_PARA,
+    fimse: tiposDeSimbolos.FIM_SE,
+    inicio: tiposDeSimbolos.INICIO,
+    inteiro: tiposDeSimbolos.INTEIRO,
+    ler: tiposDeSimbolos.LER,
+    logico: tiposDeSimbolos.LOGICO,
+    nao: tiposDeSimbolos.NEGACAO,
+    ou: tiposDeSimbolos.OU,
+    para: tiposDeSimbolos.PARA,
+    real: tiposDeSimbolos.REAL,
+    repita: tiposDeSimbolos.REPITA,
+    se: tiposDeSimbolos.SE,
+    senao: tiposDeSimbolos.SENAO,
+    variaveis: tiposDeSimbolos.VARIAVEIS,
+    verdadeiro: tiposDeSimbolos.VERDADEIRO,
+    vetor: tiposDeSimbolos.VETOR,
+};
diff --git a/fontes/lexador/dialetos/palavras-reservadas/visualg.ts b/fontes/lexador/dialetos/palavras-reservadas/visualg.ts
index f995e374..d2de3826 100644
--- a/fontes/lexador/dialetos/palavras-reservadas/visualg.ts
+++ b/fontes/lexador/dialetos/palavras-reservadas/visualg.ts
@@ -53,6 +53,7 @@ export default {
     randi: tiposDeSimbolos.METODO_BIBLIOTECA_GLOBAL,
     real: tiposDeSimbolos.REAL,
     repita: tiposDeSimbolos.REPITA,
+    retorne: tiposDeSimbolos.RETORNE,
     se: tiposDeSimbolos.SE,
     sen: tiposDeSimbolos.METODO_BIBLIOTECA_GLOBAL,
     senao: tiposDeSimbolos.SENAO,
diff --git a/fontes/tipos-de-simbolos/mapler.ts b/fontes/tipos-de-simbolos/mapler.ts
new file mode 100644
index 00000000..cc6b80a1
--- /dev/null
+++ b/fontes/tipos-de-simbolos/mapler.ts
@@ -0,0 +1,54 @@
+export default {
+    ADICAO: 'ADICAO',
+    ATE: 'ATE',
+    CADEIA: 'CADEIA',
+    CARACTERE: 'CARACTERE',
+    COLCHETE_DIREITO: 'COLCHETE_DIREITO',
+    COLCHETE_ESQUERDO: 'COLCHETE_ESQUERDO',
+    DE: 'DE',
+    DIFERENTE: 'DIFERENTE',
+    DIVISAO: 'DIVISAO',
+    DOIS_PONTOS: 'DOIS_PONTOS',
+    E: 'E',
+    ENQUANTO: 'ENQUANTO',
+    ENTAO: 'ENTAO',
+    ESCREVER: 'ESCREVER',
+    FACA: 'FACA',
+    FALSO: 'FALSO',
+    FIM: 'FIM',
+    FIM_ENQUANTO: 'FIM_ENQUANTO',
+    FIM_MODULO: 'FIM_MODULO',
+    FIM_PARA: 'FIM_PARA',
+    FIM_SE: 'FIM_SE',
+    IDENTIFICADOR: 'IDENTIFICADOR',
+    IGUAL: 'IGUAL',
+    INICIO: 'INICIO',
+    INTEIRO: 'INTEIRO',
+    LER: 'LER',
+    LOGICO: 'LOGICO',
+    MAIOR: 'MAIOR',
+    MAIOR_IGUAL: 'MAIOR_IGUAL',
+    MENOR: 'MENOR',
+    MENOR_IGUAL: 'MENOR_IGUAL',
+    MODULO: 'MODULO',
+    MULTIPLICACAO: 'MULTIPLICACAO',
+    NEGACAO: 'NEGACAO',
+    NUMERO: 'NUMERO',
+    OU: 'OU',
+    PARA: 'PARA',
+    PASSO: 'PASSO',
+    PARENTESE_DIREITO: 'PARENTESE_DIREITO',
+    PARENTESE_ESQUERDO: 'PARENTESE_ESQUERDO',
+    PONTO: 'PONTO',
+    PONTO_VIRGULA: 'PONTO_VIRGULA',
+    REAL: 'REAL',
+    REPITA: 'REPITA',
+    SE: 'SE',
+    SENAO: 'SENAO',
+    SETA_ATRIBUICAO: 'SETA_ATRIBUICAO',
+    SUBTRACAO: 'SUBTRACAO',
+    VARIAVEIS: 'VARIAVEIS',
+    VERDADEIRO: 'VERDADEIRO',
+    VETOR: 'VETOR',
+    VIRGULA: 'VIRGULA',
+};
diff --git a/fontes/tipos-de-simbolos/visualg.ts b/fontes/tipos-de-simbolos/visualg.ts
index f28e84f3..cd5942a8 100644
--- a/fontes/tipos-de-simbolos/visualg.ts
+++ b/fontes/tipos-de-simbolos/visualg.ts
@@ -56,6 +56,7 @@ export default {
     PROCEDIMENTO: 'PROCEDIMENTO',
     REAL: 'REAL',
     REPITA: 'REPITA',
+    RETORNE: 'RETORNE',
     SE: 'SE',
     SENAO: 'SENAO',
     SETA_ATRIBUICAO: 'SETA_ATRIBUICAO',
diff --git a/fontes/tradutores/tradutor-visualg.ts b/fontes/tradutores/tradutor-visualg.ts
index 8c8edd48..aa534689 100644
--- a/fontes/tradutores/tradutor-visualg.ts
+++ b/fontes/tradutores/tradutor-visualg.ts
@@ -141,53 +141,48 @@ export class TradutorVisualg {
     //     return resultado;
     // }
 
-    // logicaComumCaminhosEscolha(caminho: CaminhoEscolha): string {
-    //     let resultado = '';
-    //     this.indentacao += 4;
-    //     resultado += ' '.repeat(this.indentacao);
-    //     if (caminho?.condicoes?.length) {
-    //         for (let condicao of caminho.condicoes) {
-    //             resultado += 'case ' + this.dicionarioConstrutos[condicao.constructor.name](condicao) + ':\n';
-    //             resultado += ' '.repeat(this.indentacao);
-    //         }
-    //     }
-    //     if (caminho?.declaracoes?.length) {
-    //         for (let declaracao of caminho.declaracoes) {
-    //             resultado += ' '.repeat(this.indentacao + 4);
-    //             if (declaracao?.simboloChave?.lexema === 'retorna') {
-    //                 resultado +=
-    //                     'return ' + this.dicionarioConstrutos[declaracao.valor.constructor.name](declaracao.valor);
-    //             }
-    //             resultado += this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao) + '\n';
-    //         }
-    //         resultado += ' '.repeat(this.indentacao + 4);
-    //         resultado += 'break' + '\n';
-    //     }
+    logicaComumCaminhosEscolha(caminho: any): string {
+        let resultado = '';
+        this.indentacao += 4;
+        resultado += ' '.repeat(this.indentacao);
+        if (caminho?.condicoes?.length) {
+            for (let condicao of caminho.condicoes) {
+                resultado += 'caso ' + this.dicionarioConstrutos[condicao.constructor.name](condicao) + ':\n';
+                resultado += ' '.repeat(this.indentacao);
+            }
+        }
+        if (caminho?.declaracoes?.length) {
+            for (let declaracao of caminho.declaracoes) {
+                resultado += ' '.repeat(this.indentacao + 4);
+                resultado += this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao) + '\n';
+            }
+            resultado += ' '.repeat(this.indentacao + 4);
+        }
 
-    //     this.indentacao -= 4;
-    //     return resultado;
-    // }
+        this.indentacao -= 4;
+        return resultado;
+    }
 
-    // traduzirDeclaracaoEscolha(declaracaoEscolha: Escolha): string {
-    //     let resultado = 'switch (';
-    //     resultado +=
-    //         this.dicionarioConstrutos[declaracaoEscolha.identificadorOuLiteral.constructor.name](
-    //             declaracaoEscolha.identificadorOuLiteral
-    //         ) + ') {\n';
+    traduzirDeclaracaoEscolha(declaracaoEscolha: any): string {
+        let resultado = 'escolha (';
+        resultado +=
+            this.dicionarioConstrutos[declaracaoEscolha.identificadorOuLiteral.constructor.name](
+                declaracaoEscolha.identificadorOuLiteral
+            ) + ') {\n';
 
-    //     for (let caminho of declaracaoEscolha.caminhos) {
-    //         resultado += this.logicaComumCaminhosEscolha(caminho);
-    //     }
+        for (let caminho of declaracaoEscolha.caminhos) {
+            resultado += this.logicaComumCaminhosEscolha(caminho);
+        }
 
-    //     if (declaracaoEscolha.caminhoPadrao) {
-    //         resultado += ' '.repeat(4);
-    //         resultado += 'default:\n';
-    //         resultado += this.logicaComumCaminhosEscolha(declaracaoEscolha.caminhoPadrao);
-    //     }
+        if (declaracaoEscolha.caminhoPadrao) {
+            resultado += ' '.repeat(4);
+            resultado += 'padrao:\n';
+            resultado += this.logicaComumCaminhosEscolha(declaracaoEscolha.caminhoPadrao);
+        }
 
-    //     resultado += '}\n';
-    //     return resultado;
-    // }
+        resultado += '}\n';
+        return resultado;
+    }
 
     traduzirDeclaracaoEscreva(declaracaoEscreva: any): string {
         let resultado = 'escreva(';
@@ -242,11 +237,10 @@ export class TradutorVisualg {
     // }
 
     traduzirDeclaracaoLeia(declaracaoLeia: any) {
-        let resultado = 'leia('
+        let resultado = ''
         for (const parametro of declaracaoLeia.argumentos) {
-            resultado += this.dicionarioConstrutos[parametro.constructor.name](declaracaoLeia.argumentos[0]);
+            resultado += `var ${this.dicionarioConstrutos[parametro.constructor.name](parametro)} = leia()\n`;
         }
-        resultado += ')'
 
         return resultado;
     }
@@ -489,7 +483,7 @@ export class TradutorVisualg {
         // Continua: () => 'continue',
         EscrevaMesmaLinha: this.tradzirDeclaracaoEscrevaMesmaLinha.bind(this),
         // Enquanto: this.traduzirDeclaracaoEnquanto.bind(this),
-        // Escolha: this.traduzirDeclaracaoEscolha.bind(this),
+        Escolha: this.traduzirDeclaracaoEscolha.bind(this),
         Escreva: this.traduzirDeclaracaoEscreva.bind(this),
         // Expressao: this.traduzirDeclaracaoExpressao.bind(this),
         // Fazer: this.traduzirDeclaracaoFazer.bind(this),
diff --git a/package.json b/package.json
index 0acc3bb8..d4fb949f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
     "name": "@designliquido/delegua",
-    "version": "0.15.15",
+    "version": "0.15.16",
     "description": "Linguagem de programação simples e moderna usando português estruturado, com suporte a múltiplos dialetos",
     "main": "index.js",
     "scripts": {


Test patch:
diff --git a/testes/mapler/avaliador-sintatico.test.ts b/testes/mapler/avaliador-sintatico.test.ts
new file mode 100644
index 00000000..7ef3491b
--- /dev/null
+++ b/testes/mapler/avaliador-sintatico.test.ts
@@ -0,0 +1,228 @@
+import { LexadorMapler } from '../../fontes/lexador/dialetos';
+import { AvaliadorSintaticoMapler } from '../../fontes/avaliador-sintatico/dialetos';
+
+describe('Avaliador sintático (Mapler)', () => {
+    describe('analisar()', () => {
+        let lexador: LexadorMapler;
+        let avaliadorSintatico: AvaliadorSintaticoMapler;
+
+        beforeEach(() => {
+            lexador = new LexadorMapler();
+            avaliadorSintatico = new AvaliadorSintaticoMapler();
+        });
+
+        it('Sucesso - Olá Mundo', () => {
+            const retornoLexador = lexador.mapear([
+                'variaveis',
+                'inicio',
+                'escrever "Olá mundo";',
+                'fim'
+            ], -1);
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+            expect(retornoAvaliadorSintatico).toBeTruthy();
+            expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(1);
+        });
+
+        // it('Sucesso - Enquanto', () => {
+        //     const retornoLexador = lexador.mapear([
+        //         'algoritmo "Números de 1 a 10 (com enquanto...faca)"',
+        //         'var j: inteiro',
+        //         'inicio',
+        //         'j <- 1',
+        //         'enquanto j <= 10 faca',
+        //         '   escreva (j)',
+        //         '   j <- j + 1',
+        //         'fimenquanto',
+        //         'fimalgoritmo'
+        //     ], -1);
+        //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+        //     expect(retornoAvaliadorSintatico).toBeTruthy();
+        //     expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(3);
+        // });
+
+        // it('Sucesso - Escolha', () => {
+        //     const retornoLexador = lexador.mapear([
+        //         'algoritmo "Times"',
+        //         'var time: caractere',
+        //         'inicio',
+        //         'escreva ("Entre com o nome de um time de futebol: ")',
+        //         'leia (time)',
+        //         'escolha time',
+        //         '    caso "Flamengo", "Fluminense", "Vasco", "Botafogo"',
+        //         '        escreval ("É um time carioca.")',
+        //         '    caso "São Paulo", "Palmeiras", "Santos", "Corínthians"',
+        //         '        escreval ("É um time paulista.")',
+        //         '    outrocaso',
+        //         '        escreval ("É de outro estado.")',
+        //         'fimescolha',
+        //         'fimalgoritmo'
+        //     ], -1);
+        //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+        //     expect(retornoAvaliadorSintatico).toBeTruthy();
+        // });
+
+        // it('Sucesso - Função', () => {
+        //     const retornoLexador = lexador.mapear([
+        //         'Algoritmo "exemplo-funcoes"',
+        //         'Var',
+        //         '   n: inteiro',
+        //         '   m: inteiro',
+        //         '   res: inteiro',
+        //         'Inicio',
+        //         '   funcao soma: inteiro',
+        //         '   var aux: inteiro',
+        //         '   inicio',
+        //         '      aux <- n + m',
+        //         '      retorne aux',
+        //         '   fimfuncao',
+        //         '   n <- 4',
+        //         '   m <- -9',
+        //         '   res <- soma',
+        //         '   escreva(res)',
+        //         'Fimalgoritmo'
+        //     ], -1);
+        //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+        //     expect(retornoAvaliadorSintatico).toBeTruthy();
+        //     expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(8);
+        // });
+
+        // it('Sucesso - Interrompa', () => {
+        //     const retornoLexador = lexador.mapear([
+        //         'algoritmo "Números de 1 a 10 (com interrompa)"',
+        //         'var x: inteiro',
+        //         'inicio',
+        //         'x <- 0',
+        //         'repita',
+        //         '   x <- x + 1',
+        //         '   escreva (x)',
+        //         '   se x = 10 entao',
+        //         '      interrompa',
+        //         '   fimse',
+        //         'ate falso',
+        //         'fimalgoritmo'
+        //     ], -1);
+        //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+        //     expect(retornoAvaliadorSintatico).toBeTruthy();
+        //     expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(3);
+        // });
+
+        // it('Sucesso - Leia', () => {
+        //     const retornoLexador = lexador.mapear([
+        //         'Algoritmo "Soma 5"',
+        //         'Var',
+        //         '   n1, n2, n3, n4, n5: inteiro',
+        //         'Inicio',
+        //         '      leia(n1, n2, n3, n4, n5)',
+        //         '      escreva(n1 + n2 + n3 + n4 + n5)',
+        //         'Fimalgoritmo'
+        //     ], -1);
+
+        //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+        //     expect(retornoAvaliadorSintatico).toBeTruthy();
+        //     expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0);
+        // });
+
+        // it('Sucesso - Para', () => {
+        //     const retornoLexador = lexador.mapear([
+        //         'algoritmo "Numeros de 1 a 10"',
+        //         'var j: inteiro',
+        //         'inicio',
+        //         '    para j de 1 ate 10 faca',
+        //         '        escreva (j)',
+        //         '    fimpara',
+        //         'fimalgoritmo'
+        //     ], -1);
+        //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+        //     expect(retornoAvaliadorSintatico).toBeTruthy();
+        //     expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(2);
+        // });
+
+        // it('Sucesso - Procedimento', () => {
+        //     const retornoLexador = lexador.mapear([
+        //         'algoritmo "semnome"',
+        //         '// Função :',
+        //         '// Autor :',
+        //         '// Data : 27/02/2014',
+        //         '// Seção de Declarações ',
+        //         'var',
+        //         'a,b:inteiro',
+        //         'procedimento mostranumero (a:inteiro;b:inteiro)',
+        //         '',
+        //         'inicio',
+        //         '',
+        //         'se a > b entao',
+        //         '     escreval ("A variavel escolhida é ",a)',
+        //         'senao',
+        //         '     escreval ("A variavel escolhida é ",b)',
+        //         'fimse',
+        //         'fimprocedimento',
+        //         '',
+        //         'inicio',
+        //         'escreval ("Digite dois valores: ")',
+        //         'leia (a,b)',
+        //         'mostranumero (a,b)',
+        //         '',
+        //         'fimalgoritmo'
+        //     ], -1);
+        //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+        //     expect(retornoAvaliadorSintatico).toBeTruthy();
+        //     expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(6);
+        // });
+
+        // it('Sucesso - Repita', () => {
+        //     const retornoLexador = lexador.mapear([
+        //         'algoritmo "Números de 1 a 10 (com repita)"',
+        //         'var j: inteiro',
+        //         'inicio',
+        //         'j <- 1',
+        //         'repita',
+        //         '   escreva (j)',
+        //         '   j <- j + 1',
+        //         'ate j > 10',
+        //         'fimalgoritmo'
+        //     ], -1);
+        //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+        //     expect(retornoAvaliadorSintatico).toBeTruthy();
+        //     expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(3);
+        // });
+
+        // it('Sucesso - Xou', () => {
+        //     const retornoLexador = lexador.mapear([
+        //         'algoritmo "Exemplo Xou"',
+        //         'var A, B, C, resultA, resultB, resultC: logico',
+        //         'inicio',
+        //         'A <- verdadeiro',
+        //         'B <- verdadeiro',
+        //         'C <- falso',
+        //         'resultA <- A ou B',
+        //         'escreval("A ", resultA)',
+        //         'resultA <- A xou B',
+        //         'escreval("A ", resultA)',
+        //         'resultA <- nao B',
+        //         'escreval("A ", resultA)',
+        //         'resultB <- B',
+        //         'resultA <- (A e B) ou (A xou B)',
+        //         'resultB <- (A ou B) e (A e C)',
+        //         'resultC <- A ou C e B xou A e nao B',
+        //         'escreval("A ", resultA)',
+        //         'escreval("B ", resultB)',
+        //         'escreval("C ", resultC)',
+        //         'fimalgoritmo'
+        //     ], -1);
+            
+        //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+        //     expect(retornoAvaliadorSintatico).toBeTruthy();
+        //     expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(22);
+        // })
+    });
+});
diff --git a/testes/mapler/interpretador.test.ts b/testes/mapler/interpretador.test.ts
new file mode 100644
index 00000000..4cfcf493
--- /dev/null
+++ b/testes/mapler/interpretador.test.ts
@@ -0,0 +1,311 @@
+import { AvaliadorSintaticoMapler } from '../../fontes/avaliador-sintatico/dialetos';
+import { InterpretadorMapler } from "../../fontes/interpretador/dialetos";
+import { LexadorMapler } from '../../fontes/lexador/dialetos';
+
+describe('Interpretador', () => {
+    describe('interpretar()', () => {
+        let lexador: LexadorMapler;
+        let avaliadorSintatico: AvaliadorSintaticoMapler;
+        let interpretador: InterpretadorMapler;
+
+        beforeEach(() => {
+            lexador = new LexadorMapler();
+            avaliadorSintatico = new AvaliadorSintaticoMapler();
+            interpretador = new InterpretadorMapler(process.cwd());
+        });
+
+        describe('Cenários de sucesso', () => {
+            it('Trivial', async () => {
+                const retornoLexador = lexador.mapear([
+                    'variaveis',
+                    'inicio',
+                    'fim'
+                ], -1);
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            it('Trivial mesma linha', async () => {
+                const retornoLexador = lexador.mapear([
+                    'variaveis inicio escrever "olá mundo"; fim',
+                ], -1);
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            it('Escrever simples', async () => {
+                const retornoLexador = lexador.mapear([
+                    'variaveis',
+                    'inicio',
+                    'escrever "olá mundo";',
+                    'fim'
+                ], -1);
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            it('Escrever com variável', async () => {
+                const retornoLexador = lexador.mapear([
+                    'variaveis',
+                    'idade: inteiro;',
+                    'nome, sobrenome: cadeia;',
+                    'inicio',
+                    'idade <- 10;',
+                    'escrever "Minha idade é: ", idade;',
+                    'fim'
+                ], -1);
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            it('Escrever lógicos e outros textos', async () => {
+                const retornoLexador = lexador.mapear([
+                    'variaveis',
+                    'inicio',
+                    'escrever "";',
+                    'escrever "Mapler1 ", "Mapler2";',
+                    'escrever "Mapler3 ", 10.2;',
+                    'escrever verdadeiro;',
+                    'escrever falso;',
+                    'escrever nao verdadeiro;',
+                    'escrever nao falso;',
+                    'fim'
+                ], -1);
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
+
+            // it("Sucesso - Enquanto", async () => {
+            //     // Aqui vamos simular a resposta para três variáveis de `leia()`.
+            //     const respostas = [
+            //         -1, -2, 1
+            //     ];
+            //     interpretador.interfaceEntradaSaida = {
+            //         question: (mensagem: string, callback: Function) => {
+            //             callback(respostas.shift());
+            //         }
+            //     };
+
+            //     const retornoLexador = lexador.mapear([
+            //         'algoritmo "teste5"',
+            //         'var',
+            //         '    num1, num2: inteiro',
+            //         '    texto1, texto2: caractere',
+            //         '    teste: logico',
+            //         'inicio',
+            //         '    teste <- verdadeiro',
+            //         '    leia (num1)',
+            //         '    escreval(teste)',
+            //         '    enquanto teste = verdadeiro faca',
+            //         '         escreval("num1 não é maior que 0")',
+            //         '         leia (num1)',
+            //         '         se num1 > 0 entao',
+            //         '             teste <- falso',
+            //         '         fimse',
+            //         '    fimenquanto',
+            //         '    escreval("num1 é maior que 0")',
+            //         'fimalgoritmo'
+            //     ], -1);
+
+            //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+            //     const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+            //     expect(retornoInterpretador.erros).toHaveLength(0);
+            // });
+
+            // it('Sucesso - Leia', async () => {
+            //     // Aqui vamos simular a resposta para cinco variáveis de `leia()`.
+            //     const respostas = [1, 2, 3, 4, 5];
+            //     interpretador.interfaceEntradaSaida = {
+            //         question: (mensagem: string, callback: Function) => {
+            //             callback(respostas.shift());
+            //         }
+            //     };
+
+            //     const retornoLexador = lexador.mapear([
+            //         'Algoritmo "Soma 5"',
+            //         'Var',
+            //         '    n1, n2, n3, n4, n5: inteiro',
+            //         'Inicio',
+            //         '    leia(n1, n2, n3, n4, n5)',
+            //         '    escreva(n1 + n2 + n3 + n4 + n5)',
+            //         'Fimalgoritmo'
+            //     ], -1);
+    
+            //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+    
+            //     const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+            //     expect(retornoInterpretador.erros).toHaveLength(0);
+            // });
+
+            // it('Sucesso - IMC', async () => {
+            //     // Aqui vamos simular a resposta para duas variáveis de `leia()`.
+            //     const respostas = [78, 1.78];
+            //     interpretador.interfaceEntradaSaida = {
+            //         question: (mensagem: string, callback: Function) => {
+            //             callback(respostas.shift());
+            //         }
+            //     };
+
+            //     const retornoLexador = lexador.mapear([
+            //         'Algoritmo "CalculaIMC"',
+            //         '',
+            //         'Var',
+            //         '    M: Real',
+            //         '    A: Real',
+            //         '    IMC: Real',
+            //         '',
+            //         'Inicio',
+            //         '   Escreva("Massa(Kg): ")',
+            //         '   Leia(M)',
+            //         '   Escreva("Altura (m): ")',
+            //         '   Leia(A)',
+            //         '   IMC <- M / (A ^ 2)',
+            //         '   Escreval("IMC: ", IMC:5:2)',
+            //         '   Se (IMC >= 18.5) e (IMC < 25) entao',
+            //         '      Escreva("Parabens! Voce esta no seu peso ideal")',
+            //         '   senao',
+            //         '      Escreva("Voce nao esta na faixa de peso ideal")',
+            //         '   Fimse',
+            //         '',
+            //         'Fimalgoritmo'
+            //     ], -1);
+
+            //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+            //     const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+            //     expect(retornoInterpretador.erros).toHaveLength(0);
+            // });
+
+            // it("Sucesso - Média de Vetor", async () => {
+            //     // Aqui vamos simular a resposta para duas variáveis de `leia()`.
+            //     const respostas = [
+            //         90, 80, 50, 100, 60, 70, 75, 85, 89, 91, 
+            //         74, 79, 99, 90, 65, 78, 100, 67, 93, 88
+            //     ];
+            //     interpretador.interfaceEntradaSaida = {
+            //         question: (mensagem: string, callback: Function) => {
+            //             callback(respostas.pop());
+            //         }
+            //     };
+
+            //     const retornoLexador = lexador.mapear([
+            //         'algoritmo "media-vetor"',
+            //         'var',
+            //         'media:vetor[1..10] de real',
+            //         'i:inteiro',
+            //         'n1,n2:real',
+            //         'inicio',
+            //         'para i de 1 ate 10 faca',
+            //         '     escreval ("Digite a nota do",i,"º Aluno")',
+            //         '     leia (n1,n2)',
+            //         '     media[i]<-(n1+n2)/2',
+            //         'fimpara',
+            //         'escreval ("-")',
+            //         'para i de 1 ate 10 faca',
+            //         '       escreval ("Media do",i,"º aluno: ", media[i])',
+            //         'fimpara',
+            //         'fimalgoritmo'
+            //     ], -1);
+
+            //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+            //     const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+            //     expect(retornoInterpretador.erros).toHaveLength(0);
+            // });
+
+            // it('Sucesso - Procedimento', async () => {
+            //     // Aqui vamos simular a resposta para duas variáveis de `leia()`.
+            //     const respostas = [
+            //         2, 3
+            //     ];
+            //     interpretador.interfaceEntradaSaida = {
+            //         question: (mensagem: string, callback: Function) => {
+            //             callback(respostas.pop());
+            //         }
+            //     };
+
+            //     const retornoLexador = lexador.mapear([
+            //         'algoritmo "semnome"',
+            //         '// Função :',
+            //         '// Autor :',
+            //         '// Data : 27/02/2014',
+            //         '// Seção de Declarações ',
+            //         'var',
+            //         'a,b:inteiro',
+            //         'procedimento mostranumero (a:inteiro;b:inteiro)',
+            //         '',
+            //         'inicio',
+            //         '',
+            //         'se a > b entao',
+            //         '     escreval ("A variavel escolhida é ",a)',
+            //         'senao',
+            //         '     escreval ("A variavel escolhida é ",b)',
+            //         'fimse',
+            //         'fimprocedimento',
+            //         '',
+            //         'inicio',
+            //         'escreval ("Digite dois valores: ")',
+            //         'leia (a,b)',
+            //         'mostranumero (a,b)',
+            //         '',
+            //         'fimalgoritmo'
+            //     ], -1);
+            //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+    
+            //     const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+            //     expect(retornoInterpretador.erros).toHaveLength(0);
+            // });
+
+            // it('Sucesso - Operadores Lógicos', async () => {
+            //     const retornoLexador = lexador.mapear([
+            //         'algoritmo "Exemplo Xou"',
+            //         'var A, B, C, resultA, resultB, resultC: logico',
+            //         'inicio',
+            //         'A <- verdadeiro',
+            //         'B <- verdadeiro',
+            //         'C <- falso',
+            //         'resultA <- A ou B',
+            //         'escreval("A ", resultA)',
+            //         'resultA <- A xou B',
+            //         'escreval("A ", resultA)',
+            //         'resultA <- nao B',
+            //         'escreval("A ", resultA)',
+            //         'resultB <- B',
+            //         'resultA <- (A e B) ou (A xou B)',
+            //         'resultB <- (A ou B) e (A e C)',
+            //         'resultC <- A ou C e B xou A e nao B',
+            //         'escreval("A ", resultA)',
+            //         'escreval("B ", resultB)',
+            //         'escreval("C ", resultC)',
+            //         'fimalgoritmo'
+            //     ], -1);
+            //     const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+    
+            //     const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+            //     expect(retornoInterpretador.erros).toHaveLength(0);
+            // });
+        });
+    });
+});
diff --git a/testes/mapler/lexador.test.ts b/testes/mapler/lexador.test.ts
new file mode 100644
index 00000000..74bfc9fa
--- /dev/null
+++ b/testes/mapler/lexador.test.ts
@@ -0,0 +1,40 @@
+import { LexadorMapler } from '../../fontes/lexador/dialetos';
+
+import tiposDeSimbolos from "../../fontes/tipos-de-simbolos/mapler"
+
+describe('Lexador (Mapler)', () => {
+    describe('mapear()', () => {
+        let lexador: LexadorMapler;
+
+        beforeEach(() => {
+            lexador = new LexadorMapler();
+        });
+
+        describe('Cenários de sucesso', () => {
+            it('Sucesso - Código vazio', () => {
+                const resultado = lexador.mapear([''], -1);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado.simbolos).toHaveLength(0);
+            });
+
+            it('Sucesso - estrutura mínima', () => {
+                const resultado = lexador.mapear([
+                    "variaveis",
+                    "inicio",
+                    "fim"
+                ], -1);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado.simbolos).toHaveLength(3);
+                expect(resultado.simbolos).toEqual(
+                    expect.arrayContaining([
+                        expect.objectContaining({ tipo: tiposDeSimbolos.VARIAVEIS }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.INICIO }),
+                        expect.objectContaining({ tipo: tiposDeSimbolos.FIM }),
+                    ])
+                );
+            });
+        });
+    });
+});
diff --git a/testes/tradutores/tradutor-visualg.test.ts b/testes/tradutores/tradutor-visualg.test.ts
index c122e7a0..27f44649 100644
--- a/testes/tradutores/tradutor-visualg.test.ts
+++ b/testes/tradutores/tradutor-visualg.test.ts
@@ -1,6 +1,6 @@
 import { TradutorVisualg } from '../../fontes/tradutores/tradutor-visualg';
 
-describe('Tradutor Reverso JavaScript -> Delégua', () => {
+describe('Tradutor VisuAlg -> Delégua', () => {
     const tradutor: TradutorVisualg = new TradutorVisualg();
 
      describe('Código', () => {
@@ -88,31 +88,60 @@ describe('Tradutor Reverso JavaScript -> Delégua', () => {
             expect(resultado).toMatch(/senao {/i);
         })
 
-        // it('comparacao de valores -> igualdade', () => {
-        //     const codigo = `console.log(1 === 2)\nconsole.log(1 == '1')\nconsole.log('1' === '1')`;
-
-        //     const resultado = tradutor.traduzir(codigo);
-        //     expect(resultado).toBeTruthy();
-        //     expect(resultado).toMatch(/escreva\(1 == 2\)/i);
-        //     expect(resultado).toMatch(/escreva\(1 == '1'\)/i);
-        //     expect(resultado).toMatch(/escreva\('1' == '1'\)/i);
-        // });
+        it('leia', () => {
+            const codigo = `
+            algoritmo "semnome"
+            var
+            n1,n2,n3:real
+            inicio
+            escreval ("Digite dois valores para a soma,subtração,multiplicação e divisão: ")
+            leia (n1,n2)
+            n3<-n1+n2
+            escreval ()
+            escreval ("A soma de ",n1," mais ",n2," é igual a: ", n3)
+            fimalgoritmo
+            `
 
-        // it('for -> para', () => {
-        //     const codigo = 'for (let i = 0; i < 10; i++) { console.log(i) }'
+            const resultado = tradutor.traduzir(codigo);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/var n1 = leia\(\)/i);
+            expect(resultado).toMatch(/var n2 = leia\(\)/i);
+            expect(resultado).toMatch(/n3 = n1 \+ n2 /i);
+        });
 
-        //     const resultado = tradutor.traduzir(codigo);
-        //     expect(resultado).toBeTruthy();
-        //     expect(resultado).toMatch(/para \(var i = 0; i < 10; i\+\+\)/i);
-        //     expect(resultado).toMatch(/escreva\(i\)/i);
-        // });
+        it('escolha', () => {
+            const codigo = `
+            algoritmo "Times"
+            var time: caractere
+            inicio
+            escreva ("Entre com o nome de um time de futebol: ")
+            leia (time)
+                escolha time
+                    caso "Flamengo", "Fluminense", "Vasco", "Botafogo"
+                        escreval ("É um time carioca.")
+                    caso "São Paulo", "Palmeiras", "Santos", "Corínthians"
+                        escreval ("É um time paulista.")
+                    outrocaso
+                        escreval ("É de outro estado.")
+                fimescolha
+            fimalgoritmo
+            `
 
-        // it('array - vetor - com valores', () => {
-        //     const codigo = 'let vetor = [1, \'2\']'
-        //     const resultado = tradutor.traduzir(codigo);
-        //     expect(resultado).toBeTruthy();
-        //     expect(resultado).toMatch(/var vetor = \[1, \'2\'\]/i);
-        // });
+            const resultado = tradutor.traduzir(codigo);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/escolha \(time\)/i);
+            expect(resultado).toMatch(/caso \'Flamengo\':/i);
+            expect(resultado).toMatch(/caso \'Vasco\':/i);
+            expect(resultado).toMatch(/caso \'Botafogo\':/i);
+            expect(resultado).toMatch(/escreva\('É um time carioca.'\)/i);
+            expect(resultado).toMatch(/caso \'São Paulo\':/i);
+            expect(resultado).toMatch(/caso \'Palmeiras\':/i);
+            expect(resultado).toMatch(/caso \'Santos\':/i);
+            expect(resultado).toMatch(/caso \'Corínthians\':/i);
+            expect(resultado).toMatch(/escreva\('É um time paulista.'\)/i);
+            expect(resultado).toMatch(/padrao:/i);
+            expect(resultado).toMatch(/escreva\('É de outro estado.'\)/i);
+        });
 
         // it('array - vetor - vazio', () => {
         //     const codigo = 'let vetor = []'
diff --git a/testes/visualg/avaliador-sintatico.test.ts b/testes/visualg/avaliador-sintatico.test.ts
index 2d038f44..7b2e1d1c 100644
--- a/testes/visualg/avaliador-sintatico.test.ts
+++ b/testes/visualg/avaliador-sintatico.test.ts
@@ -147,23 +147,16 @@ describe('Avaliador sintático (VisuAlg)', () => {
         it('Sucesso - Procedimento', () => {
             const retornoLexador = lexador.mapear([
                 'algoritmo "semnome"',
-                '// Função :',
-                '// Autor :',
-                '// Data : 27/02/2014',
-                '// Seção de Declarações ',
                 'var',
                 'a,b:inteiro',
                 'procedimento mostranumero (a:inteiro;b:inteiro)',
-                '',
                 'inicio',
-                '',
                 'se a > b entao',
                 '     escreval ("A variavel escolhida é ",a)',
                 'senao',
                 '     escreval ("A variavel escolhida é ",b)',
                 'fimse',
                 'fimprocedimento',
-                '',
                 'inicio',
                 'escreval ("Digite dois valores: ")',
                 'leia (a,b)',