Skip to content

Commit

Permalink
WIP: [potigol] - implementação qual_tipo (#528)
Browse files Browse the repository at this point in the history
  • Loading branch information
pablotdv authored Oct 29, 2023
1 parent 4615635 commit a7c6e40
Show file tree
Hide file tree
Showing 16 changed files with 197 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@
"runtimeArgs": [
"--inspect-brk",
"${workspaceRoot}/node_modules/jest/bin/jest.js",
"potigol/interpretador.test.ts",
"potigol/avaliador-sintatico.test.ts",
"--runInBand"
],
"skipFiles": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
FuncaoConstruto,
Isto,
Literal,
QualTipo,
Unario,
Variavel,
Vetor,
Expand Down Expand Up @@ -409,9 +410,21 @@ export class AvaliadorSintaticoPotigol extends AvaliadorSintaticoBase {
}
expressao = this.finalizarChamada(expressao);
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO)) {
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome do método após '.'.");
const variavelMetodo = new Variavel(expressao.hashArquivo, (expressao as any).simbolo);
expressao = new AcessoMetodo(this.hashArquivo, variavelMetodo, nome);
if (this.verificarTipoSimboloAtual(tiposDeSimbolos.QUAL_TIPO)) {
const identificador = this.simbolos[this.atual - 2];
const simbolo = this.simbolos[this.atual];
const valor = expressao ? expressao : identificador.lexema;
this.avancarEDevolverAnterior();
return new QualTipo(
this.hashArquivo,
simbolo,
valor
);
} else {
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome do método após '.'.");
const variavelMetodo = new Variavel(expressao.hashArquivo, (expressao as any).simbolo);
expressao = new AcessoMetodo(this.hashArquivo, variavelMetodo, nome);
}
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
const indice = this.expressao();
const simboloFechamento = this.consumir(
Expand Down Expand Up @@ -449,10 +462,14 @@ export class AvaliadorSintaticoPotigol extends AvaliadorSintaticoBase {

const argumentos: Construto[] = [];

this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARENTESE_ESQUERDO)

do {
argumentos.push(this.expressao());
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));

this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARENTESE_DIREITO)

return new Escreva(Number(simboloAtual.linha), simboloAtual.hashArquivo, argumentos);
}

Expand Down
1 change: 1 addition & 0 deletions fontes/construtos/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ export * from './tipo-de';
export * from './unario';
export * from './variavel';
export * from './vetor';
export * from './qual-tipo';
24 changes: 24 additions & 0 deletions fontes/construtos/qual-tipo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { SimboloInterface } from '../interfaces';
import { InterpretadorInterfacePotigol } from '../interfaces/interpretador-interface-potigol';
import { Construto } from './construto';


export class QualTipo implements Construto {
linha: number;
hashArquivo: number;
valor: any;

simbolo: SimboloInterface;

constructor(hashArquivo: number, simbolo: SimboloInterface, valor: any) {
this.linha = Number(simbolo.linha);
this.hashArquivo = hashArquivo;
this.valor = valor;
this.simbolo = simbolo;
}

async aceitar(visitante: InterpretadorInterfacePotigol): Promise<string> {
return Promise.resolve(visitante.visitarExpressaoQualTipo(this));
}
}

7 changes: 7 additions & 0 deletions fontes/interfaces/interpretador-interface-potigol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { QualTipo } from '../construtos';

import { VisitanteComumInterface } from './visitante-comum-interface';

