Repository: DesignLiquido/delegua
Pull request #640 (2024-02-12 03:59:45)

[VisuAlg] Emitindo tipos para vetores
A Avaliação Sintática estava emitindo vetores sem tipo para o VisuAlg. 

Também modifiquei algumas partes da estrutura dos fontes que não estavam legais na geração da biblioteca. O VSCode, por exemplo, estava se perdendo em algumas ocasiões.


Patch:
diff --git a/fontes/analisador-semantico/analisador-semantico.ts b/fontes/analisador-semantico/analisador-semantico.ts
index e2ebd064..a0cad4ee 100644
--- a/fontes/analisador-semantico/analisador-semantico.ts
+++ b/fontes/analisador-semantico/analisador-semantico.ts
@@ -50,13 +50,13 @@ import { SimboloInterface } from '../interfaces';
 import { AnalisadorSemanticoInterface } from '../interfaces/analisador-semantico-interface';
 import { DiagnosticoAnalisadorSemantico, DiagnosticoSeveridade } from '../interfaces/erros';
 import { RetornoAnalisadorSemantico } from '../interfaces/retornos/retorno-analisador-semantico';
-import { TiposDadosInterface } from '../interfaces/tipos-dados-interface';
+import { TipoDadosElementar } from '../tipo-dados-elementar';
 import { ContinuarQuebra, RetornoQuebra, SustarQuebra } from '../quebras';
 import { AnalisadorSemanticoBase } from './analisador-semantico-base';
 import { PilhaVariaveis } from './pilha-variaveis';
 
 interface VariavelHipoteticaInterface {
-    tipo: TiposDadosInterface;
+    tipo: TipoDadosElementar;
     subtipo?: 'texto' | 'número' | 'inteiro' | 'longo' | 'lógico';
     imutavel: boolean;
     valor?: any;
diff --git a/fontes/avaliador-sintatico/avaliador-sintatico.ts b/fontes/avaliador-sintatico/avaliador-sintatico.ts
index 445ac584..1efd3f5f 100644
--- a/fontes/avaliador-sintatico/avaliador-sintatico.ts
+++ b/fontes/avaliador-sintatico/avaliador-sintatico.ts
@@ -57,7 +57,7 @@ import {
 import { RetornoAvaliadorSintatico } from '../interfaces/retornos/retorno-avaliador-sintatico';
 import { RetornoLexador } from '../interfaces/retornos/retorno-lexador';
 import { RetornoDeclaracao } from './retornos';
-import { TiposDadosInterface } from '../interfaces/tipos-dados-interface';
+import { TipoDadosElementar } from '../tipo-dados-elementar';
 import { Simbolo } from '../lexador';
 import { SeletorTuplas, Tupla } from '../construtos/tuplas';
 
@@ -108,7 +108,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
         return this.simbolos[this.atual + 1].tipo === tipo;
     }
 
-    verificarDefinicaoTipoAtual(): TiposDadosInterface {
+    verificarDefinicaoTipoAtual(): TipoDadosElementar {
         // const tipos = [
         //     tipoDeDadosDelegua.INTEIRO,
         //     tipoDeDadosDelegua.QUALQUER,
@@ -134,10 +134,10 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
 
             this.avancarEDevolverAnterior();
 
-            return contemTipoVetor as TiposDadosInterface;
+            return contemTipoVetor as TipoDadosElementar;
         }
 
-        return contemTipo as TiposDadosInterface;
+        return contemTipo as TipoDadosElementar;
     }
 
     simboloAtual(): SimboloInterface {
diff --git a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.ts b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.ts
index 216b8955..73c0bf62 100644
--- a/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.ts
+++ b/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-portugol-studio.ts
@@ -37,7 +37,7 @@ import { ParametroInterface, SimboloInterface } from '../../interfaces';
 import tiposDeSimbolos from '../../tipos-de-simbolos/portugol-studio';
 import { RetornoDeclaracao } from '../retornos';
 import { ErroAvaliadorSintatico } from '../erro-avaliador-sintatico';
-import { TiposDadosInterface } from '../../interfaces/tipos-dados-interface';
+import { TipoDadosElementar } from '../../tipo-dados-elementar';
 
 /**
  * O avaliador sintático (_Parser_) é responsável por transformar os símbolos do Lexador em estruturas de alto nível.
@@ -782,7 +782,7 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
 
         const inicializador = this.expressao();
 
-        return new Const(identificador, inicializador, tipo.lexema as TiposDadosInterface);
+        return new Const(identificador, inicializador, tipo.lexema as TipoDadosElementar);
     }
 
     resolverDeclaracaoForaDeBloco(): Declaracao | Declaracao[] | Construto | Construto[] | any {
diff --git a/fontes/avaliador-sintatico/dialetos/potigol/avaliador-sintatico-potigol.ts b/fontes/avaliador-sintatico/dialetos/potigol/avaliador-sintatico-potigol.ts
index 818f683d..d3a3abe7 100644
--- a/fontes/avaliador-sintatico/dialetos/potigol/avaliador-sintatico-potigol.ts
+++ b/fontes/avaliador-sintatico/dialetos/potigol/avaliador-sintatico-potigol.ts
@@ -42,7 +42,7 @@ import { RetornoLexador, RetornoAvaliadorSintatico } from '../../../interfaces/r
 import { AvaliadorSintaticoBase } from '../../avaliador-sintatico-base';
 
 import { ParametroInterface, SimboloInterface } from '../../../interfaces';
-import { TiposDadosInterface } from '../../../interfaces/tipos-dados-interface';
+import { TipoDadosElementar } from '../../../tipo-dados-elementar';
 import { Simbolo } from '../../../lexador';
 import { ErroAvaliadorSintatico } from '../../erro-avaliador-sintatico';
 import { RetornoDeclaracao } from '../../retornos';
@@ -815,7 +815,7 @@ export class AvaliadorSintaticoPotigol extends AvaliadorSintaticoBase {
 
             const inicializadorLeia = <LeiaMultiplo>inicializadores[0];
 
-            let tipoConversao: TiposDadosInterface;
+            let tipoConversao: TipoDadosElementar;
             switch (inicializadorLeia.simbolo.tipo) {
                 case tiposDeSimbolos.LEIA_INTEIROS:
                     tipoConversao = 'inteiro[]';
@@ -1029,7 +1029,7 @@ export class AvaliadorSintaticoPotigol extends AvaliadorSintaticoBase {
                         (expressao as Constante).simbolo,
                         valorAtribuicao,
                         tipoVariavelOuConstante
-                            ? (this.tiposPotigolParaDelegua[tipoVariavelOuConstante.lexema] as TiposDadosInterface)
+                            ? (this.tiposPotigolParaDelegua[tipoVariavelOuConstante.lexema] as TipoDadosElementar)
                             : undefined
                     );
             }
diff --git a/fontes/avaliador-sintatico/dialetos/visualg/avaliador-sintatico-visualg.ts b/fontes/avaliador-sintatico/dialetos/visualg/avaliador-sintatico-visualg.ts
index f67bb3e7..4b4c9e62 100644
--- a/fontes/avaliador-sintatico/dialetos/visualg/avaliador-sintatico-visualg.ts
+++ b/fontes/avaliador-sintatico/dialetos/visualg/avaliador-sintatico-visualg.ts
@@ -42,7 +42,7 @@ import { Simbolo } from '../../../lexador';
 
 import tiposDeSimbolos from '../../../tipos-de-simbolos/visualg';
 import { ParametroVisuAlg } from './parametro-visualg';
-import { TiposDadosInterface } from '../../../interfaces/tipos-dados-interface';
+import { TipoDadosElementar } from '../../../tipo-dados-elementar';
 import { ErroAvaliadorSintatico } from '../../erro-avaliador-sintatico';
 import { InicioAlgoritmo } from '../../../declaracoes/inicio-algoritmo';
 
@@ -76,9 +76,9 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
                 novoArray[i] = this.criarVetorNDimensional(resto);
             }
             return novoArray;
-        } else {
-            return undefined;
-        }
+        } 
+            
+        return undefined;
     }
 
     private validarDimensoesVetor(): number[] {
@@ -161,9 +161,6 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
         const inicializacoes = [];
         this.avancarEDevolverAnterior(); // Var
 
-        // Quebra de linha é opcional aqui.
-        // this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.QUEBRA_LINHA);
-
         while (!this.verificarTipoSimboloAtual(tiposDeSimbolos.INICIO)) {
             // Se ainda houver quebras de linha, volta para o começo do `while`.
             if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.QUEBRA_LINHA)) {
@@ -222,14 +219,14 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
                                         Number(dadosVariaveis.simbolo.linha),
                                         this.criarVetorNDimensional(dimensoes)
                                     ),
-                                    'vetor'
+                                    `${simboloTipo.lexema}[]` as TipoDadosElementar
                                 )
                             );
                         }
                         this.atual++;
                     } else {
                         for (let identificador of dadosVariaveis.identificadores) {
-                            const tipo = dadosVariaveis.tipo as TiposDadosInterface;
+                            const tipo = dadosVariaveis.tipo as TipoDadosElementar;
                             switch (dadosVariaveis.tipo) {
                                 case tiposDeSimbolos.CARACTER:
                                 case tiposDeSimbolos.CARACTERE:
@@ -473,7 +470,7 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
         return this.simbolos[this.atual - 2];
     }
 
-    verificarDefinicaoTipoAtual(): TiposDadosInterface {
+    verificarDefinicaoTipoAtual(): TipoDadosElementar {
         const tipos = ['inteiro', 'qualquer', 'real', 'texto', 'vazio', 'vetor', 'caracter'];
 
         const lexema = this.simboloAtual().lexema.toLowerCase();
@@ -492,10 +489,10 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
 
             this.avancarEDevolverAnterior();
 
-            return contemTipoVetor as TiposDadosInterface;
+            return contemTipoVetor as TipoDadosElementar;
         }
 
-        return contemTipo as TiposDadosInterface;
+        return contemTipo as TipoDadosElementar;
     }
 
     corpoDaFuncao(tipo: any): FuncaoConstruto {
@@ -991,7 +988,7 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
                 const dadosParametros = this.logicaComumParametroVisuAlg();
                 const tipoDadoParametro = {
                     nome: dadosParametros.simbolo.lexema,
-                    tipo: dadosParametros.tipo as TiposDadosInterface,
+                    tipo: dadosParametros.tipo as TipoDadosElementar,
                     tipoInvalido: !dadosParametros.tipo ? this.simboloAtual().lexema : null,
                 };
 
diff --git a/fontes/declaracoes/const-multiplo.ts b/fontes/declaracoes/const-multiplo.ts
index 4c2fb5b0..9c7c860f 100644
--- a/fontes/declaracoes/const-multiplo.ts
+++ b/fontes/declaracoes/const-multiplo.ts
@@ -1,6 +1,6 @@
 import { Construto } from '../construtos';
 import { VisitanteComumInterface, SimboloInterface } from '../interfaces';
-import { TiposDadosInterface } from '../interfaces/tipos-dados-interface';
+import { TipoDadosElementar } from '../tipo-dados-elementar';
 import { Declaracao } from './declaracao';
 
 /**
@@ -9,9 +9,9 @@ import { Declaracao } from './declaracao';
 export class ConstMultiplo extends Declaracao {
     simbolos: SimboloInterface[];
     inicializador: Construto;
-    tipo: TiposDadosInterface;
+    tipo: TipoDadosElementar;
 
-    constructor(simbolos: SimboloInterface[], inicializador: Construto, tipo: TiposDadosInterface = undefined) {
+    constructor(simbolos: SimboloInterface[], inicializador: Construto, tipo: TipoDadosElementar = undefined) {
         super(Number(simbolos[0].linha), simbolos[0].hashArquivo);
         this.simbolos = simbolos;
         this.inicializador = inicializador;
diff --git a/fontes/declaracoes/const.ts b/fontes/declaracoes/const.ts
index 9efca205..7ba28f16 100644
--- a/fontes/declaracoes/const.ts
+++ b/fontes/declaracoes/const.ts
@@ -1,6 +1,6 @@
 import { Construto } from '../construtos';
 import { VisitanteComumInterface, SimboloInterface } from '../interfaces';
-import { TiposDadosInterface } from '../interfaces/tipos-dados-interface';
+import { TipoDadosElementar } from '../tipo-dados-elementar';
 import { Declaracao } from './declaracao';
 
 /**
@@ -9,9 +9,9 @@ import { Declaracao } from './declaracao';
 export class Const extends Declaracao {
     simbolo: SimboloInterface;
     inicializador: Construto;
-    tipo: TiposDadosInterface;
+    tipo: TipoDadosElementar;
 
-    constructor(simbolo: SimboloInterface, inicializador: Construto, tipo: TiposDadosInterface = undefined) {
+    constructor(simbolo: SimboloInterface, inicializador: Construto, tipo: TipoDadosElementar = undefined) {
         super(Number(simbolo.linha), simbolo.hashArquivo);
         this.simbolo = simbolo;
         this.inicializador = inicializador;
diff --git a/fontes/declaracoes/var-multiplo.ts b/fontes/declaracoes/var-multiplo.ts
index 3b265714..dfcbbc55 100644
--- a/fontes/declaracoes/var-multiplo.ts
+++ b/fontes/declaracoes/var-multiplo.ts
@@ -1,6 +1,6 @@
 import { Construto } from '../construtos';
 import { VisitanteComumInterface, SimboloInterface } from '../interfaces';
-import { TiposDadosInterface } from '../interfaces/tipos-dados-interface';
+import { TipoDadosElementar } from '../tipo-dados-elementar';
 import { Declaracao } from './declaracao';
 
 /**
@@ -9,10 +9,10 @@ import { Declaracao } from './declaracao';
 export class VarMultiplo extends Declaracao {
     simbolos: SimboloInterface[];
     inicializador: Construto;
-    tipo: TiposDadosInterface;
+    tipo: TipoDadosElementar;
     referencia: boolean;
 
-    constructor(simbolos: SimboloInterface[], inicializador: Construto, tipo: TiposDadosInterface = undefined) {
+    constructor(simbolos: SimboloInterface[], inicializador: Construto, tipo: TipoDadosElementar = undefined) {
         super(Number(simbolos[0].linha), simbolos[0].hashArquivo);
         this.simbolos = simbolos;
         this.inicializador = inicializador;
diff --git a/fontes/declaracoes/var.ts b/fontes/declaracoes/var.ts
index a274973c..9379c485 100644
--- a/fontes/declaracoes/var.ts
+++ b/fontes/declaracoes/var.ts
@@ -1,6 +1,6 @@
 import { Construto } from '../construtos';
 import { VisitanteComumInterface, SimboloInterface } from '../interfaces';
-import { TiposDadosInterface } from '../interfaces/tipos-dados-interface';
+import { TipoDadosElementar } from '../tipo-dados-elementar';
 import { Declaracao } from './declaracao';
 
 /**
@@ -9,11 +9,11 @@ import { Declaracao } from './declaracao';
 export class Var extends Declaracao {
     simbolo: SimboloInterface;
     inicializador: Construto;
-    tipo: TiposDadosInterface;
+    tipo: TipoDadosElementar;
     referencia: boolean;
     desestruturacao: boolean;
 
-    constructor(simbolo: SimboloInterface, inicializador: Construto, tipo: TiposDadosInterface = undefined) {
+    constructor(simbolo: SimboloInterface, inicializador: Construto, tipo: TipoDadosElementar = undefined) {
         super(Number(simbolo.linha), simbolo.hashArquivo);
         this.simbolo = simbolo;
         this.inicializador = inicializador;
diff --git a/fontes/index.ts b/fontes/index.ts
new file mode 100644
index 00000000..c14c112a
--- /dev/null
+++ b/fontes/index.ts
@@ -0,0 +1,6 @@
+export * from './avaliador-sintatico';
+export { PontoParada, cyrb53 } from './depuracao';
+export * from './formatadores';
+export * from './interpretador';
+export * from './lexador';
+export * from './tradutores';
\ No newline at end of file
diff --git a/fontes/interfaces/parametro-interface.ts b/fontes/interfaces/parametro-interface.ts
index b314fd47..e6c8489a 100644
--- a/fontes/interfaces/parametro-interface.ts
+++ b/fontes/interfaces/parametro-interface.ts
@@ -1,9 +1,9 @@
 import { SimboloInterface } from './simbolo-interface';
-import { TiposDadosInterface } from './tipos-dados-interface';
+import { TipoDadosElementar } from '../tipo-dados-elementar';
 
 interface TipoDadoParametroInterface {
     nome: string;
-    tipo: TiposDadosInterface;
+    tipo: TipoDadosElementar;
     tipoInvalido?: string;
 }
 export interface ParametroInterface {
diff --git a/fontes/interfaces/variavel-hipotetica-interface.ts b/fontes/interfaces/variavel-hipotetica-interface.ts
index d96d1adf..f2929f90 100644
--- a/fontes/interfaces/variavel-hipotetica-interface.ts
+++ b/fontes/interfaces/variavel-hipotetica-interface.ts
@@ -1,7 +1,7 @@
-import { TiposDadosInterface } from './tipos-dados-interface';
+import { TipoDadosElementar } from '../tipo-dados-elementar';
 
 export interface VariavelHipoteticaInterface {
-    tipo: TiposDadosInterface;
+    tipo: TipoDadosElementar;
     subtipo?: 'texto' | 'número' | 'inteiro' | 'longo' | 'lógico';
     imutavel: boolean;
     valor?: any;
diff --git a/fontes/interpretador/inferenciador.ts b/fontes/interpretador/inferenciador.ts
index cd5455b6..894a776c 100644
--- a/fontes/interpretador/inferenciador.ts
+++ b/fontes/interpretador/inferenciador.ts
@@ -1,4 +1,6 @@
-export function inferirTipoVariavel(variavel: string | number | Array<any> | boolean | null | undefined) {
+export type TipoInferencia = "texto" | "número" | "longo" | "vetor" | "dicionário" | "nulo" | "lógico" | "função" | "símbolo" | "objeto" | "módulo";
+
+export function inferirTipoVariavel(variavel: string | number | Array<any> | boolean | null | undefined): TipoInferencia {
     const tipo = typeof variavel;
     switch (tipo) {
         case 'string':
diff --git a/fontes/interpretador/pilha-escopos-execucao.ts b/fontes/interpretador/pilha-escopos-execucao.ts
index 32d978b3..d6e775f5 100644
--- a/fontes/interpretador/pilha-escopos-execucao.ts
+++ b/fontes/interpretador/pilha-escopos-execucao.ts
@@ -4,7 +4,7 @@ import { SimboloInterface, VariavelInterface } from '../interfaces';
 import { EscopoExecucao } from '../interfaces/escopo-execucao';
 import { PilhaEscoposExecucaoInterface } from '../interfaces/pilha-escopos-execucao-interface';
 import { Simbolo } from '../lexador';
-import { inferirTipoVariavel } from './inferenciador';
+import { TipoInferencia, inferirTipoVariavel } from './inferenciador';
 import tipoDeDadosDelegua from '../tipos-de-dados/delegua';
 
 export class PilhaEscoposExecucao implements PilhaEscoposExecucaoInterface {
@@ -148,7 +148,7 @@ export class PilhaEscoposExecucao implements PilhaEscoposExecucaoInterface {
                         `Constante '${simbolo.lexema}' não pode receber novos valores.`
                     );
                 }
-                const tipo = variavel && variavel.hasOwnProperty('tipo') ? variavel.tipo : inferirTipoVariavel(valor);
+                const tipo = (variavel && variavel.hasOwnProperty('tipo') ? variavel.tipo : inferirTipoVariavel(valor)).toLowerCase() as TipoInferencia;
 
                 const valorResolvido = this.converterValor(tipo, valor);
                 ambiente.valores[simbolo.lexema] = {
diff --git a/fontes/interfaces/tipos-dados-interface.ts b/fontes/tipo-dados-elementar.ts
similarity index 90%
rename from fontes/interfaces/tipos-dados-interface.ts
rename to fontes/tipo-dados-elementar.ts
index a1161011..11f8773a 100644
--- a/fontes/interfaces/tipos-dados-interface.ts
+++ b/fontes/tipo-dados-elementar.ts
@@ -1,4 +1,4 @@
-export type TiposDadosInterface =
+export type TipoDadosElementar =
     | 'dicionário'
     | 'função'
     | 'inteiro'
diff --git a/index.ts b/index.ts
deleted file mode 100644
index 88201e92..00000000
--- a/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export * as avaliadores from './fontes/avaliador-sintatico';
-export { PontoParada, cyrb53 } from './fontes/depuracao';
-export * as formatadores from './fontes/formatadores';
-export * as interpretadores from './fontes/interpretador';
-export * as lexadores from './fontes/lexador';
-export * as tradutores from './fontes/tradutores';
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index bdd52b86..c1b90d97 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -3,7 +3,7 @@
         "outDir": "dist",
         "module": "CommonJS",
         "target": "es2017",
-        "rootDir": ".",
+        "rootDir": "fontes",
         "allowJs": true,
         "sourceMap": true,
         "declaration": true,


Test patch:
diff --git a/testes/visualg/interpretador.test.ts b/testes/visualg/interpretador.test.ts
index 7787ad97..1c82367c 100644
--- a/testes/visualg/interpretador.test.ts
+++ b/testes/visualg/interpretador.test.ts
@@ -619,6 +619,45 @@ describe('Interpretador', () => {
 
                 expect(retornoInterpretador.erros).toHaveLength(0);
             });
+
+            it('Sucesso - Negativos', async () => {
+                // Aqui vamos simular a resposta para três variáveis de `leia()`.
+                const respostas = [
+                    2, -1, 3
+                ];
+                interpretador.interfaceEntradaSaida = {
+                    question: (mensagem: string, callback: Function) => {
+                        callback(respostas.shift());
+                    }
+                };
+
+                const retornoLexador = lexador.mapear([
+                    'algoritmo "negativos"',
+                    'var',
+                    '  n, i: inteiro',
+                    '  vet: vetor [0..9] de inteiro',
+                    'inicio',
+                    '  escreval("Quantos numeros voce vai digitar? ")',
+                    '  leia(n)',
+                    '  para i de 0 ate n-1 faca',
+                    '    escreval("Digite um numero: ")',
+                    '    leia(vet[i])',
+                    '  fimpara',
+                    '  escreval(" ")',
+                    '  escreval("NUMEROS NEGATIVOS")',
+                    '   para i de 0 ate n-1 faca',
+                    '    se (vet[i] < 0) entao',
+                    '      escreval(vet[i])',
+                    '     fimse',
+                    '  fimpara',
+                    'fimalgoritmo'
+                ], -1);
+                const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
+
+                const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
+
+                expect(retornoInterpretador.erros).toHaveLength(0);
+            });
         });
     });
 });