Repository: DesignLiquido/delegua
Pull request #473 (2023-08-14 23:22:01)

Tradutor principal para assembly script
- [x] Terminando de implementar as traduções dos tipos.

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: 74.28%">73.22% (-1.06% 🔻)</div> |    7715/10537   |
|                                                                           🟡                                                                           | Branches   | <div title="Base coverage is: 64.18%">62.29% (-1.89% 🔻)</div> |    2514/4036    |
|                                                                           🟡                                                                           | Functions  | <div title="Base coverage is: 69.79%">69.13% (-0.66% 🔻)</div> |    1131/1636    |
|                                                                           🟡                                                                           | Lines      | <div title="Base coverage is: 74.67%">73.58% (-1.09% 🔻)</div> |    7520/10220   |

<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="tradutores/tradutor-assemblyscript.ts">`...` / tradutor-assemblyscript.ts</div> | 39.81%     | 23.12%   | 46.81%    | 39.37% |

</details>


## Test suite run success
659 tests passing in 50 suites.

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

Patch:
diff --git a/.vscode/launch.json b/.vscode/launch.json
index ede52d8d..2af23e53 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -4,6 +4,20 @@
     // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
     "version": "0.2.0",
     "configurations": [
+        {
+            "name": "Tradutor > Delégua para AssemblyScript",
+            "type": "node",
+            "request": "launch",
+            "runtimeArgs": [
+                "--inspect-brk",
+                "${workspaceRoot}/node_modules/jest/bin/jest.js",
+                "tradutores/tradutor-assemblyscript.test.ts",
+                // "birl",
+                "--runInBand"
+            ],
+            "console": "integratedTerminal",
+            "internalConsoleOptions": "neverOpen"
+        },
         {
             "name": "BIRL > Testes Interpretador",
             "type": "node",
diff --git a/fontes/avaliador-sintatico/avaliador-sintatico.ts b/fontes/avaliador-sintatico/avaliador-sintatico.ts
index a3da5f73..5ed84595 100644
--- a/fontes/avaliador-sintatico/avaliador-sintatico.ts
+++ b/fontes/avaliador-sintatico/avaliador-sintatico.ts
@@ -75,7 +75,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
         this.erros = [];
         this.performance = performance;
     }
-    
+
     declaracaoDeVariavel(): Var {
         throw new Error("Método não implementado.");
     }
@@ -1204,7 +1204,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
             let funcaoContemRetorno = corpo.find(c => c instanceof Retorna) as Retorna;
             if(funcaoContemRetorno){
                 if(tipoRetorno === 'vazio') {
-                    throw this.erro(this.simboloAtual(), `A função não pode ter nenhum tipo de retorno.`)                    
+                    throw this.erro(this.simboloAtual(), `A função não pode ter nenhum tipo de retorno.`)
                 }
 
                 const tipoValor = typeof funcaoContemRetorno.valor.valor;
diff --git a/fontes/tradutores/tradutor-assemblyscript.ts b/fontes/tradutores/tradutor-assemblyscript.ts
new file mode 100644
index 00000000..6f96e5b9
--- /dev/null
+++ b/fontes/tradutores/tradutor-assemblyscript.ts
@@ -0,0 +1,711 @@
+import {
+    AcessoIndiceVariavel,
+    AcessoMetodo,
+    Agrupamento,
+    AtribuicaoPorIndice,
+    Atribuir,
+    Binario,
+    Chamada,
+    DefinirValor,
+    FuncaoConstruto,
+    Isto,
+    Literal,
+    Logico,
+    TipoDe,
+    Unario,
+    Variavel,
+    Vetor,
+} from '../construtos';
+import {
+    Bloco,
+    Classe,
+    Const,
+    Declaracao,
+    Enquanto,
+    Escolha,
+    Escreva,
+    Expressao,
+    Falhar,
+    Fazer,
+    FuncaoDeclaracao,
+    Importar,
+    Leia,
+    Para,
+    ParaCada,
+    Retorna,
+    Se,
+    Tente,
+    Var,
+} from '../declaracoes';
+import { SimboloInterface } from '../interfaces';
+import { CaminhoEscolha } from '../interfaces/construtos';
+import tiposDeSimbolos from '../tipos-de-simbolos/delegua';
+
+export class TradutorAssemblyScript {
+    indentacao: number = 0;
+    declaracoesDeClasses: Classe[];
+
+    traduzirSimboloOperador(operador: SimboloInterface): string {
+        switch (operador.tipo) {
+            case tiposDeSimbolos.ADICAO:
+                return '+';
+            case tiposDeSimbolos.BIT_AND:
+                return '&';
+            case tiposDeSimbolos.BIT_OR:
+                return '|';
+            case tiposDeSimbolos.BIT_XOR:
+                return '^';
+            case tiposDeSimbolos.BIT_NOT:
+                return '~';
+            case tiposDeSimbolos.DIFERENTE:
+                return '!==';
+            case tiposDeSimbolos.DIVISAO:
+                return '/';
+            case tiposDeSimbolos.E:
+                return '&&';
+            case tiposDeSimbolos.EXPONENCIACAO:
+                return '**';
+            case tiposDeSimbolos.IGUAL:
+                return '=';
+            case tiposDeSimbolos.IGUAL_IGUAL:
+                return '===';
+            case tiposDeSimbolos.MAIOR:
+                return '>';
+            case tiposDeSimbolos.MAIOR_IGUAL:
+                return '>=';
+            case tiposDeSimbolos.MENOR:
+                return '<';
+            case tiposDeSimbolos.MENOR_IGUAL:
+                return '<=';
+            case tiposDeSimbolos.MODULO:
+                return '%';
+            case tiposDeSimbolos.MULTIPLICACAO:
+                return '*';
+            case tiposDeSimbolos.OU:
+                return '||';
+            case tiposDeSimbolos.SUBTRACAO:
+                return '-';
+        }
+    }
+
+    traduzirFuncoesNativas(metodo: string): string {
+        switch (metodo.toLowerCase()) {
+            case 'adicionar':
+            case 'empilhar':
+                return 'push';
+            case 'concatenar':
+                return 'concat';
+            case 'fatiar':
+                return 'slice';
+            case 'inclui':
+                return 'includes';
+            case 'inverter':
+                return 'reverse';
+            case 'juntar':
+                return 'join';
+            case 'ordenar':
+                return 'sort';
+            case 'removerprimeiro':
+                return 'shift';
+            case 'removerultimo':
+                return 'pop';
+            case 'tamanho':
+                return 'length';
+            case 'maiusculo':
+                return 'toUpperCase';
+            case 'minusculo':
+                return 'toLowerCase';
+            case 'substituir':
+                return 'replace';
+            default:
+                return metodo;
+        }
+    }
+
+    traduzirDeclaracaoEscreva(declaracaoEscreva: Escreva): string {
+        let resultado = 'console.log(';
+        for (const argumento of declaracaoEscreva.argumentos) {
+            const valor = this.dicionarioConstrutos[argumento.constructor.name](argumento);
+            resultado += valor + ', ';
+        }
+
+        resultado = resultado.slice(0, -2);
+        resultado += ')';
+        return resultado;
+    }
+
+    traduzirConstrutoLiteral(literal: Literal): string {
+        if (typeof literal.valor === 'string') return `'${literal.valor}'`;
+        return literal.valor;
+    }
+
+    resolveTipoDeclaracaoVarEContante(tipo: string): string {
+        switch (tipo) {
+            case 'texto':
+                return ': string';
+            case 'inteiro':
+            case 'real':
+                return ': f64';
+            case 'logico':
+                return ': bool';
+            case 'nulo':
+                return ': null';
+            case 'inteiro[]':
+            case 'real[]':
+                return ': f64[]';
+            case 'texto[]':
+                return ': string[]';
+            case 'logico[]':
+                return ': bool[]';
+            default:
+                return ': any';
+        }
+    }
+
+    traduzirDeclaracaoVar(declaracaoVar: Var): string {
+        let resultado = 'let ';
+        resultado += declaracaoVar.simbolo.lexema;
+        resultado += this.resolveTipoDeclaracaoVarEContante(declaracaoVar.tipo);
+        if (!declaracaoVar?.inicializador) resultado += ';';
+        else {
+            resultado += ' = ';
+            if (this.dicionarioConstrutos[declaracaoVar.inicializador.constructor.name]) {
+                resultado += this.dicionarioConstrutos[declaracaoVar.inicializador.constructor.name](
+                    declaracaoVar.inicializador
+                );
+            } else {
+                resultado += this.dicionarioDeclaracoes[declaracaoVar.inicializador.constructor.name](
+                    declaracaoVar.inicializador
+                );
+            }
+            resultado += ';';
+        }
+        return resultado;
+    }
+
+    traduzirDeclaracaoConst(declaracaoConst: Const): string {
+        let resultado = 'const ';
+        resultado += declaracaoConst.simbolo.lexema;
+        resultado += this.resolveTipoDeclaracaoVarEContante(declaracaoConst.tipo);
+        if (!declaracaoConst?.inicializador) resultado += ';';
+        else {
+            resultado += ' = ';
+            if (this.dicionarioConstrutos[declaracaoConst.inicializador.constructor.name]) {
+                resultado += this.dicionarioConstrutos[declaracaoConst.inicializador.constructor.name](
+                    declaracaoConst.inicializador
+                );
+            } else {
+                resultado += this.dicionarioDeclaracoes[declaracaoConst.inicializador.constructor.name](
+                    declaracaoConst.inicializador
+                );
+            }
+            resultado += ';';
+        }
+        return resultado;
+    }
+
+    traduzirDeclaracaoTente(declaracaoTente: Tente): string {
+        let resultado = 'try {\n';
+        this.indentacao += 4;
+        resultado += ' '.repeat(this.indentacao);
+
+        for (let condicao of declaracaoTente.caminhoTente) {
+            resultado += this.dicionarioDeclaracoes[condicao.constructor.name](condicao) + '\n';
+            resultado += ' '.repeat(this.indentacao);
+        }
+        resultado += '}';
+
+        if (declaracaoTente.caminhoPegue !== null) {
+            resultado += '\ncatch {\n';
+            resultado += ' '.repeat(this.indentacao);
+            if (Array.isArray(declaracaoTente.caminhoPegue)) {
+                for (let declaracao of declaracaoTente.caminhoPegue) {
+                    resultado += this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao) + '\n';
+                }
+            } else {
+                for (let corpo of declaracaoTente.caminhoPegue.corpo) {
+                    resultado += this.dicionarioDeclaracoes[corpo.constructor.name](corpo) + '\n';
+                }
+            }
+
+            resultado += ' '.repeat(this.indentacao);
+            resultado += '}';
+        }
+        if (declaracaoTente.caminhoFinalmente !== null) {
+            resultado += '\nfinally {\n';
+            for (let finalmente of declaracaoTente.caminhoFinalmente) {
+                resultado += this.dicionarioDeclaracoes[finalmente.constructor.name](finalmente) + '\n';
+            }
+            resultado += ' '.repeat(this.indentacao);
+            resultado += '}';
+        }
+
+        return resultado;
+    }
+
+    logicaComumBlocoEscopo(declaracoes: Declaracao[]): string {
+        let resultado = '{\n';
+        this.indentacao += 4;
+
+        if (typeof declaracoes[Symbol.iterator] === 'function') {
+            for (const declaracaoOuConstruto of declaracoes) {
+                resultado += ' '.repeat(this.indentacao);
+                const nomeConstrutor = declaracaoOuConstruto.constructor.name;
+                if (this.dicionarioConstrutos.hasOwnProperty(nomeConstrutor)) {
+                    resultado += this.dicionarioConstrutos[nomeConstrutor](declaracaoOuConstruto);
+                } else {
+                    resultado += this.dicionarioDeclaracoes[nomeConstrutor](declaracaoOuConstruto);
+                }
+
+                resultado += '\n';
+            }
+        }
+
+        this.indentacao -= 4;
+        resultado += ' '.repeat(this.indentacao) + '}\n';
+        return resultado;
+    }
+
+    logicaTraducaoMetodoClasse(metodoClasse: FuncaoDeclaracao): string {
+        this.indentacao += 4;
+        let resultado = ' '.repeat(this.indentacao);
+        resultado += metodoClasse.simbolo.lexema === 'construtor' ? 'constructor(' : metodoClasse.simbolo.lexema + '(';
+
+        for (let parametro of metodoClasse.funcao.parametros) {
+            resultado += parametro.nome.lexema + ', ';
+        }
+        if (metodoClasse.funcao.parametros.length > 0) {
+            resultado = resultado.slice(0, -2);
+        }
+
+        resultado += ') ';
+        resultado += this.logicaComumBlocoEscopo(metodoClasse.funcao.corpo);
+        resultado += ' '.repeat(this.indentacao) + '\n';
+
+        this.indentacao -= 4;
+        return resultado;
+    }
+
+    traduzirDeclaracaoClasse(declaracaoClasse: Classe): string {
+        let resultado = 'export class ';
+
+        if (declaracaoClasse.superClasse)
+            resultado += `${declaracaoClasse.simbolo.lexema} extends ${declaracaoClasse.superClasse.simbolo.lexema} {\n`;
+        else resultado += declaracaoClasse.simbolo.lexema + ' {\n';
+
+        for (let metodo of declaracaoClasse.metodos) {
+            resultado += this.logicaTraducaoMetodoClasse(metodo);
+        }
+
+        resultado += '}';
+        return resultado;
+    }
+
+    traduzirDeclaracaoSe(declaracaoSe: Se): string {
+        let resultado = 'if (';
+
+        const condicao = this.dicionarioConstrutos[declaracaoSe.condicao.constructor.name](declaracaoSe.condicao);
+
+        resultado += condicao;
+
+        resultado += ')';
+        resultado += this.dicionarioDeclaracoes[declaracaoSe.caminhoEntao.constructor.name](declaracaoSe.caminhoEntao);
+
+        if (declaracaoSe.caminhoSenao !== null) {
+            resultado += ' '.repeat(this.indentacao);
+            resultado += 'else ';
+            const se = declaracaoSe?.caminhoSenao as Se;
+            if (se?.caminhoEntao) {
+                resultado += 'if (';
+                resultado += this.dicionarioConstrutos[se.condicao.constructor.name](se.condicao);
+                resultado += ')';
+                resultado += this.dicionarioDeclaracoes[se.caminhoEntao.constructor.name](se.caminhoEntao);
+                resultado += ' '.repeat(this.indentacao);
+                if (se?.caminhoSenao) {
+                    resultado += 'else ';
+                    resultado += this.dicionarioDeclaracoes[se.caminhoSenao.constructor.name](se.caminhoSenao);
+                    return resultado;
+                }
+            }
+
+            resultado += this.dicionarioDeclaracoes[declaracaoSe.caminhoSenao.constructor.name](
+                declaracaoSe.caminhoSenao
+            );
+        }
+
+        return resultado;
+    }
+
+    traduzirDeclaracaoRetorna(declaracaoRetorna: Retorna): string {
+        let resultado = 'return ';
+        const nomeConstrutor = declaracaoRetorna.valor.constructor.name;
+        return (resultado += this.dicionarioConstrutos[nomeConstrutor](declaracaoRetorna?.valor));
+    }
+
+    traduzirDeclaracaoParaCada(declaracaoParaCada: ParaCada): string {
+        let resultado = `for (let ${declaracaoParaCada.nomeVariavelIteracao} of `;
+        resultado +=
+            this.dicionarioConstrutos[declaracaoParaCada.vetor.constructor.name](declaracaoParaCada.vetor) + ') ';
+
+        resultado += this.dicionarioDeclaracoes[declaracaoParaCada.corpo.constructor.name](declaracaoParaCada.corpo);
+        return resultado;
+    }
+
+    traduzirDeclaracaoPara(declaracaoPara: Para): string {
+        let resultado = 'for (';
+        if (declaracaoPara.inicializador.constructor.name === 'Array') {
+            resultado +=
+                this.dicionarioDeclaracoes[declaracaoPara.inicializador[0].constructor.name](
+                    declaracaoPara.inicializador[0]
+                ) + ' ';
+        } else {
+            resultado +=
+                this.dicionarioDeclaracoes[declaracaoPara.inicializador.constructor.name](
+                    declaracaoPara.inicializador
+                ) + ' ';
+        }
+
+        resultado += !resultado.includes(';') ? ';' : '';
+
+        resultado +=
+            this.dicionarioConstrutos[declaracaoPara.condicao.constructor.name](declaracaoPara.condicao) + '; ';
+        resultado +=
+            this.dicionarioConstrutos[declaracaoPara.incrementar.constructor.name](declaracaoPara.incrementar) + ') ';
+
+        resultado += this.dicionarioDeclaracoes[declaracaoPara.corpo.constructor.name](declaracaoPara.corpo);
+        return resultado;
+    }
+
+    traduzirDeclaracaoImportar(declaracaoImportar: Importar) {
+        return `'importar() não é suportado por este padrão de JavaScript'`;
+    }
+
+    traduzirDeclaracaoLeia(declaracaoLeia: Leia) {
+        return `'leia() não é suportado por este padrão de JavaScript.'`;
+    }
+
+    traduzirDeclaracaoFuncao(declaracaoFuncao: FuncaoDeclaracao): string {
+        let resultado = 'function ';
+        resultado += declaracaoFuncao.simbolo.lexema + ' (';
+
+        for (const parametro of declaracaoFuncao.funcao.parametros) {
+            resultado += parametro.nome.lexema + ', ';
+        }
+
+        if (declaracaoFuncao.funcao.parametros.length > 0) {
+            resultado = resultado.slice(0, -2);
+        }
+
+        resultado += ') ';
+
+        resultado += this.logicaComumBlocoEscopo(declaracaoFuncao.funcao.corpo);
+        return resultado;
+    }
+
+    traduzirDeclaracaoFalhar(falhar: Falhar) {
+        return `throw '${falhar.explicacao}'`;
+    }
+
+    traduzirDeclaracaoFazer(declaracaoFazer: Fazer): string {
+        let resultado = 'do ';
+        resultado += this.dicionarioDeclaracoes[declaracaoFazer.caminhoFazer.constructor.name](
+            declaracaoFazer.caminhoFazer
+        );
+        resultado +=
+            'while (' +
+            this.dicionarioConstrutos[declaracaoFazer.condicaoEnquanto.constructor.name](
+                declaracaoFazer.condicaoEnquanto
+            ) +
+            ') ';
+        return resultado;
+    }
+
+    traduzirDeclaracaoExpressao(declaracaoExpressao: Expressao): string {
+        return this.dicionarioConstrutos[declaracaoExpressao.expressao.constructor.name](declaracaoExpressao.expressao);
+    }
+
+    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';
+        }
+
+        this.indentacao -= 4;
+        return resultado;
+    }
+
+    traduzirDeclaracaoEscolha(declaracaoEscolha: Escolha): string {
+        let resultado = 'switch (';
+        resultado +=
+            this.dicionarioConstrutos[declaracaoEscolha.identificadorOuLiteral.constructor.name](
+                declaracaoEscolha.identificadorOuLiteral
+            ) + ') {\n';
+
+        for (let caminho of declaracaoEscolha.caminhos) {
+            resultado += this.logicaComumCaminhosEscolha(caminho);
+        }
+
+        if (declaracaoEscolha.caminhoPadrao) {
+            resultado += ' '.repeat(4);
+            resultado += 'default:\n';
+            resultado += this.logicaComumCaminhosEscolha(declaracaoEscolha.caminhoPadrao);
+        }
+
+        resultado += '}\n';
+        return resultado;
+    }
+
+    traduzirDeclaracaoEnquanto(declaracaoEnquanto: Enquanto): string {
+        let resultado = 'while (';
+        resultado +=
+            this.dicionarioConstrutos[declaracaoEnquanto.condicao.constructor.name](declaracaoEnquanto.condicao) + ') ';
+        resultado += this.dicionarioDeclaracoes[declaracaoEnquanto.corpo.constructor.name](declaracaoEnquanto.corpo);
+        return resultado;
+    }
+
+    traduzirDeclaracaoBloco(declaracaoBloco: Bloco): string {
+        return this.logicaComumBlocoEscopo(declaracaoBloco.declaracoes);
+    }
+
+    traduzirConstrutoVetor(vetor: Vetor): string {
+        if (!vetor.valores.length) {
+            return '[]';
+        }
+
+        let resultado = '[';
+
+        for (let valor of vetor.valores) {
+            resultado += `${this.dicionarioConstrutos[valor.constructor.name](valor)}, `;
+        }
+        if (vetor.valores.length > 0) {
+            resultado = resultado.slice(0, -2);
+        }
+
+        resultado += ']';
+
+        return resultado;
+    }
+
+    traduzirConstrutoVariavel(variavel: Variavel): string {
+        return variavel.simbolo.lexema;
+    }
+
+    traduzirConstrutoUnario(unario: Unario): string {
+        let resultado = '';
+        if ([tiposDeSimbolos.INCREMENTAR, tiposDeSimbolos.DECREMENTAR].includes(unario.operador.tipo)) {
+            resultado += unario.operando.valor ?? unario.operando.simbolo.lexema;
+            resultado += unario.operador.tipo === tiposDeSimbolos.INCREMENTAR ? '++' : '--';
+        } else {
+            resultado += this.traduzirSimboloOperador(unario.operador);
+            resultado += unario.operando.valor ?? unario.operando.simbolo.lexema;
+        }
+        return resultado;
+    }
+
+    traduzirConstrutoTipoDe(tipoDe: TipoDe): string {
+        let resultado = 'typeof ';
+
+        if (typeof tipoDe.valor === 'string') resultado += `'${tipoDe.valor}'`;
+        else if (tipoDe.valor instanceof Vetor) resultado += this.traduzirConstrutoVetor(tipoDe.valor);
+        else resultado += tipoDe.valor;
+
+        return resultado;
+    }
+
+    traduzirConstrutoLogico(logico: Logico): string {
+        let direita = this.dicionarioConstrutos[logico.direita.constructor.name](logico.direita);
+        let operador = this.traduzirSimboloOperador(logico.operador);
+        let esquerda = this.dicionarioConstrutos[logico.esquerda.constructor.name](logico.esquerda);
+
+        return `${direita} ${operador} ${esquerda}`;
+    }
+
+    traduzirFuncaoConstruto(funcaoConstruto: FuncaoConstruto): string {
+        let resultado = 'function(';
+        for (const parametro of funcaoConstruto.parametros) {
+            const tipoParametro = this.resolveTipoDeclaracaoVarEContante(parametro.tipo);
+            resultado += `${parametro.nome.lexema}${tipoParametro}, `;
+        }
+
+        if (funcaoConstruto.parametros.length > 0) {
+            resultado = resultado.slice(0, -2);
+        }
+
+        resultado += ') ';
+
+        resultado += this.logicaComumBlocoEscopo(funcaoConstruto.corpo);
+        return resultado;
+    }
+
+    traduzirConstrutoDefinirValor(definirValor: DefinirValor): string {
+        let resultado = '';
+        if (definirValor.objeto instanceof Isto) {
+            resultado = 'this.' + definirValor.nome.lexema + ' = ';
+        }
+
+        resultado += definirValor.valor.simbolo.lexema;
+        return resultado;
+    }
+
+    traduzirConstrutoChamada(chamada: Chamada): string {
+        let resultado = '';
+
+        const retorno = `${this.dicionarioConstrutos[chamada.entidadeChamada.constructor.name](
+            chamada.entidadeChamada
+        )}`;
+
+        const instanciaClasse = this.declaracoesDeClasses.some((declaracao) => declaracao?.simbolo?.lexema === retorno);
+        if (instanciaClasse) {
+            const classe = this.declaracoesDeClasses.find((declaracao) => declaracao?.simbolo?.lexema === retorno);
+            if (classe.simbolo.lexema === retorno) resultado += `new ${retorno}`;
+        } else {
+            resultado += retorno;
+        }
+        resultado += '(';
+        for (let parametro of chamada.argumentos) {
+            resultado += this.dicionarioConstrutos[parametro.constructor.name](parametro) + ', ';
+        }
+        if (chamada.argumentos.length > 0) {
+            resultado = resultado.slice(0, -2);
+        }
+        resultado += ')';
+        return resultado;
+    }
+
+    traduzirConstrutoBinario(binario: Binario): string {
+        let resultado = '';
+        if (binario.esquerda.constructor.name === 'Agrupamento')
+            resultado += '(' + this.dicionarioConstrutos[binario.esquerda.constructor.name](binario.esquerda) + ')';
+        else resultado += this.dicionarioConstrutos[binario.esquerda.constructor.name](binario.esquerda);
+
+        let operador = this.traduzirSimboloOperador(binario.operador);
+        resultado += ` ${operador} `;
+
+        if (binario.direita.constructor.name === 'Agrupamento')
+            resultado += '(' + this.dicionarioConstrutos[binario.direita.constructor.name](binario.direita) + ')';
+        else resultado += this.dicionarioConstrutos[binario.direita.constructor.name](binario.direita);
+
+        return resultado;
+    }
+
+    traduzirConstrutoAtribuir(atribuir: Atribuir): string {
+        let resultado = atribuir.simbolo.lexema;
+        resultado += ' = ' + this.dicionarioConstrutos[atribuir.valor.constructor.name](atribuir.valor);
+        return resultado;
+    }
+
+    traduzirConstrutoAtribuicaoPorIndice(AtribuicaoPorIndice: AtribuicaoPorIndice): string {
+        let resultado = '';
+
+        resultado += AtribuicaoPorIndice.objeto.simbolo.lexema + '[';
+        resultado +=
+            this.dicionarioConstrutos[AtribuicaoPorIndice.indice.constructor.name](AtribuicaoPorIndice.indice) + ']';
+        resultado += ' = ';
+
+        if (AtribuicaoPorIndice?.valor?.simbolo?.lexema) {
+            resultado += `${AtribuicaoPorIndice.valor.simbolo.lexema}`;
+        } else {
+            resultado += this.dicionarioConstrutos[AtribuicaoPorIndice.valor.constructor.name](
+                AtribuicaoPorIndice.valor
+            );
+        }
+
+        return resultado;
+    }
+
+    traduzirConstrutoAgrupamento(agrupamento: Agrupamento): string {
+        return this.dicionarioConstrutos[agrupamento.constructor.name](agrupamento.expressao || agrupamento);
+    }
+
+    trazudirConstrutoAcessoMetodo(acessoMetodo: AcessoMetodo): string {
+        if (acessoMetodo.objeto instanceof Variavel) {
+            let objetoVariavel = acessoMetodo.objeto as Variavel;
+            return `${objetoVariavel.simbolo.lexema}.${this.traduzirFuncoesNativas(acessoMetodo.simbolo.lexema)}`;
+        }
+        return `this.${acessoMetodo.simbolo.lexema}`;
+    }
+
+    traduzirAcessoIndiceVariavel(acessoIndiceVariavel: AcessoIndiceVariavel): string {
+        let resultado = '';
+
+        resultado += this.dicionarioConstrutos[acessoIndiceVariavel.entidadeChamada.constructor.name](
+            acessoIndiceVariavel.entidadeChamada
+        );
+        resultado += `[${this.dicionarioConstrutos[acessoIndiceVariavel.indice.constructor.name](
+            acessoIndiceVariavel.indice
+        )}]`;
+
+        return resultado;
+    }
+
+    dicionarioConstrutos = {
+        AcessoIndiceVariavel: this.traduzirAcessoIndiceVariavel.bind(this),
+        AcessoMetodo: this.trazudirConstrutoAcessoMetodo.bind(this),
+        Agrupamento: this.traduzirConstrutoAgrupamento.bind(this),
+        AtribuicaoPorIndice: this.traduzirConstrutoAtribuicaoPorIndice.bind(this),
+        Atribuir: this.traduzirConstrutoAtribuir.bind(this),
+        Binario: this.traduzirConstrutoBinario.bind(this),
+        Chamada: this.traduzirConstrutoChamada.bind(this),
+        DefinirValor: this.traduzirConstrutoDefinirValor.bind(this),
+        FuncaoConstruto: this.traduzirFuncaoConstruto.bind(this),
+        Isto: () => 'this',
+        Literal: this.traduzirConstrutoLiteral.bind(this),
+        Logico: this.traduzirConstrutoLogico.bind(this),
+        TipoDe: this.traduzirConstrutoTipoDe.bind(this),
+        Unario: this.traduzirConstrutoUnario.bind(this),
+        Variavel: this.traduzirConstrutoVariavel.bind(this),
+        Vetor: this.traduzirConstrutoVetor.bind(this),
+    };
+
+    dicionarioDeclaracoes = {
+        Bloco: this.traduzirDeclaracaoBloco.bind(this),
+        Enquanto: this.traduzirDeclaracaoEnquanto.bind(this),
+        Continua: () => 'continue',
+        Escolha: this.traduzirDeclaracaoEscolha.bind(this),
+        Expressao: this.traduzirDeclaracaoExpressao.bind(this),
+        Fazer: this.traduzirDeclaracaoFazer.bind(this),
+        Falhar: this.traduzirDeclaracaoFalhar.bind(this),
+        FuncaoDeclaracao: this.traduzirDeclaracaoFuncao.bind(this),
+        Importar: this.traduzirDeclaracaoImportar.bind(this),
+        Leia: this.traduzirDeclaracaoLeia.bind(this),
+        Para: this.traduzirDeclaracaoPara.bind(this),
+        ParaCada: this.traduzirDeclaracaoParaCada.bind(this),
+        Retorna: this.traduzirDeclaracaoRetorna.bind(this),
+        Se: this.traduzirDeclaracaoSe.bind(this),
+        Sustar: () => 'break',
+        Classe: this.traduzirDeclaracaoClasse.bind(this),
+        Tente: this.traduzirDeclaracaoTente.bind(this),
+        Const: this.traduzirDeclaracaoConst.bind(this),
+        Var: this.traduzirDeclaracaoVar.bind(this),
+        Escreva: this.traduzirDeclaracaoEscreva.bind(this),
+    };
+
+    traduzir(declaracoes: Declaracao[]): string {
+        let resultado = '';
+
+        this.declaracoesDeClasses = declaracoes.filter((declaracao) => declaracao instanceof Classe) as Classe[];
+
+        for (const declaracao of declaracoes) {
+            resultado += `${this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao)} \n`;
+        }
+
+        return resultado;
+    }
+}


