Skip to content

Commit

Permalink
Corrigindo o comportamento de leia_inteiro para variáveis e constan…
Browse files Browse the repository at this point in the history
…tes à esquerda da atribuição.
  • Loading branch information
leonelsanchesdasilva committed Feb 27, 2024
1 parent b544577 commit 3cc86e7
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 38 deletions.
72 changes: 71 additions & 1 deletion fontes/interpretador/comum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AcessoMetodoOuPropriedade } from '@designliquido/delegua/construtos';
import { AcessoMetodoOuPropriedade, Binario, ConstanteOuVariavel, Construto, Literal, QualTipo, Unario, Variavel } from '@designliquido/delegua/construtos';
import { DeleguaModulo, MetodoPrimitiva, ObjetoDeleguaClasse } from '@designliquido/delegua/estruturas';
import { VariavelInterface } from '@designliquido/delegua/interfaces';
import { ErroEmTempoDeExecucao } from '@designliquido/delegua/excecoes';
Expand All @@ -8,6 +8,7 @@ import { inferirTipoVariavel } from './inferenciador';
import primitivasNumero from '../bibliotecas/primitivas-numero';
import primitivasTexto from '../bibliotecas/primitivas-texto';
import primitivasVetor from '../bibliotecas/primitivas-vetor';
import { LeiaMultiplo } from '@designliquido/delegua';

