@designliquido/delegua
Version:
Linguagem de programação simples e moderna usando português estruturado.
381 lines • 16.6 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.TradutorPortugolIpt = void 0;
const construtos_1 = require("../construtos");
const declaracoes_1 = require("../declaracoes");
const dialetos_1 = require("../avaliador-sintatico/dialetos");
const dialetos_2 = require("../lexador/dialetos");
const portugol_ipt_1 = __importDefault(require("../tipos-de-simbolos/portugol-ipt"));
class TradutorPortugolIpt {
constructor() {
this.indentacao = 0;
// ── Mapeamento de funções embutidas ─────────────────────────────────────────
this.mapaFuncoes = {
ALEATORIO: 'aleatorio',
SEN: 'seno',
COS: 'cosseno',
TAN: 'tangente',
CTG: 'cotangente',
ASEN: 'arco_seno',
ACOS: 'arco_cosseno',
ATAN: 'arco_tangente',
ACTG: 'arco_cotangente',
SENH: 'seno_hiperbolico',
COSH: 'cosseno_hiperbolico',
TANH: 'tangente_hiperbolica',
CTGH: 'cotangente_hiperbolica',
EXP: 'exponencial',
ABS: 'absoluto',
RAIZ: 'raiz_quadrada',
LOG: 'logaritmo',
LN: 'logaritmo_natural',
INT: 'inteiro',
FRAC: 'parte_fracionaria',
ARRED: 'arredondar',
POTENCIA: 'potência',
COMPRIMENTO: 'tamanho',
LETRA: 'letra',
};
// ── Dicionários ──────────────────────────────────────────────────────────────
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),
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),
Const: this.traduzirDeclaracaoConst.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),
Para: this.traduzirDeclaracaoPara.bind(this),
Se: this.traduzirDeclaracaoSe.bind(this),
Var: this.traduzirDeclaracaoVar.bind(this),
};
}
// ── Operadores ───────────────────────────────────────────────────────────────
traduzirOperador(tipo) {
switch (tipo) {
case portugol_ipt_1.default.ADICAO:
return '+';
case portugol_ipt_1.default.SUBTRACAO:
return '-';
case portugol_ipt_1.default.MULTIPLICACAO:
return '*';
case portugol_ipt_1.default.DIVISAO:
return '/';
case portugol_ipt_1.default.MODULO:
return '%';
case portugol_ipt_1.default.EXPONENCIACAO:
return '**';
case portugol_ipt_1.default.IGUAL:
return '==';
case portugol_ipt_1.default.DIFERENTE:
return '!=';
case portugol_ipt_1.default.MAIOR:
return '>';
case portugol_ipt_1.default.MAIOR_IGUAL:
return '>=';
case portugol_ipt_1.default.MENOR:
return '<';
case portugol_ipt_1.default.MENOR_IGUAL:
return '<=';
case portugol_ipt_1.default.E:
return '&&';
case portugol_ipt_1.default.OU:
return '||';
case portugol_ipt_1.default.XOU:
return '^^';
default:
return tipo;
}
}
// ── Construtos ───────────────────────────────────────────────────────────────
traduzirConstruto(construto) {
const nome = construto.constructor.name;
if (this.dicionarioConstrutos.hasOwnProperty(nome)) {
return this.dicionarioConstrutos[nome](construto);
}
return `/* construto ${nome} não suportado */`;
}
traduzirConstrutoLiteral(literal) {
if (typeof literal.valor === 'string')
return `'${literal.valor}'`;
if (typeof literal.valor === 'boolean')
return literal.valor ? 'verdadeiro' : 'falso';
return String(literal.valor);
}
traduzirConstrutoVariavel(variavel) {
return variavel.simbolo.lexema;
}
traduzirConstrutoAgrupamento(agrupamento) {
return `(${this.traduzirConstruto(agrupamento.expressao)})`;
}
traduzirConstrutoBinario(binario) {
const esq = this.traduzirConstruto(binario.esquerda);
const op = this.traduzirOperador(binario.operador.tipo);
const dir = this.traduzirConstruto(binario.direita);
return `${esq} ${op} ${dir}`;
}
traduzirConstrutoLogico(logico) {
const esq = this.traduzirConstruto(logico.esquerda);
const dir = this.traduzirConstruto(logico.direita);
if (logico.operador.tipo === portugol_ipt_1.default.XOU) {
return `((${esq} && !(${dir})) || (!(${esq}) && ${dir}))`;
}
const op = this.traduzirOperador(logico.operador.tipo);
return `${esq} ${op} ${dir}`;
}
traduzirConstrutoUnario(unario) {
const operando = this.traduzirConstruto(unario.operando);
switch (unario.operador.tipo) {
case portugol_ipt_1.default.SUBTRACAO:
return `-${operando}`;
case portugol_ipt_1.default.NEGACAO:
case portugol_ipt_1.default.NAO:
return `!(${operando})`;
default:
return `!(${operando})`;
}
}
traduzirConstrutoAtribuir(atribuir) {
const alvo = this.traduzirConstruto(atribuir.alvo);
const valor = this.traduzirConstruto(atribuir.valor);
return `${alvo} = ${valor}`;
}
traduzirConstrutoChamada(chamada) {
const nomeOriginal = this.traduzirConstruto(chamada.entidadeChamada).toUpperCase();
const nomeDelegua = this.mapaFuncoes[nomeOriginal] ?? nomeOriginal.toLowerCase();
const args = chamada.argumentos.map((a) => this.traduzirConstruto(a)).join(', ');
return `${nomeDelegua}(${args})`;
}
traduzirConstrutoAcessoIndiceVariavel(acesso) {
const entidade = this.traduzirConstruto(acesso.entidadeChamada);
const indice = this.traduzirConstruto(acesso.indice);
return `${entidade}[${indice}]`;
}
traduzirConstrutoAtribuicaoPorIndice(atrib) {
const objeto = this.traduzirConstruto(atrib.objeto);
const indice = this.traduzirConstruto(atrib.indice);
const valor = this.traduzirConstruto(atrib.valor);
return `${objeto}[${indice}] = ${valor}`;
}
traduzirConstrutoVetor(vetor) {
const elementos = vetor.elementos.map((v) => this.traduzirConstruto(v)).join(', ');
return `[${elementos}]`;
}
traduzirConstrutoLeia(_leia) {
return 'leia()';
}
traduzirConstrutoFormatacaoEscrita(formatacao) {
return this.traduzirConstruto(formatacao.expressao);
}
// ── Declarações ──────────────────────────────────────────────────────────────
traduzirDeclaracao(declaracao) {
const nome = declaracao.constructor.name;
if (this.dicionarioDeclaracoes.hasOwnProperty(nome)) {
return this.dicionarioDeclaracoes[nome](declaracao);
}
return `/* declaração ${nome} não suportada */`;
}
tipoParaDelégua(tipo) {
switch (tipo) {
case 'inteiro':
return 'inteiro';
case 'texto':
return 'texto';
case 'real':
return 'real';
case 'lógico':
case 'logico':
return 'logico';
case 'caracter':
return 'caracter';
default:
return tipo;
}
}
valorPadraoPorTipo(tipo) {
switch (tipo) {
case 'inteiro':
return '0';
case 'texto':
return "''";
case 'real':
return '0.0';
case 'lógico':
case 'logico':
return 'falso';
case 'caracter':
return "' '";
default:
return 'nulo';
}
}
traduzirDeclaracaoVar(declaracaoVar) {
const nome = declaracaoVar.simbolo.lexema;
const tipo = declaracaoVar.tipo;
if (tipo && tipo.endsWith('[]')) {
// Array
const tipoBase = tipo.slice(0, -2);
const valor = declaracaoVar.inicializador
? this.traduzirConstruto(declaracaoVar.inicializador)
: '[]';
return `var ${nome}: ${tipoBase}[] = ${valor}`;
}
const tipoDelegua = tipo ? this.tipoParaDelégua(tipo) : '';
const valorPadrao = tipo ? this.valorPadraoPorTipo(tipo) : 'nulo';
const valor = declaracaoVar.inicializador
? this.traduzirConstruto(declaracaoVar.inicializador)
: valorPadrao;
if (tipoDelegua) {
return `var ${nome}: ${tipoDelegua} = ${valor}`;
}
return `var ${nome} = ${valor}`;
}
traduzirDeclaracaoConst(declaracaoConst) {
const nome = declaracaoConst.simbolo.lexema;
const valor = declaracaoConst.inicializador
? this.traduzirConstruto(declaracaoConst.inicializador)
: 'nulo';
return `const ${nome} = ${valor}`;
}
traduzirDeclaracaoExpressao(declaracaoExpressao) {
const expr = declaracaoExpressao.expressao;
// `ler x` → `x = leia()`
if (expr instanceof construtos_1.Leia) {
const linhas = [];
for (const arg of expr.argumentos) {
const alvo = arg instanceof declaracoes_1.Expressao
? this.traduzirConstruto(arg.expressao)
: this.traduzirConstruto(arg);
linhas.push(`${alvo} = leia()`);
}
return linhas.join('\n' + ' '.repeat(this.indentacao));
}
return this.traduzirConstruto(expr);
}
traduzirDeclaracaoBloco(bloco) {
let resultado = '{\n';
this.indentacao += 4;
for (const declaracao of bloco.declaracoes) {
resultado += ' '.repeat(this.indentacao);
resultado += this.traduzirDeclaracao(declaracao) + '\n';
}
this.indentacao -= 4;
resultado += ' '.repeat(this.indentacao) + '}';
return resultado;
}
traduzirDeclaracaoEscreva(declaracaoEscreva) {
const args = declaracaoEscreva.argumentos.map((a) => this.traduzirConstruto(a)).join(', ');
return `escreva(${args})`;
}
traduzirDeclaracaoEscrevaMesmaLinha(declaracaoEscreva) {
const args = declaracaoEscreva.argumentos.map((a) => this.traduzirConstruto(a)).join(', ');
return `escreva(${args})`;
}
traduzirDeclaracaoSe(declaracaoSe) {
const cond = this.traduzirConstruto(declaracaoSe.condicao);
let resultado = `se (${cond}) `;
resultado += this.traduzirDeclaracaoBloco(declaracaoSe.caminhoEntao);
if (declaracaoSe.caminhoSenao) {
resultado += ' senão ';
resultado += this.traduzirDeclaracaoBloco(declaracaoSe.caminhoSenao);
}
return resultado;
}
traduzirDeclaracaoEnquanto(declaracaoEnquanto) {
const cond = this.traduzirConstruto(declaracaoEnquanto.condicao);
let resultado = `enquanto (${cond}) `;
resultado += this.traduzirDeclaracaoBloco(declaracaoEnquanto.corpo);
return resultado;
}
traduzirDeclaracaoPara(declaracaoPara) {
// inicializador é Expressao(Atribuir(v, inicio))
let init = '';
if (declaracaoPara.inicializador) {
const ini = declaracaoPara.inicializador;
if (Array.isArray(ini)) {
init = ini.map((d) => this.traduzirDeclaracao(d)).join(', ');
}
else {
init = this.traduzirDeclaracao(ini);
}
}
const cond = declaracaoPara.condicao ? this.traduzirConstruto(declaracaoPara.condicao) : '';
const incr = declaracaoPara.incrementar
? this.traduzirConstruto(declaracaoPara.incrementar)
: '';
let resultado = `para (${init}; ${cond}; ${incr}) `;
resultado += this.traduzirDeclaracaoBloco(declaracaoPara.corpo);
return resultado;
}
traduzirDeclaracaoFazer(declaracaoFazer) {
let resultado = 'fazer ';
resultado += this.traduzirDeclaracaoBloco(declaracaoFazer.caminhoFazer);
const cond = this.traduzirConstruto(declaracaoFazer.condicaoEnquanto);
resultado += ` enquanto (${cond})`;
return resultado;
}
traduzirCaminhoEscolha(caminho) {
let resultado = '';
this.indentacao += 4;
if (caminho.condicoes && caminho.condicoes.length > 0) {
for (const cond of caminho.condicoes) {
resultado +=
' '.repeat(this.indentacao) + `caso ${this.traduzirConstruto(cond)}:\n`;
}
}
else {
resultado += ' '.repeat(this.indentacao) + 'padrão:\n';
}
this.indentacao += 4;
for (const declaracao of caminho.declaracoes) {
resultado += ' '.repeat(this.indentacao) + this.traduzirDeclaracao(declaracao) + '\n';
}
this.indentacao -= 8;
return resultado;
}
traduzirDeclaracaoEscolha(declaracaoEscolha) {
const expr = this.traduzirConstruto(declaracaoEscolha.identificadorOuLiteral);
let resultado = `escolha (${expr}) {\n`;
for (const caminho of declaracaoEscolha.caminhos) {
resultado += this.traduzirCaminhoEscolha(caminho);
}
if (declaracaoEscolha.caminhoPadrao) {
resultado += this.traduzirCaminhoEscolha(declaracaoEscolha.caminhoPadrao);
}
resultado += ' '.repeat(this.indentacao) + '}';
return resultado;
}
// ── Ponto de entrada ─────────────────────────────────────────────────────────
async traduzir(codigo) {
this.lexador = new dialetos_2.LexadorPortugolIpt();
this.avaliadorSintatico = new dialetos_1.AvaliadorSintaticoPortugolIpt();
const retornoLexador = this.lexador.mapear(codigo.split('\n'), -1);
const retornoAvaliadorSintatico = await this.avaliadorSintatico.analisar(retornoLexador, -1);
let resultado = '';
for (const declaracao of retornoAvaliadorSintatico.declaracoes) {
resultado += this.traduzirDeclaracao(declaracao) + '\n';
}
return resultado;
}
}
exports.TradutorPortugolIpt = TradutorPortugolIpt;
//# sourceMappingURL=tradutor-portugol-ipt.js.map