UNPKG

@designliquido/delegua

Version:

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

353 lines 15.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TradutorReversoCalango = void 0; const calango_1 = __importDefault(require("../tipos-de-simbolos/calango")); class TradutorReversoCalango { constructor() { this.indentacao = 0; this.dicionarioConstrutos = { AcessoIndiceVariavel: this.traduzirConstrutoAcessoIndiceVariavel.bind(this), Agrupamento: this.traduzirConstrutoAgrupamento.bind(this), AtribuicaoPorIndice: this.traduzirConstrutoAtribuicaoPorIndice.bind(this), Atribuir: this.traduzirConstrutoAtribuir.bind(this), Binario: this.traduzirConstrutoBinario.bind(this), Chamada: this.traduzirConstrutoChamada.bind(this), FormatacaoEscrita: this.traduzirConstrutoFormatacaoEscrita.bind(this), FuncaoConstruto: this.traduzirConstrutoFuncao.bind(this), Leia: this.traduzirConstrutoLeia.bind(this), Literal: this.traduzirConstrutoLiteral.bind(this), Logico: this.traduzirConstrutoLogico.bind(this), Unario: this.traduzirConstrutoUnario.bind(this), Variavel: this.traduzirConstrutoVariavel.bind(this), Vetor: this.traduzirConstrutoVetor.bind(this), }; this.dicionarioDeclaracoes = { Bloco: this.traduzirDeclaracaoBloco.bind(this), Enquanto: this.traduzirDeclaracaoEnquanto.bind(this), Escolha: this.traduzirDeclaracaoEscolha.bind(this), Escreva: this.traduzirDeclaracaoEscreva.bind(this), EscrevaMesmaLinha: this.traduzirDeclaracaoEscrevaMesmaLinha.bind(this), Expressao: this.traduzirDeclaracaoExpressao.bind(this), Fazer: this.traduzirDeclaracaoFazer.bind(this), FuncaoDeclaracao: this.traduzirDeclaracaoFuncao.bind(this), Para: this.traduzirDeclaracaoPara.bind(this), Retorna: this.traduzirDeclaracaoRetorna.bind(this), Se: this.traduzirDeclaracaoSe.bind(this), Sustar: this.traduzirDeclaracaoSustar.bind(this), Var: this.traduzirDeclaracaoVar.bind(this), }; } traduzirSimboloOperador(simbolo) { switch (simbolo?.tipo) { case calango_1.default.ADICAO: return '+'; case calango_1.default.SUBTRACAO: return '-'; case calango_1.default.MULTIPLICACAO: return '*'; case calango_1.default.DIVISAO: return '/'; case calango_1.default.DIVISAO_INTEIRA: return '\\'; case calango_1.default.MODULO: return '%'; case calango_1.default.EXPONENCIACAO: return '^'; case calango_1.default.IGUAL: case calango_1.default.IGUAL_IGUAL: return '=='; case calango_1.default.IGUAL_ATRIBUICAO: return '='; case calango_1.default.DIFERENTE: return '!='; case calango_1.default.MAIOR: return '>'; case calango_1.default.MAIOR_IGUAL: return '>='; case calango_1.default.MENOR: return '<'; case calango_1.default.MENOR_IGUAL: return '<='; case calango_1.default.E: return 'e'; case calango_1.default.OU: return 'ou'; case calango_1.default.NEGACAO: return 'nao'; default: return simbolo?.lexema || ''; } } traduzirQualquer(elemento) { if (!elemento) { return ''; } const nomeConstrutor = elemento.constructor.name; if (this.dicionarioDeclaracoes.hasOwnProperty(nomeConstrutor)) { return this.dicionarioDeclaracoes[nomeConstrutor](elemento); } if (this.dicionarioConstrutos.hasOwnProperty(nomeConstrutor)) { return this.dicionarioConstrutos[nomeConstrutor](elemento); } throw new Error(`Elemento não suportado pelo tradutor Calango reverso: ${nomeConstrutor}`); } traduzirParametro(parametro) { const nome = parametro?.nome?.lexema; const tipo = parametro?.tipoDado; if (!nome) { return ''; } if (!tipo || tipo === 'qualquer') { return nome; } return `${nome}: ${tipo}`; } logicaComumBlocoEscopo(declaracoes) { let resultado = '{\n'; this.indentacao += 4; for (const declaracaoOuConstruto of declaracoes || []) { const traducao = this.traduzirQualquer(declaracaoOuConstruto); if (!traducao) { continue; } resultado += `${' '.repeat(this.indentacao)}${traducao}\n`; } this.indentacao -= 4; resultado += `${' '.repeat(this.indentacao)}}`; return resultado; } traduzirConstrutoAcessoIndiceVariavel(acessoIndiceVariavel) { const entidade = this.traduzirQualquer(acessoIndiceVariavel.entidadeChamada); const indice = this.traduzirQualquer(acessoIndiceVariavel.indice); return `${entidade}[${indice}]`; } traduzirConstrutoAgrupamento(agrupamento) { return `(${this.traduzirQualquer(agrupamento.expressao)})`; } traduzirConstrutoAtribuicaoPorIndice(atribuicao) { const objeto = this.traduzirQualquer(atribuicao.objeto); const indice = this.traduzirQualquer(atribuicao.indice); const valor = this.traduzirQualquer(atribuicao.valor); return `${objeto}[${indice}] = ${valor}`; } traduzirConstrutoAtribuir(atribuir) { let alvo = this.traduzirQualquer(atribuir.alvo); if (atribuir.indice) { alvo += `[${this.traduzirQualquer(atribuir.indice)}]`; } const operador = atribuir.simboloOperador ? this.traduzirSimboloOperador(atribuir.simboloOperador) : '='; const valor = this.traduzirQualquer(atribuir.valor); return `${alvo} ${operador} ${valor}`; } traduzirConstrutoBinario(binario) { const esquerda = this.traduzirQualquer(binario.esquerda); const direita = this.traduzirQualquer(binario.direita); const operador = this.traduzirSimboloOperador(binario.operador); return `${esquerda} ${operador} ${direita}`; } traduzirConstrutoChamada(chamada) { const entidade = this.traduzirQualquer(chamada.entidadeChamada); const argumentos = (chamada.argumentos || []).map((argumento) => this.traduzirQualquer(argumento)); return `${entidade}(${argumentos.join(', ')})`; } traduzirConstrutoFormatacaoEscrita(formatacaoEscrita) { const avaliacaoExpressao = this.traduzirQualquer(formatacaoEscrita.expressao); return `${avaliacaoExpressao}`; } traduzirConstrutoFuncao(funcaoConstruto) { const parametros = (funcaoConstruto.parametros || []) .map((parametro) => this.traduzirParametro(parametro)) .filter((p) => p) .join(', '); let resultado = `funcao(${parametros}) `; resultado += this.logicaComumBlocoEscopo(funcaoConstruto.corpo); return resultado; } traduzirConstrutoLeia(leia) { const argumentos = (leia.argumentos || []).map((argumento) => this.traduzirQualquer(argumento)); return `leia(${argumentos.join(', ')})`; } traduzirConstrutoLiteral(literal) { if (typeof literal.valor === 'string') { const valorEscapado = literal.valor.replace(/\\/g, '\\\\').replace(/'/g, "\\'"); return `'${valorEscapado}'`; } if (literal.valor === null || literal.valor === undefined) { return 'nulo'; } if (typeof literal.valor === 'boolean') { return literal.valor ? 'verdadeiro' : 'falso'; } return String(literal.valor); } traduzirConstrutoLogico(logico) { const esquerda = this.traduzirQualquer(logico.esquerda); const direita = this.traduzirQualquer(logico.direita); const operador = this.traduzirSimboloOperador(logico.operador); return `${esquerda} ${operador} ${direita}`; } traduzirConstrutoUnario(unario) { const operador = this.traduzirSimboloOperador(unario.operador); const operando = this.traduzirQualquer(unario.operando); if (unario.incidenciaOperador === 'DEPOIS') { return `${operando}${operador}`; } if (operador === 'nao') { return `${operador} ${operando}`; } return `${operador}${operando}`; } traduzirConstrutoVariavel(variavel) { return variavel.simbolo.lexema; } traduzirConstrutoVetor(vetor) { const elementos = (vetor.elementos || []).map((elemento) => this.traduzirQualquer(elemento)); return `[${elementos.join(', ')}]`; } traduzirDeclaracaoBloco(bloco) { return this.logicaComumBlocoEscopo(bloco.declaracoes); } traduzirDeclaracaoEnquanto(declaracaoEnquanto) { const condicao = this.traduzirQualquer(declaracaoEnquanto.condicao); const corpo = this.traduzirDeclaracaoBloco(declaracaoEnquanto.corpo); return `enquanto (${condicao}) ${corpo}`; } traduzirDeclaracaoEscolha(declaracaoEscolha) { const expressao = this.traduzirQualquer(declaracaoEscolha.identificadorOuLiteral); let resultado = `escolha (${expressao}) {\n`; this.indentacao += 4; for (const caminho of declaracaoEscolha.caminhos || []) { for (const condicao of caminho.condicoes || []) { resultado += `${' '.repeat(this.indentacao)}caso ${this.traduzirQualquer(condicao)}:\n`; } this.indentacao += 4; for (const declaracao of caminho.declaracoes || []) { const traducao = this.traduzirQualquer(declaracao); if (traducao) { resultado += `${' '.repeat(this.indentacao)}${traducao}\n`; } } this.indentacao -= 4; } if (declaracaoEscolha.caminhoPadrao) { resultado += `${' '.repeat(this.indentacao)}padrao:\n`; this.indentacao += 4; for (const declaracao of declaracaoEscolha.caminhoPadrao.declaracoes || []) { const traducao = this.traduzirQualquer(declaracao); if (traducao) { resultado += `${' '.repeat(this.indentacao)}${traducao}\n`; } } this.indentacao -= 4; } this.indentacao -= 4; resultado += `${' '.repeat(this.indentacao)}}`; return resultado; } traduzirDeclaracaoEscreva(declaracaoEscreva) { let resultado = 'escreva('; for (const argumento of declaracaoEscreva.argumentos) { const valor = this.traduzirQualquer(argumento); resultado += valor + ', '; } if (declaracaoEscreva.argumentos.length > 0) { resultado = resultado.slice(0, -2); } resultado += ')'; return resultado; } traduzirDeclaracaoEscrevaMesmaLinha(declaracaoEscreva) { let resultado = 'escreva('; for (const argumento of declaracaoEscreva.argumentos) { const valor = this.traduzirQualquer(argumento); resultado += valor + ', '; } if (declaracaoEscreva.argumentos.length > 0) { resultado = resultado.slice(0, -2); } resultado += ')'; return resultado; } traduzirDeclaracaoExpressao(expressao) { return this.traduzirQualquer(expressao.expressao); } traduzirDeclaracaoFazer(fazer) { const corpo = this.traduzirDeclaracaoBloco(fazer.caminhoFazer); const condicao = this.traduzirQualquer(fazer.condicaoEnquanto); return `fazer ${corpo} enquanto (${condicao})`; } traduzirDeclaracaoFuncao(declaracaoFuncao) { const parametros = (declaracaoFuncao.funcao.parametros || []) .map((parametro) => this.traduzirParametro(parametro)) .filter((p) => p) .join(', '); const tipoRetorno = declaracaoFuncao.tipo && declaracaoFuncao.tipo !== 'qualquer' && declaracaoFuncao.tipo !== 'vazio' ? `: ${declaracaoFuncao.tipo}` : ''; let resultado = `funcao ${declaracaoFuncao.simbolo.lexema}(${parametros})${tipoRetorno} `; resultado += this.logicaComumBlocoEscopo(declaracaoFuncao.funcao.corpo); return resultado; } traduzirDeclaracaoPara(declaracaoPara) { let inicializador = ''; if (Array.isArray(declaracaoPara.inicializador)) { inicializador = declaracaoPara.inicializador .map((declaracao) => this.traduzirQualquer(declaracao)) .join(', '); } else if (declaracaoPara.inicializador) { inicializador = this.traduzirQualquer(declaracaoPara.inicializador); } const condicao = this.traduzirQualquer(declaracaoPara.condicao); const incremento = this.traduzirQualquer(declaracaoPara.incrementar); const corpo = this.traduzirDeclaracaoBloco(declaracaoPara.corpo); return `para (${inicializador}; ${condicao}; ${incremento}) ${corpo}`; } traduzirDeclaracaoRetorna(retorna) { if (!retorna.valor) { return 'retorna'; } return `retorna ${this.traduzirQualquer(retorna.valor)}`; } traduzirDeclaracaoSe(declaracaoSe) { const condicao = this.traduzirQualquer(declaracaoSe.condicao); const caminhoEntao = this.traduzirQualquer(declaracaoSe.caminhoEntao); let resultado = `se (${condicao}) ${caminhoEntao}`; const caminhosSeSenao = declaracaoSe.caminhosSeSenao || []; for (const caminhoSeSenao of caminhosSeSenao) { resultado += ` senao se (${this.traduzirQualquer(caminhoSeSenao.condicao)}) ${this.traduzirQualquer(caminhoSeSenao.caminho)}`; } if (declaracaoSe.caminhoSenao) { resultado += ` senao ${this.traduzirQualquer(declaracaoSe.caminhoSenao)}`; } return resultado; } traduzirDeclaracaoSustar(_sustar) { return 'sustar'; } traduzirDeclaracaoVar(declaracaoVar) { if (!declaracaoVar.inicializador) { return `var ${declaracaoVar.simbolo.lexema}`; } return `var ${declaracaoVar.simbolo.lexema} = ${this.traduzirQualquer(declaracaoVar.inicializador)}`; } traduzir(declaracoes) { const linhas = []; for (const declaracao of declaracoes) { const traducao = this.traduzirQualquer(declaracao); if (traducao) { linhas.push(traducao); } } return linhas.join('\n'); } } exports.TradutorReversoCalango = TradutorReversoCalango; //# sourceMappingURL=tradutor-reverso-calango.js.map