Skip to content

Commit

Permalink
[potigol] - implementação leia multiplo (#548)
Browse files Browse the repository at this point in the history
* [potigol] - implementação leia multiplo
* Removendo import incorreto.

---------

Co-authored-by: Leonel Sanches da Silva <[email protected]>
  • Loading branch information
pablotdv and leonelsanchesdasilva authored Nov 8, 2023
1 parent fd38bc4 commit b5bc6c4
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -372,19 +372,16 @@ export class AvaliadorSintaticoPotigol extends AvaliadorSintaticoBase {
tiposDeSimbolos.PARENTESE_ESQUERDO,
`Esperado parêntese esquerdo após ${simboloLeiaDefinido.lexema}.`
);
if (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.INTEIRO, tiposDeSimbolos.REAL)) {
throw this.erro(
this.simbolos[this.atual],
`Esperado número de argumentos como inteiro ou real em ${simboloLeiaDefinido.lexema}`
);
}
let numeroArgumentosLeia = this.simbolos[this.atual - 1];

const argumento = this.expressao();

this.consumir(
tiposDeSimbolos.PARENTESE_DIREITO,
`Esperado parêntese direito após número de parâmetros em chamada de ${simboloLeiaDefinido.lexema}.`
);
const leiaDefinido = new LeiaMultiplo(simboloLeiaDefinido, []);
leiaDefinido.numeroArgumentosEsperados = parseInt(numeroArgumentosLeia.literal);

const leiaDefinido = new LeiaMultiplo(simboloLeiaDefinido, argumento);

return leiaDefinido;
default:
const simboloIdentificador: SimboloInterface = this.avancarEDevolverAnterior();
Expand Down Expand Up @@ -803,8 +800,7 @@ export class AvaliadorSintaticoPotigol extends AvaliadorSintaticoBase {
if (inicializador instanceof Leia && identificadores.length > 1) {
inicializador = new LeiaMultiplo(
inicializador.simbolo,
inicializador.argumentos,
inicializador.numeroArgumentosEsperados
inicializador.argumentos[0],
);
}

Expand All @@ -821,18 +817,8 @@ export class AvaliadorSintaticoPotigol extends AvaliadorSintaticoBase {
);
}

// `leia_inteiros`, `leia_reais` e `leia_textos` pedem um inteiro como argumento,
// que pode ser usado para verificar se a expressão faz sentido ou não aqui.
const inicializadorLeia = <LeiaMultiplo>inicializadores[0];
if (inicializadorLeia.numeroArgumentosEsperados > 0) {
if (identificadores.length !== inicializadorLeia.numeroArgumentosEsperados) {
throw this.erro(
this.simbolos[this.atual],
`Quantidade de identificadores à esquerda do igual é diferente da quantidade de valores passada por parâmetro à direita em ${inicializadorLeia.simbolo.lexema}.`
);
}
}


