Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/principal' into biblioteca-internet
Browse files Browse the repository at this point in the history
  • Loading branch information
leonelsanchesdasilva committed May 2, 2024
2 parents ed81702 + 93c8c1c commit 82ab368
Show file tree
Hide file tree
Showing 17 changed files with 582 additions and 133 deletions.
240 changes: 145 additions & 95 deletions fontes/avaliador-sintatico/avaliador-sintatico-portugol-studio.ts

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions fontes/bibliotecas/calendario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ export async function hora_atual(formato_12h: boolean): Promise<number> {
const data = new Date();
if (!formato_12h) {
return data.getHours();
} else {
let hora = data.getHours() % 12;
if (hora === 0) {
hora = 12;
}
return hora;
}

let hora = data.getHours() % 12;
if (hora === 0) {
hora = 12;
}
return hora;
}

export async function minuto_atual(): Promise<number> {
Expand Down Expand Up @@ -73,9 +73,9 @@ export async function dia_semana_completo(
}

return dia;
} else {
throw new Error(`'${numero_dia}' não corresponde a um dia da semana válido.`);
}
}

throw new Error(`'${numero_dia}' não corresponde a um dia da semana válido.`);
}

export async function dia_semana_curto(numero_dia: number, caixa_alta: boolean, caixa_baixa: boolean): Promise<string> {
Expand All @@ -91,9 +91,9 @@ export async function dia_semana_curto(numero_dia: number, caixa_alta: boolean,
}

return dia;
} else {
throw new Error(`'${numero_dia}' não corresponde a um dia da semana válido.`);
}
}

throw new Error(`'${numero_dia}' não corresponde a um dia da semana válido.`);
}

export async function dia_semana_abreviado(
Expand All @@ -113,7 +113,7 @@ export async function dia_semana_abreviado(
}

return dia;
} else {
throw new Error(`'${numero_dia}' não corresponde a um dia da semana válido.`);
}

throw new Error(`'${numero_dia}' não corresponde a um dia da semana válido.`);
}
2 changes: 2 additions & 0 deletions fontes/construtos/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './limpa';
export * from './matriz';
17 changes: 17 additions & 0 deletions fontes/construtos/limpa.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Construto } from "@designliquido/delegua";

import { VisitantePortugolStudioInterface } from "../interfaces";

export class Limpa implements Construto {
linha: number;
hashArquivo: number;

constructor(hashArquivo: number, linha: number) {
this.hashArquivo = hashArquivo;
this.linha = linha;
}

async aceitar(visitante: VisitantePortugolStudioInterface): Promise<any> {
return await visitante.visitarExpressaoLimpa(this);
}
}
22 changes: 22 additions & 0 deletions fontes/construtos/matriz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { VisitanteComumInterface } from "@designliquido/delegua";
import { Construto } from "@designliquido/delegua/construtos";

import { InterpretadorPortugolStudio } from "../interpretador";

export class Matriz implements Construto {
linha: number;
hashArquivo: number;
dimensoes: number[];
valores: any;

constructor(hashArquivo: number, linha: number, dimensoes: number[], valores: any) {
this.linha = linha;
this.hashArquivo = hashArquivo;
this.dimensoes = dimensoes;
this.valores = valores;
}

async aceitar(visitante: VisitanteComumInterface): Promise<any> {
return await (visitante as InterpretadorPortugolStudio).visitarExpressaoMatriz(this);
}
}
19 changes: 19 additions & 0 deletions fontes/formatador/formatador-portugol-studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
Atribuir,
Binario,
Chamada,
Comentario,
Construto,
DefinirValor,
Dicionario,
Expand Down Expand Up @@ -77,6 +78,22 @@ export class FormatadorPortugolStudio implements VisitanteComumInterface {
this.deveIndentar = true;
}

visitarDeclaracaoComentario(declaracao: Comentario): void | Promise<any> {
if (declaracao.multilinha) {
this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}/`;

for (let linhaConteudo of (declaracao.conteudo as string[])) {
this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}* ${linhaConteudo.replace(/\s+/g, " ")}${this.quebraLinha}`;
}

