UNPKG

@designliquido/delegua

Version:

Linguagem de programação simples e moderna usando português estruturado.

547 lines 28.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AvaliadorSintaticoPortugolIpt = void 0; const construtos_1 = require("../../construtos"); const simbolo_1 = require("../../lexador/simbolo"); const declaracoes_1 = require("../../declaracoes"); const avaliador_sintatico_base_1 = require("../avaliador-sintatico-base"); const portugol_ipt_1 = __importDefault(require("../../tipos-de-simbolos/portugol-ipt")); class AvaliadorSintaticoPortugolIpt extends avaliador_sintatico_base_1.AvaliadorSintaticoBase { simboloAtualEh(tipo) { return !this.estaNoFinal() && this.simbolos[this.atual].tipo === tipo; } fechamentoEnquantoAtual() { return (this.simboloAtualEh(portugol_ipt_1.default.FIMENQUANTO) || (this.simboloAtualEh(portugol_ipt_1.default.FIM) && this.simbolos[this.atual + 1]?.tipo === portugol_ipt_1.default.ENQUANTO)); } consumirFechamentoEnquanto() { if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.FIMENQUANTO)) { return; } this.consumir(portugol_ipt_1.default.FIM, "Esperado 'fimenquanto' ou 'fim enquanto'."); this.consumir(portugol_ipt_1.default.ENQUANTO, "Esperado 'enquanto' após 'fim'."); } fechamentoEscolheAtual() { return (this.simboloAtualEh(portugol_ipt_1.default.FIMESCOLHE) || (this.simboloAtualEh(portugol_ipt_1.default.FIM) && this.simbolos[this.atual + 1]?.tipo === portugol_ipt_1.default.ESCOLHE)); } consumirFechamentoEscolhe() { if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.FIMESCOLHE)) { return; } this.consumir(portugol_ipt_1.default.FIM, "Esperado 'fimescolhe' ou 'fim escolhe'."); this.consumir(portugol_ipt_1.default.ESCOLHE, "Esperado 'escolhe' após 'fim'."); } avaliarExpressaoNumericaConstante(expressao) { if (expressao instanceof construtos_1.Literal && typeof expressao.valor === 'number') { return Number(expressao.valor); } if (expressao instanceof construtos_1.Agrupamento) { return this.avaliarExpressaoNumericaConstante(expressao.expressao); } if (expressao instanceof construtos_1.Unario) { const operando = this.avaliarExpressaoNumericaConstante(expressao.operando); if (operando === null) return null; switch (expressao.operador.tipo) { case portugol_ipt_1.default.SUBTRACAO: return -operando; default: return null; } } if (expressao instanceof construtos_1.Binario) { const esquerda = this.avaliarExpressaoNumericaConstante(expressao.esquerda); const direita = this.avaliarExpressaoNumericaConstante(expressao.direita); if (esquerda === null || direita === null) return null; switch (expressao.operador.tipo) { case portugol_ipt_1.default.ADICAO: return esquerda + direita; case portugol_ipt_1.default.SUBTRACAO: return esquerda - direita; case portugol_ipt_1.default.MULTIPLICACAO: return esquerda * direita; case portugol_ipt_1.default.DIVISAO: return esquerda / direita; case portugol_ipt_1.default.MODULO: return esquerda % direita; case portugol_ipt_1.default.EXPONENCIACAO: return Math.pow(esquerda, direita); default: return null; } } return null; } // ── Helpers ──────────────────────────────────────────────────────────────── /** * Consome quebras de linha opcionais. */ consumirQuebrasLinha() { while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.QUEBRA_LINHA)) ; } /** * Coleta declarações até encontrar um token cujo tipo esteja em `tiposParada`. * O token de parada NÃO é consumido. */ async resolverBloco(tiposParada) { const declaracoes = []; const primeiroSimbolo = this.simbolos[this.atual]; while (!this.estaNoFinal() && !tiposParada.includes(this.simbolos[this.atual].tipo)) { const resolucao = await this.resolverDeclaracaoForaDeBloco(); if (Array.isArray(resolucao)) { declaracoes.push(...resolucao); } else if (resolucao !== null && resolucao !== undefined) { declaracoes.push(resolucao); } } return new declaracoes_1.Bloco(this.hashArquivo, Number(primeiroSimbolo?.linha ?? 0), declaracoes.filter((d) => d)); } // ── Expressões ───────────────────────────────────────────────────────────── async primario() { switch (this.simbolos[this.atual].tipo) { case portugol_ipt_1.default.IDENTIFICADOR: { const simboloIdentificador = this.avancarEDevolverAnterior(); return new construtos_1.Variavel(this.hashArquivo, simboloIdentificador); } case portugol_ipt_1.default.INTEIRO: case portugol_ipt_1.default.NUMERO: case portugol_ipt_1.default.TEXTO: { const simboloAnterior = this.avancarEDevolverAnterior(); if (simboloAnterior.literal === null) { throw this.erro(simboloAnterior, 'Esperado expressão.'); } return new construtos_1.Literal(this.hashArquivo, Number(simboloAnterior.linha), simboloAnterior.literal); } case portugol_ipt_1.default.PARENTESE_ESQUERDO: { this.avancarEDevolverAnterior(); const expressao = await this.expressao(); this.consumir(portugol_ipt_1.default.PARENTESE_DIREITO, "Esperado ')' após a expressão."); return new construtos_1.Agrupamento(this.hashArquivo, Number(this.simbolos[this.atual].linha), expressao); } } throw this.erro(this.simbolos[this.atual], 'Esperado expressão.'); } /** * Suporta chamadas de funções embutidas: SEN(x), COS(x), POTENCIA(b,e), etc. */ async chamar() { let expressao = await this.primario(); while (true) { if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.PARENTESE_ESQUERDO)) { const argumentos = []; if (!this.verificarTipoSimboloAtual(portugol_ipt_1.default.PARENTESE_DIREITO)) { do { argumentos.push(await this.expressao()); } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.VIRGULA)); } this.consumir(portugol_ipt_1.default.PARENTESE_DIREITO, "Esperado ')' após argumentos."); expressao = new construtos_1.Chamada(this.hashArquivo, expressao, argumentos); } else if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.COLCHETE_ESQUERDO)) { const indice = await this.expressao(); const fechamento = this.consumir(portugol_ipt_1.default.COLCHETE_DIREITO, "Esperado ']' após índice."); expressao = new construtos_1.AcessoIndiceVariavel(this.hashArquivo, expressao, indice, fechamento); } else { break; } } return expressao; } /** * Override de `unario()` para incluir operadores unários aritméticos. * `NAO` é tratado em `e()` para ter precedência menor que comparações. */ async unario() { if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.NEGACAO, portugol_ipt_1.default.SUBTRACAO)) { const operador = this.simbolos[this.atual - 1]; const direito = await this.unario(); return new construtos_1.Unario(this.hashArquivo, operador, direito, 'ANTES'); } return await this.chamar(); } /** * Override de `e()` para suportar o operador lógico `NAO` com precedência * menor que comparações: `nao x = 0` → `nao (x = 0)`. */ async e() { let expressao; if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.NAO)) { const operador = this.simbolos[this.atual - 1]; const operando = await this.comparacaoIgualdade(); expressao = new construtos_1.Unario(this.hashArquivo, operador, operando, 'ANTES'); } else { expressao = await this.comparacaoIgualdade(); } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.E)) { const operador = this.simbolos[this.atual - 1]; const direito = await this.comparacaoIgualdade(); expressao = new construtos_1.Logico(this.hashArquivo, expressao, operador, direito); } return expressao; } /** * Override de `ou()` para incluir o operador lógico `XOU`. */ async ou() { let expressao = await this.e(); while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.OU, portugol_ipt_1.default.XOU)) { const operador = this.simbolos[this.atual - 1]; const direito = await this.e(); expressao = new construtos_1.Logico(this.hashArquivo, expressao, operador, direito); } return expressao; } async atribuir() { const expressao = await this.ou(); if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.SETA_ATRIBUICAO)) { const setaAtribuicao = this.simbolos[this.atual - 1]; 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.AcessoIndiceVariavel) { return new construtos_1.AtribuicaoPorIndice(this.hashArquivo, expressao.linha, expressao.entidadeChamada, expressao.indice, valor); } throw this.erro(setaAtribuicao, 'Tarefa de atribuição inválida'); } return expressao; } // ── Declarações ──────────────────────────────────────────────────────────── /** * `escrever expr [, expr ...]` */ async declaracaoEscreva() { const simboloAtual = this.avancarEDevolverAnterior(); const argumentos = []; do { const valor = await this.expressao(); argumentos.push(new construtos_1.FormatacaoEscrita(this.hashArquivo, Number(simboloAtual.linha), valor)); } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.VIRGULA)); return new declaracoes_1.EscrevaMesmaLinha(Number(simboloAtual.linha), this.hashArquivo, argumentos); } /** * `se cond entao ... [senao ...] fimse` */ async declaracaoSe() { this.avancarEDevolverAnterior(); // consome 'se' const condicao = await this.expressao(); this.consumir(portugol_ipt_1.default.ENTAO, "Esperado 'então' após condição do se."); this.consumirQuebrasLinha(); const caminhoEntao = await this.resolverBloco([ portugol_ipt_1.default.SENAO, portugol_ipt_1.default.FIMSE, ]); this.consumirQuebrasLinha(); let caminhoSenao = null; if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.SENAO)) { this.consumirQuebrasLinha(); caminhoSenao = await this.resolverBloco([portugol_ipt_1.default.FIMSE]); } this.consumirQuebrasLinha(); this.consumir(portugol_ipt_1.default.FIMSE, "Esperado 'fimse' para fechar instrução se."); return new declaracoes_1.Se(condicao, caminhoEntao, [], caminhoSenao); } /** * `enquanto cond faz ... fimenquanto` */ async declaracaoEnquanto() { this.avancarEDevolverAnterior(); // consome 'enquanto' const condicao = await this.expressao(); this.consumir(portugol_ipt_1.default.FAZ, "Esperado 'faz' após condição do enquanto."); this.consumirQuebrasLinha(); const declaracoes = []; const primeiroSimbolo = this.simbolos[this.atual]; while (!this.estaNoFinal() && !this.fechamentoEnquantoAtual()) { const resolucao = await this.resolverDeclaracaoForaDeBloco(); if (Array.isArray(resolucao)) { declaracoes.push(...resolucao); } else if (resolucao !== null && resolucao !== undefined) { declaracoes.push(resolucao); } } const corpo = new declaracoes_1.Bloco(this.hashArquivo, Number(primeiroSimbolo?.linha ?? 0), declaracoes.filter((d) => d)); this.consumirFechamentoEnquanto(); return new declaracoes_1.Enquanto(condicao, corpo); } /** * `para v de ini ate fim [passo p]` + corpo + `proximo` */ async declaracaoPara() { const simboloPara = this.avancarEDevolverAnterior(); // consome 'para' const linha = Number(simboloPara.linha); const identificador = this.consumir(portugol_ipt_1.default.IDENTIFICADOR, "Esperado identificador após 'para'."); this.consumir(portugol_ipt_1.default.DE, "Esperado 'de' após variável do 'para'."); const inicioExpr = await this.expressao(); this.consumir(portugol_ipt_1.default.ATE, "Esperado 'ate' após valor inicial do 'para'."); const fimExpr = await this.expressao(); let passoExpr = new construtos_1.Literal(this.hashArquivo, linha, 1, 'inteiro'); if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.PASSO)) { passoExpr = await this.expressao(); } this.consumirQuebrasLinha(); const corpo = await this.resolverBloco([portugol_ipt_1.default.PROXIMO]); this.consumir(portugol_ipt_1.default.PROXIMO, "Esperado 'proximo' para fechar o laço 'para'."); const varIteracao = new construtos_1.Variavel(this.hashArquivo, identificador, 'inteiro'); const simboloMenorIgual = new simbolo_1.Simbolo(portugol_ipt_1.default.MENOR_IGUAL, '<=', null, linha, this.hashArquivo); const simboloAdicao = new simbolo_1.Simbolo(portugol_ipt_1.default.ADICAO, '+', null, linha, this.hashArquivo); const inicializador = new declaracoes_1.Expressao(new construtos_1.Atribuir(this.hashArquivo, varIteracao, inicioExpr)); const condicao = new construtos_1.Binario(this.hashArquivo, varIteracao, simboloMenorIgual, fimExpr); const incrementar = new construtos_1.Atribuir(this.hashArquivo, varIteracao, new construtos_1.Binario(this.hashArquivo, varIteracao, simboloAdicao, passoExpr)); return new declaracoes_1.Para(this.hashArquivo, linha, inicializador, condicao, incrementar, corpo); } /** * `repete ... ate cond` * Semântica: executa o corpo e repete enquanto a condição for FALSA (repeat-until). * Mapeado para `Fazer` com a condição invertida via `nao`. */ async declaracaoRepete() { const simboloRepete = this.avancarEDevolverAnterior(); // consome 'repete' this.consumirQuebrasLinha(); const corpo = await this.resolverBloco([portugol_ipt_1.default.ATE]); this.consumir(portugol_ipt_1.default.ATE, "Esperado 'ate' para fechar o laço 'repete'."); const condicaoAte = await this.expressao(); // Inverte a condição: o loop continua enquanto `ate cond` for falso const operadorNao = new simbolo_1.Simbolo(portugol_ipt_1.default.NAO, 'nao', null, condicaoAte.linha, this.hashArquivo); const condicaoInvertida = new construtos_1.Unario(this.hashArquivo, operadorNao, condicaoAte, 'ANTES'); return new declaracoes_1.Fazer(this.hashArquivo, Number(simboloRepete.linha), corpo, condicaoInvertida); } /** * `faz ... enquanto cond` * O `enquanto` de fechamento é distinguido no lexer (FAZENQUANTO) do `enquanto` de abertura. */ async declaracaoFazer() { const simboloFaz = this.avancarEDevolverAnterior(); // consome 'faz' this.consumirQuebrasLinha(); const corpo = await this.resolverBloco([portugol_ipt_1.default.FAZENQUANTO]); this.consumir(portugol_ipt_1.default.FAZENQUANTO, "Esperado 'enquanto' para fechar o laço 'faz'."); const condicao = await this.expressao(); return new declaracoes_1.Fazer(this.hashArquivo, Number(simboloFaz.linha), corpo, condicao); } /** * `escolhe expr caso v[, v...]: instr ... [defeito: instr] fimescolhe` */ declaracaoEscolha() { this.avancarEDevolverAnterior(); // consome 'escolhe' const identificador = this.primario(); // A versão síncrona é necessária porque a interface do base declara este como não-async. // Fazemos o cast após — o analisar() é async e usa await nos callers. throw new Error('Use declaracaoEscolhaAsync() internamente.'); } async declaracaoEscolhaAsync() { this.avancarEDevolverAnterior(); // consome 'escolhe' const identificador = await this.expressao(); this.consumirQuebrasLinha(); const caminhos = []; let caminhoPadrao = null; while (!this.estaNoFinal() && !this.fechamentoEscolheAtual()) { this.consumirQuebrasLinha(); if (this.estaNoFinal() || this.fechamentoEscolheAtual()) { break; } if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.CASO)) { // Múltiplos valores por caso: `caso 1, 2, 3:` const condicoes = []; do { condicoes.push(await this.expressao()); } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.VIRGULA)); this.consumir(portugol_ipt_1.default.DOIS_PONTOS, "Esperado ':' após valor do 'caso'."); this.consumirQuebrasLinha(); const bloco = await this.resolverBloco([ portugol_ipt_1.default.CASO, portugol_ipt_1.default.DEFEITO, portugol_ipt_1.default.FIMESCOLHE, portugol_ipt_1.default.FIM, ]); caminhos.push({ condicoes, declaracoes: bloco.declaracoes }); } else if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.DEFEITO)) { this.consumir(portugol_ipt_1.default.DOIS_PONTOS, "Esperado ':' após 'defeito'."); this.consumirQuebrasLinha(); const bloco = await this.resolverBloco([ portugol_ipt_1.default.FIMESCOLHE, portugol_ipt_1.default.FIM, ]); caminhoPadrao = { condicoes: [], declaracoes: bloco.declaracoes }; } else { break; } } this.consumirFechamentoEscolhe(); return new declaracoes_1.Escolha(identificador, caminhos, caminhoPadrao); } /** * `ler var [, var ...]` */ async expressaoLeia() { const simboloAtual = this.avancarEDevolverAnterior(); const argumentos = []; do { argumentos.push(await this.resolverDeclaracaoForaDeBloco()); } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.VIRGULA)); return new construtos_1.Leia(simboloAtual, argumentos); } /** * Declara variáveis de um dado tipo, com suporte a arrays e valor inicial. * Ex: `inteiro x`, `real y = 3.14`, `logico v[5]` */ async declaracaoVariaveis(tipoToken, tipoDelegua, valorPadrao) { const simboloTipo = this.avancarEDevolverAnterior(); const linha = Number(simboloTipo.linha); const inicializacoes = []; do { const identificador = this.consumir(portugol_ipt_1.default.IDENTIFICADOR, `Esperado identificador após '${simboloTipo.lexema}'.`); // Array: `inteiro v[10]` if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.COLCHETE_ESQUERDO)) { const expressaoTamanho = await this.expressao(); const tamanhoConstante = this.avaliarExpressaoNumericaConstante(expressaoTamanho); if (tamanhoConstante === null || !Number.isInteger(tamanhoConstante) || tamanhoConstante < 0) { throw this.erro(identificador, 'Tamanho do vetor deve ser expressão numérica inteira constante e não-negativa.'); } const tamanho = Number(tamanhoConstante); this.consumir(portugol_ipt_1.default.COLCHETE_DIREITO, "Esperado ']' após tamanho do vetor."); const elementos = Array.from({ length: tamanho }, () => new construtos_1.Literal(this.hashArquivo, linha, valorPadrao, tipoDelegua)); inicializacoes.push(new declaracoes_1.Var(identificador, new construtos_1.Vetor(this.hashArquivo, linha, elementos, `${tipoDelegua}[]`))); } else { // Inicialização opcional: `inteiro x = 5` (usa = como igualdade aqui, não seta) let valorInicial = new construtos_1.Literal(this.hashArquivo, linha, valorPadrao, tipoDelegua); if (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.IGUAL)) { valorInicial = await this.expressao(); } inicializacoes.push(new declaracoes_1.Var(identificador, valorInicial, tipoDelegua)); } } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.VIRGULA)); return inicializacoes; } /** * `constante tipo nome = valor` */ async declaracaoConstante() { this.avancarEDevolverAnterior(); // consome 'constante' // Tipo obrigatório após 'constante' const tipoSimbolo = this.simbolos[this.atual]; const mapaValoresPadrao = { [portugol_ipt_1.default.INTEIRO]: 0, [portugol_ipt_1.default.TEXTO]: '', [portugol_ipt_1.default.REAL]: 0.0, [portugol_ipt_1.default.LOGICO]: false, [portugol_ipt_1.default.CARACTER]: '', }; const mapaTipos = { [portugol_ipt_1.default.INTEIRO]: 'inteiro', [portugol_ipt_1.default.TEXTO]: 'texto', [portugol_ipt_1.default.REAL]: 'real', [portugol_ipt_1.default.LOGICO]: 'lógico', [portugol_ipt_1.default.CARACTER]: 'caracter', }; if (!(tipoSimbolo.tipo in mapaValoresPadrao)) { throw this.erro(tipoSimbolo, "Esperado tipo após 'constante'."); } this.avancarEDevolverAnterior(); // consome o tipo const tipoDelegua = mapaTipos[tipoSimbolo.tipo]; const constantes = []; do { const identificador = this.consumir(portugol_ipt_1.default.IDENTIFICADOR, `Esperado identificador após '${tipoSimbolo.lexema}'.`); this.consumir(portugol_ipt_1.default.IGUAL, "Esperado '=' após nome da constante."); const valor = await this.expressao(); constantes.push(new declaracoes_1.Const(identificador, valor, tipoDelegua, true)); } while (this.verificarSeSimboloAtualEIgualA(portugol_ipt_1.default.VIRGULA)); return constantes; } // ── Ponto de entrada de declarações ──────────────────────────────────────── async resolverDeclaracaoForaDeBloco() { const simboloAtual = this.simbolos[this.atual]; switch (simboloAtual.tipo) { case portugol_ipt_1.default.ESCREVER: return await this.declaracaoEscreva(); case portugol_ipt_1.default.LER: return new declaracoes_1.Expressao(await this.expressaoLeia()); case portugol_ipt_1.default.SE: return await this.declaracaoSe(); case portugol_ipt_1.default.ENQUANTO: return await this.declaracaoEnquanto(); case portugol_ipt_1.default.PARA: return await this.declaracaoPara(); case portugol_ipt_1.default.REPETE: return await this.declaracaoRepete(); case portugol_ipt_1.default.FAZ: return await this.declaracaoFazer(); case portugol_ipt_1.default.ESCOLHE: return await this.declaracaoEscolhaAsync(); case portugol_ipt_1.default.INTEIRO: return await this.declaracaoVariaveis(portugol_ipt_1.default.INTEIRO, 'inteiro', 0); case portugol_ipt_1.default.TEXTO: if (simboloAtual.literal === null && String(simboloAtual.lexema).toLowerCase() === 'texto') { return await this.declaracaoVariaveis(portugol_ipt_1.default.TEXTO, 'texto', ''); } return new declaracoes_1.Expressao(await this.expressao()); case portugol_ipt_1.default.REAL: return await this.declaracaoVariaveis(portugol_ipt_1.default.REAL, 'real', 0.0); case portugol_ipt_1.default.LOGICO: return await this.declaracaoVariaveis(portugol_ipt_1.default.LOGICO, 'lógico', false); case portugol_ipt_1.default.CARACTER: return await this.declaracaoVariaveis(portugol_ipt_1.default.CARACTER, 'caracter', ''); case portugol_ipt_1.default.CONSTANTE: return await this.declaracaoConstante(); case portugol_ipt_1.default.VARIAVEL: { // 'variavel' é apenas um modificador opcional; avança e processa o tipo this.avancarEDevolverAnterior(); return await this.resolverDeclaracaoForaDeBloco(); } case portugol_ipt_1.default.QUEBRA_LINHA: this.avancarEDevolverAnterior(); return null; default: return new declaracoes_1.Expressao(await this.expressao()); } } // ── Métodos obrigatórios não usados em Portugol IPT ──────────────────────── blocoEscopo() { throw new Error('Método não implementado.'); } corpoDaFuncao(_tipo) { throw new Error('Portugol IPT não suporta funções definidas pelo utilizador.'); } // ── Ponto de entrada principal ───────────────────────────────────────────── async analisar(retornoLexador, hashArquivo) { this.erros = []; this.atual = 0; this.blocos = 0; this.hashArquivo = hashArquivo || 0; this.simbolos = retornoLexador?.simbolos || []; this.consumirQuebrasLinha(); this.consumir(portugol_ipt_1.default.INICIO, "Esperado 'inicio' para marcar o início do algoritmo."); let declaracoes = []; while (!this.estaNoFinal() && this.simbolos[this.atual].tipo !== portugol_ipt_1.default.FIM) { const resolucao = await this.resolverDeclaracaoForaDeBloco(); if (Array.isArray(resolucao)) { declaracoes = declaracoes.concat(resolucao); } else if (resolucao !== null && resolucao !== undefined) { declaracoes.push(resolucao); } } return { declaracoes: declaracoes.filter((d) => d), erros: this.erros, }; } } exports.AvaliadorSintaticoPortugolIpt = AvaliadorSintaticoPortugolIpt; //# sourceMappingURL=avaliador-sintatico-portugol-ipt.js.map