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

Refatoração de funções paraTexto e toString quanto a estruturas #647

Merged
merged 3 commits into from
Feb 16, 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
2 changes: 1 addition & 1 deletion fontes/construtos/unario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class Unario<TTipoSimbolo extends string = string> implements Construto {
hashArquivo: number;

operador: SimboloInterface<TTipoSimbolo>;
operando: Construto;
operando: any;
incidenciaOperador: 'ANTES' | 'DEPOIS';

constructor(
Expand Down
2 changes: 1 addition & 1 deletion fontes/estruturas/chamavel.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ArgumentoInterface } from '../interpretador/argumento-interface';

export class Chamavel {
export abstract class Chamavel {
valorAridade: number;

aridade(): number {
Expand Down
21 changes: 17 additions & 4 deletions fontes/estruturas/classe-padrao.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
import { Chamavel } from './chamavel';
import { ObjetoPadrao } from './objeto-padrao';

/**
* Classe de importação de classes de bibliotecas do JavaScript.
*/
export class ClassePadrao extends Chamavel {
nome: string;
funcaoDeClasse: any;
// TypeScript não tem exatamente um tipo de construtor para classe.
// O tipo abaixo é o mais próximo que existe desse tipo.
funcaoDeClasse: { new(...args: any[]): any; };

constructor(nome: string, funcaoDeClasse: any) {
constructor(nome: string, funcaoDeClasse: { new(...args: any[]): any; }) {
super();
this.nome = nome;
this.funcaoDeClasse = funcaoDeClasse;
}

/**
* Método utilizado pelo VSCode para inspecionar esta classe em depuração.
* @returns {string} A representação da classe como texto.
*/
toString(): string {
return `<classe-padrão ${this.nome}>`;
}

/**
* Método utilizado por Delégua para representar esta classe quando impressa.
* @returns {string} A representação da classe como texto.
*/
paraTexto(): string {
return `<classe-padrão ${this.nome}>`;
}
Expand All @@ -25,7 +38,7 @@ export class ClassePadrao extends Chamavel {
* @param simbolo
*/
chamar(argumentos: any[], simbolo: any): any {
const novoObjeto: any = new this.funcaoDeClasse();
const novoObjeto: any = new this.funcaoDeClasse(argumentos);
return novoObjeto;
}
}
8 changes: 8 additions & 0 deletions fontes/estruturas/delegua-classe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ export class DeleguaClasse extends Chamavel {
return undefined;
}

/**
* Método utilizado por Delégua para representar esta classe quando impressa.
* @returns {string} A representação da classe como texto.
*/
paraTexto(): string {
let texto = `<classe ${this.simboloOriginal.lexema}`;
for (let propriedade of this.propriedades) {
Expand All @@ -76,6 +80,10 @@ export class DeleguaClasse extends Chamavel {
return texto;
}

/**
* Método utilizado pelo VSCode para inspecionar esta classe em depuração.
* @returns {string} A representação da classe como texto.
*/
toString(): string {
return this.paraTexto();
}
Expand Down
15 changes: 15 additions & 0 deletions fontes/estruturas/delegua-funcao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ export class DeleguaFuncao extends Chamavel {
return this.declaracao?.parametros?.length || 0;
}

/**
* Método utilizado por Delégua para representar esta função quando impressa.
* @returns {string} A representação da função como texto.
*/
paraTexto(): string {
if (this.nome === null) return '<função>';
let resultado = `<função ${this.nome}`;
Expand All @@ -47,6 +51,7 @@ export class DeleguaFuncao extends Chamavel {
parametro.tipoDado && parametro.tipoDado.tipo ? `: ${parametro.tipoDado.tipo}, ` : ', '
}`;
}

if (this.declaracao.parametros.length > 0) {
parametros = `argumentos=<${parametros.slice(0, -2)}>`;
}
Expand All @@ -60,13 +65,23 @@ export class DeleguaFuncao extends Chamavel {
if (parametros) {
resultado += ` ${parametros}`;
}

if (retorno) {
resultado += ` ${retorno}`;
}

resultado += '>';
return resultado;
}

/**
* Método utilizado pelo VSCode para inspecionar esta função em depuração.
* @returns {string} A representação da função como texto.
*/
toString(): string {
return this.paraTexto();
}

async chamar(visitante: VisitanteComumInterface, argumentos: Array<ArgumentoInterface>): Promise<any> {
const ambiente = new EspacoVariaveis();
const parametros = this.declaracao.parametros || [];
Expand Down
12 changes: 12 additions & 0 deletions fontes/estruturas/funcao-padrao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,19 @@ export class FuncaoPadrao extends Chamavel {
return await this.funcao.apply(this, argumentos);
}

/**
* Método utilizado por Delégua para inspecionar esta função em depuração.
* @returns {string} A representação da função como texto.
*/
paraTexto(): string {
return '<função>';
}

/**
* Método utilizado pelo VSCode para representar esta função quando impressa.
* @returns {string} A representação da classe como texto.
*/
toString(): string {
return '<função>';
}
}
18 changes: 17 additions & 1 deletion fontes/estruturas/metodo-primitiva.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class MetodoPrimitiva extends Chamavel {
primitiva: any;
metodo: Function;

constructor(primitiva: any, metodo: Function, requerInterpretador: boolean = false) {
constructor(primitiva: any, metodo: Function) {
super();
this.primitiva = primitiva;
this.metodo = metodo;
Expand All @@ -25,4 +25,20 @@ export class MetodoPrimitiva extends Chamavel {
async chamar(interpretador: VisitanteComumInterface, argumentos: any[] = []): Promise<any> {
return await this.metodo(interpretador, this.primitiva, ...argumentos);
}

/**
* Método utilizado por Delégua para inspecionar este método em depuração.
* @returns {string} A representação do método como texto.
*/
paraTexto(): string {
return `<método nome=${this.metodo} primitiva=${this.primitiva}>`;
}

/**
* Método utilizado pelo VSCode para representar este método quando impressa.
* @returns {string} A representação do método como texto.
*/
toString(): string {
return this.paraTexto();
}
}
14 changes: 13 additions & 1 deletion fontes/estruturas/modulo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,19 @@ export class DeleguaModulo {
this.componentes = {};
}

/**
* Método utilizado por Delégua para inspecionar este módulo em depuração.
* @returns {string} A representação da função como texto.
*/
paraTexto(): string {
return this.nome ? `<módulo ${this.nome}>` : '<módulo>';
}

/**
* Método utilizado pelo VSCode para representar este módulo quando impressa.
* @returns {string} A representação do módulo como texto.
*/
toString(): string {
return this.nome ? `<modulo ${this.nome}>` : '<modulo>';
return this.paraTexto();
}
}
12 changes: 12 additions & 0 deletions fontes/estruturas/objeto-delegua-classe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,19 @@ export class ObjetoDeleguaClasse {
this.propriedades[simbolo.lexema] = valor;
}

/**
* Método utilizado por Delégua para inspecionar este objeto em depuração.
* @returns {string} A representação do objeto como texto.
*/
paraTexto(): string {
return '<Objeto ' + this.classe.simboloOriginal.lexema + '>';
}

/**
* Método utilizado pelo VSCode para representar este objeto quando impresso.
* @returns {string} A representação do objeto como texto.
*/
toString(): string {
return this.paraTexto();
}
}
14 changes: 13 additions & 1 deletion fontes/estruturas/objeto-padrao.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Um objeto padrão é uma instância de uma Classe Padrão (JavaScript).
* TODO: Marcado para depreciação na próxima versão.
* TODO: Marcado para depreciação em futuras versões.
*/
export class ObjetoPadrao {
classePadrao: string;
Expand All @@ -9,6 +9,10 @@ export class ObjetoPadrao {
this.classePadrao = classePadrao;
}

/**
* Método utilizado por Delégua para inspecionar este objeto em depuração.
* @returns {string} A representação do objeto como texto.
*/
paraTexto(): string {
let retornoTexto = `<objeto-padrão da classe ${this.classePadrao}>\n`;
for (const [nome, valor] of Object.entries(this)) {
Expand All @@ -17,4 +21,12 @@ export class ObjetoPadrao {
retornoTexto += `</objeto-padrão>`;
return retornoTexto;
}

/**
* Método utilizado pelo VSCode para representar este objeto quando impresso.
* @returns {string} A representação do objeto como texto.
*/
toString(): string {
return this.paraTexto();
}
}
23 changes: 22 additions & 1 deletion fontes/interpretador/interpretador-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1610,9 +1610,30 @@ export class InterpretadorBase implements InterpretadorInterface {
return formato.format(objeto);
}

if (Array.isArray(objeto)) return objeto;
if (Array.isArray(objeto)) {
let retornoVetor: string = '[';
for (let elemento of objeto) {
retornoVetor += `${this.paraTexto(elemento)},`;
}

retornoVetor = retornoVetor.slice(0, -1);
retornoVetor += ']';
return retornoVetor;
}

if (objeto.valor instanceof ObjetoPadrao) return objeto.valor.paraTexto();
if (objeto instanceof ObjetoDeleguaClasse || objeto instanceof DeleguaFuncao) return objeto.paraTexto();
switch (objeto.constructor.name) {
case 'Object':
if ('tipo' in objeto) {
switch (objeto.tipo) {
case 'dicionário':
return JSON.stringify(objeto.valor);
default:
return objeto.valor.paraTexto();
}
}
}
if (typeof objeto === tipoDeDadosPrimitivos.OBJETO) return JSON.stringify(objeto);

return objeto.toString();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AvaliadorSintatico } from "../fontes/avaliador-sintatico";
import { InterpretadorComDepuracao } from "../fontes/interpretador";
import { Lexador } from "../fontes/lexador";
import { AvaliadorSintatico } from "../../fontes/avaliador-sintatico";
import { InterpretadorComDepuracao } from "../../fontes/interpretador";
import { Lexador } from "../../fontes/lexador";

describe('Interpretador com Depuração', () => {
let lexador: Lexador;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AvaliadorSintatico } from '../fontes/avaliador-sintatico';
import { InterpretadorBase } from '../fontes/interpretador';
import { Lexador } from '../fontes/lexador';
import { AvaliadorSintatico } from '../../fontes/avaliador-sintatico';
import { InterpretadorBase } from '../../fontes/interpretador';
import { Lexador } from '../../fontes/lexador';

describe('Interpretador', () => {
describe('interpretar()', () => {
Expand Down Expand Up @@ -271,6 +271,28 @@ describe('Interpretador', () => {

expect(_saida).toBe('<função retorneAlgo>');
});

it('Escrita de vetor com outros objetos dentro', async () => {
let saidas: string[] = [];
const retornoLexador = lexador.mapear([
`funcao retorne() {`,
` retorna ''`,
`}`,
`const dic = {`,
` "chave": 10`,
`}`,
`escreva([dic])`,
`escreva([retorne])"`,
], -1);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

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

await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
expect(saidas).toBeTruthy();
});
});

describe('Escolha - Caso', () => {
Expand Down Expand Up @@ -1105,7 +1127,7 @@ describe('Interpretador', () => {
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

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

const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
Expand All @@ -1127,7 +1149,7 @@ describe('Interpretador', () => {
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('Olá,mundo');
expect(saida).toEqual('[Olá,mundo]');
};

const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
Expand All @@ -1146,7 +1168,7 @@ describe('Interpretador', () => {
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

interpretador.funcaoDeRetorno = (saida: any) => {
expect(saida).toEqual('maçã,banana,morango');
expect(saida).toEqual('[maçã,banana,morango]');
};

const retornoInterpretador = await interpretador.interpretar(retornoAvaliadorSintatico.declaracoes);
Expand Down Expand Up @@ -1359,8 +1381,8 @@ describe('Interpretador', () => {

expect(retornoInterpretador.erros).toHaveLength(0);
expect(saidas).toHaveLength(2);
expect(saidas[0]).toEqual('a,b,c');
expect(saidas[1]).toEqual('1,2,3');
expect(saidas[0]).toEqual('[a,b,c]');
expect(saidas[1]).toEqual('[1,2,3]');
});
});

Expand All @@ -1379,7 +1401,7 @@ describe('Interpretador', () => {
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

interpretador.funcaoDeRetorno = (saida: string) => {
expect(saida).toEqual('12,8,4,2');
expect(saida).toEqual('[12,8,4,2]');
};

const retornoInterpretador = await interpretador.interpretar(
Expand Down
Loading