Repository: DesignLiquido/delegua
Pull request #408 (2023-05-24 01:01:54)

Tradutor Delégua para Python

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: 54.36%">54.54% (+0.17% 🔼)</div> |    7400/13569   |
|                                                                           🔴                                                                           | Branches   | <div title="Base coverage is: 44.74%">44.9% (+0.16% 🔼)</div>  |    2252/5016    |
|                                                                           🔴                                                                           | Functions  | <div title="Base coverage is: 47.71%">47.88% (+0.17% 🔼)</div> |    1075/2245    |
|                                                                           🔴                                                                           | Lines      | <div title="Base coverage is: 54.23%">54.41% (+0.17% 🔼)</div> |    7231/13290   |


<details><summary>Show files with reduced coverage 🔻</summary>
<br/>

| <div title="Status of coverage:&#10; 🟢 - ok&#10; 🟡 - slightly more than threshold&#10; 🔴 - under the threshold">St.<sup>:grey_question:</sup></div> | File                                                                                         | Statements                                                     | Branches                                                       | Functions                                                   | Lines                                                          |
| :----------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------- | :------------------------------------------------------------- | :------------------------------------------------------------- | :---------------------------------------------------------- | :------------------------------------------------------------- |
|                                                                           🟢                                                                           | <div title="avaliador-sintatico/avaliador-sintatico.ts">`...` / avaliador-sintatico.ts</div> | <div title="Base coverage is: 93.09%">92.96% (-0.12% 🔻)</div> | <div title="Base coverage is: 82.48%">82.27% (-0.21% 🔻)</div> | 94.44%                                                      | <div title="Base coverage is: 93.17%">93.04% (-0.13% 🔻)</div> |
|                                                                           🟡                                                                           | <div title="tradutores/tradutor-python.ts">`...` / tradutor-python.ts</div>                  | <div title="Base coverage is: 66.67%">75% (+8.33% 🔼)</div>    | <div title="Base coverage is: 100%">61.9% (-38.1% 🔻)</div>    | <div title="Base coverage is: 80%">72.73% (-7.27% 🔻)</div> | <div title="Base coverage is: 65.22%">74.58% (+9.36% 🔼)</div> |

</details>

## Test suite run success
513 tests passing in 45 suites.

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

Patch:
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 0fe469d4..cfcc73b0 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -790,6 +790,23 @@
             "console": "integratedTerminal",
             "internalConsoleOptions": "neverOpen"
         },
