Repository: DesignLiquido/delegua
Pull request #454 (2023-06-12 20:18:37)

Melhorando escreva
Ajustando interpolação de string no escreva em tempo de execução.

github-actions[bot]: <!-- jest coverage report action for options with hash 781087021f8e6c43aac1e668f4520603 -->

## Coverage report 



| <div title="Status of coverage:&#10; 🟢 - ok&#10; 🟡 - slightly more than threshold&#10; 🔴 - under the threshold">St.<sup>:grey_question:</sup></div> | Category   | Percentage                                                     | Covered / Total |
| :----------------------------------------------------------------------------------------------------------------------------------------------------: | :--------- | :------------------------------------------------------------- | :-------------: |
|                                                                           🟡                                                                           | Statements | <div title="Base coverage is: 73.56%">73.61% (+0.04% 🔼)</div> |    7362/10002   |
|                                                                           🟡                                                                           | Branches   | <div title="Base coverage is: 63.35%">63.18% (-0.16% 🔻)</div> |    2370/3751    |
|                                                                           🟡                                                                           | Functions  | <div title="Base coverage is: 69.12%">69.16% (+0.04% 🔼)</div> |    1090/1576    |
|                                                                           🟡                                                                           | Lines      | <div title="Base coverage is: 73.97%">74.01% (+0.04% 🔼)</div> |    7181/9703    |


<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="interpretador/dialetos/birl/interpretador-birl.ts">`...` / interpretador-birl.ts</div> | <div title="Base coverage is: 57.91%">59.66% (+1.75% 🔼)</div> | <div title="Base coverage is: 52.38%">50.7% (-1.68% 🔻)</div> | <div title="Base coverage is: 50%">51.52% (+1.52% 🔼)</div> | <div title="Base coverage is: 58.75%">60.41% (+1.66% 🔼)</div> |

</details>

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

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

Patch:
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
index 9365d1bc..e024d855 100644
--- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-birl.ts
@@ -285,6 +285,8 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
         throw new Error('Método não implementado.');
     }
 
+
+
     declaracaoEscreva(): Escreva {
         const primeiroSimbolo = this.consumir(tiposDeSimbolos.CE, 'Esperado expressão `CE` para escrever mensagem.');
         this.consumir(tiposDeSimbolos.QUER, 'Esperado expressão `QUER` após `CE` para escrever mensagem.');
@@ -296,15 +298,24 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
             tiposDeSimbolos.PARENTESE_ESQUERDO,
             'Esperado parêntese esquerdo após interrogação para escrever mensagem.'
         );
+        const argumentos = [];
+
+        argumentos.push(this.declaracao());
 
-        const argumento = this.declaracao();
+        while(!this.verificarTipoSimboloAtual(tiposDeSimbolos.PARENTESE_DIREITO)) {
+            if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA)) {
+                const variavelParaEscrita = this.declaracao();
+                argumentos.push(variavelParaEscrita);
+            }
+
+        }
 
         this.consumir(
             tiposDeSimbolos.PARENTESE_DIREITO,
             'Esperado parêntese direito após argumento para escrever mensagem.'
         );
 