let tipoConversao: TiposDadosInterface;
switch (inicializadorLeia.simbolo.tipo) {
case tiposDeSimbolos.LEIA_INTEIROS:
Expand Down
10 changes: 4 additions & 6 deletions fontes/declaracoes/leia-multiplo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,14 @@ import { Declaracao } from './declaracao';
export class LeiaMultiplo extends Declaracao {
simbolo: SimboloInterface;
id: string;
argumentos: Construto[];
tipo?: string;
numeroArgumentosEsperados?: number;

constructor(simbolo: SimboloInterface, argumentos: Construto[], numeroArgumentosEsperados?: number) {
argumento: Construto;

constructor(simbolo: SimboloInterface, argumento: Construto) {
super(simbolo.linha, simbolo.hashArquivo);
this.simbolo = simbolo;
this.id = uuidv4();
this.argumentos = argumentos;
this.numeroArgumentosEsperados = numeroArgumentosEsperados;
this.argumento = argumento;
}

async aceitar(visitante: VisitanteComumInterface): Promise<any> {
Expand Down
32 changes: 23 additions & 9 deletions fontes/interpretador/interpretador-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,16 +219,30 @@ export class InterpretadorBase implements InterpretadorInterface {
* @returns Promise com o resultado da leitura.
*/
async visitarExpressaoLeiaMultiplo(expressao: LeiaMultiplo): Promise<any> {
const mensagem = expressao.argumentos && expressao.argumentos[0] ? expressao.argumentos[0].valor : '> ';
return new Promise((resolucao) =>
this.interfaceEntradaSaida.question(mensagem, (resposta: any) => {
resolucao(
String(resposta)
.split(/(\s+)/)
.filter((r) => !/(\s+)/.test(r))
const mensagem = '> ';
if (expressao.argumento instanceof Literal) {
let valor = expressao.argumento.valor;
if (typeof valor === 'string') {
return new Promise((resolucao) =>
this.interfaceEntradaSaida.question(mensagem, (resposta: any) => {
resolucao(
String(resposta)
.split(valor)
.filter((r) => !/(\s+)/.test(r))
);
})
);
})
);
}

let respostas = [];
for (let i = 0; i < valor; i++) {
this.interfaceEntradaSaida.question(mensagem, (resposta: any) => {
respostas.push(resposta);
})
}
return Promise.resolve(respostas);
}
return Promise.resolve();
}

/**
Expand Down
10 changes: 0 additions & 10 deletions testes/potigol/avaliador-sintatico.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,16 +428,6 @@ describe('Avaliador sintático', () => {
})
);
});

it('Sucesso - Declaração de múltiplas constantes, lado direito usando `leia_inteiros` com número errado de parâmetros', () => {
const retornoLexador = lexador.mapear(['a, b, c = leia_inteiros(1)'], -1);
expect(() => avaliadorSintatico.analisar(retornoLexador, -1)).toThrow(ErroAvaliadorSintatico);
expect(() => avaliadorSintatico.analisar(retornoLexador, -1)).toThrow(
expect.objectContaining({
message: "Quantidade de identificadores à esquerda do igual é diferente da quantidade de valores passada por parâmetro à direita em leia_inteiros.",
})
);
});
});
});
});
128 changes: 127 additions & 1 deletion testes/potigol/interpretador.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,134 @@ describe('Interpretador', () => {
const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(retornoInterpretador.erros).toHaveLength(0);
});
})

describe('Leia Multiplo', () => {
it('Dado um leia_inteiros separador por virgula, escreva deve imprimir o valor lido', async () => {
const retornoLexador = lexador.mapear([
'escreva(leia_inteiros(","))'
], -1);

})
const resposta = '1,2,3';
interpretador.interfaceEntradaSaida = {
question: (mensagem: string, callback: Function) => {
callback(resposta);
}
};

interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('[1, 2, 3]');
};

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

it('Dado um leia_inteiros, escreva deve imprimir o valor lido', async () => {
const retornoLexador = lexador.mapear([
'escreva(leia_inteiros(3))'
], -1);

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

interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('[1, 2, 3]');
};

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

it('Dado um leia_reais separador por virgula, escreva deve imprimir o valor lido', async () => {
const retornoLexador = lexador.mapear([
'escreva(leia_reais(","))'
], -1);

const resposta = '1,2,3';
interpretador.interfaceEntradaSaida = {
question: (mensagem: string, callback: Function) => {
callback(resposta);
}
};

interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('[1, 2, 3]');
};

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

it('Dado um leia_reais, escreva deve imprimir o valor lido', async () => {
const retornoLexador = lexador.mapear([
'escreva(leia_reais(3))'
], -1);

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

interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('[1, 2, 3]');
};

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

it('Dado um leia_textos separador por virgula, escreva deve imprimir o valor lido', async () => {
const retornoLexador = lexador.mapear([
'escreva(leia_textos(","))'
], -1);

const resposta = 'a,b,c';
interpretador.interfaceEntradaSaida = {
question: (mensagem: string, callback: Function) => {
callback(resposta);
}
};

interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('[a, b, c]');
};

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

it('Dado um leia_textos, escreva deve imprimir o valor lido', async () => {
const retornoLexador = lexador.mapear([
'escreva(leia_textos(3))'
], -1);

const respostas = ['a', 'b', 'c'];
interpretador.interfaceEntradaSaida = {
question: (mensagem: string, callback: Function) => {
callback(respostas.shift());
}
};

interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('[a, b, c]');
};

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

0 comments on commit b5bc6c4

Please sign in to comment.