Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Melhoria validação de Tuplas e definição de tipos #631

Merged
merged 1 commit into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions fontes/avaliador-sintatico/avaliador-sintatico.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import tiposDeSimbolos from '../tipos-de-simbolos/delegua';
import tipoDeDadosDelegua from '../tipos-de-dados/delegua';
import hrtime from 'browser-process-hrtime';

import { AvaliadorSintaticoInterface, ParametroInterface, SimboloInterface } from '../interfaces';
Expand Down Expand Up @@ -107,13 +108,21 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
}

verificarDefinicaoTipoAtual(): TiposDadosInterface {
const tipos = ['inteiro', 'qualquer', 'real', 'texto', 'vazio', 'vetor'];
// const tipos = [
// tipoDeDadosDelegua.INTEIRO,
// tipoDeDadosDelegua.QUALQUER,
// tipoDeDadosDelegua.REAL,
// tipoDeDadosDelegua.TEXTO,
// tipoDeDadosDelegua.VAZIO,
// tipoDeDadosDelegua.VETOR
// ];
const tipos = [...Object.values(tipoDeDadosDelegua)]

const lexema = this.simboloAtual().lexema.toLowerCase();
const contemTipo = tipos.find((tipo) => tipo === lexema);

if (contemTipo && this.verificarTipoProximoSimbolo(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
const tiposVetores = ['inteiro[]', 'qualquer[]', 'real[]', 'texto[]'];
const tiposVetores = ['inteiro[]', 'numero[]', 'número[]', 'qualquer[]', 'real[]', 'texto[]'];
this.avancarEDevolverAnterior();

if (!this.verificarTipoProximoSimbolo(tiposDeSimbolos.COLCHETE_DIREITO)) {
Expand Down Expand Up @@ -1131,6 +1140,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
}

for (let [indice, identificador] of identificadores.entries()) {
tipo = inicializadores[indice] instanceof Tupla ? tipoDeDadosDelegua.TUPLA : tipo;
retorno.push(new Var(identificador, inicializadores[indice], tipo));
}

Expand Down
29 changes: 23 additions & 6 deletions fontes/interpretador/interpretador-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export class InterpretadorBase implements InterpretadorInterface {
throw new Error('Método não implementado.');
}

async visitarExpressaoTupla(expressao: any): Promise<any> {
async visitarExpressaoTupla(expressao: Tupla): Promise<any> {
const chaves = Object.keys(expressao)
const valores = [];
for (let chave of chaves) {
Expand Down Expand Up @@ -207,11 +207,11 @@ export class InterpretadorBase implements InterpretadorInterface {

if (
tipoDe instanceof Binario ||
tipoDe instanceof Chamada ||
tipoDe instanceof TipoDe ||
tipoDe instanceof Unario ||
tipoDe instanceof Variavel ||
tipoDe instanceof Agrupamento ||
tipoDe instanceof Chamada
tipoDe instanceof Agrupamento
) {
tipoDe = await this.avaliar(tipoDe);
return tipoDe.tipo || inferirTipoVariavel(tipoDe);
Expand Down Expand Up @@ -650,6 +650,24 @@ export class InterpretadorBase implements InterpretadorInterface {

if (entidadeChamada instanceof MetodoPrimitiva) {
const argumentosResolvidos: any[] = [];

if (expressao instanceof Chamada) {
if (expressao.entidadeChamada instanceof AcessoMetodoOuPropriedade) {
if (expressao.entidadeChamada.objeto instanceof Variavel) {
let eTupla = this.procurarVariavel(expressao.entidadeChamada.objeto.simbolo)
if (eTupla.subtipo === tipoDeDadosDelegua.TUPLA) {
leonelsanchesdasilva marked this conversation as resolved.
Show resolved Hide resolved
return Promise.reject(
new ErroEmTempoDeExecucao(
expressao.entidadeChamada.objeto.simbolo,
'Tupla é imutável, seus elementos não podem ser alterados, adicionados ou removidos.',
expressao.linha
)
);
}
}
}
}

for (const argumento of expressao.argumentos) {
const valorResolvido: any = await this.avaliar(argumento);
argumentosResolvidos.push(
Expand Down Expand Up @@ -1206,7 +1224,7 @@ export class InterpretadorBase implements InterpretadorInterface {
let indice = promises[1];
const valor = promises[2];

if (objeto.imutavel) {
leonelsanchesdasilva marked this conversation as resolved.
Show resolved Hide resolved
if (objeto.subtipo === tipoDeDadosDelegua.TUPLA) {
return Promise.reject(
new ErroEmTempoDeExecucao(
expressao.objeto.simbolo.lexema,
Expand Down Expand Up @@ -1547,9 +1565,8 @@ export class InterpretadorBase implements InterpretadorInterface {
if (declaracao.tipo !== undefined && declaracao.tipo !== null) {
subtipo = declaracao.tipo;
}

const eTupla = declaracao.inicializador instanceof Tupla;

let eTupla = declaracao.tipo === tipoDeDadosDelegua.TUPLA;
this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, valorFinal, subtipo, eTupla);

return null;
Expand Down
2 changes: 1 addition & 1 deletion fontes/interpretador/pilha-escopos-execucao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export class PilhaEscoposExecucao implements PilhaEscoposExecucaoInterface {
valor: this.converterValor(tipo, valor),
tipo: tipo,
subtipo: undefined,
imutavel: imutavel,
imutavel,
};

if (subtipo !== undefined) {
Expand Down
4 changes: 4 additions & 0 deletions fontes/tipos-de-dados/delegua.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export default {
NÚMERO: 'número',
NULO: 'nulo',
OBJETO: 'objeto',
QUALQUER: 'qualquer',
REAL: 'real',
TEXTO: 'texto',
TUPLA: 'tupla',
VAZIO: 'vazio',
VETOR: 'vetor'
};
16 changes: 15 additions & 1 deletion testes/interpretador.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1627,7 +1627,7 @@ describe('Interpretador', () => {
);
});

it('Tupla - Dupla', async () => {
it('Tupla Dupla - Atribuição por indice', async () => {
const retornoLexador = lexador.mapear([
"var t = [(1, 2)]",
"t[0] = 3",
Expand All @@ -1640,6 +1640,20 @@ describe('Interpretador', () => {
'Não é possível modificar uma tupla. As tuplas são estruturas de dados imutáveis.'
);
});

it('Tupla Dupla - Primitiva adicionar()', async () => {
const retornoLexador = lexador.mapear([
"var t = [(1, 2)]",
"t.adicionar(3)"
], -1);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);

expect(retornoInterpretador.erros[0].erroInterno.mensagem).toBe(
'Tupla é imutável, seus elementos não podem ser alterados, adicionados ou removidos.'
);
});
})
});
});
Expand Down
Loading