Repository: DesignLiquido/delegua
Pull request #274 (2023-02-10 23:24:02)

Visualg: `leia()` aceita N argumentos


Patch:
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 3946b45d..0929877e 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -435,7 +435,7 @@
             "runtimeArgs": [
                 "--inspect-brk",
                 "${workspaceRoot}/node_modules/jest/bin/jest.js",
-                "guarani",
+                "visualg",
                 "--runInBand"
             ],
             "skipFiles": ["<node_internals>/**", "node_modules/**"],
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts
index 9ba0f6e4..1b0cfcf6 100644
--- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-visualg.ts
@@ -584,12 +584,19 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
         return new Sustar(simboloAtual);
     }
 
+    /**
+     * Análise de uma declaração `leia()`. No VisuAlg, `leia()` aceita 1..N argumentos.
+     * @returns Uma declaração `Leia`.
+     */
     declaracaoLeia(): Leia {
         const simboloAtual = this.avancarEDevolverAnterior();
 
         this.consumir(tiposDeSimbolos.PARENTESE_ESQUERDO, "Esperado '(' antes do argumento em instrução `leia`.");
 
-        const argumento = this.declaracao();
+        const argumentos = [];
+        do {
+            argumentos.push(this.declaracao());
+        } while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
 
         this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após o argumento em instrução `leia`.");
 
@@ -598,7 +605,7 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
             'Esperado quebra de linha após fechamento de parênteses pós instrução `leia`.'
         );
 
-        return new Leia(simboloAtual.hashArquivo, Number(simboloAtual.linha), [argumento]);
+        return new Leia(simboloAtual.hashArquivo, Number(simboloAtual.linha), argumentos);
     }
 
     declaracaoPara(): Para {
diff --git a/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts b/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts
index 6dc38a48..253186fc 100644
--- a/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts
+++ b/fontes/interpretador/dialetos/visualg/interpretador-visualg.ts
@@ -94,14 +94,15 @@ export class InterpretadorVisuAlg extends InterpretadorBase {
      */
     async visitarExpressaoLeia(expressao: Leia): Promise<any> {
         const mensagem = '> ';
-        const argumento = (expressao.argumentos[0] as Variavel).simbolo.lexema;
-        const promessaLeitura: Function = () => new Promise((resolucao) =>
-            this.interfaceEntradaSaida.question(mensagem, (resposta: any) => {
-                resolucao(resposta);
-            })
-        );
+        for (let argumento of expressao.argumentos) {
+            const promessaLeitura: Function = () => new Promise((resolucao) =>
+                this.interfaceEntradaSaida.question(mensagem, (resposta: any) => {
+                    resolucao(resposta);
+                })
+            );
 
-        const valorLido = await promessaLeitura();
-        this.pilhaEscoposExecucao.definirVariavel(argumento, valorLido);
+            const valorLido = await promessaLeitura();
+            this.pilhaEscoposExecucao.definirVariavel((<Variavel>argumento).simbolo.lexema, valorLido);
+        }
     }
 }


Test patch:
diff --git a/testes/visualg/avaliador-sintatico.test.ts b/testes/visualg/avaliador-sintatico.test.ts
index cdf850c9..d9ce896a 100644
--- a/testes/visualg/avaliador-sintatico.test.ts
+++ b/testes/visualg/avaliador-sintatico.test.ts
@@ -111,6 +111,23 @@ describe('Avaliador sintático (VisuAlg)', () => {
             expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(3);
         });
 
+        it('Sucesso - Leia', () => {
+            const retornoLexador = lexador.mapear([
+                'Algoritmo "Soma 5"',
+                'Var',
+                '   n1, n2, n3, n4, n5: inteiro',
+                'Inicio',
+                '      leia(n1, n2, n3, n4, n5)',
+                '      escreva(n1 + n2 + n3 + n4 + n5)',
+                'Fimalgoritmo'
+            ], -1);
+
+            const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+
+            expect(retornoAvaliadorSintatico).toBeTruthy();
+            expect(retornoAvaliadorSintatico.declaracoes.length).toBeGreaterThan(0);
+        });
+
         it('Sucesso - Para', () => {
             const retornoLexador = lexador.mapear([
                 'algoritmo "Numeros de 1 a 10"',
diff --git a/testes/visualg/interpretador.test.ts b/testes/visualg/interpretador.test.ts
index 500e1f73..95238ff5 100644
--- a/testes/visualg/interpretador.test.ts
+++ b/testes/visualg/interpretador.test.ts
@@ -27,6 +27,32 @@ describe('Interpretador', () => {
 
                 expect(retornoInterpretador.erros).toHaveLength(0);
             });
+
+            it('Sucesso - Leia', async () => {
+                // Aqui vamos simular a resposta para cinco variáveis de `leia()`.
+                const respostas = [1, 2, 3, 4, 5];
+                interpretador.interfaceEntradaSaida = {
+                    question: (mensagem: string, callback: Function) => {
+                        callback(respostas.pop());
+                    }
+                };
+
+                const retornoLexador = lexador.mapear([
+                    'Algoritmo "Soma 5"',
+                    'Var',
+                    '    n1, n2, n3, n4, n5: inteiro',
+                    'Inicio',
+                    '    leia(n1, n2, n3, n4, n5)',
+                    '    escreva(n1 + n2 + n3 + n4 + n5)',
+                    'Fimalgoritmo'
+                ], -1);
+    
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador);
+    
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
         });
     });
 });