export interface InterpretadorInterfacePotigol extends VisitanteComumInterface {
visitarExpressaoQualTipo(expressao: QualTipo): Promise<string>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
FimPara,
FormatacaoEscrita,
Literal,
QualTipo,
Super,
TipoDe,
Variavel,
Expand Down Expand Up @@ -98,6 +99,10 @@ export class InterpretadorEguaClassico implements InterpretadorInterface {
throw new Error('Método não implementado.');
}

visitarExpressaoQualTipo(expressao: QualTipo): Promise<any> {
throw new Error('Método não implementado.');
}

visitarExpressaoFalhar(expressao: any): Promise<any> {
throw new Error('Método não implementado.');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AcessoMetodo, Construto, ExpressaoRegular, FimPara, FormatacaoEscrita, Super, TipoDe, Variavel } from '../../../../construtos';
import { AcessoMetodo, Construto, ExpressaoRegular, FimPara, FormatacaoEscrita, QualTipo, Super, TipoDe, Variavel } from '../../../../construtos';
import {
Bloco,
Const,
Expand Down Expand Up @@ -75,15 +75,19 @@ export class ResolvedorEguaClassico implements ResolvedorInterface, Interpretado
this.classeAtual = TipoClasse.NENHUM;
this.cicloAtual = TipoClasse.NENHUM;
}

visitarExpressaoExpressaoRegular(expressao: ExpressaoRegular): Promise<any> {
throw new Error('Método não implementado.');
}

visitarExpressaoTipoDe(expressao: TipoDe): Promise<any> {
throw new Error('Método não implementado.');
}

visitarExpressaoQualTipo(expressao: QualTipo): Promise<any> {
throw new Error('Método não implementado.');
}

visitarExpressaoFalhar(expressao: any): Promise<any> {
throw new Error('Método não implementado.');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Atribuir, Construto, ExpressaoRegular, FimPara, FormatacaoEscrita, Literal, Super, TipoDe, Variavel } from '../../../construtos';
import { Atribuir, Construto, ExpressaoRegular, FimPara, FormatacaoEscrita, Literal, QualTipo, Super, TipoDe, Variavel } from '../../../construtos';
import {
Bloco,
Classe,
Expand Down Expand Up @@ -81,6 +81,10 @@ export class InterpretadorPortugolIpt implements InterpretadorInterface {
throw new Error('Método não implementado.');
}

visitarExpressaoQualTipo(expressao: QualTipo): Promise<any> {
throw new Error('Método não implementado.');
}

visitarExpressaoFalhar(expressao: any): Promise<any> {
throw new Error('Método não implementado.');
}
Expand Down
5 changes: 3 additions & 2 deletions fontes/interpretador/dialetos/potigol/inferenciador.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ export function inferirTipoVariavel(variavel: string | number | Array<any> | boo
case 'string':
return 'Texto';
case 'number':
return 'Número';
if (variavel.toString().indexOf('.') > -1) return 'Real';
return 'Inteiro';
case 'bigint':
return 'Longo';
case 'boolean':
return 'Lógico';
case 'undefined':
return 'Nulo';
case 'object':
if (Array.isArray(variavel)) return 'vetor';
if (Array.isArray(variavel)) return 'Lista';
if (variavel === null) return 'nulo';
if (variavel.constructor.name === 'DeleguaModulo') return 'módulo';
return 'Dicionário';
Expand Down
28 changes: 26 additions & 2 deletions fontes/interpretador/dialetos/potigol/interpretador-potigol.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { InterpretadorBase } from '../../interpretador-base';

import { registrarBibliotecaGlobalPotigol } from '../../../bibliotecas/dialetos/potigol/biblioteca-global';
import { AcessoMetodo } from '../../../construtos';
import { AcessoMetodo, Binario, ConstanteOuVariavel, Literal, QualTipo, Unario, Variavel } from '../../../construtos';

import * as comum from './comum';
import { ObjetoPadrao } from '../../../estruturas';
import { inferirTipoVariavel } from './inferenciador';
import { InterpretadorInterfacePotigol } from '../../../interfaces/interpretador-interface-potigol';

/**
* Uma implementação do interpretador de Potigol.
*/
export class InterpretadorPotigol extends InterpretadorBase {
export class InterpretadorPotigol extends InterpretadorBase implements InterpretadorInterfacePotigol {
constructor(
diretorioBase: string,
performance = false,
Expand Down Expand Up @@ -55,4 +57,26 @@ export class InterpretadorPotigol extends InterpretadorBase {
async visitarExpressaoAcessoMetodo(expressao: AcessoMetodo): Promise<any> {
return comum.visitarExpressaoAcessoMetodo(this, expressao);
}

async visitarExpressaoQualTipo(expressao: QualTipo): Promise<string> {
let qualTipo = expressao.valor;

if (expressao?.valor instanceof ConstanteOuVariavel) {
const nome = expressao?.valor.simbolo.lexema
qualTipo = this.pilhaEscoposExecucao.topoDaPilha().ambiente.valores[nome].valor
}

if (
qualTipo instanceof Binario ||
qualTipo instanceof Literal ||
qualTipo instanceof QualTipo ||
qualTipo instanceof Unario ||
qualTipo instanceof Variavel
) {
qualTipo = await this.avaliar(qualTipo);
return qualTipo.tipo || inferirTipoVariavel(qualTipo);
}

return inferirTipoVariavel(qualTipo?.valores || qualTipo);
}
}
5 changes: 5 additions & 0 deletions fontes/interpretador/interpretador-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
FormatacaoEscrita,
Literal,
Logico,
QualTipo,
Super,
TipoDe,
Unario,
Expand Down Expand Up @@ -171,6 +172,10 @@ export class InterpretadorBase implements InterpretadorInterface {
return inferirTipoVariavel(tipoDe?.valores || tipoDe);
}

async visitarExpressaoQualTipo(expressao: QualTipo): Promise<string> {
throw new Error('Método não implementado.');
}

visitarExpressaoFalhar(expressao: Falhar): Promise<any> {
throw new ErroEmTempoDeExecucao(expressao.simbolo, expressao.explicacao, expressao.linha);
}
Expand Down
1 change: 1 addition & 0 deletions fontes/lexador/dialetos/palavras-reservadas/potigol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ export const palavrasReservadas = {
tipo: tiposDeSimbolos.TIPO,
var: tiposDeSimbolos.VARIAVEL,
verdadeiro: tiposDeSimbolos.VERDADEIRO,
qual_tipo: tiposDeSimbolos.QUAL_TIPO,
};
1 change: 1 addition & 0 deletions fontes/tipos-de-simbolos/potigol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ export default {
VERDADEIRO: 'VERDADEIRO',
VARIAVEL: 'VARIAVEL',
VIRGULA: 'VIRGULA',
QUAL_TIPO: 'QUAL_TIPO',
};
16 changes: 16 additions & 0 deletions testes/interpretador.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,22 @@ describe('Interpretador', () => {
expect(retornoInterpretador.erros).toHaveLength(0);
});

it('Tipo de número', async () => {
const retornoLexador = lexador.mapear([
"escreva(tipo de 123)",
], -1);

interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual("número");
};

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

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

expect(retornoInterpretador.erros).toHaveLength(0);
});

it('Ordem lexicográfica de textos', async () => {
const retornoLexador = lexador.mapear([
"escreva('batata' > 'arroz')",
Expand Down
2 changes: 1 addition & 1 deletion testes/potigol/avaliador-sintatico.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ describe('Avaliador sintático', () => {
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(1);
expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(2);
});

it('Sucesso - Mod e Div', () => {
Expand Down
81 changes: 74 additions & 7 deletions testes/potigol/interpretador.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,71 @@ describe('Interpretador', () => {
});
});

describe('Declaração de lista', () => {
it('Dado em vetor, escreva deve imprirmir o vetor', async () => {
describe('qual_tipo', () => {
it('Dado um inteiro, escreva qual_tipo deve retornar Inteiro', async () => {
const retornoLexador = lexador.mapear([
'a = [3, 4]',
'escreva (a)'
'a = 3',
'escreva(a.qual_tipo)'
], -1);

// Substitua a função de saída
interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('[3, 4]');
expect(saida).toEqual("Inteiro");
};

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(retornoInterpretador.erros).toHaveLength(0);
});

it.skip('WIP: Dado em vetor, escreva qual_tipo deve imprirmir Lista', async () => {

it('Dado um inteiro, escreva qual_tipo deve retornar Inteiro 2', async () => {
const retornoLexador = lexador.mapear([
'escreva(3.qual_tipo)'
], -1);

// Substitua a função de saída
interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual("Inteiro");
};

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(retornoInterpretador.erros).toHaveLength(0);
});

it('Dado um real, escreva qual_tipo deve retornar Real', async () => {
const retornoLexador = lexador.mapear([
'a = 3.1',
'escreva(a.qual_tipo)'
], -1);

// Substitua a função de saída
interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual("Real");
};

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(retornoInterpretador.erros).toHaveLength(0);
});

it('Dado uma variável, escreva qual_tipo deve atribuir Inteiro', async () => {
const retornoLexador = lexador.mapear([
'a = 3.qual_tipo',
'escreva(a)'
], -1);

// Substitua a função de saída
interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual("Inteiro");
};

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(retornoInterpretador.erros).toHaveLength(0);
});

it('Dado um vetor, escreva qual_tipo deve imprirmir Lista', async () => {
const retornoLexador = lexador.mapear([
'a = [3, 4]',
'escreva (a.qual_tipo)'
Expand All @@ -77,6 +124,26 @@ describe('Interpretador', () => {
const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(retornoInterpretador.erros).toHaveLength(0);
});
});

describe('Declaração de lista', () => {
it('Dado um vetor, escreva deve imprirmir o vetor', async () => {
const retornoLexador = lexador.mapear([
'a = [3, 4]',
'escreva (a)'
], -1);

// Substitua a função de saída
interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('[3, 4]');
};

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(retornoInterpretador.erros).toHaveLength(0);
});


})
});
});

0 comments on commit a7c6e40

Please sign in to comment.