UNPKG

@designliquido/delegua

Version:

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

751 lines 32.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.InterpretadorPortugolIpt = void 0; const construtos_1 = require("../../../construtos"); const declaracoes_1 = require("../../../declaracoes"); const espaco_memoria_1 = require("../../espaco-memoria"); const estruturas_1 = require("../../estruturas"); const excecoes_1 = require("../../../excecoes"); const quebras_1 = require("../../../quebras"); const pilha_escopos_execucao_1 = require("../../pilha-escopos-execucao"); const inferenciador_1 = require("../../../inferenciador"); const portugol_ipt_1 = __importDefault(require("../../../tipos-de-simbolos/portugol-ipt")); class InterpretadorPortugolIpt { constructor(diretorioBase, funcaoDeRetorno = null, funcaoDeRetornoMesmaLinha = null) { this.funcaoDeRetorno = null; this.funcaoDeRetornoMesmaLinha = null; this.classeAtualEmExecucao = null; this.resultadoInterpretador = []; this.diretorioBase = diretorioBase; this.funcaoDeRetorno = funcaoDeRetorno || console.log; this.funcaoDeRetornoMesmaLinha = funcaoDeRetornoMesmaLinha || process.stdout.write.bind(process.stdout); this.erros = []; this.declaracoes = []; this.pilhaEscoposExecucao = new pilha_escopos_execucao_1.PilhaEscoposExecucao(); const escopoExecucao = { declaracoes: [], declaracaoAtual: 0, espacoMemoria: new espaco_memoria_1.EspacoMemoria(), finalizado: false, tipo: 'outro', emLacoRepeticao: false, }; this.pilhaEscoposExecucao.empilhar(escopoExecucao); } // ── Utilitários ───────────────────────────────────────────────────────────── resolverValor(objeto) { if (objeto === null || objeto === undefined) return objeto; if (objeto.hasOwnProperty('valor')) return objeto.valor; return objeto; } eVerdadeiro(objeto) { if (objeto === null) return false; if (typeof objeto === 'boolean') return Boolean(objeto); if (objeto.hasOwnProperty('valor')) return Boolean(objeto.valor); return true; } eIgual(esquerda, direita) { if (esquerda === null && direita === null) return true; if (esquerda === null) return false; return esquerda === direita; } verificarOperandosNumeros(operador, direita, esquerda) { const valorDireita = this.resolverValor(direita); const valorEsquerda = this.resolverValor(esquerda); const tipoDireita = direita?.tipo ?? (typeof valorDireita === 'number' ? 'número' : String(NaN)); const tipoEsquerda = esquerda?.tipo ?? (typeof valorEsquerda === 'number' ? 'número' : String(NaN)); const tiposNumericos = ['inteiro', 'numero', 'número', 'real']; const eNumericoOuQualquer = (tipo, valor) => tiposNumericos.includes(tipo.toLowerCase()) || (tipo === 'qualquer' && typeof valor === 'number'); if (eNumericoOuQualquer(tipoDireita, valorDireita) && eNumericoOuQualquer(tipoEsquerda, valorEsquerda)) return; throw new excecoes_1.ErroEmTempoDeExecucao(operador, 'Operadores precisam ser números.', operador.linha); } paraTexto(objeto) { if (objeto === null || objeto === undefined) return 'nulo'; if (typeof objeto === 'boolean') return objeto ? 'verdadeiro' : 'falso'; if (objeto instanceof Date) { return Intl.DateTimeFormat('pt', { dateStyle: 'full', timeStyle: 'full' }).format(objeto); } if (Array.isArray(objeto)) return objeto; if (objeto.valor instanceof estruturas_1.ObjetoPadrao) return objeto.valor.paraTexto(); if (typeof objeto === 'object') return JSON.stringify(objeto); return objeto.toString(); } // ── Expressões ────────────────────────────────────────────────────────────── visitarExpressaoLiteral(expressao) { return Promise.resolve(expressao.valor); } async visitarExpressaoAgrupamento(expressao) { return await this.avaliar(expressao.expressao); } async visitarExpressaoBinaria(expressao) { try { const esquerda = await this.avaliar(expressao.esquerda); const direita = await this.avaliar(expressao.direita); const valorEsquerdo = this.resolverValor(esquerda); const valorDireito = this.resolverValor(direita); const tipoEsquerdo = esquerda?.hasOwnProperty('tipo') ? esquerda.tipo : (0, inferenciador_1.inferirTipoVariavel)(esquerda); const tipoDireito = direita?.hasOwnProperty('tipo') ? direita.tipo : (0, inferenciador_1.inferirTipoVariavel)(direita); const tiposNumericos = ['inteiro', 'numero', 'número', 'real']; const ambosNumericos = (tiposNumericos.includes(tipoEsquerdo) || (tipoEsquerdo === 'qualquer' && typeof valorEsquerdo === 'number')) && (tiposNumericos.includes(tipoDireito) || (tipoDireito === 'qualquer' && typeof valorDireito === 'number')); switch (expressao.operador.tipo) { case portugol_ipt_1.default.EXPONENCIACAO: this.verificarOperandosNumeros(expressao.operador, esquerda, direita); return Math.pow(valorEsquerdo, valorDireito); case portugol_ipt_1.default.MAIOR: this.verificarOperandosNumeros(expressao.operador, esquerda, direita); return Number(valorEsquerdo) > Number(valorDireito); case portugol_ipt_1.default.MAIOR_IGUAL: this.verificarOperandosNumeros(expressao.operador, esquerda, direita); return Number(valorEsquerdo) >= Number(valorDireito); case portugol_ipt_1.default.MENOR: this.verificarOperandosNumeros(expressao.operador, esquerda, direita); return Number(valorEsquerdo) < Number(valorDireito); case portugol_ipt_1.default.MENOR_IGUAL: this.verificarOperandosNumeros(expressao.operador, esquerda, direita); return Number(valorEsquerdo) <= Number(valorDireito); case portugol_ipt_1.default.SUBTRACAO: this.verificarOperandosNumeros(expressao.operador, esquerda, direita); return Number(valorEsquerdo) - Number(valorDireito); case portugol_ipt_1.default.ADICAO: if (ambosNumericos) { return Number(valorEsquerdo) + Number(valorDireito); } return String(valorEsquerdo) + String(valorDireito); case portugol_ipt_1.default.DIVISAO: this.verificarOperandosNumeros(expressao.operador, esquerda, direita); return Number(valorEsquerdo) / Number(valorDireito); case portugol_ipt_1.default.DIVISAO_INTEIRA: this.verificarOperandosNumeros(expressao.operador, esquerda, direita); return Math.floor(Number(valorEsquerdo) / Number(valorDireito)); case portugol_ipt_1.default.MULTIPLICACAO: if (tipoEsquerdo === 'texto' || tipoDireito === 'texto') { if (tipoEsquerdo === 'texto' && tipoDireito === 'texto') { return Number(valorEsquerdo) * Number(valorDireito); } if (tipoEsquerdo === 'texto') return valorEsquerdo.repeat(Number(valorDireito)); return valorDireito.repeat(Number(valorEsquerdo)); } return Number(valorEsquerdo) * Number(valorDireito); case portugol_ipt_1.default.MODULO: this.verificarOperandosNumeros(expressao.operador, esquerda, direita); return Number(valorEsquerdo) % Number(valorDireito); case portugol_ipt_1.default.DIFERENTE: return !this.eIgual(valorEsquerdo, valorDireito); case portugol_ipt_1.default.IGUAL: return this.eIgual(valorEsquerdo, valorDireito); } } catch (erro) { return Promise.reject(erro); } } async visitarExpressaoLogica(expressao) { const esquerda = await this.avaliar(expressao.esquerda); switch (expressao.operador.tipo) { case portugol_ipt_1.default.OU: if (this.eVerdadeiro(esquerda)) return true; return this.eVerdadeiro(await this.avaliar(expressao.direita)); case portugol_ipt_1.default.XOU: { const ve = this.eVerdadeiro(esquerda); const vd = this.eVerdadeiro(await this.avaliar(expressao.direita)); return ve !== vd; } case portugol_ipt_1.default.E: if (!this.eVerdadeiro(esquerda)) return false; return this.eVerdadeiro(await this.avaliar(expressao.direita)); } return await this.avaliar(expressao.direita); } async visitarExpressaoUnaria(expressao) { const operando = await this.avaliar(expressao.operando); const valor = this.resolverValor(operando); switch (expressao.operador.tipo) { case portugol_ipt_1.default.SUBTRACAO: return -Number(valor); case portugol_ipt_1.default.NEGACAO: case portugol_ipt_1.default.NAO: return !this.eVerdadeiro(valor); } throw new excecoes_1.ErroEmTempoDeExecucao(expressao.operador, `Operador unário desconhecido: ${expressao.operador.lexema}`, expressao.operador.linha); } async visitarExpressaoDeAtribuicao(expressao) { const valor = await this.avaliar(expressao.valor); const valorFinal = this.resolverValor(valor); const alvo = expressao.alvo; this.pilhaEscoposExecucao.atribuirVariavel(alvo.simbolo, valorFinal); return valorFinal; } visitarExpressaoDeVariavel(expressao) { return this.pilhaEscoposExecucao.obterValorVariavel(expressao.simbolo); } async visitarExpressaoLeia(expressao) { for (const arg of expressao.argumentos) { const resposta = await new Promise((resolve) => this.interfaceEntradaSaida.question('> ', (r) => resolve(r))); // arg é um Expressao (declaração) envolvendo um Variavel const construto = arg instanceof declaracoes_1.Expressao ? arg.expressao : arg; if (construto instanceof construtos_1.Variavel) { const valorConvertido = typeof resposta === 'string' && !Number.isNaN(Number(resposta)) ? Number(resposta) : resposta; this.pilhaEscoposExecucao.atribuirVariavel(construto.simbolo, valorConvertido); } } return null; } async visitarExpressaoFormatacaoEscrita(declaracao) { const conteudo = await this.avaliar(declaracao.expressao); const valorConteudo = this.resolverValor(conteudo); const tipoConteudo = conteudo.hasOwnProperty('tipo') ? conteudo.tipo : typeof conteudo; let resultado = valorConteudo; if (['número', 'number'].includes(tipoConteudo) && declaracao.casasDecimais > 0) { resultado = valorConteudo.toLocaleString('pt', { maximumFractionDigits: declaracao.casasDecimais, }); } if (declaracao.espacos > 0) resultado += ' '.repeat(declaracao.espacos); return resultado; } // ── Acesso a vetores ──────────────────────────────────────────────────────── async visitarExpressaoAcessoIndiceVariavel(expressao) { const objetoAvaliado = await this.avaliar(expressao.entidadeChamada); const indiceAvaliado = await this.avaliar(expressao.indice); const objeto = this.resolverValor(objetoAvaliado); const indice = this.resolverValor(indiceAvaliado); if (Array.isArray(objeto)) { if (indice < 0 || indice >= objeto.length) { return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Índice do vetor fora do intervalo.', expressao.linha)); } return objeto[indice]; } return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, 'Acesso por índice só é suportado em vetores.', expressao.linha)); } async visitarExpressaoAtribuicaoPorIndice(expressao) { const objetoAvaliado = await this.avaliar(expressao.objeto); const indiceAvaliado = await this.avaliar(expressao.indice); const valorAvaliado = await this.avaliar(expressao.valor); const objeto = this.resolverValor(objetoAvaliado); const indice = this.resolverValor(indiceAvaliado); const valor = this.resolverValor(valorAvaliado); if (Array.isArray(objeto)) { objeto[indice] = valor; return valor; } return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(null, 'Atribuição por índice só é suportada em vetores.', expressao.linha)); } // ── Chamadas de funções embutidas ─────────────────────────────────────────── async visitarExpressaoDeChamada(expressao) { const callee = expressao.entidadeChamada; if (!(callee instanceof construtos_1.Variavel)) { return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(null, 'Chamada de função inválida.', expressao.linha)); } const nome = callee.simbolo.lexema.toUpperCase(); const args = []; for (const arg of expressao.argumentos) { args.push(this.resolverValor(await this.avaliar(arg))); } return this.chamarFuncaoEmbutida(nome, args, expressao.linha); } chamarFuncaoEmbutida(nome, args, linha) { switch (nome) { // ── 0 argumentos ── case 'ALEATORIO': return Math.random(); // ── 1 argumento ── case 'SEN': return Math.sin(args[0]); case 'COS': return Math.cos(args[0]); case 'TAN': return Math.tan(args[0]); case 'CTG': return 1 / Math.tan(args[0]); case 'ASEN': return Math.asin(args[0]); case 'ACOS': return Math.acos(args[0]); case 'ATAN': return Math.atan(args[0]); case 'ACTG': return 1 / Math.atan(args[0]); case 'SENH': return Math.sinh(args[0]); case 'COSH': return Math.cosh(args[0]); case 'TANH': return Math.tanh(args[0]); case 'CTGH': return 1 / Math.tanh(args[0]); case 'EXP': return Math.exp(args[0]); case 'ABS': return Math.abs(args[0]); case 'RAIZ': return Math.sqrt(args[0]); case 'LOG': return Math.log10(args[0]); case 'LN': return Math.log(args[0]); case 'INT': return Math.trunc(args[0]); case 'FRAC': return args[0] - Math.trunc(args[0]); case 'ARRED': return Math.round(args[0]); // ── 2 argumentos ── case 'POTENCIA': return Math.pow(args[0], args[1]); // ── Texto ── case 'COMPRIMENTO': return String(args[0]).length; case 'LETRA': return String(args[0]).charAt(Number(args[1])); default: throw new excecoes_1.ErroEmTempoDeExecucao(null, `Função embutida desconhecida: '${nome}'.`, linha); } } // ── Declarações ───────────────────────────────────────────────────────────── async visitarDeclaracaoDeExpressao(declaracao) { return declaracao.expressao.aceitar(this); } async visitarDeclaracaoEscreva(declaracao) { try { const formatoTexto = await this.avaliarArgumentosEscreva(declaracao.argumentos); this.funcaoDeRetorno(formatoTexto); return null; } catch (erro) { this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo, }); } } async visitarDeclaracaoEscrevaMesmaLinha(declaracao) { try { const formatoTexto = await this.avaliarArgumentosEscreva(declaracao.argumentos); this.funcaoDeRetornoMesmaLinha(formatoTexto); return null; } catch (erro) { this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo, }); } } async avaliarArgumentosEscreva(argumentos) { let formatoTexto = ''; for (const argumento of argumentos) { const resultado = await this.avaliar(argumento); formatoTexto += `${this.paraTexto(this.resolverValor(resultado))} `; } return formatoTexto.trimEnd(); } async visitarDeclaracaoVar(declaracao) { let valorFinal = null; if (declaracao.inicializador !== null) { const avaliado = await this.avaliar(declaracao.inicializador); if (avaliado !== null && avaliado !== undefined) { valorFinal = this.resolverValor(avaliado); } } this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, valorFinal, declaracao.tipo); return null; } async visitarDeclaracaoConst(declaracao) { let valorFinal = null; if (declaracao.inicializador !== null) { const avaliado = await this.avaliar(declaracao.inicializador); if (avaliado !== null && avaliado !== undefined) { valorFinal = this.resolverValor(avaliado); } } this.pilhaEscoposExecucao.definirConstante(declaracao.simbolo.lexema, valorFinal, declaracao.tipo); return null; } async visitarDeclaracaoSe(declaracao) { if (this.eVerdadeiro(await this.avaliar(declaracao.condicao))) { return await this.executar(declaracao.caminhoEntao); } if (declaracao.caminhoSenao !== null) { return await this.executar(declaracao.caminhoSenao); } return null; } async visitarDeclaracaoEnquanto(declaracao) { while (this.eVerdadeiro(await this.avaliar(declaracao.condicao))) { try { const resultado = await this.executar(declaracao.corpo); if (resultado instanceof quebras_1.SustarQuebra) return null; if (resultado instanceof quebras_1.ContinuarQuebra) continue; if (resultado instanceof quebras_1.Quebra) break; } catch (erro) { this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo, }); return Promise.reject(erro); } } return null; } async visitarDeclaracaoPara(declaracao) { const inicializador = Array.isArray(declaracao.inicializador) ? declaracao.inicializador[0] : declaracao.inicializador; if (inicializador) await this.avaliar(inicializador); while (true) { if (declaracao.condicao && !this.eVerdadeiro(await this.avaliar(declaracao.condicao))) break; try { const resultado = await this.executar(declaracao.corpo); if (resultado instanceof quebras_1.SustarQuebra) return null; if (resultado instanceof quebras_1.ContinuarQuebra) { /* continua para incremento */ } else if (resultado instanceof quebras_1.Quebra) break; } catch (erro) { this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo, }); return Promise.reject(erro); } if (declaracao.incrementar) await this.avaliar(declaracao.incrementar); } return null; } async visitarDeclaracaoFazer(declaracao) { do { try { const resultado = await this.executar(declaracao.caminhoFazer); if (resultado instanceof quebras_1.SustarQuebra) return null; if (resultado instanceof quebras_1.ContinuarQuebra) continue; if (resultado instanceof quebras_1.Quebra) break; } catch (erro) { this.erros.push({ erroInterno: erro, linha: declaracao.linha, hashArquivo: declaracao.hashArquivo, }); return Promise.reject(erro); } } while (this.eVerdadeiro(await this.avaliar(declaracao.condicaoEnquanto))); return null; } async visitarDeclaracaoEscolha(declaracao) { const valorCondicao = this.resolverValor(await this.avaliar(declaracao.identificadorOuLiteral)); let encontrado = false; for (const caminho of declaracao.caminhos) { for (const condicao of caminho.condicoes) { const valorCondicaoAvaliado = this.resolverValor(await this.avaliar(condicao)); if (valorCondicaoAvaliado === valorCondicao) { encontrado = true; await this.executarBloco(caminho.declaracoes); break; } } if (encontrado) break; } if (!encontrado && declaracao.caminhoPadrao) { await this.executarBloco(declaracao.caminhoPadrao.declaracoes); } return null; } visitarDeclaracaoComentario(declaracao) { return Promise.resolve(); } // ── Bloco e escopo ─────────────────────────────────────────────────────────── async executarBloco(declaracoes, ambiente) { const escopoExecucao = { declaracoes: declaracoes, declaracaoAtual: 0, espacoMemoria: ambiente || new espaco_memoria_1.EspacoMemoria(), finalizado: false, tipo: 'outro', emLacoRepeticao: false, }; this.pilhaEscoposExecucao.empilhar(escopoExecucao); return await this.executarUltimoEscopo(); } async visitarExpressaoBloco(declaracao) { return await this.executarBloco(declaracao.declaracoes); } // ── Métodos obrigatórios da interface não usados em Portugol IPT ──────────── /* istanbul ignore next */ visitarExpressaoTuplaN(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoAcessoIntervaloVariavel(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoTextoDocumentacao(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoSeparador(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoComentario(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoArgumentoReferenciaFuncao(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoReferenciaFuncao(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoAcessoMetodo(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoAcessoPropriedade(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoTendoComo(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoInicioAlgoritmo(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoCabecalhoPrograma(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoTupla(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoAcessoElementoMatriz(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoAtribuicaoPorIndicesMatriz(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoExpressaoRegular(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoTipoDe(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoFalhar(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoParaCada(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoVarMultiplo(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoConstMultiplo(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoContinua(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoSustar(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoRetornar(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoFuncaoConstruto(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoDefinirValor(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoDefinicaoFuncao(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoClasse(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoAcessoMetodoOuPropriedade(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoIsto(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoDicionario(_expressao) { throw new Error('Método não implementado.'); } async visitarExpressaoVetor(expressao) { const valores = []; for (const elemento of expressao.valores) { const avaliado = await this.avaliar(elemento); valores.push(this.resolverValor(avaliado)); } return valores; } /* istanbul ignore next */ visitarExpressaoSuper(_expressao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarExpressaoFimPara(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoTente(_declaracao) { throw new Error('Método não implementado.'); } /* istanbul ignore next */ visitarDeclaracaoImportar(_declaracao) { throw new Error('Método não implementado.'); } // ── Motor de execução ──────────────────────────────────────────────────────── async avaliar(expressao) { return await expressao.aceitar(this); } procurarVariavel(simbolo) { return this.pilhaEscoposExecucao.obterValorVariavel(simbolo); } async executar(declaracao, mostrarResultado = false) { const resultado = await declaracao.aceitar(this); if (mostrarResultado) this.funcaoDeRetorno(this.paraTexto(resultado)); if (resultado || typeof resultado === 'boolean') { this.resultadoInterpretador.push(this.paraTexto(resultado)); } return resultado; } async executarUltimoEscopo(manterAmbiente = false) { const ultimoEscopo = this.pilhaEscoposExecucao.topoDaPilha(); try { let retornoExecucao; for (; !(retornoExecucao instanceof quebras_1.Quebra) && ultimoEscopo.declaracaoAtual < ultimoEscopo.declaracoes.length; ultimoEscopo.declaracaoAtual++) { retornoExecucao = await this.executar(ultimoEscopo.declaracoes[ultimoEscopo.declaracaoAtual]); } return retornoExecucao; } catch (erro) { return Promise.reject(erro); } finally { this.pilhaEscoposExecucao.removerUltimo(); if (manterAmbiente) { const escopoAnterior = this.pilhaEscoposExecucao.topoDaPilha(); escopoAnterior.espacoMemoria.valores = Object.assign(escopoAnterior.espacoMemoria.valores, ultimoEscopo.espacoMemoria.valores); } } } async executarChamavel(chamavel, argumentos) { if (chamavel instanceof estruturas_1.FuncaoPadrao) { return chamavel.chamar(this, argumentos, null); } const argumentosFormatados = argumentos.map((valor) => ({ nome: null, valor, })); return chamavel.chamar(this, argumentosFormatados, null); } async interpretar(declaracoes, manterAmbiente) { this.erros = []; const escopoExecucao = { declaracoes: declaracoes, declaracaoAtual: 0, espacoMemoria: new espaco_memoria_1.EspacoMemoria(), finalizado: false, tipo: 'outro', emLacoRepeticao: false, }; this.pilhaEscoposExecucao.empilhar(escopoExecucao); try { const retornoOuErro = await this.executarUltimoEscopo(manterAmbiente); if (retornoOuErro instanceof excecoes_1.ErroEmTempoDeExecucao) { this.erros.push(retornoOuErro); } } catch (erro) { this.erros.push(erro); } finally { const retorno = { erros: this.erros, resultado: this.resultadoInterpretador, }; this.resultadoInterpretador = []; return retorno; } } } exports.InterpretadorPortugolIpt = InterpretadorPortugolIpt; //# sourceMappingURL=interpretador-portugol-ipt.js.map