Test patch:
diff --git a/testes/tradutores/tradutor-assemblyscript.test.ts b/testes/tradutores/tradutor-assemblyscript.test.ts
new file mode 100644
index 00000000..116888f3
--- /dev/null
+++ b/testes/tradutores/tradutor-assemblyscript.test.ts
@@ -0,0 +1,226 @@
+import { Lexador, Simbolo } from "../../fontes/lexador";
+import { AvaliadorSintatico } from "../../fontes/avaliador-sintatico";
+import tiposDeSimbolos from '../../fontes/tipos-de-simbolos/delegua';
+import { TradutorAssemblyScript } from '../../fontes/tradutores/tradutor-assemblyscript';
+import { Bloco, Escreva, Se } from "../../fontes/declaracoes";
+import { Binario, Literal, Variavel } from "../../fontes/construtos";
+
+describe('Tradutor Delégua -> AssemblyScript', () => {
+    const tradutor: TradutorAssemblyScript = new TradutorAssemblyScript();
+
+    describe('Programático', () => {
+        it('se -> if, programático', () => {
+            const se = new Se(
+                new Binario(
+                    -1,
+                    new Variavel(-1, new Simbolo(tiposDeSimbolos.IDENTIFICADOR, 'a', null, 1, -1)),
+                    new Simbolo(tiposDeSimbolos.IGUAL_IGUAL, '', null, 1, -1),
+                    new Literal(-1, 1, 1)
+                ),
+                new Bloco(-1, 1, [new Escreva(2, -1, [new Literal(-1, 1, 10)])]),
+                null,
+                null
+            );
+            const resultado = tradutor.traduzir([se]);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/if/i);
+            expect(resultado).toMatch(/a === 1/i);
+            expect(resultado).toMatch(/console\.log\(10\)/i);
+        });
+    })
+
+    describe('Codigo', () => {
+        let lexador: Lexador;
+        let avaliadorSintatico: AvaliadorSintatico;
+
+        beforeEach(() => {
+            lexador = new Lexador();
+            avaliadorSintatico = new AvaliadorSintatico();
+        })
+
+        it('escreva -> console.log', () => {
+            const retornoLexador = lexador.mapear([
+                'escreva("Olá, mundo!")',
+            ], -1);
+
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, 1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/console\.log\('Olá, mundo!'\)/i);
+        })
+
+        describe('Variáveis', () => {
+            it('var -> let -> number -> f64', () => {
+                const retornoLexador = lexador.mapear([
+                    'var a: inteiro;',
+                ], -1)
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, 1);
+
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/let a: f64;/i);
+            })
+
+            it('var -> let -> string -> string', () => {
+                const retornoLexador = lexador.mapear([
+                    'var a: texto = "teste"',
+                ], -1)
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, 1);
+
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/let a: string = 'teste'/i);
+            })
+            it('var -> sem inicializador -> let', () => {
+                const retornoLexador = lexador.mapear([
+                    'var a;'
+                ], -1)
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, 1);
+
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/let a: any;/i);
+            })
+            it('constante -> const -> number -> f64', () => {
+                const retornoLexador = lexador.mapear([
+                    'constante a: inteiro = 1'
+                ], -1)
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, 1);
+
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/const a: f64 = 1/i);
+            })
+            it('constante -> const -> string -> string', () => {
+                const retornoLexador = lexador.mapear([
+                    'constante a: texto = "teste"',
+                ], -1)
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, 1);
+
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/const a: string = 'teste'/i);
+            })
+            it('var -> let com tipo iniciado -> number -> f64', () => {
+                const retornoLexador = lexador.mapear([
+                    'var a: inteiro = 1'
+                ], -1)
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, 1);
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/let a: f64 = 1/i);
+            })
+            it('var -> let com tipo iniciado -> string -> string', () => {
+                const retornoLexador = lexador.mapear([
+                    'var a: texto = "teste"'
+                ], -1)
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, 1);
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/let a: string = 'teste'/i);
+            })
+            it('var -> let com tipo iniciado -> real -> f64', () => {
+                const retornoLexador = lexador.mapear([
+                    'var a: real = 1.1'
+                ], -1)
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, 1);
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/let a: f64 = 1.1/i);
+            })
+            it('falhar - throw', () => {
+                const retornoLexador = lexador.mapear(
+                    [
+                        'falhar \"erro inesperado!\"',
+                    ],
+                    -1
+                );
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/throw 'erro inesperado!'/i);
+            });
+            it('tipo de - typeof', () => {
+                const retornoLexador = lexador.mapear(
+                    [
+                        'escreva(tipo de 1)',
+                        'escreva(tipo de \'2\')',
+                        'escreva(tipo de nulo)',
+                        'escreva(tipo de [1, 2, 3])',
+                        // 'classe Cachorro {}',
+                        // 'escreva(tipo de Cachorro)'
+                    ],
+                    -1
+                );
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/typeof 1/i);
+                expect(resultado).toMatch(/typeof \'2\'/i);
+                expect(resultado).toMatch(/typeof null/i);
+                expect(resultado).toMatch(/typeof \[1, 2, 3\]/i);
+            });
+
+            it('bit a bit', () => {
+                const retornoLexador = lexador.mapear(
+                    [
+                        'escreva(8 | 1)',
+                        'escreva(8 & 1)',
+                        'escreva(8 ^ 1)',
+                        'escreva(~2)',
+                        'var a: inteiro = 3',
+                        'var c = -a + 3'
+                    ],
+                    -1
+                );
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/console\.log\(8 | 1\)/i);
+                expect(resultado).toMatch(/console\.log\(8 & 1\)/i);
+                expect(resultado).toMatch(/console\.log\(8 \^ 1\)/i);
+                expect(resultado).toMatch(/console\.log\(~2\)/i);
+                expect(resultado).toMatch(/let a: f64 = 3/i);
+                expect(resultado).toMatch(/let c: any = -a \+ 3/i);
+            });
+            });
+            it('definindo funcao com variavel', () => {
+                const retornoLexador = lexador.mapear(
+                    [
+                        'var a = funcao(parametro1: inteiro, parametro2: inteiro) { escreva(\'Oi\')\nescreva(\'Olá\') \n retorna 123 }',
+                        'a(1, 2)'
+                    ],
+                    -1
+                );
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+                const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+                expect(resultado).toBeTruthy();
+                expect(resultado).toMatch(/let a: any = function\(parametro1: f64, parametro2: f64\) {/i);
+                expect(resultado).toMatch(/console\.log\('Oi'\)/i);
+                expect(resultado).toMatch(/console\.log\('Olá'\)/i);
+                expect(resultado).toMatch(/a\(1, 2\)/i);
+            });
+        })
+    })