-        return new Escreva(Number(primeiroSimbolo.linha), this.hashArquivo, [argumento]);
+        return new Escreva(Number(primeiroSimbolo.linha), this.hashArquivo, argumentos);
     }
 
     declaracaoFazer(): Fazer {
diff --git a/fontes/interpretador/dialetos/birl/interpretador-birl.ts b/fontes/interpretador/dialetos/birl/interpretador-birl.ts
index ebb0ab85..f2c7d7a7 100644
--- a/fontes/interpretador/dialetos/birl/interpretador-birl.ts
+++ b/fontes/interpretador/dialetos/birl/interpretador-birl.ts
@@ -1,4 +1,14 @@
-import { Atribuir, Construto, FimPara, FormatacaoEscrita, Literal, Super, TipoDe, Unario, Variavel } from '../../../construtos';
+import {
+    Atribuir,
+    Construto,
+    FimPara,
+    FormatacaoEscrita,
+    Literal,
+    Super,
+    TipoDe,
+    Unario,
+    Variavel,
+} from '../../../construtos';
 import {
     Bloco,
     Classe,
@@ -22,7 +32,15 @@ import {
     Var,
 } from '../../../declaracoes';
 import { EspacoVariaveis } from '../../../espaco-variaveis';
-import { Chamavel, DeleguaClasse, DeleguaFuncao, DeleguaModulo, FuncaoPadrao, MetodoPrimitiva, ObjetoPadrao } from '../../../estruturas';
+import {
+    Chamavel,
+    DeleguaClasse,
+    DeleguaFuncao,
+    DeleguaModulo,
+    FuncaoPadrao,
+    MetodoPrimitiva,
+    ObjetoPadrao,
+} from '../../../estruturas';
 import { ErroEmTempoDeExecucao } from '../../../excecoes';
 import { InterpretadorInterface, ParametroInterface, SimboloInterface, VariavelInterface } from '../../../interfaces';
 import { ErroInterpretador } from '../../../interfaces/erros/erro-interpretador';
@@ -385,7 +403,11 @@ export class InterpretadorBirl implements InterpretadorInterface {
                     argumentos.push(null);
                 }
             } else {
-                if (parametros && parametros.length > 0 && parametros[parametros.length - 1].abrangencia === 'multiplo') {
+                if (
+                    parametros &&
+                    parametros.length > 0 &&
+                    parametros[parametros.length - 1].abrangencia === 'multiplo'
+                ) {
                     const novosArgumentos = argumentos.slice(0, parametros.length - 1);
                     novosArgumentos.push(argumentos.slice(parametros.length - 1, argumentos.length));
                     argumentos = novosArgumentos;
@@ -649,14 +671,72 @@ export class InterpretadorBirl implements InterpretadorInterface {
         throw new Error('Método não implementado.');
     }
 
+    protected async substituirValor(
+        stringOriginal: string,
+        novoValor: number | string,
+        simboloTipo: string
+    ): Promise<string> {
+        let substituida = false;
+        let resultado = '';
+
+        for (let i = 0; i < stringOriginal.length; i++) {
+            if (stringOriginal[i] === '%' && stringOriginal[i + 1] === simboloTipo && !substituida) {
+                switch (simboloTipo) {
+                    case 'd':
+                    case 'i':
+                    case 'u':
+                    case 'f':
+                    case 'F':
+                    case 'e':
+                    case 'E':
+                    case 'g':
+                    case 'G':
+                    case 'x':
+                    case 'X':
+                    case 'o':
+                    case 'c':
+                    case 's':
+                    case 'p':
+                        resultado += novoValor.toString();
+                        break;
+                    default:
+                        resultado += stringOriginal[i];
+                        break;
+                }
+                substituida = true;
+                i++;
+            } else {
+                resultado += stringOriginal[i];
+            }
+        }
+
+        return resultado;
+    }
+
+    protected async resolverInterpolacao(formatoTexto: string, valor: number | string, tipo: string): Promise<string> {
+        switch (tipo) {
+            case 'número':
+                return await this.substituirValor(formatoTexto, valor as number, 'd');
+            case 'texto':
+                return await this.substituirValor(formatoTexto, valor as string, 's');
+            default:
+                return formatoTexto;
+        }
+    }
+
     protected async avaliarArgumentosEscreva(argumentos: Construto[]): Promise<string> {
         let formatoTexto: string = '';
 
         for (const argumento of argumentos) {
-            const resultadoAvaliacao = await this.avaliar(argumento);
-            let valor = resultadoAvaliacao?.hasOwnProperty('valor') ? resultadoAvaliacao.valor : resultadoAvaliacao;
-
-            formatoTexto += `${this.paraTexto(valor)} `;
+            let valor = null;
+            if (argumento instanceof Variavel) {
+                valor = await this.avaliar(argumento);
+                formatoTexto = await this.resolverInterpolacao(formatoTexto, valor.valor, valor.tipo);
+            } else {
+                const resultadoAvaliacao = await this.avaliar(argumento);
+                valor = resultadoAvaliacao?.hasOwnProperty('valor') ? resultadoAvaliacao.valor : resultadoAvaliacao;
+                formatoTexto += `${this.paraTexto(valor)} `;
+            }
         }
 
         return formatoTexto.trimEnd();


Test patch:
diff --git a/testes/birl/interpretador.test.ts b/testes/birl/interpretador.test.ts
index d1c703f4..d5d49c07 100644
--- a/testes/birl/interpretador.test.ts
+++ b/testes/birl/interpretador.test.ts
@@ -15,6 +15,23 @@ describe('Interpretador', () => {
                 interpretador = new InterpretadorBirl(process.cwd());
             });
 
+            it('Sucesso - declaração - escreva com variavel', async () => {
+                const retornoLexador = lexador.mapear([
+                    'HORA DO SHOW\n',
+                    '   FRANGO X = "testeeeeeeeeeeeeeeeeeeeeee";\n',
+                    '   CE QUER VER ESSA PORRA? ("A variavel X tem valor: %s\n", X);\n',
+                    '   BORA CUMPADE 0;\n',
+                    'BIRL\n',
+                ])
+
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador).toBeTruthy();
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            })
+
             it('Sucesso - declaração - chamarFuncao', async () => {
                 const retornoLexador = lexador.mapear([
                     'HORA DO SHOW \n',