@designliquido/delegua
Version:
Linguagem de programação simples e moderna usando português estruturado.
970 lines • 53.2 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AvaliadorSintaticoPrisma = void 0;
const browser_process_hrtime_1 = __importDefault(require("browser-process-hrtime"));
const construtos_1 = require("../../construtos");
const declaracoes_1 = require("../../declaracoes");
const avaliador_sintatico_base_1 = require("../avaliador-sintatico-base");
const erro_avaliador_sintatico_1 = require("../erro-avaliador-sintatico");
const inferenciador_1 = require("../../inferenciador");
const pilha_escopos_1 = require("../pilha-escopos");
const informacao_escopo_1 = require("../informacao-escopo");
const comum_1 = require("../comum");
const informacao_elemento_sintatico_1 = require("../../informacao-elemento-sintatico");
const lexador_1 = require("../../lexador");
const prisma_1 = __importDefault(require("../../tipos-de-simbolos/prisma"));
const primitivas_dicionario_1 = __importDefault(require("../../bibliotecas/primitivas-dicionario"));
const primitivas_numero_1 = __importDefault(require("../../bibliotecas/primitivas-numero"));
const primitivas_texto_1 = __importDefault(require("../../bibliotecas/primitivas-texto"));
const primitivas_vetor_1 = __importDefault(require("../../bibliotecas/primitivas-vetor"));
/**
* O avaliador sintático (_Parser_) é responsável por transformar os símbolos do Lexador em estruturas de alto nível.
* Essas estruturas de alto nível são as partes que executam lógica de programação de fato.
* Há dois grupos de estruturas de alto nível: Construtos e Declarações.
*
* Este avaliador sintático é específico para o dialeto Prisma da linguagem Delégua.
*/
class AvaliadorSintaticoPrisma extends avaliador_sintatico_base_1.AvaliadorSintaticoBase {
constructor(performance = false) {
super();
this.atual = 0;
this.blocos = 0;
this.performance = performance;
this.pilhaEscopos = new pilha_escopos_1.PilhaEscopos();
this.primitivasConhecidas = {};
this.tiposDefinidosEmCodigo = {};
(0, comum_1.registrarPrimitiva)(this.primitivasConhecidas, 'dicionário', primitivas_dicionario_1.default);
(0, comum_1.registrarPrimitiva)(this.primitivasConhecidas, 'número', primitivas_numero_1.default);
(0, comum_1.registrarPrimitiva)(this.primitivasConhecidas, 'texto', primitivas_texto_1.default);
(0, comum_1.registrarPrimitiva)(this.primitivasConhecidas, 'vetor', primitivas_vetor_1.default);
}
sincronizar() {
this.avancarEDevolverAnterior();
while (!this.estaNoFinal()) {
switch (this.simbolos[this.atual].tipo) {
case prisma_1.default.CLASSE:
case prisma_1.default.FUNCAO:
case prisma_1.default.FUNÇÃO:
case prisma_1.default.LOCAL:
case prisma_1.default.PARA:
case prisma_1.default.SE:
case prisma_1.default.ENQUANTO:
case prisma_1.default.IMPRIMA:
case prisma_1.default.RETORNE:
return;
}
this.avancarEDevolverAnterior();
}
}
consumir(tipo, mensagemDeErro) {
if (this.verificarTipoSimboloAtual(tipo))
return this.avancarEDevolverAnterior();
let simboloErro = this.simbolos[this.atual];
if (this.simbolos.length === 0) {
simboloErro = {
hashArquivo: this.hashArquivo,
linha: 1,
};
}
else if (this.atual >= this.simbolos.length) {
simboloErro = this.simbolos[this.simbolos.length - 1];
}
throw this.erro(simboloErro, mensagemDeErro);
}
simboloNaPosicao(posicao) {
return this.simbolos[this.atual + posicao];
}
avancarEDevolverAnterior() {
if (!this.estaNoFinal())
this.atual += 1;
return this.simboloAnterior();
}
verificarSeSimboloAtualEIgualA(...argumentos) {
for (let i = 0; i < argumentos.length; i++) {
const tipoAtual = argumentos[i];
if (this.verificarTipoSimboloAtual(tipoAtual)) {
this.avancarEDevolverAnterior();
return true;
}
}
return false;
}
async primario() {
var _a;
const simboloAtual = this.simbolos[this.atual];
let valores = [];
switch (simboloAtual.tipo) {
case prisma_1.default.COLCHETE_ESQUERDO:
this.avancarEDevolverAnterior();
switch (this.simbolos[this.atual].tipo) {
case prisma_1.default.COLCHETE_ESQUERDO: // Texto multilinhas
return this.construtoTextoMultilinhas();
default:
throw this.erro(simboloAtual, 'Terminar.');
}
case prisma_1.default.CHAVE_ESQUERDA:
// Prisma tem o conceito de tabela, que não é exatamente um dicionário, mas é próximo.
// Aqui, vamos tratar como dicionário para simplificar.
this.avancarEDevolverAnterior();
const chaves = [];
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.CHAVE_DIREITA)) {
return new construtos_1.Dicionario(this.hashArquivo, simboloAtual.linha, [], []);
}
let indice = 1;
do {
let chave;
if (this.verificarTipoSimboloAtual(prisma_1.default.IDENTIFICADOR) &&
((_a = this.simbolos[this.atual + 1]) === null || _a === void 0 ? void 0 : _a.tipo) === prisma_1.default.IGUAL) {
// Chave nomeada: {nome = "João"}
const chaveIdentificador = this.avancarEDevolverAnterior();
this.avancarEDevolverAnterior(); // consume IGUAL
chave = new construtos_1.Literal(this.hashArquivo, simboloAtual.linha, chaveIdentificador.lexema);
}
else {
chave = new construtos_1.Literal(this.hashArquivo, simboloAtual.linha, String(indice));
}
const valor = await this.ou();
chaves.push(chave);
valores.push(valor);
indice++;
} while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.VIRGULA));
this.consumir(prisma_1.default.CHAVE_DIREITA, `Esperado fechamento de chave em tabela.`);
return new construtos_1.Dicionario(this.hashArquivo, simboloAtual.linha, chaves, valores);
case prisma_1.default.FALSO:
case prisma_1.default.VERDADEIRO:
const simboloLogico = this.avancarEDevolverAnterior();
return new construtos_1.Literal(this.hashArquivo, simboloAtual.linha, simboloLogico.tipo === prisma_1.default.VERDADEIRO, 'lógico');
case prisma_1.default.FUNCAO:
case prisma_1.default.FUNÇÃO:
const simboloFuncao = this.avancarEDevolverAnterior();
const corpoDaFuncao = await this.corpoDaFuncao(simboloFuncao.lexema);
this.pilhaEscopos.definirInformacoesVariavel(simboloFuncao.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(simboloFuncao.lexema, 'função'));
return corpoDaFuncao;
case prisma_1.default.IMPORTAR:
return this.expressaoImportar();
case prisma_1.default.NULO:
this.avancarEDevolverAnterior();
return new construtos_1.Literal(this.hashArquivo, simboloAtual.linha, null);
case prisma_1.default.ISTO:
const simboloIsto = this.avancarEDevolverAnterior();
return new construtos_1.Isto(this.hashArquivo, simboloAtual.linha, simboloIsto);
case prisma_1.default.LEIA:
return this.expressaoLeia();
case prisma_1.default.NUMERO:
case prisma_1.default.TEXTO:
const simboloLiteral = this.avancarEDevolverAnterior();
const tipoInferido = (0, inferenciador_1.inferirTipoVariavel)(simboloLiteral.literal);
return new construtos_1.Literal(this.hashArquivo, Number(simboloLiteral.linha), simboloLiteral.literal, tipoInferido);
case prisma_1.default.IDENTIFICADOR:
const simboloIdentificador = this.avancarEDevolverAnterior();
let tipoOperando;
if (simboloIdentificador.lexema in this.tiposDefinidosEmCodigo) {
tipoOperando = simboloIdentificador.lexema;
}
else {
try {
tipoOperando = this.pilhaEscopos.obterTipoVariavelPorNome(simboloIdentificador.lexema);
}
catch (erro) {
throw this.erro(simboloIdentificador, erro.message);
}
}
return new construtos_1.Variavel(this.hashArquivo, simboloIdentificador, tipoOperando);
case prisma_1.default.PARENTESE_ESQUERDO:
this.avancarEDevolverAnterior();
const expressao = await this.expressao();
this.consumir(prisma_1.default.PARENTESE_DIREITO, "Esperado ')' após a expressão.");
return new construtos_1.Agrupamento(this.hashArquivo, simboloAtual.linha, expressao);
case prisma_1.default.SUPER:
const simboloSuper = this.avancarEDevolverAnterior();
return new construtos_1.Super(this.hashArquivo, simboloSuper, this.superclasseAtual);
}
throw this.erro(this.simbolos[this.atual], 'Esperado expressão.');
}
async expressaoImportar() {
this.avancarEDevolverAnterior();
this.consumir(prisma_1.default.PARENTESE_ESQUERDO, "Esperado '(' após declaração.");
const caminho = await this.expressao();
this.consumir(prisma_1.default.PARENTESE_DIREITO, "Esperado ')' após declaração.");
return new construtos_1.ImportarComoConstruto(caminho);
}
/**
* Construto para texto multilinhas.
* @returns
*/
construtoTextoMultilinhas() {
const segundoColchete = this.consumir(prisma_1.default.COLCHETE_ESQUERDO, "Esperado '[' antes do texto multilinhas.");
let texto = '';
let linha = segundoColchete.linha;
while (!this.verificarSeSimboloAtualEIgualA(prisma_1.default.COLCHETE_DIREITO)) {
texto += this.simbolos[this.atual].lexema + ' ';
if (this.simbolos[this.atual].linha !== linha) {
texto += '\n';
linha = this.simbolos[this.atual].linha;
}
this.avancarEDevolverAnterior();
}
this.consumir(prisma_1.default.COLCHETE_DIREITO, "Esperado ']' após o texto multilinhas.");
return new construtos_1.Literal(this.hashArquivo, segundoColchete.linha, texto);
}
async expressaoLeia() {
const simboloLeia = this.avancarEDevolverAnterior();
this.consumir(prisma_1.default.PARENTESE_ESQUERDO, "Esperado '(' antes dos valores em leia.");
const argumentos = [];
if (!this.verificarTipoSimboloAtual(prisma_1.default.PARENTESE_DIREITO)) {
do {
argumentos.push(await this.expressao());
} while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.VIRGULA));
}
this.consumir(prisma_1.default.PARENTESE_DIREITO, "Esperado ')' após os valores em leia.");
return new construtos_1.Leia(simboloLeia, argumentos);
}
async finalizarChamada(entidadeChamada) {
const argumentos = [];
if (!this.verificarTipoSimboloAtual(prisma_1.default.PARENTESE_DIREITO)) {
do {
if (argumentos.length >= 255) {
throw this.erro(this.simbolos[this.atual], 'Não pode haver mais de 255 argumentos.');
}
argumentos.push(await this.expressao());
} while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.VIRGULA));
}
this.consumir(prisma_1.default.PARENTESE_DIREITO, "Esperado ')' após os argumentos.");
return new construtos_1.Chamada(this.hashArquivo, entidadeChamada, argumentos);
}
async chamar() {
let expressao = await this.primario();
while (true) {
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.PARENTESE_ESQUERDO)) {
expressao = await this.finalizarChamada(expressao);
}
else if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.PONTO)) {
const nome = this.consumir(prisma_1.default.IDENTIFICADOR, "Esperado nome do método após '.'.");
expressao = new construtos_1.AcessoMetodoOuPropriedade(this.hashArquivo, expressao, nome);
}
else if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.COLCHETE_ESQUERDO)) {
const indice = await this.expressao();
const simboloFechamento = this.consumir(prisma_1.default.COLCHETE_DIREITO, "Esperado ']' após escrita do indice.");
expressao = new construtos_1.AcessoIndiceVariavel(this.hashArquivo, expressao, indice, simboloFechamento);
}
else {
break;
}
}
return expressao;
}
async unario() {
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.NEGACAO, prisma_1.default.SUBTRACAO, prisma_1.default.BIT_NOT, prisma_1.default.NAO, prisma_1.default.COMPRIMENTO)) {
const operador = this.simboloAnterior();
const direito = await this.unario();
return new construtos_1.Unario(this.hashArquivo, operador, direito);
}
return await this.chamar();
}
async exponenciacao() {
let expressao = await this.unario();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.EXPONENCIACAO)) {
const operador = this.simboloAnterior();
const direito = await this.unario();
expressao = new construtos_1.Binario(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async multiplicar() {
let expressao = await this.exponenciacao();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.DIVISAO, prisma_1.default.DIVISAO_INTEIRA, prisma_1.default.MULTIPLICACAO, prisma_1.default.MODULO)) {
const operador = this.simboloAnterior();
const direito = await this.exponenciacao();
expressao = new construtos_1.Binario(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async adicaoOuSubtracao() {
let expressao = await this.multiplicar();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.SUBTRACAO, prisma_1.default.ADICAO)) {
const operador = this.simboloAnterior();
const direito = await this.multiplicar();
expressao = new construtos_1.Binario(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async concatenacao() {
let expressao = await this.adicaoOuSubtracao();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.CONCATENACAO)) {
const operador = this.simboloAnterior();
const direito = await this.adicaoOuSubtracao();
expressao = new construtos_1.Binario(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async bitShift() {
let expressao = await this.concatenacao();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.MENOR_MENOR, prisma_1.default.MAIOR_MAIOR)) {
const operador = this.simboloAnterior();
const direito = await this.adicaoOuSubtracao();
expressao = new construtos_1.Binario(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async bitE() {
let expressao = await this.bitShift();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.BIT_AND)) {
const operador = this.simboloAnterior();
const direito = await this.bitShift();
expressao = new construtos_1.Binario(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async bitOu() {
let expressao = await this.bitE();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.BIT_OR, prisma_1.default.BIT_XOR)) {
const operador = this.simboloAnterior();
const direito = await this.bitE();
expressao = new construtos_1.Binario(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async comparar() {
let expressao = await this.bitOu();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.MAIOR, prisma_1.default.MAIOR_IGUAL, prisma_1.default.MENOR, prisma_1.default.MENOR_IGUAL)) {
const operador = this.simboloAnterior();
const direito = await this.bitOu();
expressao = new construtos_1.Binario(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async comparacaoIgualdade() {
let expressao = await this.comparar();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.DIFERENTE, prisma_1.default.IGUAL_IGUAL)) {
const operador = this.simboloAnterior();
const direito = await this.comparar();
expressao = new construtos_1.Binario(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async em() {
let expressao = await this.comparacaoIgualdade();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.EM)) {
const operador = this.simboloAnterior();
const direito = await this.comparacaoIgualdade();
expressao = new construtos_1.Logico(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async e() {
let expressao = await this.em();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.E)) {
const operador = this.simboloAnterior();
const direito = await this.em();
expressao = new construtos_1.Logico(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async ou() {
let expressao = await this.e();
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.OU)) {
const operador = this.simboloAnterior();
const direito = await this.e();
expressao = new construtos_1.Logico(this.hashArquivo, expressao, operador, direito);
}
return expressao;
}
async ternario() {
let expressaoOuCondicao = await this.ou();
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.INTERROGACAO)) {
const operador = this.simboloAnterior();
const caminhoEntao = await this.e();
this.consumir(prisma_1.default.OU, "Esperado palavra reservada 'ou' após caminho positivo em operador ternário.");
const caminhoSenao = await this.ternario();
expressaoOuCondicao = new construtos_1.SeTernario(this.hashArquivo, expressaoOuCondicao, caminhoEntao, operador, caminhoSenao);
}
return expressaoOuCondicao;
}
async atribuir() {
const expressao = await this.ternario();
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.IGUAL) ||
this.verificarSeSimboloAtualEIgualA(prisma_1.default.MAIS_IGUAL)) {
const igual = this.simboloAnterior();
const valor = await this.atribuir();
if (expressao instanceof construtos_1.Variavel) {
return new construtos_1.Atribuir(this.hashArquivo, expressao, valor);
}
if (expressao instanceof construtos_1.AcessoMetodoOuPropriedade) {
return new construtos_1.DefinirValor(this.hashArquivo, 0, expressao.objeto, expressao.simbolo, valor);
}
if (expressao instanceof construtos_1.AcessoIndiceVariavel) {
return new construtos_1.AtribuicaoPorIndice(this.hashArquivo, 0, expressao.entidadeChamada, expressao.indice, valor);
}
throw this.erro(igual, 'Tarefa de atribuição inválida');
}
return expressao;
}
async expressao() {
return await this.atribuir();
}
async declaracaoEscreva() {
const simboloEscreva = this.simboloAnterior();
this.consumir(prisma_1.default.PARENTESE_ESQUERDO, "Esperado '(' antes dos valores em imprima.");
const argumentos = [];
if (!this.verificarTipoSimboloAtual(prisma_1.default.PARENTESE_DIREITO)) {
do {
argumentos.push(await this.expressao());
} while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.VIRGULA));
}
this.consumir(prisma_1.default.PARENTESE_DIREITO, "Esperado ')' após os valores em imprima.");
this.verificarSeSimboloAtualEIgualA(prisma_1.default.PONTO_E_VIRGULA);
return new declaracoes_1.Escreva(Number(simboloEscreva.linha), simboloEscreva.hashArquivo, argumentos);
}
async declaracaoExpressao() {
const expressao = await this.expressao();
return new declaracoes_1.Expressao(expressao);
}
async blocoEscopo() {
this.pilhaEscopos.empilhar(new informacao_escopo_1.InformacaoEscopo());
let declaracoes = [];
while (!this.verificarTipoSimboloAtual(prisma_1.default.FIM) && !this.estaNoFinal()) {
const retornoDeclaracao = await this.resolverDeclaracaoForaDeBloco();
if (Array.isArray(retornoDeclaracao)) {
declaracoes = declaracoes.concat(retornoDeclaracao);
}
else {
declaracoes.push(retornoDeclaracao);
}
}
this.consumir(prisma_1.default.FIM, "Esperado 'fim' após o bloco.");
this.pilhaEscopos.removerUltimo();
return declaracoes.filter((d) => d);
}
async declaracaoDeLocal() {
const identificador = this.consumir(prisma_1.default.IDENTIFICADOR, 'Esperado nome de variável.');
let inicializador = null;
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.IGUAL)) {
inicializador = await this.expressao();
}
this.consumir(prisma_1.default.PONTO_E_VIRGULA, "Esperado ';' após declaração de variável.");
// Para Prisma, mantemos a tipagem inferida de forma simples por enquanto.
const tipo = 'qualquer';
this.pilhaEscopos.definirInformacoesVariavel(identificador.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(identificador.lexema, tipo));
return new declaracoes_1.Var(identificador, inicializador, tipo);
}
async declaracaoEnquanto() {
try {
this.blocos += 1;
const condicao = await this.expressao();
const bloco = (await this.resolverDeclaracao());
return new declaracoes_1.Enquanto(condicao, bloco);
}
finally {
this.blocos -= 1;
}
}
async declaracaoEscolha() {
try {
this.blocos += 1;
const condicao = await this.expressao();
const caminhos = [];
let caminhoPadrao = null;
while (!this.verificarTipoSimboloAtual(prisma_1.default.FIM) && !this.estaNoFinal()) {
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.CASO)) {
const caminhoCondicoes = [await this.expressao()];
while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.CASO)) {
caminhoCondicoes.push(await this.expressao());
}
this.consumir(prisma_1.default.ENTAO, "Esperado palavra reservada 'entao' ou 'então' após valor do 'caso'.");
const declaracoes = [];
while (!this.estaNoFinal() &&
![
prisma_1.default.CASO,
prisma_1.default.PADRAO,
prisma_1.default.FIM,
].includes(this.simbolos[this.atual].tipo)) {
declaracoes.push(await this.resolverDeclaracaoForaDeBloco());
}
caminhos.push({
condicoes: caminhoCondicoes,
declaracoes: declaracoes.filter((d) => d),
});
}
else if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.PADRAO)) {
if (caminhoPadrao !== null) {
const excecao = new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(this.simbolos[this.atual], "Você só pode ter um 'padrao' em cada declaração de 'escolha'.");
this.erros.push(excecao);
throw excecao;
}
this.consumir(prisma_1.default.ENTAO, "Esperado palavra reservada 'entao' ou 'então' após declaração do 'padrao'.");
const declaracoes = [];
while (!this.estaNoFinal() &&
![
prisma_1.default.CASO,
prisma_1.default.PADRAO,
prisma_1.default.FIM,
].includes(this.simbolos[this.atual].tipo)) {
declaracoes.push(await this.resolverDeclaracaoForaDeBloco());
}
caminhoPadrao = {
condicoes: [],
declaracoes: declaracoes.filter((d) => d),
};
}
else {
throw this.erro(this.simbolos[this.atual], "Esperado 'caso', 'padrao' ou 'fim' em declaração 'escolha'.");
}
}
this.consumir(prisma_1.default.FIM, "Esperado palavra-chave 'fim' para fechamento de declaração 'escolha'.");
return new declaracoes_1.Escolha(condicao, caminhos, caminhoPadrao);
}
finally {
this.blocos -= 1;
}
}
async declaracaoSe() {
const simboloSe = this.simbolos[this.atual];
const condicao = await this.expressao();
this.consumir(prisma_1.default.ENTAO, "Esperado palavra reservada 'entao' ou 'então' após condição em declaração 'se'.");
const declaracoes = [];
do {
declaracoes.push(await this.resolverDeclaracaoForaDeBloco());
} while (!this.estaNoFinal() &&
![prisma_1.default.SENAO, prisma_1.default.SENÃO, prisma_1.default.FIM].includes(this.simbolos[this.atual].tipo));
let caminhoSenao = null;
let fimConsumidoNoCaminhoSenao = false;
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.SENAO, prisma_1.default.SENÃO)) {
const simboloSenao = this.simbolos[this.atual - 1];
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.SE)) {
caminhoSenao = await this.declaracaoSe();
fimConsumidoNoCaminhoSenao = true;
}
else {
const declaracoesSenao = [];
do {
declaracoesSenao.push(await this.resolverDeclaracaoForaDeBloco());
} while (![prisma_1.default.FIM].includes(this.simbolos[this.atual].tipo));
caminhoSenao = new declaracoes_1.Bloco(this.hashArquivo, Number(simboloSenao.linha), declaracoesSenao.filter((d) => d));
}
}
if (!fimConsumidoNoCaminhoSenao) {
this.consumir(prisma_1.default.FIM, "Esperado palavra-chave 'fim' para fechamento de declaração 'se'.");
}
return new declaracoes_1.Se(condicao, new declaracoes_1.Bloco(this.hashArquivo, Number(simboloSe.linha), declaracoes.filter((d) => d)), [], caminhoSenao);
}
async declaracaoTente() {
const simboloTente = this.simboloAnterior();
const blocoTente = [];
while (!this.estaNoFinal() &&
![
prisma_1.default.PEGUE,
prisma_1.default.FINALMENTE,
prisma_1.default.FIM,
].includes(this.simbolos[this.atual].tipo)) {
blocoTente.push(await this.resolverDeclaracaoForaDeBloco());
}
let blocoPegue = null;
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.PEGUE)) {
const declaracoesPegue = [];
while (!this.estaNoFinal() &&
![prisma_1.default.FINALMENTE, prisma_1.default.FIM].includes(this.simbolos[this.atual].tipo)) {
declaracoesPegue.push(await this.resolverDeclaracaoForaDeBloco());
}
blocoPegue = declaracoesPegue.filter((d) => d);
}
let blocoFinalmente = null;
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.FINALMENTE)) {
const declaracoesFinalmente = [];
while (!this.estaNoFinal() && !this.verificarTipoSimboloAtual(prisma_1.default.FIM)) {
declaracoesFinalmente.push(await this.resolverDeclaracaoForaDeBloco());
}
blocoFinalmente = declaracoesFinalmente.filter((d) => d);
}
this.consumir(prisma_1.default.FIM, "Esperado palavra-chave 'fim' para fechamento de declaração 'tente'.");
return new declaracoes_1.Tente(simboloTente.hashArquivo, Number(simboloTente.linha), blocoTente.filter((d) => d), blocoPegue, null, blocoFinalmente);
}
async declaracaoQuebre() {
if (this.blocos < 1) {
throw this.erro(this.simboloAnterior(), "'quebre' deve estar dentro de um laço de repetição.");
}
this.consumir(prisma_1.default.PONTO_E_VIRGULA, "Esperado ';' após 'quebre'.");
return new declaracoes_1.Sustar(this.simbolos[this.atual]);
}
declaracaoContinua() {
if (this.blocos < 1) {
throw this.erro(this.simboloAnterior(), "'continua' precisa estar em um laço de repetição.");
}
this.consumir(prisma_1.default.PONTO_E_VIRGULA, "Esperado ';' após 'continua'.");
return new declaracoes_1.Continua(this.simbolos[this.atual]);
}
async declaracaoRetorna() {
const palavraChave = this.simboloAnterior();
let valor = null;
if (!this.verificarTipoSimboloAtual(prisma_1.default.PONTO_E_VIRGULA)) {
valor = await this.expressao();
}
this.consumir(prisma_1.default.PONTO_E_VIRGULA, "Esperado ';' após valor de retorno.");
return new declaracoes_1.Retorna(palavraChave, valor);
}
async declaracaoImportar() {
this.avancarEDevolverAnterior();
this.consumir(prisma_1.default.PARENTESE_ESQUERDO, "Esperado '(' após declaração.");
const caminho = await this.expressao();
this.consumir(prisma_1.default.PARENTESE_DIREITO, "Esperado ')' após declaração.");
return new declaracoes_1.Importar(caminho);
}
async corpoDaFuncao(tipo) {
const parenteseEsquerdo = this.consumir(prisma_1.default.PARENTESE_ESQUERDO, `Esperado '(' após o nome ${tipo}.`);
let parametros = [];
if (!this.verificarTipoSimboloAtual(prisma_1.default.PARENTESE_DIREITO)) {
parametros = await this.logicaComumParametros();
}
this.consumir(prisma_1.default.PARENTESE_DIREITO, "Esperado ')' após parâmetros.");
let tipoRetorno = 'qualquer';
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.SETA)) {
tipoRetorno = 'qualquer'; // Simplificado por enquanto
}
const corpo = await this.blocoEscopo();
return new construtos_1.FuncaoConstruto(this.hashArquivo, 0, parametros, corpo, tipoRetorno, false);
}
async logicaComumParametros() {
const parametros = [];
do {
if (parametros.length >= 255) {
throw this.erro(this.simbolos[this.atual], 'Função não pode ter mais de 255 parâmetros.');
}
const parametro = {};
parametro.abrangencia = 'padrao';
parametro.nome = this.consumir(prisma_1.default.IDENTIFICADOR, 'Esperado nome do parâmetro.');
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.IGUAL)) {
parametro.valorPadrao = await this.primario();
}
this.pilhaEscopos.definirInformacoesVariavel(parametro.nome.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(parametro.nome.lexema, parametro.tipoDado || 'qualquer'));
parametros.push(parametro);
} while (this.verificarSeSimboloAtualEIgualA(prisma_1.default.VIRGULA));
return parametros;
}
async funcao(tipo) {
const simbolo = this.consumir(prisma_1.default.IDENTIFICADOR, `Esperado nome ${tipo}.`);
this.pilhaEscopos.definirInformacoesVariavel(simbolo.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(simbolo.lexema, 'qualquer'));
const corpoDaFuncao = await this.corpoDaFuncao(tipo);
const tipoDaFuncao = `função<${corpoDaFuncao.tipo}>`;
this.pilhaEscopos.definirInformacoesVariavel(simbolo.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(simbolo.lexema, tipoDaFuncao));
const funcaoDeclaracao = new declaracoes_1.FuncaoDeclaracao(simbolo, corpoDaFuncao, tipoDaFuncao);
this.pilhaEscopos.registrarReferenciaFuncao(simbolo.lexema, funcaoDeclaracao);
return funcaoDeclaracao;
}
async resolverDeclaracao() {
const simboloAtual = this.simbolos[this.atual];
switch (simboloAtual.tipo) {
case prisma_1.default.CONTINUA:
this.avancarEDevolverAnterior();
return this.declaracaoContinua();
case prisma_1.default.PONTO_E_VIRGULA:
// Ignora ponto e vírgula supérfluo
this.avancarEDevolverAnterior();
return null;
case prisma_1.default.ENTAO:
case prisma_1.default.INICIO:
case prisma_1.default.FAZER:
const simboloInicioBloco = this.avancarEDevolverAnterior();
return new declaracoes_1.Bloco(simboloInicioBloco.hashArquivo, Number(simboloInicioBloco.linha), await this.blocoEscopo());
case prisma_1.default.ENQUANTO:
this.avancarEDevolverAnterior();
return await this.declaracaoEnquanto();
case prisma_1.default.ESCOLHA:
this.avancarEDevolverAnterior();
return await this.declaracaoEscolha();
case prisma_1.default.IDENTIFICADOR:
const proximoSimbolo = this.simbolos[this.atual + 1];
if (proximoSimbolo && proximoSimbolo.tipo === prisma_1.default.IGUAL) {
return await this.declaracaoOuAtribuicaoVariaveis();
}
// Avaliar como expressão normal, sair do `switch`.
break;
case prisma_1.default.IMPRIMA:
this.avancarEDevolverAnterior();
return await this.declaracaoEscreva();
case prisma_1.default.PARA:
return await this.declaracaoPara();
case prisma_1.default.QUEBRE:
this.avancarEDevolverAnterior();
return this.declaracaoQuebre();
case prisma_1.default.SE:
this.avancarEDevolverAnterior();
return await this.declaracaoSe();
case prisma_1.default.RETORNE:
this.avancarEDevolverAnterior();
return await this.declaracaoRetorna();
case prisma_1.default.TENTE:
this.avancarEDevolverAnterior();
return await this.declaracaoTente();
case prisma_1.default.LOCAL:
this.avancarEDevolverAnterior();
return await this.declaracaoDeLocal();
}
return await this.declaracaoExpressao();
}
async declaracaoOuAtribuicaoVariaveis() {
const identificador = this.avancarEDevolverAnterior();
this.consumir(prisma_1.default.IGUAL, "Esperado '=' após identificador.");
if (this.estaNoFinal()) {
throw this.erro(this.simboloAnterior(), 'Esperado valor após o símbolo de igual.');
}
const valor = await this.expressao();
const tipo = this.logicaComumInferenciaTiposVariaveisEConstantes(valor, 'qualquer');
if (this.pilhaEscopos.variavelJaDefinida(identificador.lexema)) {
return new declaracoes_1.Expressao(new construtos_1.Atribuir(identificador.hashArquivo, new construtos_1.Variavel(identificador.hashArquivo, identificador), valor));
}
const retornoVar = new declaracoes_1.Var(identificador, valor, tipo);
// Pelo manual de Prisma, variáveis implícitas estão sempre no escopo global.
retornoVar.escopo = 'global';
return retornoVar;
}
/**
* Segundo o manual de Prisma, os tipos válidos para a linguagem são:
* número, string , tabela, funcao , userdata, boolean, nulo.
* @param inicializador O construto do inicializador.
* @param tipoPrevio Se há um tipo prévio definido. `qualquer` não é válido em Prisma:
* O tipo sempre resolve para algum outro.
* @returns O tipo inferido.
*/
logicaComumInferenciaTiposVariaveisEConstantes(inicializador, tipoPrevio) {
if (tipoPrevio !== 'qualquer') {
return tipoPrevio;
}
switch (inicializador.constructor) {
case construtos_1.Literal:
return inicializador.tipo;
// TODO: Terminar
default:
console.log(inicializador.constructor.name);
}
}
async declaracaoParaCada(simboloPara) {
const variavelIteracao = this.consumir(prisma_1.default.IDENTIFICADOR, "Esperado identificador de variável após 'para cada'.");
this.consumir(prisma_1.default.EM, "Esperado palavra reservada 'em' após variável de iteração.");
const vetorOuDicionario = await this.expressao();
this.consumir(prisma_1.default.INICIO, `espera-se 'inicio' proximo a '${this.simbolos[this.atual].lexema}'.`);
this.pilhaEscopos.definirInformacoesVariavel(variavelIteracao.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(variavelIteracao.lexema, 'qualquer'));
const declaracoesBlocoParaCada = [];
while (!this.estaNoFinal() && !this.verificarTipoSimboloAtual(prisma_1.default.FIM)) {
declaracoesBlocoParaCada.push(await this.resolverDeclaracaoForaDeBloco());
}
this.consumir(prisma_1.default.FIM, "Esperado 'fim' após bloco do para cada.");
const corpo = new declaracoes_1.Bloco(this.hashArquivo, Number(simboloPara.linha) + 1, declaracoesBlocoParaCada.filter((d) => d));
return new declaracoes_1.ParaCada(this.hashArquivo, Number(simboloPara.linha), new construtos_1.Variavel(this.hashArquivo, variavelIteracao, 'qualquer'), vetorOuDicionario, corpo);
}
async declaracaoPara() {
try {
this.blocos += 1;
const simboloPara = this.avancarEDevolverAnterior();
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.CADA)) {
return await this.declaracaoParaCada(simboloPara);
}
const variavelIteracao = this.consumir(prisma_1.default.IDENTIFICADOR, "Esperado identificador de variável após 'para'.");
this.consumir(prisma_1.default.IGUAL, `'=' or 'em' esperado próximo a '${this.simbolos[this.atual].lexema}'.`);
const literalOuVariavelInicio = await this.adicaoOuSubtracao();
this.consumir(prisma_1.default.VIRGULA, `Espera-se '=' próximo a '${this.simbolos[this.atual].lexema}'.`);
const literalOuVariavelFim = await this.adicaoOuSubtracao();
let operadorCondicao = new lexador_1.Simbolo(prisma_1.default.MENOR_IGUAL, '<=', null, Number(simboloPara.linha), this.hashArquivo);
let passo = new construtos_1.Literal(this.hashArquivo, Number(simboloPara.linha), 1);
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.VIRGULA)) {
passo = await this.adicaoOuSubtracao();
}
if (!this.verificarSeSimboloAtualEIgualA(prisma_1.default.INICIO, prisma_1.default.FAZER)) {
throw this.erro(this.simbolos[this.atual], `espera-se 'inicio' ou 'fazer' proximo a '${this.simbolos[this.atual].lexema}'.`);
}
// Aqui já é seguro inicializar a variável.
this.pilhaEscopos.definirInformacoesVariavel(variavelIteracao.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(variavelIteracao.lexema, 'inteiro'));
const declaracoesBlocoPara = [];
let simboloAtualBlocoPara = this.simbolos[this.atual];
while (simboloAtualBlocoPara.tipo !== prisma_1.default.FIM) {
declaracoesBlocoPara.push(await this.resolverDeclaracaoForaDeBloco());
simboloAtualBlocoPara = this.simbolos[this.atual];
}
this.avancarEDevolverAnterior(); // fim
const corpo = new declaracoes_1.Bloco(this.hashArquivo, Number(simboloPara.linha) + 1, declaracoesBlocoPara.filter((d) => d));
const para = new declaracoes_1.Para(this.hashArquivo, Number(simboloPara.linha),
// Inicialização: declara a variável de iteração.
new declaracoes_1.Var(variavelIteracao, literalOuVariavelInicio, 'inteiro'),
// Condição.
new construtos_1.Binario(this.hashArquivo, new construtos_1.Variavel(this.hashArquivo, variavelIteracao, 'inteiro'), operadorCondicao, literalOuVariavelFim),
// Incremento simples.
new construtos_1.Atribuir(this.hashArquivo, new construtos_1.Variavel(this.hashArquivo, variavelIteracao, 'inteiro'), new construtos_1.Binario(this.hashArquivo, new construtos_1.Variavel(this.hashArquivo, variavelIteracao, 'inteiro'), new lexador_1.Simbolo(prisma_1.default.ADICAO, '+', null, Number(simboloPara.linha), this.hashArquivo), passo)), corpo);
return para;
}
finally {
this.blocos -= 1;
}
}
async resolverDeclaracaoForaDeBloco() {
try {
if ((this.verificarTipoSimboloAtual(prisma_1.default.FUNCAO) ||
this.verificarTipoSimboloAtual(prisma_1.default.FUNÇÃO)) &&
this.verificarTipoProximoSimbolo(prisma_1.default.IDENTIFICADOR)) {
this.avancarEDevolverAnterior();
return await this.funcao('funcao');
}
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.CLASSE))
return await this.declaracaoDeClasse();
return await this.resolverDeclaracao();
}
catch (erro) {
this.sincronizar();
this.erros.push(erro);
return null;
}
}
async metodoClassePrisma(construtor) {
const simbolo = construtor
? new lexador_1.Simbolo(prisma_1.default.CONSTRUTOR, 'construtor', null, Number(this.simboloAnterior().linha), this.hashArquivo)
: this.consumir(prisma_1.default.IDENTIFICADOR, 'Esperado nome do método.');
this.consumir(prisma_1.default.PARENTESE_ESQUERDO, "Esperado '(' após nome do método.");
let parametros = [];
if (!this.verificarTipoSimboloAtual(prisma_1.default.PARENTESE_DIREITO)) {
parametros = await this.logicaComumParametros();
}
this.consumir(prisma_1.default.PARENTESE_DIREITO, "Esperado ')' após parâmetros.");
this.consumir(prisma_1.default.CHAVE_ESQUERDA, "Esperado '{' antes do corpo do método.");
const declaracoesCorpo = [];
while (!this.estaNoFinal() && !this.verificarTipoSimboloAtual(prisma_1.default.CHAVE_DIREITA)) {
declaracoesCorpo.push(await this.resolverDeclaracaoForaDeBloco());
}
this.consumir(prisma_1.default.CHAVE_DIREITA, "Esperado '}' após o corpo do método.");
const corpoDaFuncao = new construtos_1.FuncaoConstruto(this.hashArquivo, Number(simbolo.linha), parametros, declaracoesCorpo.filter((d) => d), 'qualquer', false);
const tipoDaFuncao = `função<${corpoDaFuncao.tipo}>`;
return new declaracoes_1.FuncaoDeclaracao(simbolo, corpoDaFuncao, tipoDaFuncao);
}
propriedadesDeclaradasEmMetodo(metodo) {
const propriedades = [];
const nomesPropriedades = new Set();
for (const declaracao of metodo.funcao.corpo) {
if (!(declaracao instanceof declaracoes_1.Expressao)) {
continue;
}
if (!(declaracao.expressao instanceof construtos_1.DefinirValor)) {
continue;
}
if (!(declaracao.expressao.objeto instanceof construtos_1.Isto)) {
continue;
}
const nomePropriedade = declaracao.expressao.nome.lexema;
if (nomesPropriedades.has(nomePropriedade)) {
continue;
}
nomesPropriedades.add(nomePropriedade);
propriedades.push(new declaracoes_1.PropriedadeClasse(declaracao.expressao.nome, 'qualquer'));
}
return propriedades;
}
async declaracaoDeClasse() {
const simbolo = this.consumir(prisma_1.default.IDENTIFICADOR, 'Esperado nome da classe.');
let superClasse = null;
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.PARENTESE_ESQUERDO)) {
const simboloSuperclasse = this.consumir(prisma_1.default.IDENTIFICADOR, 'Esperado nome da Superclasse.');
this.superclasseAtual = simboloSuperclasse.lexema;
superClasse = new construtos_1.Variavel(this.hashArquivo, this.simboloAnterior());
this.consumir(prisma_1.default.PARENTESE_DIREITO, "Esperado ')' após declaração.");
}
this.consumir(prisma_1.default.CHAVE_ESQUERDA, "Esperado '{' antes do escopo da classe.");
const metodos = [];
while (!this.estaNoFinal() &&
(this.verificarTipoSimboloAtual(prisma_1.default.CONSTRUTOR) ||
this.verificarTipoSimboloAtual(prisma_1.default.FUNCAO) ||
this.verificarTipoSimboloAtual(prisma_1.default.FUNÇÃO))) {
if (this.verificarSeSimboloAtualEIgualA(prisma_1.default.CONSTRUTOR)) {
metodos.push(await this.metodoClassePrisma(true));
continue;
}
this.verificarSeSimboloAtualEIgualA(prisma_1.default.FUNCAO, prisma_1.default.FUNÇÃO);
metodos.push(await this.metodoClassePrisma(false));
}
this.consumir(prisma_1.default.CHAVE_DIREITA, "Esperado '}' após métodos da classe.");
const propriedades = [];
const nomesPropriedades = new Set();
for (const metodo of metodos) {
const propriedadesDoMetodo = this.propriedadesDeclaradasEmMetodo(metodo);
for (const propriedade of propriedadesDoMetodo) {
if (nomesPropriedades.has(propriedade.nome.lexema)) {
continue;
}
nomesPropriedades.add(propriedade.nome.lexema);
propriedades.push(propriedade);
}
}
this.superclasseAtual = undefined;
const definicaoClasse = new declaracoes_1.Classe(simbolo, superClasse ? [superClasse] : [], metodos, propriedades);
this.tiposDefinidosEmCodigo[definicaoClasse.simbolo.lexema] = definicaoClasse;
return definicaoClasse;
}
inicializarPilhaEscopos() {
this.pilhaEscopos = new pilha_escopos_1.PilhaEscopos();
this.pilhaEscopos.empilhar(new informacao_escopo_1.InformacaoEscopo());
// Registrar funções nativas (built-ins) do Prisma no escopo do parser
// para evitar erros de variável não definida durante análise semântica
this.pilhaEscopos.definirInformacoesVariavel('tipo', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tipo', 'função', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valor', 'qualquer'),
]));
this.pilhaEscopos.definirInformacoesVariavel('poe', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('poe', 'função', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valores', 'qualquer'),
]));
this.pilhaEscopos.definirInformacoesVariavel('tamanho', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tamanho', 'número', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('objeto', 'qualquer'),
]));
this.pilhaEscopos.definirInformacoesVariavel('pares', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('pares', 'tabela', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tabela', 'tabela'),
]));
this.pilhaEscopos.definirInformacoesVariavel('ipares', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('ipares', 'tabela', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tabela', 'tabela'),
]));
this.pilhaEscopos.definirInformacoesVariavel('convnumero', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('convnumero', 'número', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valor', 'qualquer'),
]));
this.pilhaEscopos.definirInformacoesVariavel('convstring', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('convstring', 'texto', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valor', 'qualquer'),
]));
this.pilhaEscopos.definirInformacoesVariavel('aleatorio', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('aleatorio', 'função', true, []));
this.pilhaEscopos.definirInformacoesVariavel('aleatorio_entre', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('aleatorio_entre', 'número', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('minimo', 'número'),
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('maximo', 'número'),
]));
this.pilhaEscopos.definirInformacoesVariavel('coletelixo', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('coletelixo', 'número', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('acao', 'texto'),
]));
this.pilhaEscopos.definirInformacoesVariavel('piso', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('piso', 'número', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('n', 'número'),
]));
this.pilhaEscopos.definirInformacoesVariavel('teto', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('teto', 'número', true, [
new informacao_elemento_sintatico_1.InformacaoElementoSintatico('n', 'número'),
]));
}
async analisar(retornoLexador, hashArquivo) {
const inicioAnalise = (0, browser_process_hrtime_1.default)();
this.erros = [];
this.atual = 0;
this.blocos = 0;
this.inicializarPilhaEscopos();
this.tiposDefinidosEmCodigo = {};
this.hashArquivo = hashArquivo || 0;
this.simbolos = (retornoLexador === null || retornoLexador === void 0 ? void 0 : retornoLexador.simbolos) || [];
let declaracoes = [];
while (!this.estaNoFinal()) {
const retornoDeclaracao = await this.resolverDeclaracaoForaDeBloco();
if (Array.isArray(retornoDeclaracao)) {
declaracoes = declaracoes.concat(retornoDeclaracao);
}
else if (retornoDeclaracao !== null) {
declaracoes.push(retornoDeclaracao);
}
}
if (this.performance) {
const deltaAnalise = (0, browser_process_hrtime_1.default)(inicioAnalise);
console.log(`[Avaliador Sintático] Tempo para análise: ${deltaAnalise[0] * 1e9 + deltaAnalise[1]}ns`);
}
return {
declaracoes: declaracoes,
erros: this.erros,
};
}
}
exports.AvaliadorSintaticoPrisma = AvaliadorSintaticoPrisma;
//# sourceMappingURL=avaliador-sintatico-prisma.js.map