this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)} */${this.quebraLinha}`;
} else {
this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}// `;
this.codigoFormatado += (declaracao.conteudo as string).replace(/\s+/g, " ");
this.codigoFormatado += `${this.quebraLinha}`;
}
}

visitarDeclaracaoTendoComo(declaracao: TendoComo): void | Promise<any> {
throw new Error('Método não implementado.');
}
Expand All @@ -92,9 +109,11 @@ export class FormatadorPortugolStudio implements VisitanteComumInterface {
visitarExpressaoTupla(expressao: Tupla): Promise<any> {
throw new Error('Método não implementado');
}

visitarDeclaracaoClasse(declaracao: Classe) {
throw new Error('Método não implementado');
}

visitarDeclaracaoConst(declaracao: Const): any {
this.codigoFormatado += `${' '.repeat(this.indentacaoAtual)}const ${declaracao.tipo} ${
declaracao.simbolo.lexema
Expand Down
1 change: 1 addition & 0 deletions fontes/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './visitante-portugol-studio-interface';
7 changes: 7 additions & 0 deletions fontes/interfaces/visitante-portugol-studio-interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { VisitanteComumInterface } from "@designliquido/delegua";

import { Limpa } from "../construtos/limpa";

export interface VisitantePortugolStudioInterface extends VisitanteComumInterface {
visitarExpressaoLimpa(expressao: Limpa): void | Promise<any>;
}
73 changes: 72 additions & 1 deletion fontes/interpretador/comum.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
import { Variavel } from '@designliquido/delegua/construtos';
import { Construto, Variavel } from '@designliquido/delegua/construtos';
import { Expressao, Importar, Leia } from '@designliquido/delegua/declaracoes';
import { PilhaEscoposExecucaoInterface } from '@designliquido/delegua/interfaces/pilha-escopos-execucao-interface';
import { DeleguaModulo, FuncaoPadrao } from '@designliquido/delegua/estruturas';
import { ErroEmTempoDeExecucao } from '@designliquido/delegua/excecoes';
import { InterpretadorBase } from '@designliquido/delegua';

import { Matriz } from '../construtos/matriz';

import * as calendario from '../bibliotecas/calendario';
import * as matematica from '../bibliotecas/matematica';
import * as texto from '../bibliotecas/texto';
import * as util from '../bibliotecas/util';

function carregarBibliotecaCalendario(): DeleguaModulo {
const metodos: { [nome: string]: FuncaoPadrao } = {
dia_mes_atual: new FuncaoPadrao(0, calendario.dia_mes_atual),
dia_semana_atual: new FuncaoPadrao(0, calendario.dia_semana_atual),
mes_atual: new FuncaoPadrao(0, calendario.mes_atual),
ano_atual: new FuncaoPadrao(0, calendario.ano_atual),
hora_atual: new FuncaoPadrao(0, calendario.hora_atual),
minuto_atual: new FuncaoPadrao(0, calendario.minuto_atual),
segundo_atual: new FuncaoPadrao(0, calendario.segundo_atual),
milisegundo_atual: new FuncaoPadrao(0, calendario.milisegundo_atual),
dia_semana_completo: new FuncaoPadrao(0, calendario.dia_semana_completo),
dia_semana_curto: new FuncaoPadrao(0, calendario.dia_semana_completo),
};

const objetoCalendario = new DeleguaModulo('Calendario');
objetoCalendario.componentes = metodos;
return objetoCalendario;
}

function carregarBibliotecaMatematica(): DeleguaModulo {
const metodos: { [nome: string]: FuncaoPadrao } = {
potencia: new FuncaoPadrao(2, matematica.potencia),
Expand Down Expand Up @@ -60,8 +83,29 @@ function carregarBibliotecaUtil(): DeleguaModulo {
return objetoUtil;
}

/**
* Avaliação de argumentos para `escreva`. Diferentemente de outros dialetos, aqui não ocorre `trimEnd`, já que `\n`
* É significativo para Portugol Studio.
* @param interpretador A instância do interpretador.
* @param argumentos Os argumentos.
* @returns {string} O texto formatado.
*/
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)} `;
}

return formatoTexto;
}