+        {
+            "name": "Testes unitários - Tradutor Delégua para Python",
+            "type": "node",
+            "request": "launch",
+            "runtimeArgs": [
+                "--inspect-brk",
+                "${workspaceRoot}/node_modules/jest/bin/jest.js",
+                "tradutor-python.test.ts",
+                "--runInBand"
+            ],
+            "skipFiles": [
+                "<node_internals>/**",
+                "node_modules/**"
+            ],
+            "console": "integratedTerminal",
+            "internalConsoleOptions": "neverOpen"
+        },
         {
             "type": "node",
             "request": "launch",
diff --git a/fontes/avaliador-sintatico/avaliador-sintatico.ts b/fontes/avaliador-sintatico/avaliador-sintatico.ts
index a617c840..cfe2b7dc 100644
--- a/fontes/avaliador-sintatico/avaliador-sintatico.ts
+++ b/fontes/avaliador-sintatico/avaliador-sintatico.ts
@@ -930,7 +930,8 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
      * @returns Um Construto do tipo Var.
      */
     declaracaoDeVariavel(): Var {
-        const simbolo: SimboloInterface = this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome de variável.');
+        const simbolo: SimboloInterface = this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome de variável.');;
+
         let inicializador = null;
         if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
             inicializador = this.expressao();
@@ -946,7 +947,8 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface {
      * @returns Um Construto do tipo Const.
      */
     declaracaoDeConstante(): Const {
-        const simbolo: SimboloInterface = this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome de constante.');
+        const simbolo: SimboloInterface = this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome de constante.');;
+
         let inicializador = null;
         if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
             inicializador = this.expressao();
diff --git a/fontes/interfaces/visitante-comum-interface.ts b/fontes/interfaces/visitante-comum-interface.ts
index acd60c4f..cec4f609 100644
--- a/fontes/interfaces/visitante-comum-interface.ts
+++ b/fontes/interfaces/visitante-comum-interface.ts
@@ -1,5 +1,4 @@
-import { EspacoVariaveis } from '../espaco-variaveis';
-import { Atribuir, Construto, FimPara, Literal, Super } from '../construtos';
+import { Atribuir, FimPara, Literal, Super } from '../construtos';
 import {
     Bloco,
     Classe,
diff --git a/fontes/tradutores/tradutor-javascript.ts b/fontes/tradutores/tradutor-javascript.ts
index fe057e07..d1359a6d 100644
--- a/fontes/tradutores/tradutor-javascript.ts
+++ b/fontes/tradutores/tradutor-javascript.ts
@@ -646,9 +646,9 @@ export class TradutorJavaScript implements TradutorInterface {
         Leia: this.traduzirDeclaracaoLeia.bind(this),
         Para: this.traduzirDeclaracaoPara.bind(this),
         ParaCada: this.traduzirDeclaracaoParaCada.bind(this),
-        Sustar: () => 'break',
         Retorna: this.traduzirDeclaracaoRetorna.bind(this),
         Se: this.traduzirDeclaracaoSe.bind(this),
+        Sustar: () => 'break',
         Tente: this.traduzirDeclaracaoTente.bind(this),
         Var: this.traduzirDeclaracaoVar.bind(this),
     };
diff --git a/fontes/tradutores/tradutor-python.ts b/fontes/tradutores/tradutor-python.ts
index c202047f..f5cb1ef7 100644
--- a/fontes/tradutores/tradutor-python.ts
+++ b/fontes/tradutores/tradutor-python.ts
@@ -1,10 +1,91 @@
-import { Literal } from "../construtos";
-import { Declaracao, Escreva, Leia } from "../declaracoes";
-import { TradutorInterface } from "../interfaces";
+import { Agrupamento, Atribuir, Binario, Chamada, Literal, Logico, Variavel, Vetor } from "../construtos";
+import { Bloco, Declaracao, Escreva, Expressao, FuncaoDeclaracao, Leia, ParaCada, Retorna, Se, Var } from "../declaracoes";
+import { SimboloInterface, TradutorInterface } from "../interfaces";
+import tiposDeSimbolos from '../tipos-de-simbolos/delegua';
 
 export class TradutorPython implements TradutorInterface {
+    indentacao: number = 0;
+
+    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 'and';
+            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 'or';
+            case tiposDeSimbolos.SUBTRACAO:
+                return '-';
+        }
+    }
+
+    logicaComumBlocoEscopo(declaracoes: Declaracao[]): string {
+        let resultado = '';
+        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;
+    }
+
+    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 `${esquerda} ${operador} ${direita}`;
+    }
+    
     traduzirConstrutoLiteral(literal: Literal): string {
         if (typeof literal.valor === 'string') return `'${literal.valor}'`;
+        if (typeof literal.valor === 'boolean') {
+            return literal.valor ? 'True' : 'False';
+        }
+        if (!literal.valor) return 'None';
         return literal.valor;
     }
     
@@ -32,14 +113,201 @@ export class TradutorPython implements TradutorInterface {
 
         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;
+    }
+
+    traduzirDeclaracaoFuncao(declaracaoFuncao: FuncaoDeclaracao): string {
+        let resultado = 'def ';
+        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;
+    }
+
+    traduzirDeclaracaoSe(declaracaoSe: Se): string {
+        let resultado = 'if ';
+
+        const condicao = this.dicionarioConstrutos[declaracaoSe.condicao.constructor.name](declaracaoSe.condicao);
+
+        resultado += condicao;
+
+        resultado += ':\n';
+        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 += 'elif ';
+                resultado += this.dicionarioConstrutos[se.condicao.constructor.name](se.condicao);
+                resultado += ':\n';
+                resultado += this.dicionarioDeclaracoes[se.caminhoEntao.constructor.name](se.caminhoEntao);
+                resultado += ' '.repeat(this.indentacao);
+                if (se?.caminhoSenao) {
+                    resultado += 'else:\n';
+                    resultado += this.dicionarioDeclaracoes[se.caminhoSenao.constructor.name](se.caminhoSenao);
+                    return resultado;
+                }
+            } else {
+                resultado += 'else:\n';
+            }
+
+            resultado += this.dicionarioDeclaracoes[declaracaoSe.caminhoSenao.constructor.name](
+                declaracaoSe.caminhoSenao
+            );
+        }
+
+        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;
+    }
+
+    traduzirDeclaracaoRetorna(declaracaoRetorna: Retorna): string {
+        let resultado = 'return ';
+        const nomeConstrutor = declaracaoRetorna.valor.constructor.name;
+        return (resultado += this.dicionarioConstrutos[nomeConstrutor](declaracaoRetorna?.valor));
+    }
+
+    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;
+    }
+
+    traduzirDeclaracaoVar(declaracaoVar: Var): string {
+        let resultado = '';
+        resultado += declaracaoVar.simbolo.lexema;
+        // 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
+            );
+        }
+        // }
+        return resultado;
+    }
+
+    traduzirDeclaracaoParaCada(declaracaoParaCada: ParaCada): string {
+        let resultado = `for ${declaracaoParaCada.nomeVariavelIteracao} in `;
+        resultado +=
+            this.dicionarioConstrutos[declaracaoParaCada.vetor.constructor.name](declaracaoParaCada.vetor) + ":\n";
+
+        resultado += this.dicionarioDeclaracoes[declaracaoParaCada.corpo.constructor.name](declaracaoParaCada.corpo);
+        return resultado;
+    }
+
+    traduzirConstrutoAtribuir(atribuir: Atribuir): string {
+        let resultado = atribuir.simbolo.lexema;
+        resultado += ' = ' + this.dicionarioConstrutos[atribuir.valor.constructor.name](atribuir.valor);
+        return resultado;
+    }
+    
+    traduzirConstrutoVariavel(variavel: Variavel): string {
+        return variavel.simbolo.lexema;
+    }
+
+    traduzirDeclaracaoExpressao(declaracaoExpressao: Expressao): string {
+        return this.dicionarioConstrutos[declaracaoExpressao.expressao.constructor.name](declaracaoExpressao.expressao);
+    }
+
+    traduzirDeclaracaoBloco(declaracaoBloco: Bloco): string {
+        return this.logicaComumBlocoEscopo(declaracaoBloco.declaracoes);
+    }
+
+    traduzirConstrutoAgrupamento(agrupamento: Agrupamento): string {
+        return this.dicionarioConstrutos[agrupamento.constructor.name](agrupamento.expressao || agrupamento);
+    }
     
     dicionarioConstrutos = {
+        Agrupamento: this.traduzirConstrutoAgrupamento.bind(this),
+        Atribuir: this.traduzirConstrutoAtribuir.bind(this),
+        Binario: this.traduzirConstrutoBinario.bind(this),
+        Chamada: this.traduzirConstrutoChamada.bind(this),
         Literal: this.traduzirConstrutoLiteral.bind(this),
+        Logico: this.traduzirConstrutoLogico.bind(this),
+        Variavel: this.traduzirConstrutoVariavel.bind(this),
+        Vetor: this.traduzirConstrutoVetor.bind(this),
     }
 
     dicionarioDeclaracoes = {
+        Bloco: this.traduzirDeclaracaoBloco.bind(this),
+        Continua: () => 'continue',
         Escreva: this.traduzirDeclaracaoEscreva.bind(this),
+        Expressao: this.traduzirDeclaracaoExpressao.bind(this),
+        FuncaoDeclaracao: this.traduzirDeclaracaoFuncao.bind(this),
         Leia: this.traduzirDeclaracaoLeia.bind(this),
+        ParaCada: this.traduzirDeclaracaoParaCada.bind(this),
+        Retorna: this.traduzirDeclaracaoRetorna.bind(this),
+        Se: this.traduzirDeclaracaoSe.bind(this),
+        Sustar: () => 'break',
+        Var: this.traduzirDeclaracaoVar.bind(this),
     }
 
     traduzir(declaracoes: Declaracao[]): string {


Test patch:
diff --git a/testes/tradutores/tradutor-python.test.ts b/testes/tradutores/tradutor-python.test.ts
index b654ebde..aee6b863 100644
--- a/testes/tradutores/tradutor-python.test.ts
+++ b/testes/tradutores/tradutor-python.test.ts
@@ -27,5 +27,286 @@ describe('Tradutor Delégua -> Python', () => {
             expect(resultado).toBeTruthy();
             expect(resultado).toMatch(/print\('Olá mundo'\)/i);
         });
+
+        it('Agrupamento', () => {
+            const retornoLexador = lexador.mapear(
+                ['escreva((2 * 3) + (4 ^ 2))'], 
+                -1
+            );
+
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/print\(\(2 \* 3\) \+ \(4 \^ 2\)\)/i);
+        });
+
+        it('Atribuir', () => {
+            const retornoLexador = lexador.mapear(
+                [
+                    'var a = 1',
+                    'var b = \'1\'',
+                    'var c = verdadeiro',
+                    'var d = falso',
+                    'var f = nulo',
+                    '2 * 2'
+                ], 
+                -1
+            );
+
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/a = 1/i);
+            expect(resultado).toMatch(/b = \'1\'/i);
+            expect(resultado).toMatch(/c = True/i);
+            expect(resultado).toMatch(/d = False/i);
+            expect(resultado).toMatch(/f = None/i);
+            expect(resultado).toMatch(/2 \* 2/i);
+        });
+
+        it('Escreva verdadeiro e falso com operadores lógicos', () => {
+            const retornoLexador = lexador.mapear(
+                [
+                    'escreva(falso)',
+                    'escreva(verdadeiro)',
+                    'escreva(verdadeiro == verdadeiro)',
+                    'escreva(verdadeiro != verdadeiro)',
+                    'escreva(falso == falso)',
+                    'escreva(falso != falso)',
+                    'escreva(verdadeiro e falso)',
+                    'escreva(verdadeiro ou falso)',
+                ],
+                -1
+            );
+
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/print\(False\)/i);
+            expect(resultado).toMatch(/print\(True\)/i);
+            expect(resultado).toMatch(/print\(True == True\)/i);
+            expect(resultado).toMatch(/print\(True != True\)/i);
+            expect(resultado).toMatch(/print\(False == False\)/i);
+            expect(resultado).toMatch(/print\(False != False\)/i);
+            expect(resultado).toMatch(/print\(True and False\)/i);
+            expect(resultado).toMatch(/print\(True or False\)/i);
+        });
+
+        it('Escreva verdadeiro e falso com operadores lógicos', () => {
+            const retornoLexador = lexador.mapear(
+                [
+                    'funcao olaMundo () {',
+                    'escreva(\'Olá Mundo!!!\')',
+                    '}',
+                ],
+                -1
+            );
+
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/def olaMundo\(\):/i);
+            expect(resultado).toMatch(/print\(\'Olá Mundo!!!\'\)/i);
+        });
+
+        it('Escreva verdadeiro e falso com operadores lógicos', () => {
+            const retornoLexador = lexador.mapear(
+                [
+                    'funcao olaMundo (textoQualquer) {',
+                    'escreva(\'Olá Mundo!!!\', textoQualquer)',
+                    '}',
+                ],
+                -1
+            );
+
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/def olaMundo\(textoQualquer\):/i);
+            expect(resultado).toMatch(/print\(\'Olá Mundo!!!\', textoQualquer\)/i);
+        });
+
+        it('Para Cada \'em\' - vetor variável', async () => {
+            const retornoLexador = lexador.mapear([
+                "para cada elemento em [1, 2, 3] {",
+                "   escreva('Valor: ', elemento)",
+                "}",
+            ], -1);
+
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/for elemento in \[1, 2, 3\]:/i);
+            expect(resultado).toMatch(/print\(\'Valor: \', elemento\)/i);
+        });
+
+        it('função com retorno nulo -> function', () => {
+            const codigo = ['funcao minhaFuncao() { retorna nulo }'];
+            const retornoLexador = lexador.mapear(codigo, -1);
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/def minhaFuncao\(\):/i);
+            expect(resultado).toMatch(/return None/i);
+        });
+
+        it('função com retorno lógico de texto e número -> function', () => {
+            const codigo = ["funcao minhaFuncao() { retorna '1' == 1 }"];
+            const retornoLexador = lexador.mapear(codigo, -1);
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/def minhaFuncao\(\):/i);
+            expect(resultado).toMatch(/return '1' == 1/i);
+        });
+
+        it('função com retorno lógico de número -> function', () => {
+            const codigo = ['funcao minhaFuncao() { retorna 1 == 1 }'];
+            const retornoLexador = lexador.mapear(codigo, -1);
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/def minhaFuncao\(\):/i);
+            expect(resultado).toMatch(/return 1 == 1/i);
+        });
+
+        it('função com retorno lógico de texto -> function', () => {
+            const codigo = ["funcao minhaFuncao() { retorna '1' == '1' }"];
+            const retornoLexador = lexador.mapear(codigo, -1);
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/def minhaFuncao\(\):/i);
+            expect(resultado).toMatch(/return '1' == '1'/i);
+        });
+
+        it('função com retorno número -> function', () => {
+            const codigo = ['funcao minhaFuncao() { retorna 10 }'];
+            const retornoLexador = lexador.mapear(codigo, -1);
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/def minhaFuncao\(\):/i);
+            expect(resultado).toMatch(/return 10/i);
+        });
+
+        it('função com retorno texto -> function', () => {
+            const codigo = ["funcao minhaFuncao() { retorna 'Ola Mundo!!!' }"];
+            const retornoLexador = lexador.mapear(codigo, -1);
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/def minhaFuncao\(\):/i);
+            expect(resultado).toMatch(/return 'Ola Mundo!!!'/i);
+        });
+
+        it('função com retorno -> function', () => {
+            const codigo = ["funcao minhaFuncao() { retorna 'Ola Mundo!!!' }"];
+            const retornoLexador = lexador.mapear(codigo, -1);
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/def minhaFuncao\(\):/i);
+            expect(resultado).toMatch(/return 'Ola Mundo!!!'/i);
+        });
+
+        it('se -> if, código', () => {
+            const retornoLexador = lexador.mapear(['se (a == 1) {', '    escreva(10)', '}'], -1);
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/if a \=\= 1:/i);
+            expect(resultado).toMatch(/print\(10\)/i);
+        });
+
+        it('senão -> else, código', () => {
+            const retornoLexador = lexador.mapear(
+                ['se (a == 1) {', '    escreva(10)', '} senão {', '   escreva(20)', '}'],
+                -1
+            );
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/if a \=\= 1:/i);
+            expect(resultado).toMatch(/print\(10\)/i);
+            expect(resultado).toMatch(/else:/i);
+            expect(resultado).toMatch(/print\(20\)/i);
+        });
+
+        it('se senão 01 -> if else, código', () => {
+            const retornoLexador = lexador.mapear(
+                [
+                    'var a = 20',
+                    'se (a == 10) {',
+                    '   escreva(10)',
+                    '} senão se (a == 20) {',
+                    '   escreva(20)',
+                    '} senão {',
+                    "   escreva('Não é 10 e não é 20')",
+                    '}',
+                ],
+                -1
+            );
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/if a \=\= 10:/i);
+            expect(resultado).toMatch(/print\(10\)/i);
+            expect(resultado).toMatch(/elif a \=\= 20:/i);
+            expect(resultado).toMatch(/print\(20\)/i);
+            expect(resultado).toMatch(/else:/i);
+            expect(resultado).toMatch(/print\('Não é 10 e não é 20'\)/i);
+        });
+
+        it.skip('se senão 02 -> if else, código', () => {
+            const retornoLexador = lexador.mapear(
+                [
+                    'var a = 20',
+                    'se (a == 10) {',
+                    '   escreva(10)',
+                    '} senão se (a == 20) {',
+                    '   escreva(20)',
+                    '} senão se (a == 30) {',
+                    '   escreva(30)',
+                    '} senão {',
+                    "   escreva('Não é nenhum desses valores: 10, 20, 30')",
+                    '}',
+                ],
+                -1
+            );
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+            const resultado = tradutor.traduzir(retornoAvaliadorSintatico.declaracoes);
+            expect(resultado).toBeTruthy();
+            expect(resultado).toMatch(/if a \=\= 10:/i);
+            expect(resultado).toMatch(/print\(10\)/i);
+            expect(resultado).toMatch(/elif a \=\= 20:/i);
+            expect(resultado).toMatch(/print\(20\)/i);
+            expect(resultado).toMatch(/elif a \=\= 30:/i);
+            expect(resultado).toMatch(/print\(30\)/i);
+            expect(resultado).toMatch(/else:/i);
+            expect(resultado).toMatch(/print\('Não é nenhum desses valores: 10, 20, 30'\)/i);
+        });
     });
 });
\ No newline at end of file