@designliquido/delegua
Version:
Linguagem de programação simples e moderna usando português estruturado.
926 lines • 44.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.aleatorio = aleatorio;
exports.aleatorio_entre = aleatorio_entre;
exports.algum = algum;
exports.arredondar = arredondar;
exports.encontrar = encontrar;
exports.encontrar_indice = encontrar_indice;
exports.encontrar_ultimo = encontrar_ultimo;
exports.encontrar_ultimo_indice = encontrar_ultimo_indice;
exports.filtrar_por = filtrar_por;
exports.incluido = incluido;
exports.inteiro = inteiro;
exports.intervalo = intervalo;
exports.mapear = mapear;
exports.maximo = maximo;
exports.minimo = minimo;
exports.numero = numero;
exports.ordenar = ordenar;
exports.para_cada = para_cada;
exports.primeiro_em_condicao = primeiro_em_condicao;
exports.real = real;
exports.reduzir = reduzir;
exports.somar = somar;
exports.tamanho = tamanho;
exports.texto = texto;
exports.todos = todos;
exports.todos_em_condicao = todos_em_condicao;
exports.tupla = tupla;
exports.vetor = vetor;
const excecoes_1 = require("../../../excecoes");
const objeto_delegua_classe_1 = require("../../../interpretador/estruturas/objeto-delegua-classe");
const funcao_padrao_1 = require("../../../interpretador/estruturas/funcao-padrao");
const descritor_tipo_classe_1 = require("../../../interpretador/estruturas/descritor-tipo-classe");
const estruturas_1 = require("../../../interpretador/estruturas");
const construtos_1 = require("../../../construtos");
const quebras_1 = require("../../../quebras");
/**
* Compara dois valores (números ou vetores).
* Retorna:
* > 0 se a > b
* < 0 se a < b
* 0 se a == b
* Lança erro se os tipos forem incompatíveis.
*/
function compararElementosRecursivamente(a, b) {
if (typeof a === 'number' && typeof b === 'number') {
return a - b;
}
if (Array.isArray(a) && Array.isArray(b)) {
const tamanho = Math.min(a.length, b.length);
for (let i = 0; i < tamanho; i++) {
const comparacao = compararElementosRecursivamente(a[i], b[i]);
if (comparacao !== 0)
return comparacao;
}
return a.length - b.length;
}
// Tipos incompatíveis (ex: comparar número com vetor)
throw new Error('Tipos incompatíveis para comparação.');
}
/**
* Retorna um número aleatório entre 0 e 1.
* @returns {Promise<number>} Número real.
*/
async function aleatorio(interpretador) {
return Promise.resolve(Math.random());
}
/**
* Retorna um número aleatório de acordo com o parâmetro passado.
* Mínimo(inclusivo) - Máximo(exclusivo).
* @param {number} minimo O número mínimo.
* @param {number} maximo O número máximo.
* @returns {Promise<number>} Um número real entre os valores máximo e mínimo especificados.
*/
async function aleatorio_entre(interpretador, minimo, maximo) {
if (arguments.length <= 0) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'A função recebe ao menos um parâmetro.'));
}
const valorMinimo = minimo.hasOwnProperty('valor')
? minimo.valor
: minimo;
if (arguments.length === 2) {
if (typeof valorMinimo !== 'number') {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'O parâmetro deve ser um número.'));
}
return Math.floor(Math.random() * (0 - valorMinimo)) + valorMinimo;
}
if (arguments.length > 3) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'A quantidade de parâmetros máxima para esta função é 2.'));
}
const valorMaximo = maximo.hasOwnProperty('valor')
? maximo.valor
: maximo;
if (typeof valorMinimo !== 'number' || typeof valorMaximo !== 'number') {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Os dois parâmetros devem ser do tipo número.'));
}
return Promise.resolve(Math.floor(Math.random() * (valorMaximo - valorMinimo)) + valorMinimo);
}
/**
* Verifica se algum dos elementos satisfaz à condição para por parâmetro.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} vetor Uma variável de Delégua ou um vetor nativo de JavaScript.
* @param {VariavelInterface | any} funcaoPesquisa A função que ensina o método de pesquisa.
* @returns {Promise<boolean>} Verdadeiro se há algum elemento no vetor com a condição. Falso caso contrário.
*/
async function algum(interpretador, vetor, funcaoPesquisa) {
const valorVetor = vetor.hasOwnProperty('valor') ? vetor.valor : vetor;
const valorFuncaoPesquisa = funcaoPesquisa.hasOwnProperty('valor')
? funcaoPesquisa.valor
: funcaoPesquisa;
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função deve ser um vetor.'));
}
if (valorFuncaoPesquisa.constructor !== estruturas_1.DeleguaFuncao) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O segundo parâmetro da função deve ser uma função.'));
}
for (let indice = 0; indice < valorVetor.length; ++indice) {
if (await valorFuncaoPesquisa.chamar(interpretador, [valorVetor[indice]])) {
return true;
}
}
return false;
}
/**
* Arredonda um número para uma quantidade específica de casas decimais.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {any} numero O número a ser arredondado.
* @param {any} casasDecimais A quantidade de casas decimais para o arredondamento.
* @returns {Promise<number>} O número arredondado.
*/
async function arredondar(interpretador, numero, casasDecimais) {
const valorNumero = interpretador.resolverValor(numero);
const valorCasas = interpretador.resolverValor(casasDecimais);
if (numero == undefined || numero == null) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(null, 'Erro: arredondar() deve receber um número.', interpretador.linhaDeclaracaoAtual));
}
if (typeof numero !== 'number') {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(null, `Erro de Tipo: arredondar() espera um número, mas recebeu '${typeof valorNumero}'.`, interpretador.linhaDeclaracaoAtual));
}
const fator = Math.pow(10, valorCasas);
const resultado = Math.round(valorNumero * fator) / fator;
return Promise.resolve(resultado);
}
/**
* Encontra o primeiro elemento de um vetor cuja função de pesquisa retorne
* verdadeiro na avaliação de cada elemento.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} vetor Uma variável de Delégua ou um vetor nativo de JavaScript.
* @param {VariavelInterface | any} funcaoPesquisa A função que ensina o método de pesquisa.
* @returns {Promise<any>} Um elemento, caso o elemento seja encontraro, ou nulo em caso contrário.
*/
async function encontrar(interpretador, vetor, funcaoPesquisa) {
const valorVetor = vetor.hasOwnProperty('valor') ? vetor.valor : vetor;
const valorFuncaoPesquisa = funcaoPesquisa.hasOwnProperty('valor')
? funcaoPesquisa.valor
: funcaoPesquisa;
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função deve ser um vetor.'));
}
if (valorFuncaoPesquisa.constructor !== estruturas_1.DeleguaFuncao) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O segundo parâmetro da função deve ser uma função.'));
}
for (let indice = 0; indice < valorVetor.length; ++indice) {
if (await valorFuncaoPesquisa.chamar(interpretador, [valorVetor[indice]])) {
return valorVetor[indice];
}
}
return null;
}
/**
* Encontra o índice do primeiro elemento de um vetor cuja função de pesquisa retorne
* verdadeiro na avaliação de cada elemento.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} vetor Uma variável de Delégua ou um vetor nativo de JavaScript.
* @param {VariavelInterface | any} funcaoPesquisa A função que ensina o método de pesquisa.
* @returns {Promise<number>} O número correspondente ao índice se o elemento for encontrado, ou nulo em caso contrário.
*/
async function encontrar_indice(interpretador, vetor, funcaoPesquisa) {
const valorVetor = vetor.hasOwnProperty('valor') ? vetor.valor : vetor;
const valorFuncaoPesquisa = funcaoPesquisa.hasOwnProperty('valor')
? funcaoPesquisa.valor
: funcaoPesquisa;
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função deve ser um vetor.'));
}
if (valorFuncaoPesquisa.constructor !== estruturas_1.DeleguaFuncao) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O segundo parâmetro da função deve ser uma função.'));
}
for (let indice = 0; indice < valorVetor.length; ++indice) {
if (await valorFuncaoPesquisa.chamar(interpretador, [valorVetor[indice]])) {
return indice;
}
}
return -1;
}
/**
* Encontrar o último elemento de um vetor cuja função de pesquisa retorne
* verdadeiro na avaliação de cada elemento.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} vetor Uma variável de Delégua ou um vetor nativo de JavaScript.
* @param {VariavelInterface | any} funcaoPesquisa A função que ensina o método de pesquisa.
* @returns {Promise<any>} O número correspondente ao índice se o elemento for encontrado, ou nulo em caso contrário.
*/
async function encontrar_ultimo(interpretador, vetor, funcaoPesquisa) {
const valorVetor = vetor.hasOwnProperty('valor') ? vetor.valor : vetor;
const valorFuncaoPesquisa = funcaoPesquisa.hasOwnProperty('valor')
? funcaoPesquisa.valor
: funcaoPesquisa;
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função deve ser um vetor.'));
}
if (valorFuncaoPesquisa.constructor !== estruturas_1.DeleguaFuncao) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O segundo parâmetro da função deve ser uma função.'));
}
for (let indice = valorVetor.length - 1; indice >= 0; --indice) {
if (await valorFuncaoPesquisa.chamar(interpretador, [valorVetor[indice]])) {
return valorVetor[indice];
}
}
return null;
}
/**
*
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} vetor Uma variável de Delégua ou um vetor nativo de JavaScript.
* @param {VariavelInterface | any} funcaoPesquisa A função que ensina o método de pesquisa.
* @returns {Promise<number>} O número correspondente ao índice se o elemento for encontrado, ou nulo em caso contrário.
*/
async function encontrar_ultimo_indice(interpretador, vetor, funcaoPesquisa) {
const valorVetor = vetor.hasOwnProperty('valor') ? vetor.valor : vetor;
const valorFuncaoPesquisa = funcaoPesquisa.hasOwnProperty('valor')
? funcaoPesquisa.valor
: funcaoPesquisa;
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função deve ser um vetor.'));
}
if (valorFuncaoPesquisa.constructor !== estruturas_1.DeleguaFuncao) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O segundo parâmetro da função deve ser uma função.'));
}
for (let indice = valorVetor.length - 1; indice >= 0; --indice) {
if (await valorFuncaoPesquisa.chamar(interpretador, [valorVetor[indice]])) {
return indice;
}
}
return null;
}
/**
*
* @param interpretador
* @param vetor
* @param funcaoFiltragem
* @returns
*/
async function filtrar_por(interpretador, vetor, funcaoFiltragem) {
if (vetor === null || vetor === undefined)
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função filtrarPor() não pode ser nulo.'));
const valorVetor = vetor.hasOwnProperty('valor') ? vetor.valor : vetor;
const valorFuncaoFiltragem = funcaoFiltragem.hasOwnProperty('valor')
? funcaoFiltragem.valor
: funcaoFiltragem;
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função filtrarPor() deve ser um vetor.'));
}
if (valorFuncaoFiltragem.constructor !== estruturas_1.DeleguaFuncao) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O segundo parâmetro da função filtrarPor() deve ser uma função.'));
}
const resultados = [];
for (let indice = 0; indice < valorVetor.length; ++indice) {
const informacoesValor = await valorFuncaoFiltragem.chamar(interpretador, [
valorVetor[indice],
]);
if (informacoesValor === null || informacoesValor === undefined) {
continue;
}
const deveRetornarValor = informacoesValor.valorRetornado.valor;
if (deveRetornarValor === false)
continue;
resultados.push(valorVetor[indice]);
}
return resultados;
}
/**
*
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} vetor Uma variável de Delégua ou um vetor nativo de JavaScript.
* @param valor
* @returns
*/
async function incluido(interpretador, vetor, valor) {
const valorVetor = vetor.hasOwnProperty('valor') ? vetor.valor : vetor;
const valorValor = valor.hasOwnProperty('valor') ? valor.valor : valor;
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função deve ser um vetor.'));
}
for (let indice = 0; indice < valorVetor.length; ++indice) {
if (valorVetor[indice] == valorValor) {
return true;
}
}
return false;
}
function validacao_comum_numeros(interpretador, valorParaConverter) {
if (isNaN(valorParaConverter)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Valor não parece ser um número. Somente números ou textos com números podem ser convertidos para inteiro.'));
}
if (!/^(-)?\d+(\.\d+)?$/.test(valorParaConverter)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Valor não parece estar estruturado como um número (texto vazio, falso ou não definido). Somente números ou textos com números podem ser convertidos para inteiro.'));
}
return null;
}
/**
* Converte um valor em um número inteiro.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} valorParaConverter O valor a ser convertido.
* @returns {Promise<any>} Uma Promise com o resultado da conversão.
*/
async function inteiro(interpretador, valorParaConverter) {
if (valorParaConverter === null || valorParaConverter === undefined)
return Promise.resolve(0);
const valor = valorParaConverter.hasOwnProperty('valor')
? valorParaConverter.valor
: valorParaConverter;
const resultadoValidacao = validacao_comum_numeros(interpretador, valor);
return resultadoValidacao || Promise.resolve(parseInt(valor));
}
/**
* Cria um vetor com números inteiros no intervalo especificado.
* O valor inicial é inclusivo e o valor final é exclusivo.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | number} valorInicial O valor inicial (inclusivo).
* @param {VariavelInterface | number} valorFinal O valor final (exclusivo).
* @param {VariavelInterface | number} valorPasso O valor do passo.
* @returns {Promise<number[]>} Um vetor com os números no intervalo.
*/
async function intervalo(interpretador, valorInicial, valorFinal, valorPasso) {
const primeiroParam = interpretador.resolverValor(valorInicial);
const segundoParam = interpretador.resolverValor(valorFinal);
const terceiroParam = interpretador.resolverValor(valorPasso);
let inicioInteiro;
let fimInteiro;
let passoInteiro = 1;
// intervalo(parada) - apenas um parâmetro
if (segundoParam === undefined || segundoParam === null) {
if (typeof primeiroParam !== 'number' || isNaN(primeiroParam)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'O parâmetro deve ser do tipo número ou inteiro.'));
}
inicioInteiro = 0;
fimInteiro = Math.floor(primeiroParam);
}
// intervalo(inicio, parada) ou intervalo(inicio, parada, passo)
else {
if (typeof primeiroParam !== 'number' ||
isNaN(primeiroParam) ||
typeof segundoParam !== 'number' ||
isNaN(segundoParam)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Os parâmetros de início e fim devem ser do tipo número ou inteiro.'));
}
inicioInteiro = Math.floor(primeiroParam);
fimInteiro = Math.floor(segundoParam);
// Se há um terceiro parâmetro (passo)
if (terceiroParam !== undefined && terceiroParam !== null) {
if (typeof terceiroParam !== 'number' || isNaN(terceiroParam)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'O parâmetro de passo deve ser do tipo número ou inteiro.'));
}
passoInteiro = Math.floor(terceiroParam);
if (passoInteiro === 0) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'O passo não pode ser zero.'));
}
}
}
const resultado = [];
if (passoInteiro > 0) {
for (let i = inicioInteiro; i < fimInteiro; i += passoInteiro) {
resultado.push(i);
}
}
else {
// Parâmetro passo sendo um número negativo
for (let i = inicioInteiro; i > fimInteiro; i += passoInteiro) {
resultado.push(i);
}
}
return Promise.resolve(resultado);
}
/**
* Dado um vetor e uma função de mapeamento, executa a função de mapeamento
* passando como argumento cada elemento do vetor.
* @param interpretador A instância do interpretador.
* @param vetor O vetor
* @param funcaoMapeamento A função de mapeamento.
* @returns O resultado acumulado da execução da função de mapeamento.
*/
async function mapear(interpretador, vetor, funcaoMapeamento) {
if (vetor === null || vetor === undefined)
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função mapear() não pode ser nulo.'));
const valorVetor = interpretador.resolverValor(vetor);
const valorFuncaoMapeamento = interpretador.resolverValor(funcaoMapeamento);
const resultados = [];
for (let indice = 0; indice < valorVetor.length; ++indice) {
const informacoesRetorno = await valorFuncaoMapeamento.chamar(interpretador, [
valorVetor[indice],
]);
if (!informacoesRetorno.hasOwnProperty('valorRetornado')) {
console.warn(`Retorno inconsistente em mapear(): ${JSON.stringify(informacoesRetorno)}.`);
continue;
}
if (!(informacoesRetorno.valorRetornado instanceof quebras_1.RetornoQuebra)) {
console.warn(`mapear() finalizado com valor retornado diferente do esperado: ${JSON.stringify(informacoesRetorno)}.`);
continue;
}
resultados.push(informacoesRetorno.valorRetornado.valor);
}
return resultados;
}
/**
* Encontra o maior número dentro de um vetor.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} vetor Uma variável de Pituguês ou um vetor nativo de JavaScript contendo números.
* @returns {Promise<number>} O maior número encontrado no vetor.
*/
async function maximo(interpretador, vetor) {
if (vetor === null || vetor === undefined) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O parâmetro da função maximo() não pode ser nulo.'));
}
const valorVetor = interpretador.resolverValor(vetor);
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O parâmetro da função maximo() deve ser um vetor.'));
}
if (vetor.length == 0) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O vetor não pode estar vazio.'));
}
let maiorValor = valorVetor[0];
try {
for (let i = 1; i < valorVetor.length; i++) {
const elementoAtual = valorVetor[i];
if (compararElementosRecursivamente(elementoAtual, maiorValor) > 0) {
maiorValor = elementoAtual;
}
}
}
catch (erro) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Não é possível comparar elementos de tipos diferentes dentro do vetor (ex: números com vetores).'));
}
return Promise.resolve(maiorValor);
}
/**
* Encontra o menor número dentro de um vetor.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} vetor Uma variável de Pituguês ou um vetor nativo de JavaScript contendo números.
* @returns {Promise<number>} O menor número encontrado no vetor.
*/
async function minimo(interpretador, vetor) {
if (vetor === null || vetor === undefined) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O parâmetro da função minimo() não pode ser nulo.'));
}
const valorVetor = interpretador.resolverValor(vetor);
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O parâmetro da função minimo() deve ser um vetor.'));
}
if (valorVetor.length == 0) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O vetor não pode estar vazio.'));
}
let menorValor = valorVetor[0];
try {
for (let i = 1; i < valorVetor.length; i++) {
const elementoAtual = valorVetor[i];
if (compararElementosRecursivamente(elementoAtual, menorValor) < 0) {
menorValor = elementoAtual;
}
}
}
catch (erro) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Não é possível comparar elementos de tipos diferentes dentro do vetor (ex: números com vetores).'));
}
return Promise.resolve(menorValor);
}
/**
* Converte um valor em um número, com parte decimal ou não.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} valorParaConverter O valor a ser convertido.
* @returns {Promise<any>} Uma Promise com o resultado da conversão.
*/
async function numero(interpretador, valorParaConverter) {
if (valorParaConverter === null || valorParaConverter === undefined)
return Promise.resolve(0);
const valor = valorParaConverter.hasOwnProperty('valor')
? valorParaConverter.valor
: valorParaConverter;
const resultadoValidacao = validacao_comum_numeros(interpretador, valor);
return resultadoValidacao || Promise.resolve(Number(valor));
}
/**
*
* @param vetor
* @returns
*/
async function ordenar(interpretador, vetor) {
if (vetor === null || vetor === undefined)
throw new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função ordenar() não pode ser nulo.');
const objeto = vetor.hasOwnProperty('valor') ? vetor.valor : vetor;
if (!Array.isArray(objeto)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Valor inválido. Objeto inserido não é um vetor.'));
}
let trocado;
const tamanho = objeto.length;
do {
trocado = false;
for (let i = 0; i < tamanho - 1; i++) {
if (objeto[i] > objeto[i + 1]) {
[objeto[i], objeto[i + 1]] = [objeto[i + 1], objeto[i]];
trocado = true;
}
}
} while (trocado);
return Promise.resolve(objeto);
}
/**
*
* @param interpretador
* @param vetor
* @param funcaoFiltragem
* @returns
*/
async function para_cada(interpretador, vetor, funcaoFiltragem) {
if (vetor === null || vetor === undefined)
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função paraCada() não pode ser nulo.'));
const valorVetor = interpretador.resolverValor(vetor);
const valorFuncaoFiltragem = interpretador.resolverValor(funcaoFiltragem);
for (let indice = 0; indice < valorVetor.length; ++indice) {
await valorFuncaoFiltragem.chamar(interpretador, [valorVetor[indice]]);
}
}
/**
*
* @param interpretador
* @param vetor
* @param funcaoFiltragem
* @returns
*/
async function primeiro_em_condicao(interpretador, vetor, funcaoFiltragem) {
if (vetor === null || vetor === undefined)
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função primeiroEmCondicao() não pode ser nulo.'));
const valorVetor = interpretador.resolverValor(vetor);
const valorFuncaoFiltragem = interpretador.resolverValor(funcaoFiltragem);
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função primeiroEmCondicao() deve ser um vetor.'));
}
if (valorFuncaoFiltragem.constructor.name !== 'DeleguaFuncao') {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O segundo parâmetro da função primeiroEmCondicao() deve ser uma função.'));
}
for (let indice = 0; indice < valorVetor.length; ++indice) {
const valorResolvido = await valorFuncaoFiltragem.chamar(interpretador, [
valorVetor[indice],
]);
if (valorResolvido !== null) {
return valorResolvido;
}
}
return undefined;
}
/**
*
* @param interpretador
* @param numero
* @returns
*/
async function real(interpretador, numero) {
if (numero === null || numero === undefined)
return Promise.resolve(parseFloat('0'));
const valor = numero.hasOwnProperty('valor') ? numero.valor : numero;
if (!/^(-)?\d+(\.\d+)?$/.test(valor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Valor não parece estar estruturado como um número (texto/valor vazio, falso ou não definido). Somente números ou textos com números podem ser convertidos para real.'));
}
return Promise.resolve(parseFloat(valor));
}
/**
*
* @param interpretador
* @param vetor
* @param funcaoReducao
* @param valorInicial
* @returns
*/
async function reduzir(interpretador, vetor, funcaoReducao, valorInicial = null) {
const valorVetor = vetor.hasOwnProperty('valor') ? vetor.valor : vetor;
const valorFuncaoReducao = funcaoReducao.hasOwnProperty('valor')
? funcaoReducao.valor
: funcaoReducao;
const valorPadrao = valorInicial && valorInicial.hasOwnProperty && valorInicial.hasOwnProperty('valor')
? valorInicial.valor
: valorInicial;
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro da função deve ser um vetor.'));
}
if (valorFuncaoReducao.constructor.name !== 'DeleguaFuncao') {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O segundo parâmetro da função deve ser uma função.'));
}
// Se não houver valor inicial e vetor vazio, não é possível reduzir
if ((valorPadrao === null || valorPadrao === undefined) &&
(!Array.isArray(valorVetor) || valorVetor.length === 0)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Não é possível reduzir um vetor vazio sem valor inicial.'));
}
let resultado = valorPadrao;
let inicio = 0;
if (resultado === null || resultado === undefined) {
resultado = valorVetor[0];
inicio = 1;
}
for (let index = inicio; index < valorVetor.length; ++index) {
resultado = await valorFuncaoReducao.chamar(interpretador, [resultado, valorVetor[index]]);
}
return resultado;
}
/**
* Realiza a soma de todos os números dentro de um vetor.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} vetor Uma variável de Pituguês ou um vetor nativo de JavaScript contendo números.
* @returns {Promise<number>} A soma de todos os elementos do vetor.
*/
async function somar(interpretador, vetor) {
if (vetor === null || vetor === undefined) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O parâmetro da função somar() não pode ser nulo.'));
}
const valorVetor = interpretador.resolverValor(vetor);
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O parâmetro da função somar() deve ser um vetor.'));
}
if (valorVetor.length === 0)
return Promise.resolve(0);
let somaDosElementos = 0;
for (let elemento of valorVetor) {
if (typeof elemento !== 'number' || isNaN(elemento)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'A função somar() aceita apenas vetores contendo números.'));
}
somaDosElementos += elemento;
}
return Promise.resolve(somaDosElementos);
}
/**
*
* @param objeto
* @returns
*/
async function tamanho(interpretador, objeto) {
const valorObjeto = objeto.hasOwnProperty('valor') ? objeto.valor : objeto;
if (typeof valorObjeto === 'number') {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Função global tamanho() não funciona com números.'));
}
if (valorObjeto instanceof objeto_delegua_classe_1.ObjetoDeleguaClasse) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Função global tamanho não funciona com objetos complexos.'));
}
if (valorObjeto instanceof estruturas_1.DeleguaFuncao) {
return Promise.resolve(valorObjeto.declaracao.parametros.length);
}
if (valorObjeto instanceof funcao_padrao_1.FuncaoPadrao) {
return Promise.resolve(valorObjeto.valorAridade);
}
if (valorObjeto instanceof descritor_tipo_classe_1.DescritorTipoClasse) {
const metodos = valorObjeto.metodos;
let tamanho = 0;
const metodoInicializacao = metodos.inicializacao;
if (metodoInicializacao &&
!Array.isArray(metodoInicializacao) &&
metodoInicializacao.eInicializador) {
tamanho = metodoInicializacao.declaracao.parametros.length;
}
return Promise.resolve(tamanho);
}
return Promise.resolve(valorObjeto.length);
}
/**
* Transforma o valor ou variável em texto.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} valorParaConverter O valor ou variável.
* @returns {Promise<string>} O valor resolvido em texto.
*/
async function texto(interpretador, valorParaConverter) {
return Promise.resolve(`${valorParaConverter.hasOwnProperty('valor') ? valorParaConverter.valor : valorParaConverter}`);
}
/**
* Retorna verdadeiro se todos os elementos do iterável forem truly.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} iteravel O primeiro parâmetro, qualquer dado que seja iterável (vetores, tuplas, dicionários etc.).
* @returns {Promise<boolean>} Verdadeiro, se todos os valores do iterável forem Truly.
*/
async function todos(interpretador, iteravel) {
const valorIteravel = interpretador.resolverValor(iteravel);
const ehObjetoOuDicionario = valorIteravel && typeof valorIteravel === 'object' && !Array.isArray(valorIteravel);
const ehIteravelNativo = valorIteravel && typeof valorIteravel[Symbol.iterator] === 'function';
if (!ehIteravelNativo && !ehObjetoOuDicionario) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro deve ser um iterável.'));
}
const itens = ehIteravelNativo ? valorIteravel : Object.values(valorIteravel);
for (const valor of itens) {
const valorResolvido = interpretador.resolverValor(valor);
if (!interpretador.eVerdadeiro(valorResolvido))
return false;
}
return true;
}
/**
* Retorna verdadeiro se todos os elementos do primeiro parâmetro retornam verdadeiro ao
* serem aplicados como argumentos da função passada como segundo parâmetro.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any} iteravel O primeiro parâmetro, qualquer dado que seja iterável (vetores, tuplas, dicionários etc.).
* @param {VariavelInterface | any} funcaoCondicional A função que será executada com cada
* valor do vetor passado como primeiro parâmetro.
* @returns {Promise<boolean>} Verdadeiro, se todos os valores do iterável fazem a função passada
* por parâmetro devolver verdadeiro, ou falso em caso contrário.
*/
async function todos_em_condicao(interpretador, iteravel, funcaoCondicional) {
const simboloChamada = {
linha: interpretador.linhaDeclaracaoAtual,
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
};
const valorIteravel = interpretador.resolverValor(iteravel);
const ehObjetoOuDicionario = valorIteravel && typeof valorIteravel === 'object' && !Array.isArray(valorIteravel);
const ehIteravelNativo = valorIteravel && typeof valorIteravel[Symbol.iterator] === 'function';
if (!ehIteravelNativo && !ehObjetoOuDicionario) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O primeiro parâmetro deve ser um iterável.'));
}
const valorFuncao = interpretador.resolverValor(funcaoCondicional);
const naoEhUmaFuncao = !(valorFuncao instanceof estruturas_1.DeleguaFuncao || valorFuncao instanceof funcao_padrao_1.FuncaoPadrao);
if (!valorFuncao || naoEhUmaFuncao) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Parâmetro inválido. O segundo parâmetro deve ser uma função.'));
}
const itens = ehIteravelNativo ? valorIteravel : Object.values(valorIteravel);
for (const valor of itens) {
const resultadoChamada = await valorFuncao.chamar(interpretador, [valor], simboloChamada);
const resultadoResolvido = interpretador.resolverValor(resultadoChamada);
if (!interpretador.eVerdadeiro(resultadoResolvido))
return false;
}
return true;
}
/**
* Transforma um vetor de elementos em uma tupla de N elementos, sendo N a
* largura do vetor.
* @param {InterpretadorInterface} interpretador A instância do interpretador.
* @param {VariavelInterface | any[]} vetor O vetor.
* @returns A tupla resolvida.
*/
async function tupla(interpretador, vetor) {
const valorVetor = interpretador.resolverValor(vetor);
if (!Array.isArray(valorVetor)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Argumento de função nativa `tupla` não parece ser um vetor.'));
}
const elementos = valorVetor.map((item) => {
const valorResolvido = interpretador.resolverValor(item);
const literal = new construtos_1.Literal(interpretador.hashArquivoDeclaracaoAtual, interpretador.linhaDeclaracaoAtual, valorResolvido);
if (typeof valorResolvido === 'string') {
literal.paraTextoSaida = () => `'${valorResolvido}'`;
}
return literal;
});
return new construtos_1.TuplaN(interpretador.hashArquivoDeclaracaoAtual, interpretador.linhaDeclaracaoAtual, elementos);
}
async function vetor(interpretador, tupla) {
const objetoTupla = interpretador.resolverValor(tupla);
if (!(objetoTupla instanceof construtos_1.TuplaN)) {
return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
linha: interpretador.linhaDeclaracaoAtual,
}, 'Argumento de função nativa `vetor` não parece ser uma tupla.'));
}
const resultado = objetoTupla.elementos.map((elemento) => interpretador.resolverValor(elemento));
return Promise.resolve(resultado);
}
//# sourceMappingURL=biblioteca-global.js.map