Repository: DesignLiquido/delegua
Pull request #584 (2024-01-19 01:22:50)

Reescrita do formatador de Delégua.
- Força da preguiça (@samuelrvg, se quiser terminar, fique à vontade);
- Redesenhando o formatador para trabalhar a partir da avaliação sintática. Pelo conjunto léxico não deu muito certo.


Patch:
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
index ea9123bf..3898e3e5 100644
--- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
@@ -195,7 +195,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
     }
 
     declaracaoEnquanto(): Enquanto {
-        this.consumir(tiposDeSimbolos.NEGATIVA, 'Esperado expressão `NEGATIVA` para iniciar o bloco `ENQUANTO`.');
+        const simboloNegatica = this.consumir(tiposDeSimbolos.NEGATIVA, 'Esperado expressão `NEGATIVA` para iniciar o bloco `ENQUANTO`.');
         this.consumir(
             tiposDeSimbolos.BAMBAM,
             'Esperado expressão `BAMBAM` após `NEGATIVA` para iniciar o bloco `ENQUANTO`.'
@@ -217,7 +217,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
         }
 
         this.consumir(tiposDeSimbolos.BIRL, 'Esperado expressão `BIRL` para fechar o bloco `ENQUANTO`.');
-        return new Enquanto(codicao, declaracoes);
+        return new Enquanto(codicao, new Bloco(this.hashArquivo, simboloNegatica.linha, declaracoes));
     }
 
     declaracaoExpressao(): Expressao {
diff --git a/fontes/avaliador-sintatico/dialetos/potigol/avaliador-sintatico-potigol.ts b/fontes/avaliador-sintatico/dialetos/potigol/avaliador-sintatico-potigol.ts
index e84922e5..e17fac46 100644
--- a/fontes/avaliador-sintatico/dialetos/potigol/avaliador-sintatico-potigol.ts
+++ b/fontes/avaliador-sintatico/dialetos/potigol/avaliador-sintatico-potigol.ts
@@ -116,7 +116,7 @@ export class AvaliadorSintaticoPotigol extends AvaliadorSintaticoBase {
         tipoRetorno?: SimboloInterface
     ): FuncaoDeclaracao {
         const corpo = new FuncaoConstruto(simboloPrimario.hashArquivo, simboloPrimario.linha, parametros, [
-            this.expressao(),
+            new Expressao(this.expressao()),
         ]);
         return new FuncaoDeclaracao(simboloPrimario, corpo, tipoRetorno);
     }
diff --git a/fontes/construtos/definir-valor.ts b/fontes/construtos/definir-valor.ts
index 16b2bba0..2e9ce7ff 100644
--- a/fontes/construtos/definir-valor.ts
+++ b/fontes/construtos/definir-valor.ts
@@ -1,15 +1,15 @@
-import { VisitanteComumInterface } from '../interfaces';
+import { SimboloInterface, VisitanteComumInterface } from '../interfaces';
 import { Construto } from './construto';
 
 export class DefinirValor implements Construto {
     linha: number;
     hashArquivo: number;
 
-    objeto: any;
-    nome: any;
+    objeto: Construto;
+    nome: SimboloInterface;
     valor: any;
 
-    constructor(hashArquivo: number, linha: number, objeto: any, nome: any, valor: any) {
+    constructor(hashArquivo: number, linha: number, objeto: Construto, nome: SimboloInterface, valor: any) {
         this.linha = linha;
         this.hashArquivo = hashArquivo;
 
diff --git a/fontes/construtos/funcao.ts b/fontes/construtos/funcao.ts
index 14a63291..423c6582 100644
--- a/fontes/construtos/funcao.ts
+++ b/fontes/construtos/funcao.ts
@@ -1,3 +1,4 @@
+import { Declaracao } from '../declaracoes';
 import { VisitanteComumInterface, ParametroInterface } from '../interfaces';
 import { Construto } from './construto';
 
@@ -7,13 +8,13 @@ export class FuncaoConstruto implements Construto {
 
     parametros: ParametroInterface[];
     tipoRetorno?: string;
-    corpo: any[];
+    corpo: Declaracao[];
 
     constructor(
         hashArquivo: number,
         linha: number,
         parametros: ParametroInterface[],
-        corpo: any[],
+        corpo: Declaracao[],
         tipoRetorno?: string
     ) {
         this.linha = linha;
diff --git a/fontes/declaracoes/enquanto.ts b/fontes/declaracoes/enquanto.ts
index 77dd6054..e3b76351 100644
--- a/fontes/declaracoes/enquanto.ts
+++ b/fontes/declaracoes/enquanto.ts
@@ -1,12 +1,13 @@
 import { Construto } from '../construtos';
 import { VisitanteComumInterface } from '../interfaces';
+import { Bloco } from './bloco';
 import { Declaracao } from './declaracao';
 
 export class Enquanto extends Declaracao {
     condicao: Construto;
-    corpo: any;
+    corpo: Bloco;
 
-    constructor(condicao: Construto, corpo: any) {
+    constructor(condicao: Construto, corpo: Bloco) {
         super(condicao.linha, condicao.hashArquivo);
         this.condicao = condicao;
         this.corpo = corpo;
diff --git a/fontes/declaracoes/fazer.ts b/fontes/declaracoes/fazer.ts
index 3270e123..3d0e548a 100644
--- a/fontes/declaracoes/fazer.ts
+++ b/fontes/declaracoes/fazer.ts
@@ -1,9 +1,11 @@
+import { Construto } from '../construtos';
 import { VisitanteComumInterface } from '../interfaces';
+import { Bloco } from './bloco';
 import { Declaracao } from './declaracao';
 
 export class Fazer extends Declaracao {
-    caminhoFazer: any;
-    condicaoEnquanto: any;
+    caminhoFazer: Bloco;
+    condicaoEnquanto: Construto;
 
     constructor(hashArquivo: number, linha: number, caminhoFazer: any, condicaoEnquanto: any) {
         super(linha, hashArquivo);
diff --git a/fontes/declaracoes/para.ts b/fontes/declaracoes/para.ts
index b69b6cc1..4c33fc16 100644
--- a/fontes/declaracoes/para.ts
+++ b/fontes/declaracoes/para.ts
@@ -8,8 +8,8 @@ import { Declaracao } from './declaracao';
  * uma condição de continuação e uma instrução de incremento.
  */
 export class Para extends Declaracao {
-    inicializador: any;
-    condicao: any;
+    inicializador?: Declaracao | Declaracao[];
+    condicao: Construto;
     incrementar: Construto;
     corpo: Bloco;
     inicializada: boolean;
diff --git a/fontes/declaracoes/tente.ts b/fontes/declaracoes/tente.ts
index 255dbb8b..4b44e6c9 100644
--- a/fontes/declaracoes/tente.ts
+++ b/fontes/declaracoes/tente.ts
@@ -6,10 +6,10 @@ import { Declaracao } from './declaracao';
  * Declaração `tente`.
  */
 export class Tente extends Declaracao {
-    caminhoTente: any[];
+    caminhoTente: Declaracao[];
     caminhoPegue: FuncaoConstruto | Declaracao[];
     caminhoSenao: any[];
-    caminhoFinalmente: any[];
+    caminhoFinalmente: Declaracao[];
 
     constructor(
         hashArquivo: number,
diff --git a/fontes/formatadores/delegua.ts b/fontes/formatadores/delegua.ts
index c6fcd9ef..99811345 100644
--- a/fontes/formatadores/delegua.ts
+++ b/fontes/formatadores/delegua.ts
@@ -1,4 +1,54 @@
-import { SimboloInterface } from '../interfaces';
+import {
+    AcessoIndiceVariavel,
+    AcessoMetodoOuPropriedade,
+    Agrupamento,
+    AtribuicaoPorIndice,
+    Atribuir,
+    Binario,
+    Chamada,
+    Construto,
+    DefinirValor,
+    ExpressaoRegular,
+    FimPara,
+    FormatacaoEscrita,
+    FuncaoConstruto,
+    Isto,
+    Literal,
+    Super,
+    TipoDe,
+    Unario,
+    Variavel,
+    Vetor,
+} from '../construtos';
+import {
+    Classe,
+    Const,
+    ConstMultiplo,
+    Expressao,
+    FuncaoDeclaracao,
+    Enquanto,
+    Escolha,
+    Escreva,
+    Fazer,
+    Importar,
+    Para,
+    ParaCada,
+    Se,
+    Tente,
+    Var,
+    VarMultiplo,
+    Bloco,
+    Continua,
+    EscrevaMesmaLinha,
+    Leia,
+    LeiaMultiplo,
+    Retorna,
+    Sustar,
+    Declaracao,
+    Falhar,
+} from '../declaracoes';
+import { VisitanteComumInterface } from '../interfaces';
+import { SustarQuebra } from '../quebras';
 
 import tiposDeSimbolos from '../tipos-de-simbolos/delegua';
 
@@ -6,79 +56,685 @@ import tiposDeSimbolos from '../tipos-de-simbolos/delegua';
  * O formatador de código Delégua.
  * Normalmente usado por IDEs, mas pode ser usado por linha de comando ou programaticamente.
  */
-export class FormatadorDelegua {
-    indentacao: number;
-    blocoAberto: boolean;
+export class FormatadorDelegua implements VisitanteComumInterface {
+    indentacaoAtual: number;
+    quebraLinha: string;
+    tamanhoIndentacao: number;
+    codigoFormatado: string;
+    devePularLinha: boolean;
+    deveIndentar: boolean;
 
-    constructor() {
-        this.indentacao = 0;
-        this.blocoAberto = true;
+    constructor(quebraLinha: string, tamanhoIndentacao: number = 4) {
+        this.quebraLinha = quebraLinha;
+        this.tamanhoIndentacao = tamanhoIndentacao;
+
+        this.indentacaoAtual = 0;
+        this.codigoFormatado = '';
+        this.devePularLinha = true;
+        this.deveIndentar = true;
+    }
+
+    visitarDeclaracaoClasse(declaracao: Classe) {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}classe ${declaracao.simbolo.lexema} {${this.quebraLinha}`;
+
+        this.indentacaoAtual += this.tamanhoIndentacao;
+        for (let propriedade of declaracao.propriedades) {
+            this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}${propriedade.nome.lexema}: ${propriedade.tipo || 'qualquer'}${this.quebraLinha}`;
+        }
+
+        this.codigoFormatado += `${this.quebraLinha}`;
+
+        for (let metodo of declaracao.metodos) {
+            this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}${metodo.simbolo.lexema}`;
+            this.visitarExpressaoFuncaoConstruto(metodo.funcao);
+        }
+        
+        this.indentacaoAtual -= this.tamanhoIndentacao;
+
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
+    }
+
+    visitarDeclaracaoConst(declaracao: Const): any {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}constante ${declaracao.simbolo.lexema}`;
+        if (declaracao.inicializador) {
+            this.codigoFormatado += ` = `;
+            this.formatarDeclaracaoOuConstruto(declaracao.inicializador);
+        }
+
+        if (this.devePularLinha) {
+            this.codigoFormatado += this.quebraLinha;
+        }
+    }
+
+    visitarDeclaracaoConstMultiplo(declaracao: ConstMultiplo): any {
+        // TODO: Até então o código nunca passa por aqui, porque o avaliador sintático
+        // converte `ConstMultiplo` em várias declarações `const`.
+        // Talvez mudar a avaliação sintática para não fazer mais isso.
+        console.log(declaracao);
+    }
+
+    visitarDeclaracaoDeAtribuicao(expressao: Atribuir) {
+        if (
+            [
+                tiposDeSimbolos.MAIS_IGUAL,
+                tiposDeSimbolos.MENOS_IGUAL,
+                tiposDeSimbolos.MULTIPLICACAO_IGUAL,
+                tiposDeSimbolos.DIVISAO_IGUAL,
+                tiposDeSimbolos.DIVISAO_INTEIRA_IGUAL,
+                tiposDeSimbolos.MODULO_IGUAL,
+            ].includes(expressao.valor.operador.tipo)
+        ) {
+            this.visitarExpressaoBinaria(expressao.valor);
+        } else {
+            this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}`;
+            this.codigoFormatado += `${expressao.simbolo.lexema} = `;
+            this.formatarDeclaracaoOuConstruto(expressao.valor);
+        }
+
+        this.codigoFormatado += `${this.quebraLinha}`;
+    }
+
+    visitarDeclaracaoDeExpressao(declaracao: Expressao) {
+        this.codigoFormatado += ' '.repeat(this.indentacaoAtual);
+        this.formatarDeclaracaoOuConstruto(declaracao.expressao);
+    }
+
+    visitarDeclaracaoDefinicaoFuncao(declaracao: FuncaoDeclaracao) {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}função `;
+        if (declaracao.simbolo) {
+            this.codigoFormatado += `${declaracao.simbolo.lexema}`;
+        }
+
+        this.formatarDeclaracaoOuConstruto(declaracao.funcao);
+    }
+
+    visitarDeclaracaoEnquanto(declaracao: Enquanto) {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}enquanto `;
+        this.formatarDeclaracaoOuConstruto(declaracao.condicao);
+        this.formatarDeclaracaoOuConstruto(declaracao.corpo);
+    }
+
+    visitarDeclaracaoEscolha(declaracao: Escolha) {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}escolha `;
+        this.formatarDeclaracaoOuConstruto(declaracao.identificadorOuLiteral);
+        this.codigoFormatado += ` {${this.quebraLinha}`;
+
+        this.indentacaoAtual += this.tamanhoIndentacao;
+        for (let caminho of declaracao.caminhos) {
+            for (let declaracoes of caminho.condicoes) {
+                this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}caso `;
+                this.formatarDeclaracaoOuConstruto(declaracoes);
+                this.codigoFormatado += ':';
+                this.codigoFormatado += this.quebraLinha;
+            }
+
+            for (let declaracoes of caminho.declaracoes) {
+                this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}`;
+                this.formatarDeclaracaoOuConstruto(declaracoes);
+            }
+        }
+
+        for (let padrao of declaracao.caminhoPadrao.declaracoes) {
+            this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}padrao:`;
+            this.codigoFormatado += this.quebraLinha;
+            this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}`;
+            this.formatarDeclaracaoOuConstruto(padrao);
+        }
+
+        this.indentacaoAtual -= this.tamanhoIndentacao;
+
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
+    }
+
+    visitarDeclaracaoEscreva(declaracao: Escreva) {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}escreva(`;
+        for (let argumento of declaracao.argumentos) {
+            this.formatarDeclaracaoOuConstruto(argumento);
+        }
+
+        this.codigoFormatado += `)${this.quebraLinha}`;
+    }
+
+    visitarDeclaracaoFazer(declaracao: Fazer) {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}fazer {${this.quebraLinha}`;
+        this.indentacaoAtual += this.tamanhoIndentacao;
+        for (let declaracaoBloco of declaracao.caminhoFazer.declaracoes) {
+            this.formatarDeclaracaoOuConstruto(declaracaoBloco);
+        }
+
+        this.indentacaoAtual -= this.tamanhoIndentacao;
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}} enquanto `;
+        this.formatarDeclaracaoOuConstruto(declaracao.condicaoEnquanto);
+        this.codigoFormatado += `${this.quebraLinha}`;
+    }
+
+    visitarDeclaracaoImportar(declaracao: Importar) {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}importar(`;
+        this.formatarDeclaracaoOuConstruto(declaracao.caminho);
+        this.codigoFormatado += `)`;
+    }
+
+    visitarDeclaracaoPara(declaracao: Para): any {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}para `;
+        this.devePularLinha = false;
+        if (declaracao.inicializador) {
+            if (Array.isArray(declaracao.inicializador)) {
+                this.deveIndentar = false;
+                for (let declaracaoInicializador of declaracao.inicializador) {
+                    this.formatarDeclaracaoOuConstruto(declaracaoInicializador);
+                }
+                this.deveIndentar = true;
+            } else {
+                this.formatarDeclaracaoOuConstruto(declaracao.inicializador);
+            }
+        }
+
+        this.codigoFormatado += `; `;
+        this.formatarDeclaracaoOuConstruto(declaracao.condicao);
+
+        this.codigoFormatado += `; `;
+        this.formatarDeclaracaoOuConstruto(declaracao.incrementar);
+        this.devePularLinha = true;
+        this.codigoFormatado += ` {${this.quebraLinha}`;
+
+        this.indentacaoAtual += this.tamanhoIndentacao;
+        for (let declaracaoBloco of declaracao.corpo.declaracoes) {
+            this.formatarDeclaracaoOuConstruto(declaracaoBloco);
+        }
+
+        this.indentacaoAtual -= this.tamanhoIndentacao;
+
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
+    }
+
+    visitarDeclaracaoParaCada(declaracao: ParaCada): Promise<any> {
+        throw new Error('Método não implementado.');
+    }
+
+    visitarDeclaracaoSe(declaracao: Se) {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}se `;
+        this.formatarDeclaracaoOuConstruto(declaracao.condicao);
+        this.codigoFormatado += ` {${this.quebraLinha}`;
+
+        this.indentacaoAtual += this.tamanhoIndentacao;
+        for (let declaracaoBloco of (declaracao.caminhoEntao as Bloco).declaracoes) {
+            this.formatarDeclaracaoOuConstruto(declaracaoBloco);
+        }
+
+        this.indentacaoAtual -= this.tamanhoIndentacao;
+        if (declaracao.caminhoSenao) {
+            this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}} senão {${this.quebraLinha}`;
+            this.indentacaoAtual += this.tamanhoIndentacao;
+            for (let declaracaoBloco of (declaracao.caminhoSenao as Bloco).declaracoes) {
+                this.formatarDeclaracaoOuConstruto(declaracaoBloco);
+            }
+            this.indentacaoAtual -= this.tamanhoIndentacao;
+        }
+
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
+    }
+
+    visitarDeclaracaoTente(declaracao: Tente) {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}tente {${this.quebraLinha}`;
+        this.indentacaoAtual += this.tamanhoIndentacao;
+        for (let declaracaoBloco of declaracao.caminhoTente) {
+            this.formatarDeclaracaoOuConstruto(declaracaoBloco);
+        }
+
+        this.indentacaoAtual -= this.tamanhoIndentacao;
+
+        if (declaracao.caminhoPegue) {
+            this.codigoFormatado += `} pegue {${this.quebraLinha}`;
+            if (declaracao.caminhoPegue instanceof FuncaoConstruto) {
+                // Se tem um parâmetro de erro.
+            } else {
+                // Se não tem um parâmetro de erro.
+                this.indentacaoAtual += this.tamanhoIndentacao;
+                for (let declaracaoBloco of declaracao.caminhoPegue as Declaracao[]) {
+                    this.formatarDeclaracaoOuConstruto(declaracaoBloco);
+                }
+            }
+        }
+
+        this.indentacaoAtual -= this.tamanhoIndentacao;
+
+        if (declaracao.caminhoFinalmente) {
+            this.codigoFormatado += `} finalmente {${this.quebraLinha}`;
+            this.indentacaoAtual += this.tamanhoIndentacao;
+            for (let declaracaoBloco of declaracao.caminhoFinalmente) {
+                this.formatarDeclaracaoOuConstruto(declaracaoBloco);
+            }
+        }
+
+        this.indentacaoAtual -= this.tamanhoIndentacao;
+
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
+    }
+
+    visitarDeclaracaoVar(declaracao: Var): any {
+        if (this.deveIndentar) {
+            this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}`;
+        }
+
+        this.codigoFormatado += `var ${declaracao.simbolo.lexema}`;
+        if (declaracao.inicializador) {
+            this.codigoFormatado += ` = `;
+            this.formatarDeclaracaoOuConstruto(declaracao.inicializador);
+        }
+
+        if (this.devePularLinha) {
+            this.codigoFormatado += this.quebraLinha;
+        }
+    }
+
+    visitarDeclaracaoVarMultiplo(declaracao: VarMultiplo): any {
+        // TODO: Até então o código nunca passa por aqui, porque o avaliador sintático
+        // converte `VarMultiplo` em várias declarações `var`.
+        // Talvez mudar a avaliação sintática para não fazer mais isso.
+        console.log(declaracao);
+    }
+
+    visitarExpressaoAcessoIndiceVariavel(expressao: AcessoIndiceVariavel) {
+        this.formatarDeclaracaoOuConstruto(expressao.entidadeChamada);
+        this.codigoFormatado += `[`;
+        this.formatarDeclaracaoOuConstruto(expressao.indice);
+        this.codigoFormatado += `]`;
+    }
+
+    visitarExpressaoAcessoMetodo(expressao: AcessoMetodoOuPropriedade) {
+        this.formatarDeclaracaoOuConstruto(expressao.objeto);
+        this.codigoFormatado += '.';
+        this.codigoFormatado += expressao.simbolo.lexema;
+    }
+
+    visitarExpressaoAgrupamento(expressao: Agrupamento): any {
+        this.codigoFormatado += '(';
+        this.formatarDeclaracaoOuConstruto(expressao.expressao);
+        this.codigoFormatado += ')';
+    }
+
+    visitarExpressaoAtribuicaoPorIndice(expressao: AtribuicaoPorIndice): any {
+        this.formatarDeclaracaoOuConstruto(expressao.objeto);
+        this.codigoFormatado += '[';
+        this.formatarDeclaracaoOuConstruto(expressao.indice);
+        this.codigoFormatado += '] = ';
+        this.formatarDeclaracaoOuConstruto(expressao.valor);
+        this.codigoFormatado += this.quebraLinha;
+    }
+
+    visitarExpressaoAtribuicaoPorIndicesMatriz(expressao: any): Promise<any> {
+        // Implementar somente para VisuAlg que tem atribuição diferente de Delégua - matriz[1, 2] = 1
+        throw new Error('Método não implementado.');
+    }
+
+    visitarExpressaoAcessoElementoMatriz(expressao: any) {
+        // Implementar somente para VisuAlg que tem acesso ao elemento da matriz diferente de Delégua - var valor = matriz[1, 2]
+        throw new Error('Método não implementado.');
+    }
+
+    visitarExpressaoBinaria(expressao: Binario) {
+        this.formatarDeclaracaoOuConstruto(expressao.esquerda);
+        switch (expressao.operador.tipo) {
+            case tiposDeSimbolos.ADICAO:
+                this.codigoFormatado += ` + `;
+                break;
+            case tiposDeSimbolos.DIVISAO:
+                this.codigoFormatado += ` / `;
+                break;
+            case tiposDeSimbolos.DIVISAO_IGUAL:
+                this.codigoFormatado += ` /= `;
+                break;
+            case tiposDeSimbolos.DIVISAO_INTEIRA:
+                this.codigoFormatado += ` \\ `;
+                break;
+            case tiposDeSimbolos.DIVISAO_INTEIRA_IGUAL:
+                this.codigoFormatado += ` \\= `;
+                break;
+            case tiposDeSimbolos.EXPONENCIACAO:
+                this.codigoFormatado += ` ** `;
+                break;
+            case tiposDeSimbolos.IGUAL_IGUAL:
+                this.codigoFormatado += ` == `;
+                break;
+            case tiposDeSimbolos.MAIOR:
+                this.codigoFormatado += ` > `;
+                break;
+            case tiposDeSimbolos.MAIOR_IGUAL:
+                this.codigoFormatado += ` >= `;
+                break;
+            case tiposDeSimbolos.MAIS_IGUAL:
+                this.codigoFormatado += ` += `;
+                break;
+            case tiposDeSimbolos.MENOR:
+                this.codigoFormatado += ` < `;
+                break;
+            case tiposDeSimbolos.MENOR_IGUAL:
+                this.codigoFormatado += ` <= `;
+                break;
+            case tiposDeSimbolos.MENOS_IGUAL:
+                this.codigoFormatado += ` -= `;
+                break;
+            case tiposDeSimbolos.MODULO:
+                this.codigoFormatado += ` % `;
+                break;
+            case tiposDeSimbolos.MODULO_IGUAL:
+                this.codigoFormatado += ` %= `;
+                break;
+            case tiposDeSimbolos.MULTIPLICACAO:
+                this.codigoFormatado += ` * `;
+                break;
+            case tiposDeSimbolos.MULTIPLICACAO_IGUAL:
+                this.codigoFormatado += ` * `;
+                break;
+            case tiposDeSimbolos.SUBTRACAO:
+                this.codigoFormatado += ` - `;
+                break;
+        }
+
+        this.formatarDeclaracaoOuConstruto(expressao.direita);
+    }
+
+    private formatarBlocoOuVetorDeclaracoes(declaracoes: Declaracao[]) {
+        this.codigoFormatado += ` {${this.quebraLinha}`;
+        this.indentacaoAtual += this.tamanhoIndentacao;
+        for (let declaracaoBloco of declaracoes) {
+            this.formatarDeclaracaoOuConstruto(declaracaoBloco);
+        }
+
+        this.indentacaoAtual -= this.tamanhoIndentacao;
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}}${this.quebraLinha}`;
+    }
+
+    visitarExpressaoBloco(declaracao: Bloco): any {
+        this.formatarBlocoOuVetorDeclaracoes(declaracao.declaracoes);
+    }
+
+    visitarExpressaoContinua(declaracao?: Continua): any {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}continua${this.quebraLinha}`;
+    }
+
+    visitarExpressaoDeChamada(expressao: Chamada) {
+        this.formatarDeclaracaoOuConstruto(expressao.entidadeChamada);
+        this.codigoFormatado += '(';
+        for (let argumento of expressao.argumentos) {
+            this.formatarDeclaracaoOuConstruto(argumento);
+            this.codigoFormatado += ', ';
+        }
+
+        if (expressao.argumentos.length > 0) {
+            this.codigoFormatado = this.codigoFormatado.slice(0, -2);
+        }
+
+        this.codigoFormatado += ')';
+    }
+
+    visitarExpressaoDefinirValor(expressao: DefinirValor) {
+        this.formatarDeclaracaoOuConstruto(expressao.objeto);
+        this.codigoFormatado += `.${expressao.nome.lexema} = `;
+        this.formatarDeclaracaoOuConstruto(expressao.valor);
+        this.codigoFormatado += `${this.quebraLinha}`;
+    }
+
+    visitarExpressaoDeleguaFuncao(expressao: any) {
+        throw new Error('Método não implementado.');
+    }
+
+    visitarExpressaoDeVariavel(expressao: Variavel) {
+        this.codigoFormatado += expressao.simbolo.lexema;
+    }
+
+    visitarExpressaoDicionario(expressao: any) {
+        throw new Error('Método não implementado.');
+    }
+    visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): any {
+        this.codigoFormatado += `||${expressao.valor}||`;
+    }
+
+    visitarDeclaracaoEscrevaMesmaLinha(declaracao: EscrevaMesmaLinha) {
+        throw new Error('Método não implementado.');
+    }
+
+    visitarExpressaoFalhar(expressao: Falhar): any {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}falhar`;
+        if (expressao.explicacao) {
+            this.codigoFormatado += ` `;
+            this.formatarDeclaracaoOuConstruto(expressao.explicacao);
+        }
+
+        this.codigoFormatado += `${this.quebraLinha}`;
+    }
+    visitarExpressaoFimPara(declaracao: FimPara) {
+        throw new Error('Método não implementado.');
+    }
+    visitarExpressaoFormatacaoEscrita(declaracao: FormatacaoEscrita) {
+        throw new Error('Método não implementado.');
+    }
+
+    visitarExpressaoFuncaoConstruto(expressao: FuncaoConstruto) {
+        this.codigoFormatado += `(`;
+        for (let argumento of expressao.parametros) {
+            this.codigoFormatado += `${argumento.nome.lexema}${
+                argumento.tipoDado && argumento.tipoDado.tipo ? `: ${argumento.tipoDado.tipo}, ` : ', '
+            }`;
+        }
+
+        if (expressao.parametros.length > 0) {
+            this.codigoFormatado = this.codigoFormatado.slice(0, -2);
+        }
+
+        this.codigoFormatado += `) `;
+        this.formatarBlocoOuVetorDeclaracoes(expressao.corpo);
+    }
+
+    visitarExpressaoIsto(expressao: Isto) {
+        this.codigoFormatado += `isto`;
+    }
+
+    visitarExpressaoLeia(expressao: Leia): Promise<any> {
+        throw new Error('Método não implementado.');
+    }
+    visitarExpressaoLeiaMultiplo(expressao: LeiaMultiplo): Promise<any> {
+        throw new Error('Método não implementado.');
+    }
+
+    visitarExpressaoLiteral(expressao: Literal): any {
+        if (typeof expressao.valor === 'string') {
+            this.codigoFormatado += `'${expressao.valor}'`;
+            return;
+        }
+
+        this.codigoFormatado += expressao.valor;
+    }
+
+    visitarExpressaoLogica(expressao: any) {
+        throw new Error('Método não implementado.');
+    }
+
+    visitarExpressaoRetornar(declaracao: Retorna): any {
+        this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}retorna`;
+        if (declaracao.valor) {
+            this.codigoFormatado += ` `;
+            this.formatarDeclaracaoOuConstruto(declaracao.valor);
+        }
+
+        this.codigoFormatado += `${this.quebraLinha}`;
+    }
+
+    visitarExpressaoSuper(expressao: Super) {
+        // TODO: `expressao.metodo` deveria ser um `Construto`, não um `Simbolo` aqui. 
+        this.codigoFormatado += `super.${expressao.metodo.lexema}()`;
+        console.log(expressao);
+    }
+
+    visitarExpressaoSustar(declaracao?: Sustar): SustarQuebra {
+        throw new Error('Método não implementado.');
+    }
+
+    visitarExpressaoTipoDe(expressao: TipoDe): Promise<any> {
+        throw new Error('Método não implementado.');
+    }
+
+    visitarExpressaoUnaria(expressao: Unario) {
+        let operador: string;
+        switch (expressao.operador.tipo) {
+            case tiposDeSimbolos.INCREMENTAR:
+                operador = `++`;
+                break;
+            case tiposDeSimbolos.DECREMENTAR:
+                operador = `--`;
+                break;
+        }
+
+        switch (expressao.incidenciaOperador) {
+            case 'ANTES':
+                this.codigoFormatado += operador;
+                this.formatarDeclaracaoOuConstruto(expressao.operando);
+                break;
+            case 'DEPOIS':
+                this.formatarDeclaracaoOuConstruto(expressao.operando);
+                this.codigoFormatado += operador;
+                break;
+        }
+
+        if (this.devePularLinha) {
+            this.codigoFormatado += this.quebraLinha;
+        }
+    }
+
+    visitarExpressaoVetor(expressao: Vetor) {
+        this.codigoFormatado += '[';
+        for (let valor of expressao.valores) {
+            this.formatarDeclaracaoOuConstruto(valor);
+            this.codigoFormatado += ', ';
+        }
+
+        if (expressao.valores.length > 0) {
+            this.codigoFormatado = this.codigoFormatado.slice(0, -2);
+        }
+
+        this.codigoFormatado += ']';
+    }
+
+    formatarDeclaracaoOuConstruto(declaracaoOuConstruto: Declaracao | Construto): void {
+        switch (declaracaoOuConstruto.constructor.name) {
+            case 'AcessoIndiceVariavel':
+                this.visitarExpressaoAcessoIndiceVariavel(declaracaoOuConstruto as AcessoIndiceVariavel);
+                break;
+            case 'AcessoMetodoOuPropriedade':
+                this.visitarExpressaoAcessoMetodo(declaracaoOuConstruto as AcessoMetodoOuPropriedade);
+                break;
+            case 'Agrupamento':
+                this.visitarExpressaoAgrupamento(declaracaoOuConstruto as Agrupamento);
+                break;
+            case 'AtribuicaoPorIndice':
+                this.visitarExpressaoAtribuicaoPorIndice(declaracaoOuConstruto as AtribuicaoPorIndice);
+                break;
+            case 'Atribuir':
+                this.visitarDeclaracaoDeAtribuicao(declaracaoOuConstruto as Atribuir);
+                break;
+            case 'Binario':
+                this.visitarExpressaoBinaria(declaracaoOuConstruto as Binario);
+                break;
+            case 'Bloco':
+                this.visitarExpressaoBloco(declaracaoOuConstruto as Bloco);
+                break;
+            case 'Chamada':
+                this.visitarExpressaoDeChamada(declaracaoOuConstruto as Chamada);
+                break;
+            case 'Classe':
+                this.visitarDeclaracaoClasse(declaracaoOuConstruto as Classe);
+                break;
+            case 'Continua':
+                this.visitarExpressaoContinua(declaracaoOuConstruto as Continua);
+                break;
+            case 'DefinirValor':
+                this.visitarExpressaoDefinirValor(declaracaoOuConstruto as DefinirValor);
+                break;
+            case 'Escolha':
+                this.visitarDeclaracaoEscolha(declaracaoOuConstruto as Escolha);
+                break;
+            case 'Enquanto':
+                this.visitarDeclaracaoEnquanto(declaracaoOuConstruto as Enquanto);
+                break;
+            case 'Escreva':
+                this.visitarDeclaracaoEscreva(declaracaoOuConstruto as Escreva);
+                break;
+            case 'Expressao':
+                this.visitarDeclaracaoDeExpressao(declaracaoOuConstruto as Expressao);
+                break;
+            case 'ExpressaoRegular':
+                this.visitarExpressaoExpressaoRegular(declaracaoOuConstruto as ExpressaoRegular);
+                break;
+            case 'Falhar':
+                this.visitarExpressaoFalhar(declaracaoOuConstruto as Falhar)
+                break;
+            case 'Fazer':
+                this.visitarDeclaracaoFazer(declaracaoOuConstruto as Fazer);
+                break;
+            case 'FuncaoConstruto':
+                this.visitarExpressaoFuncaoConstruto(declaracaoOuConstruto as FuncaoConstruto);
+                break;
+            case 'FuncaoDeclaracao':
+                this.visitarDeclaracaoDefinicaoFuncao(declaracaoOuConstruto as FuncaoDeclaracao);
+                break;
+            case 'Importar':
+                this.visitarDeclaracaoImportar(declaracaoOuConstruto as Importar);
+                break;                
+            case 'Isto':
+                this.visitarExpressaoIsto(declaracaoOuConstruto as Isto);
+                break;
+            case 'Literal':
+                this.visitarExpressaoLiteral(declaracaoOuConstruto as Literal);
+                break;
+            case 'Para':
+                this.visitarDeclaracaoPara(declaracaoOuConstruto as Para);
+                break;
+            case 'Retorna':
+                this.visitarExpressaoRetornar(declaracaoOuConstruto as Retorna);
+                break;
+            case 'Se':
+                this.visitarDeclaracaoSe(declaracaoOuConstruto as Se);
+                break;
+            case 'Super':
+                this.visitarExpressaoSuper(declaracaoOuConstruto as Super);
+                break;
+            case 'Tente':
+                this.visitarDeclaracaoTente(declaracaoOuConstruto as Tente);
+                break;
+            case 'Unario':
+                this.visitarExpressaoUnaria(declaracaoOuConstruto as Unario);
+                break;
+            case 'Const':
+                this.visitarDeclaracaoConst(declaracaoOuConstruto as Const);
+                break;
+            case 'Var':
+                this.visitarDeclaracaoVar(declaracaoOuConstruto as Var);
+                break;
+            case 'Variavel':
+                this.visitarExpressaoDeVariavel(declaracaoOuConstruto as Variavel);
+                break;
+            case 'Vetor':
+                this.visitarExpressaoVetor(declaracaoOuConstruto as Vetor);
+                break;
+            default:
+                console.log(declaracaoOuConstruto.constructor.name);
+                break;
+        }
     }
 
     /**
      * Devolve código formatado de acordo com os símbolos encontrados.
-     * @param simbolos Um vetor de símbolos.
-     * @param quebraLinha O símbolo de quebra de linha. Normalmente `\r\n` para Windows e `\n` para outros sistemas operacionais.
-     * @param tamanhoIndentacao O tamanho de cada bloco de indentação (por padrão, 4)
+     * @param {Declaracao[]} declaracoes Um vetor de declarações.
      * @returns Código Delégua formatado.
      */
-    formatar(simbolos: SimboloInterface[], quebraLinha: string, tamanhoIndentacao: number = 4): string {
-        let resultado = '';
-        let deveQuebrarLinha: boolean = false;
-
-        for (let simbolo of simbolos) {
-            switch (simbolo.tipo) {
-                case tiposDeSimbolos.CHAVE_ESQUERDA:
-                    this.indentacao += tamanhoIndentacao;
-                    resultado += '{' + quebraLinha;
-                    resultado += ' '.repeat(this.indentacao);
-                    break;
-                case tiposDeSimbolos.CHAVE_DIREITA:
-                    this.indentacao -= tamanhoIndentacao;
-                    resultado += quebraLinha + ' '.repeat(this.indentacao) + '}' + quebraLinha;
-                    break;
-                case tiposDeSimbolos.ESCREVA:
-                    deveQuebrarLinha = true;
-                case tiposDeSimbolos.ENQUANTO:
-                case tiposDeSimbolos.FAZER:
-                case tiposDeSimbolos.FINALMENTE:
-                case tiposDeSimbolos.PARA:
-                case tiposDeSimbolos.PEGUE:
-                case tiposDeSimbolos.RETORNA:
-                case tiposDeSimbolos.SE:
-                case tiposDeSimbolos.SENAO:
-                case tiposDeSimbolos.SENÃO:
-                case tiposDeSimbolos.TENTE:
-                case tiposDeSimbolos.VARIAVEL:
-                    resultado += quebraLinha + ' '.repeat(this.indentacao) + simbolo.lexema + ' ';
-                    break;
-                case tiposDeSimbolos.PARENTESE_ESQUERDO:
-                    resultado += '(';
-                    break;
-                case tiposDeSimbolos.PARENTESE_DIREITO:
-                    resultado = resultado.trimEnd();
-                    resultado += ')';
-                    if (deveQuebrarLinha) {
-                        deveQuebrarLinha = false;
-                        resultado += quebraLinha;
-                    } else {
-                        resultado += ' ';
-                    }
-
-                    break;
-                case tiposDeSimbolos.FUNCAO:
-                case tiposDeSimbolos.FUNÇÃO:
-                case tiposDeSimbolos.IDENTIFICADOR:
-                case tiposDeSimbolos.IGUAL:
-                case tiposDeSimbolos.IGUAL_IGUAL:
-                    resultado += simbolo.lexema + ' ';
-                    break;
-                default:
-                    resultado += simbolo.lexema;
-                    break;
-            }
+    formatar(declaracoes: Declaracao[]): string {
+        this.codigoFormatado = '';
+        this.indentacaoAtual = 0;
+
+        for (let declaracao of declaracoes) {
+            this.formatarDeclaracaoOuConstruto(declaracao);
         }
 
-        return resultado;
+        return this.codigoFormatado;
     }
 }
diff --git a/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.ts b/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.ts
index 5e5967c7..36211ac0 100644
--- a/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.ts
+++ b/fontes/interpretador/dialetos/egua-classico/interpretador-egua-classico.ts
@@ -155,7 +155,7 @@ export class InterpretadorEguaClassico implements InterpretadorInterface {
         return expressao.valor;
     }
 
-    avaliar(expressao: Construto): VariavelInterface | any {
+    avaliar(expressao: Construto | Declaracao): VariavelInterface | any {
         return expressao.aceitar(this);
     }
 
@@ -454,7 +454,7 @@ export class InterpretadorEguaClassico implements InterpretadorInterface {
 
     async visitarDeclaracaoPara(declaracao: Para) {
         if (declaracao.inicializador !== null) {
-            await this.avaliar(declaracao.inicializador);
+            await this.avaliar(declaracao.inicializador as any);
         }
         while (true) {
             if (declaracao.condicao !== null) {
diff --git a/fontes/interpretador/dialetos/visualg/comum.ts b/fontes/interpretador/dialetos/visualg/comum.ts
index d50a5f84..3c582603 100644
--- a/fontes/interpretador/dialetos/visualg/comum.ts
+++ b/fontes/interpretador/dialetos/visualg/comum.ts
@@ -237,8 +237,8 @@ export async function visitarExpressaoLogica(interpretador: InterpretadorBase, e
 export async function resolverIncrementoPara(interpretador: InterpretadorBase, declaracao: Para): Promise<any> {
     if (declaracao.resolverIncrementoEmExecucao) {
         const promises = await Promise.all([
-            avaliar(interpretador, declaracao.condicao.esquerda),
-            avaliar(interpretador, declaracao.condicao.direita),
+            avaliar(interpretador, (declaracao.condicao as any).esquerda),
+            avaliar(interpretador, (declaracao.condicao as any).direita),
         ]);
         const operandoEsquerdo = promises[0];
         const operandoDireito = promises[1];
@@ -246,7 +246,7 @@ export async function resolverIncrementoPara(interpretador: InterpretadorBase, d
         const valorAtualDireito = operandoDireito.hasOwnProperty('valor') ? operandoDireito.valor : operandoDireito;
 
         if (valorAtualEsquerdo < valorAtualDireito) {
-            declaracao.condicao.operador = new Simbolo(
+            (declaracao.condicao as any).operador = new Simbolo(
                 tiposDeSimbolos.MENOR_IGUAL,
                 '',
                 '',
@@ -266,7 +266,7 @@ export async function resolverIncrementoPara(interpretador: InterpretadorBase, d
                 1
             );
         } else {
-            declaracao.condicao.operador = new Simbolo(
+            (declaracao.condicao as any).operador = new Simbolo(
                 tiposDeSimbolos.MAIOR_IGUAL,
                 '',
                 '',
diff --git a/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.ts b/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.ts
index a4869714..fe8cb449 100644
--- a/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.ts
+++ b/fontes/interpretador/dialetos/visualg/interpretador-visualg-com-depuracao.ts
@@ -153,7 +153,7 @@ export class InterpretadorVisuAlgComDepuracao extends InterpretadorComDepuracao
         const cloneDeclaracao = _.cloneDeep(declaracao) as Para;
         const corpoExecucao = cloneDeclaracao.corpo as Bloco;
         if (cloneDeclaracao.inicializador !== null) {
-            await this.avaliar(cloneDeclaracao.inicializador);
+            await this.avaliar(cloneDeclaracao.inicializador as any);
             // O incremento vai ao final do bloco de escopo.
             if (cloneDeclaracao.incrementar !== null) {
                 await comum.resolverIncrementoPara(this, cloneDeclaracao);
diff --git a/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts b/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts
index e8021e07..c06fdfed 100644
--- a/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts
+++ b/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts
@@ -153,7 +153,7 @@ export class InterpretadorVisuAlg extends InterpretadorBase {
 
     async visitarDeclaracaoPara(declaracao: Para): Promise<any> {
         if (declaracao.inicializador !== null) {
-            await this.avaliar(declaracao.inicializador);
+            await this.avaliar(declaracao.inicializador as any);
             await comum.resolverIncrementoPara(this, declaracao);
         }
 


Test patch:
diff --git a/testes/formatadores/formatador-delegua.test.ts b/testes/formatadores/formatador-delegua.test.ts
index ce5f379d..249a7180 100644
--- a/testes/formatadores/formatador-delegua.test.ts
+++ b/testes/formatadores/formatador-delegua.test.ts
@@ -1,18 +1,287 @@
-import * as sistemaOperacional from 'node:os';
+import * as sistemaOperacional from 'os';
 
 import { FormatadorDelegua } from '../../fontes/formatadores';
 import { Lexador } from '../../fontes/lexador';
+import { AvaliadorSintatico } from '../../fontes/avaliador-sintatico';
 
 describe('Formatadores > Delégua', () => {
-    const formatador = new FormatadorDelegua();
+    const formatador = new FormatadorDelegua(sistemaOperacional.EOL);
+    const avaliadorSintatico = new AvaliadorSintatico();
     const lexador = new Lexador();
 
-    it('Trivial', () => {
+    it('Atribuições múltiplas', () => {
+        const resultadoLexador = lexador.mapear([
+            "var a, b, c = 1, 2, 3 const d,f,g=4,5,6",
+        ], -1);
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(7);
+    })
+
+    it('Classes', () => {
+        const resultadoLexador = lexador.mapear([
+            `classe Teste {propriedade1: numero propriedade2: texto construtor(){isto.propriedade1=0 isto.propriedade2="123"}testeMetodo(argumento1: numero){isto.propriedade1=argumento1}}`,
+        ], -1);
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(13);
+    });
+
+    // TODO: Corrigir avaliação de estrutura `super` antes de religar este teste.
+    it.skip('Classes com herança, uso de super', () => {
+        const resultadoLexador = lexador.mapear([
+            `classe Ancestral{propriedade1: numero construtor(){super.propriedade1=0 }}`,
+            `classe Teste herda Ancestral{ super()}`,
+        ], -1);
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(13);
+    });
+
+    it('Escolha', () => {
+        const resultadoLexador = lexador.mapear([
+            "escolha (2) { caso 1: escreva('correspondente à opção 1'); caso 2: caso 3: escreva('correspondente à opção 2 e 3'); padrao: escreva('Sem opção correspondente'); }",
+        ], -1);
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(10);
+    });
+
+    it('Enquanto', () => {
+        const resultadoLexador = lexador.mapear(
+            ["var a = 1 enquanto a < 10 { a += 1}"], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(5);
+    });
+
+    it('Fazer', () => {
+        const resultadoLexador = lexador.mapear(
+            ["var a = 1 fazer { a++ } enquanto a < 10 "],
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(5);
+    });
+
+    it('Funções', () => {
+        const resultadoLexador = lexador.mapear(
+            ["funcao teste() { retorna 1} var a = teste() escreva(a)"],
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(6);
+    });
+
+    it('Funções, indentação bem zoada', () => {
+        const resultadoLexador = lexador.mapear(
+            [
+                "funcao temDigitoRepetido(num) {",
+                "    var str = texto( num);",
+                "  para (var i =1; i< tamanho(str);i++   ) {",
+                "        se (str[i] != str[0]) {",
+                "     retorna falso;",
+                "}",
+                "    }",
+                "   retorna verdadeiro;",
+                "}",
+            ], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(10);
+    });
+
+    it('Funções com argumentos tipados', () => {
+        const resultadoLexador = lexador.mapear(
+            [
+                'função f(a:texto,b:inteiro, c: texto, d){ escreva(a +b)}',
+            ], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(4);
+    });
+
+    it('Expressões Regulares', () => {
+        const resultadoLexador = lexador.mapear(
+            [
+                "var str = \"olá mundo, olá universo\" var novaStr = str.substituir(||/olá/g||, \"oi\") escreva(novaStr);",
+            ], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(4);
+    });
+
+    it('Para', () => {
+        const resultadoLexador = lexador.mapear(
+            ["para var a = 1; a < 10; a++ { se a %2==0 { continua } escreva(a) }"], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(7);
+    });
+
+    it('Se', () => {
         const resultadoLexador = lexador.mapear(
-            ["tente { escreva('sucesso') } pegue { escreva('pegue') } finalmente { escreva('pronto') }"], 
+            ["se a == 1 { escreva(a) } senao {escreva(a + 1)} "], 
             -1
         );
-        const resultado = formatador.formatar(resultadoLexador.simbolos, sistemaOperacional.EOL);
-        expect(resultado.split('\n')).toHaveLength(19);
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(6);
+    });
+
+    it('Tente', () => {
+        const resultadoLexador = lexador.mapear(
+            ["tente { escreva('sucesso') } pegue {escreva('pegue')} finalmente { escreva('pronto') }"], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(8);
+    });
+
+    it('Variaveis', () => {
+        const resultadoLexador = lexador.mapear(
+            ["var a=1 fixo c = 2"], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(3);
+    });
+
+    it('Vetor', () => {
+        const resultadoLexador = lexador.mapear(
+            ["var a = [1,2,3] const c=[4,5,6] escreva(a[0])"], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        console.log(resultado);
+        expect(linhasResultado).toHaveLength(4);
+    });
+
+    it('Falhar', () => {
+        const resultadoLexador = lexador.mapear(
+            [
+                "funcao temDigitoRepetido(num) {",
+                "    var str = texto( num);",
+                "  para (var i =1; i< tamanho(str);i++   ) {",
+                "        se (str[i] != str[0]) {",
+                "     falhar \"Erro!!!\"",
+                "}",
+                "    }",
+                "   retorna verdadeiro;",
+                "}",
+            ], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(10);
+    });
+
+    it('Importar', () => {
+        const resultadoLexador = lexador.mapear(
+            [
+                "var dm = importar('@designliquido/delegua-matematica')var m = importar('matematica') dm.raizQuadrada(9) // Imprime 3",
+            ], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        console.log(resultado);
+        expect(linhasResultado).toHaveLength(3);
+    });
+
+    it('Atribuição por Indice', () => {
+        const resultadoLexador = lexador.mapear(
+            ["var fila = []; fila[0] = 1 fila[1] = 2 fila[3] = 3 escreva(fila[3])"], 
+            -1
+        );
+
+        const resultadoAvaliacaoSintatica = avaliadorSintatico.analisar(resultadoLexador, -1);
+        const resultado = formatador.formatar(resultadoAvaliacaoSintatica.declaracoes);
+        const linhasResultado = resultado.split(sistemaOperacional.EOL);
+        
+        // console.log(resultado);
+        expect(linhasResultado).toHaveLength(6);
     });
-});
\ No newline at end of file
+});