export async function visitarExpressaoImportarComum(expressao: Importar): Promise<any> {
switch (expressao.caminho.valor) {
case 'Calendario':
return carregarBibliotecaCalendario();
case 'Matematica':
return carregarBibliotecaMatematica();
case 'Texto':
Expand Down Expand Up @@ -101,3 +145,30 @@ export async function visitarExpressaoLeiaComum(
pilhaEscoposExecucao.definirVariavel(simbolo.lexema, valorLido);
}
}

export async function visitarExpressaoMatrizComum(
interpretador: InterpretadorBase,
expressao: Matriz
): Promise<any> {
return await resolverValoresMatriz(interpretador, expressao.valores);
}

/**
* Função recursiva que visita todos os valores de uma matriz.
* @param interpretador A instância do interpretador.
* @param valores A matriz de valores das dimensões ainda não resolvidas.
*/
async function resolverValoresMatriz(interpretador: InterpretadorBase, valores: any[]) {
const valoresResolvidos = [];
if (valores && valores.length > 0) {
for (let i = 0; i < valores.length; i++) {
if (Array.isArray(valores[i])) {
valoresResolvidos.push(await resolverValoresMatriz(interpretador, valores[i]));
} else {
valoresResolvidos.push(await interpretador.avaliar(valores[i]));
}
}
}

return valoresResolvidos;
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
import { Importar, Leia } from '@designliquido/delegua/declaracoes';
import { InterpretadorComDepuracao } from '@designliquido/delegua/interpretador/interpretador-com-depuracao';
import { PilhaEscoposExecucaoPortugolStudio } from './pilha-escopos-execucao-portugol-studio';
import { DeleguaModulo } from '@designliquido/delegua/estruturas';

import { PilhaEscoposExecucaoPortugolStudio } from './pilha-escopos-execucao-portugol-studio';
import { Matriz } from '../construtos/matriz';
import { VisitantePortugolStudioInterface } from '../interfaces';
import { Limpa } from '../construtos';

import * as comum from './comum';

export class InterpretadorPortugolStudioComDepuracao extends InterpretadorComDepuracao {
export class InterpretadorPortugolStudioComDepuracao extends InterpretadorComDepuracao implements VisitantePortugolStudioInterface {
mensagemPrompt: string;
funcaoLimpa: Function = () => { console.log('Função "limpa()" não está ligada a uma interface de entrada e saída.') };

constructor(diretorioBase: string, funcaoDeRetorno: Function = null, funcaoDeRetornoMesmaLinha: Function = null) {
constructor(diretorioBase: string, funcaoDeRetorno: Function = null, funcaoDeRetornoMesmaLinha: Function = null, funcaoLimpa: Function = null) {
super(diretorioBase, funcaoDeRetorno, funcaoDeRetornoMesmaLinha);

if (funcaoLimpa !== null) {
this.funcaoLimpa = funcaoLimpa;
}

this.mensagemPrompt = '> ';
this.pilhaEscoposExecucao = new PilhaEscoposExecucaoPortugolStudio();
}

async visitarExpressaoLimpa(expressao: Limpa): Promise<any> {
this.funcaoLimpa();
return Promise.resolve();
}

async visitarDeclaracaoImportar(declaracao: Importar): Promise<DeleguaModulo> {
return comum.visitarExpressaoImportarComum(declaracao);
}
Expand All @@ -28,6 +43,10 @@ export class InterpretadorPortugolStudioComDepuracao extends InterpretadorComDep
return comum.visitarExpressaoLeiaComum(this.interfaceEntradaSaida, this.pilhaEscoposExecucao, expressao);
}

async visitarExpressaoMatriz(expressao: Matriz): Promise<any> {
return comum.visitarExpressaoMatrizComum(this, expressao);
}

/**
* No Portugol Studio, como o bloco de execução da função `inicio` é criado
* pelo avaliador sintático, precisamos ter uma forma aqui de avançar o
Expand Down
46 changes: 43 additions & 3 deletions fontes/interpretador/interpretador-portugol-studio.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
import { Importar, Leia } from '@designliquido/delegua/declaracoes';
import { EscrevaMesmaLinha, Importar, Leia } from '@designliquido/delegua/declaracoes';
import { InterpretadorBase } from '@designliquido/delegua/interpretador/interpretador-base';
import { EscopoExecucao } from '@designliquido/delegua/interfaces/escopo-execucao';
import { EspacoVariaveis } from '@designliquido/delegua/espaco-variaveis';
import { DeleguaModulo } from '@designliquido/delegua/estruturas';

import { Matriz } from '../construtos/matriz';
import { PilhaEscoposExecucaoPortugolStudio } from './pilha-escopos-execucao-portugol-studio';
import { VisitantePortugolStudioInterface } from '../interfaces';
import { Limpa } from '../construtos';

import * as comum from './comum';

export class InterpretadorPortugolStudio extends InterpretadorBase {
constructor(diretorioBase: string, performance = false, funcaoDeRetorno: Function = null) {
export class InterpretadorPortugolStudio extends InterpretadorBase implements VisitantePortugolStudioInterface {
funcaoLimpa: Function = () => { console.log('Função "limpa()" não está ligada a uma interface de entrada e saída.') };

constructor(diretorioBase: string, performance = false, funcaoDeRetorno: Function = null, funcaoLimpa: Function = null) {
super(diretorioBase, performance, funcaoDeRetorno);

if (funcaoLimpa !== null) {
this.funcaoLimpa = funcaoLimpa;
}

this.pilhaEscoposExecucao = new PilhaEscoposExecucaoPortugolStudio();
const escopoExecucao: EscopoExecucao = {
declaracoes: [],
Expand All @@ -21,6 +32,11 @@ export class InterpretadorPortugolStudio extends InterpretadorBase {
};
this.pilhaEscoposExecucao.empilhar(escopoExecucao);
}

async visitarExpressaoLimpa(expressao: Limpa): Promise<any> {
this.funcaoLimpa();
return Promise.resolve();
}

async visitarDeclaracaoImportar(declaracao: Importar): Promise<DeleguaModulo> {
return comum.visitarExpressaoImportarComum(declaracao);
Expand All @@ -35,4 +51,28 @@ export class InterpretadorPortugolStudio extends InterpretadorBase {
async visitarExpressaoLeia(expressao: Leia): Promise<any> {
return comum.visitarExpressaoLeiaComum(this.interfaceEntradaSaida, this.pilhaEscoposExecucao, expressao);
}

async visitarExpressaoMatriz(expressao: Matriz): Promise<any> {
return comum.visitarExpressaoMatrizComum(this, expressao);
}

/**
* Execução de uma escrita na saída padrão, sem quebras de linha.
* Implementada para alguns dialetos, como VisuAlg.
* @param declaracao A declaração.
* @returns Sempre nulo, por convenção de visita.
*/
async visitarDeclaracaoEscrevaMesmaLinha(declaracao: EscrevaMesmaLinha): Promise<any> {
try {
const formatoTexto: string = await comum.avaliarArgumentosEscreva(this, declaracao.argumentos);
this.funcaoDeRetornoMesmaLinha(formatoTexto);
return null;
} catch (erro: any) {
this.erros.push({
erroInterno: erro,
linha: declaracao.linha,
hashArquivo: declaracao.hashArquivo,
});
}
}
}
1 change: 1 addition & 0 deletions fontes/lexador/palavras-reservadas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const palavrasReservadas = {
inclua: tiposDeSimbolos.INCLUA,
inteiro: tiposDeSimbolos.INTEIRO,
leia: tiposDeSimbolos.LEIA,
limpa: tiposDeSimbolos.LIMPA,
logico: tiposDeSimbolos.LOGICO,
nao: tiposDeSimbolos.NEGACAO,
ou: tiposDeSimbolos.OU,
Expand Down
1 change: 1 addition & 0 deletions fontes/tipos-de-simbolos/lexico-regular.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default {
INCLUA: 'INCLUA',
INTEIRO: 'INTEIRO',
LEIA: 'LEIA',
LIMPA: 'LIMPA',
LOGICO: 'LOGICO',
MAIOR: 'MAIOR',
MAIOR_IGUAL: 'MAIOR_IGUAL',
Expand Down
Loading

0 comments on commit 82ab368

Please sign in to comment.