/**
* Executa um acesso a método, normalmente de um objeto de classe.
Expand Down Expand Up @@ -83,6 +84,75 @@ export async function visitarExpressaoAcessoMetodo(
);
}

export async function visitarExpressaoLeiaMultiplo(
interpretador: InterpretadorBase,
expressao: LeiaMultiplo
): Promise<any> {
let respostas = [];
// O argumento sempre vem preenchido aqui.
// Se for um literal, o literal contém o número de valores a serem lidos
// da entrada.
let valores = 0;
const argumento = expressao.argumento;
if (argumento instanceof Literal) {
valores = argumento.valor;
}

for (let i = 0; i < valores; i++) {
await interpretador.interfaceEntradaSaida.question('> ', (resposta: any) => {
respostas.push(resposta);
});
}

return Promise.resolve(respostas);
}

export async function visitarExpressaoQualTipo(
interpretador: InterpretadorBase,
expressao: QualTipo
): Promise<string> {
let qualTipo = expressao.valor;

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

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

return inferirTipoVariavel(qualTipo?.valores || qualTipo);
}

export async function avaliarArgumentosEscreva(
interpretador: InterpretadorBase,
argumentos: Construto[]
): Promise<string> {
let formatoTexto: string = '';

for (const argumento of argumentos) {
const resultadoAvaliacao = await interpretador.avaliar(argumento);
let valor = resultadoAvaliacao?.hasOwnProperty('valor') ? resultadoAvaliacao.valor : resultadoAvaliacao;
formatoTexto += `${interpretador.paraTexto(valor)},`;
}

formatoTexto = formatoTexto.slice(0, -1);

if (argumentos.length > 1) {
formatoTexto = `(${formatoTexto})`;
}

return formatoTexto;
}

/**
* Resolve todas as interpolações em um texto.
* @param {texto} textoOriginal O texto original com as variáveis interpoladas.
Expand Down
15 changes: 14 additions & 1 deletion fontes/interpretador/interpretador-potigol-com-depuracao.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { registrarBibliotecaGlobalPotigol } from '@designliquido/delegua/bibliotecas/dialetos/potigol/biblioteca-global';
import { AcessoMetodoOuPropriedade } from '@designliquido/delegua/construtos';
import { AcessoMetodoOuPropriedade, Construto, QualTipo } from '@designliquido/delegua/construtos';
import { InterpretadorComDepuracao } from '@designliquido/delegua/interpretador/interpretador-com-depuracao';

import * as comum from './comum';
import { LeiaMultiplo } from '@designliquido/delegua';

export class InterpretadorPotigolComDepuracao extends InterpretadorComDepuracao {
constructor(diretorioBase: string, funcaoDeRetorno: Function = null, funcaoDeRetornoMesmaLinha: Function = null) {
Expand All @@ -24,4 +25,16 @@ export class InterpretadorPotigolComDepuracao extends InterpretadorComDepuracao
async visitarExpressaoAcessoMetodo(expressao: AcessoMetodoOuPropriedade): Promise<any> {
return comum.visitarExpressaoAcessoMetodo(this, expressao);
}

async visitarExpressaoLeiaMultiplo(expressao: LeiaMultiplo): Promise<any> {
return comum.visitarExpressaoLeiaMultiplo(this, expressao);
}

async visitarExpressaoQualTipo(expressao: QualTipo): Promise<string> {
return comum.visitarExpressaoQualTipo(this, expressao);
}

async avaliarArgumentosEscreva(argumentos: Construto[]): Promise<string> {
return comum.avaliarArgumentosEscreva(this, argumentos);
}
}
41 changes: 7 additions & 34 deletions fontes/interpretador/interpretador-potigol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { InterpretadorInterfacePotigol } from '../interfaces/interpretador-inter
import { registrarBibliotecaGlobalPotigol } from '../bibliotecas/biblioteca-global';
import { inferirTipoVariavel } from './inferenciador';
import * as comum from './comum';
import { LeiaMultiplo } from '@designliquido/delegua';

/**
* Uma implementação do interpretador de Potigol.
Expand Down Expand Up @@ -67,43 +68,15 @@ export class InterpretadorPotigol extends InterpretadorBase implements Interpret
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);
}
async visitarExpressaoLeiaMultiplo(expressao: LeiaMultiplo): Promise<any> {
return comum.visitarExpressaoLeiaMultiplo(this, expressao);
}

return inferirTipoVariavel(qualTipo?.valores || qualTipo);
async visitarExpressaoQualTipo(expressao: QualTipo): Promise<string> {
return comum.visitarExpressaoQualTipo(this, expressao);
}

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)},`;
}

formatoTexto = formatoTexto.slice(0, -1);

if (argumentos.length > 1) {
formatoTexto = `(${formatoTexto})`;
}

return formatoTexto;
return comum.avaliarArgumentosEscreva(this, argumentos);
}
}
33 changes: 31 additions & 2 deletions testes/interpretador.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ describe('Interpretador', () => {
});
});

describe('Leia vetores', () => {
describe('Leia inteiros', () => {
it('Dado um leia_inteiros separador por virgula, escreva deve imprimir o valor lido', async () => {
const retornoLexador = lexador.mapear([
'escreva(leia_inteiros(","))'
Expand All @@ -299,7 +299,7 @@ describe('Interpretador', () => {
'escreva(leia_inteiros(3))'
], -1);

const respostas = [1, 2, 3];
const respostas = ["1", "2", "3"];
interpretador.interfaceEntradaSaida = {
question: (mensagem: string, callback: Function) => {
callback(respostas.shift());
Expand All @@ -315,6 +315,33 @@ describe('Interpretador', () => {
expect(retornoInterpretador.erros).toHaveLength(0);
});

it('leia_inteiros, lado esquerdo com constantes', async () => {
const saidas: string[] = [];
const retornoLexador = lexador.mapear([
'a, b = leia_inteiro',
'escreva "X = {a + b}"'
], -1);

const respostas = ["1", "2"];
interpretador.interfaceEntradaSaida = {
question: (mensagem: string, callback: Function) => {
callback(respostas.shift());
}
};

interpretador.funcaoDeRetorno = (saida: any) => {
saidas.push(saida);
};

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(retornoInterpretador.erros).toHaveLength(0);
expect(saidas).toHaveLength(1);
expect(saidas[0]).toBe('X = 3');
});
});

describe('Leia reais', () => {
it('Dado um leia_reais separador por virgula, escreva deve imprimir o valor lido', async () => {
const retornoLexador = lexador.mapear([
'escreva(leia_reais(","))'
Expand Down Expand Up @@ -356,7 +383,9 @@ describe('Interpretador', () => {
const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(retornoInterpretador.erros).toHaveLength(0);
});
});

describe('Leia textos', () => {
it('Dado um leia_textos separador por virgula, escreva deve imprimir o valor lido', async () => {
const retornoLexador = lexador.mapear([
'escreva(leia_textos(","))'
Expand Down

0 comments on commit 3cc86e7

Please sign in to comment.