@designliquido/delegua
Version:
Linguagem de programação simples e moderna usando português estruturado.
1,028 lines • 58.4 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.TradutorAssemblyScript = void 0;
const construtos_1 = require("../construtos");
const declaracoes_1 = require("../declaracoes");
const delegua_1 = __importDefault(require("../tipos-de-simbolos/delegua"));
class TradutorAssemblyScript {
constructor() {
this.indentacao = 0;
this.dicionarioConstrutos = {
AcessoIndiceVariavel: this.traduzirConstrutoAcessoIndiceVariavel.bind(this),
AcessoMetodo: this.traduzirConstrutoAcessoMetodo.bind(this),
AcessoMetodoOuPropriedade: this.traduzirConstrutoAcessoMetodo.bind(this),
AcessoPropriedade: this.traduzirConstrutoAcessoPropriedade.bind(this),
Agrupamento: this.traduzirConstrutoAgrupamento.bind(this),
ArgumentoReferenciaFuncao: this.traduzirConstrutoArgumentoReferenciaFuncao.bind(this),
AtribuicaoPorIndice: this.traduzirConstrutoAtribuicaoPorIndice.bind(this),
Atribuir: this.traduzirConstrutoAtribuir.bind(this),
Binario: this.traduzirConstrutoBinario.bind(this),
Chamada: this.traduzirConstrutoChamada.bind(this),
ComentarioComoConstruto: this.traduzirConstrutoComentario.bind(this),
Deceto: this.traduzirConstrutoDeceto.bind(this),
DefinirValor: this.traduzirConstrutoDefinirValor.bind(this),
Dicionario: this.traduzirConstrutoDicionario.bind(this),
Dupla: this.traduzirConstrutoDupla.bind(this),
Elvis: this.traduzirConstrutoElvis.bind(this),
ExpressaoRegular: this.traduzirConstrutoExpressaoRegular.bind(this),
FuncaoConstruto: this.traduzirFuncaoConstruto.bind(this),
Isto: () => 'this',
Literal: this.traduzirConstrutoLiteral.bind(this),
Logico: this.traduzirConstrutoLogico.bind(this),
Noneto: this.traduzirConstrutoNoneto.bind(this),
Octeto: this.traduzirConstrutoOcteto.bind(this),
Quarteto: this.traduzirConstrutoQuarteto.bind(this),
Quinteto: this.traduzirConstrutoQuinteto.bind(this),
ReferenciaFuncao: this.traduzirConstrutoReferenciaFuncao.bind(this),
Separador: this.traduzirConstrutoSeparador.bind(this),
SeTernario: this.traduzirConstrutoSeTernario.bind(this),
Sexteto: this.traduzirConstrutoSexteto.bind(this),
Septeto: this.traduzirConstrutoSepteto.bind(this),
TipoDe: this.traduzirConstrutoTipoDe.bind(this),
Trio: this.traduzirConstrutoTrio.bind(this),
TuplaN: this.traduzirConstrutoTuplaN.bind(this),
Unario: this.traduzirConstrutoUnario.bind(this),
Variavel: this.traduzirConstrutoVariavel.bind(this),
Vetor: this.traduzirConstrutoVetor.bind(this),
};
this.dicionarioDeclaracoes = {
Ajuda: this.traduzirDeclaracaoAjuda.bind(this),
Bloco: this.traduzirDeclaracaoBloco.bind(this),
Enquanto: this.traduzirDeclaracaoEnquanto.bind(this),
Comentario: this.traduzirConstrutoComentario.bind(this),
Continua: () => 'continue',
Escolha: this.traduzirDeclaracaoEscolha.bind(this),
Expressao: this.traduzirDeclaracaoExpressao.bind(this),
Fazer: this.traduzirDeclaracaoFazer.bind(this),
Falhar: this.traduzirDeclaracaoFalhar.bind(this),
FuncaoDeclaracao: this.traduzirDeclaracaoFuncao.bind(this),
Importar: this.traduzirDeclaracaoImportar.bind(this),
Leia: this.traduzirDeclaracaoLeia.bind(this),
Para: this.traduzirDeclaracaoPara.bind(this),
ParaCada: this.traduzirDeclaracaoParaCada.bind(this),
Retorna: this.traduzirDeclaracaoRetorna.bind(this),
Se: this.traduzirDeclaracaoSe.bind(this),
Sustar: () => 'break',
Classe: this.traduzirDeclaracaoClasse.bind(this),
Tente: this.traduzirDeclaracaoTente.bind(this),
Const: this.traduzirDeclaracaoConst.bind(this),
ConstMultiplo: this.traduzirDeclaracaoConstMultiplo.bind(this),
Var: this.traduzirDeclaracaoVar.bind(this),
VarMultiplo: this.traduzirDeclaracaoVarMultiplo.bind(this),
Escreva: this.traduzirDeclaracaoEscreva.bind(this),
EscrevaMesmaLinha: this.traduzirDeclaracaoEscrevaMesmaLinha.bind(this),
TendoComo: this.traduzirDeclaracaoTendoComo.bind(this),
TextoDocumentacao: this.traduzirDeclaracaoTextoDocumentacao.bind(this),
};
}
traduzirSimboloOperador(operador) {
switch (operador.tipo) {
case delegua_1.default.ADICAO:
return '+';
case delegua_1.default.BIT_AND:
return '&';
case delegua_1.default.BIT_OR:
return '|';
case delegua_1.default.CIRCUMFLEXO:
return '^';
case delegua_1.default.BIT_NOT:
return '~';
case delegua_1.default.DIFERENTE:
return '!=';
case delegua_1.default.DIVISAO:
return '/';
case delegua_1.default.E:
return '&&';
case delegua_1.default.EXPONENCIACAO:
return '**';
case delegua_1.default.IGUAL:
return '=';
case delegua_1.default.IGUAL_IGUAL:
return '==';
case delegua_1.default.MAIOR:
return '>';
case delegua_1.default.MAIOR_IGUAL:
return '>=';
case delegua_1.default.MENOR:
return '<';
case delegua_1.default.MENOR_IGUAL:
return '<=';
case delegua_1.default.MODULO:
return '%';
case delegua_1.default.MULTIPLICACAO:
return '*';
case delegua_1.default.OU:
return '||';
case delegua_1.default.SUBTRACAO:
return '-';
}
}
traduzirFuncoesNativas(metodo) {
switch (metodo.toLowerCase()) {
// Array methods
case 'adicionar':
case 'empilhar':
return 'push';
case 'concatenar':
return 'concat';
case 'fatiar':
return 'slice';
case 'inclui':
case 'incluido':
return 'includes';
case 'inverter':
return 'reverse';
case 'juntar':
return 'join';
case 'ordenar':
return 'sort';
case 'removerprimeiro':
return 'shift';
case 'removerultimo':
return 'pop';
case 'tamanho':
return 'length';
case 'indice':
case 'indiceode':
return 'indexOf';
// String methods
case 'maiusculo':
return 'toUpperCase';
case 'minusculo':
return 'toLowerCase';
case 'substituir':
return 'replace';
case 'trimcomeco':
return 'trimStart';
case 'trimfim':
return 'trimEnd';
case 'trim':
return 'trim';
case 'comeca':
return 'startsWith';
case 'termina':
return 'endsWith';
case 'contém':
case 'contem':
return 'includes';
// Math constants and methods (would need Math. prefix in AS)
case 'abs':
case 'absoluto':
return 'Math.abs';
case 'ceil':
case 'teto':
return 'Math.ceil';
case 'floor':
case 'piso':
return 'Math.floor';
case 'round':
case 'arredondar':
return 'Math.round';
case 'sqrt':
case 'raizquadrada':
return 'Math.sqrt';
case 'pow':
case 'potencia':
return 'Math.pow';
case 'max':
case 'maximo':
return 'Math.max';
case 'min':
case 'minimo':
return 'Math.min';
case 'sin':
case 'seno':
return 'Math.sin';
case 'cos':
case 'cosseno':
return 'Math.cos';
case 'tan':
case 'tangente':
return 'Math.tan';
case 'pi':
return 'Math.PI';
case 'e':
return 'Math.E';
default:
return metodo;
}
}
traduzirFuncaoNativaGlobal(nomeFuncao, argumentos) {
switch (nomeFuncao.toLowerCase()) {
// Math functions
case 'aleatorio':
return `Math.random()`;
case 'aleatorioEntre':
case 'aleatorioente':
if (argumentos.length >= 2) {
return `(Math.random() * (${argumentos[1]} - ${argumentos[0]}) + ${argumentos[0]})`;
}
return null;
case 'arredondar':
return argumentos.length > 0 ? `Math.round(${argumentos[0]})` : null;
case 'inteiro':
return argumentos.length > 0 ? `Math.trunc(${argumentos[0]})` : null;
case 'numero':
return argumentos.length > 0 ? `Number(${argumentos[0]})` : null;
case 'texto':
return argumentos.length > 0 ? `String(${argumentos[0]})` : null;
case 'longo':
return argumentos.length > 0 ? `parseInt(${argumentos[0]})` : null;
case 'real':
return argumentos.length > 0 ? `parseFloat(${argumentos[0]})` : null;
// Array functions
case 'tamanho':
return argumentos.length > 0 ? `(${argumentos[0]}).length` : null;
case 'intervalo':
// intervalo(inicio, fim, passo?) - returns array of numbers
if (argumentos.length >= 2) {
if (argumentos.length >= 3) {
return `Array.from({length: (${argumentos[1]} - ${argumentos[0]}) / ${argumentos[2]}}, (_, i) => ${argumentos[0]} + i * ${argumentos[2]})`;
}
return `Array.from({length: ${argumentos[1]} - ${argumentos[0]}}, (_, i) => ${argumentos[0]} + i)`;
}
return null;
case 'maximo':
return argumentos.length > 0 ? `Math.max(...${argumentos[0]})` : null;
case 'minimo':
return argumentos.length > 0 ? `Math.min(...${argumentos[0]})` : null;
// These need custom implementation or are too complex for Phase 5
case 'mapear':
case 'filtrarPor':
case 'reduzir':
case 'ordenar':
case 'encontrar':
case 'encontrarIndice':
case 'incluido':
case 'todos':
case 'algum':
// These would require closures/lambda support - not easily translated
return null;
default:
return null;
}
}
traduzirConstrutoArgumentoReferenciaFuncao(argumentoReferenciaFuncao, argumentos) {
const argumentosResolvidos = [];
for (const argumento of argumentos) {
const argumentoResolvido = this.dicionarioConstrutos[argumento.constructor.name](argumento);
argumentosResolvidos.push(argumentoResolvido);
}
let textoArgumentos = argumentosResolvidos.reduce((atual, proximo) => (atual += proximo + ', '), '');
textoArgumentos = textoArgumentos.slice(0, -2);
return `${argumentoReferenciaFuncao.simboloFuncao.lexema}(${textoArgumentos})`;
}
traduzirConstrutoReferenciaFuncao(referenciaFuncao, argumentos) {
const argumentosResolvidos = [];
for (const argumento of argumentos) {
const argumentoResolvido = this.dicionarioConstrutos[argumento.constructor.name](argumento);
argumentosResolvidos.push(argumentoResolvido);
}
let textoArgumentos = argumentosResolvidos.reduce((atual, proximo) => (atual += proximo + ', '), '');
textoArgumentos = textoArgumentos.slice(0, -2);
return `${referenciaFuncao.simboloFuncao.lexema}(${textoArgumentos})`;
}
traduzirConstrutoSeparador(separador) {
return `${separador.conteudo} `;
}
traduzirDeclaracaoEscreva(declaracaoEscreva) {
let resultado = 'trace(';
for (const argumento of declaracaoEscreva.argumentos) {
const valor = this.dicionarioConstrutos[argumento.constructor.name](argumento);
resultado += valor + ', ';
}
resultado = resultado.slice(0, -2);
resultado += ')';
return resultado;
}
traduzirConstrutoLiteral(literal) {
if (typeof literal.valor === 'string')
return `"${literal.valor}"`;
return String(literal.valor);
}
resolveTipoDeclaracaoVarEContante(tipo) {
switch (tipo) {
case 'texto':
return ': string';
case 'inteiro':
return ': i32';
case 'longo':
return ': i64';
case 'inteiro_curto':
case 'inteiroCurto':
return ': i16';
case 'byte':
return ': i8';
case 'numero':
case 'número':
case 'real':
return ': f64';
case 'real_curto':
case 'realCurto':
return ': f32';
case 'logico':
case 'lógico':
return ': bool';
case 'vazio':
case 'nada':
return ': void';
case 'nulo':
throw new Error(`Tipo 'nulo' não é válido no AssemblyScript. Use 'Type | null' para tipos anuláveis.`);
case 'inteiro[]':
return ': i32[]';
case 'longo[]':
return ': i64[]';
case 'real[]':
case 'numero[]':
case 'número[]':
return ': f64[]';
case 'texto[]':
return ': string[]';
case 'logico[]':
case 'lógico[]':
return ': bool[]';
case 'dicionario':
case 'dicionário':
return ': Map<string, i32>';
case 'dupla':
return ': i32[]';
case 'trio':
return ': i32[]';
case 'quarteto':
return ': i32[]';
case 'quinteto':
return ': i32[]';
case 'sexteto':
return ': i32[]';
case 'septeto':
return ': i32[]';
case 'octeto':
return ': i32[]';
case 'noneto':
return ': i32[]';
case 'deceto':
return ': i32[]';
case 'tupla':
return ': i32[]';
default:
throw new Error(`Tipo não reconhecido ou não suportado no AssemblyScript: '${tipo}'. AssemblyScript requer anotações de tipo explícitas.`);
}
}
traduzirDeclaracaoVar(declaracaoVar) {
let resultado = 'let ';
resultado += declaracaoVar.simbolo.lexema;
resultado += this.resolveTipoDeclaracaoVarEContante(declaracaoVar.tipo);
if (!(declaracaoVar === null || declaracaoVar === void 0 ? void 0 : declaracaoVar.inicializador))
resultado += ';';
else {
resultado += ' = ';
if (this.dicionarioConstrutos[declaracaoVar.inicializador.constructor.name]) {
resultado += this.dicionarioConstrutos[declaracaoVar.inicializador.constructor.name](declaracaoVar.inicializador);
}
else {
resultado += this.dicionarioDeclaracoes[declaracaoVar.inicializador.constructor.name](declaracaoVar.inicializador);
}
resultado += ';';
}
return resultado;
}
traduzirDeclaracaoConst(declaracaoConst) {
let resultado = 'const ';
resultado += declaracaoConst.simbolo.lexema;
resultado += this.resolveTipoDeclaracaoVarEContante(declaracaoConst.tipo);
if (!(declaracaoConst === null || declaracaoConst === void 0 ? void 0 : declaracaoConst.inicializador))
resultado += ';';
else {
resultado += ' = ';
if (this.dicionarioConstrutos[declaracaoConst.inicializador.constructor.name]) {
resultado += this.dicionarioConstrutos[declaracaoConst.inicializador.constructor.name](declaracaoConst.inicializador);
}
else {
resultado += this.dicionarioDeclaracoes[declaracaoConst.inicializador.constructor.name](declaracaoConst.inicializador);
}
resultado += ';';
}
return resultado;
}
traduzirDeclaracaoTente(declaracaoTente) {
let resultado = '/* AVISO: AssemblyScript não suporta try/catch/finally. Este código pode não funcionar como esperado. */\n';
resultado += 'try {\n';
this.indentacao += 4;
resultado += ' '.repeat(this.indentacao);
for (let condicao of declaracaoTente.caminhoTente) {
resultado += this.dicionarioDeclaracoes[condicao.constructor.name](condicao) + '\n';
resultado += ' '.repeat(this.indentacao);
}
resultado += '}';
if (declaracaoTente.caminhoPegue !== null) {
resultado += '\ncatch {\n';
resultado += ' '.repeat(this.indentacao);
if (Array.isArray(declaracaoTente.caminhoPegue)) {
for (let declaracao of declaracaoTente.caminhoPegue) {
resultado +=
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao) + '\n';
}
}
else {
for (let corpo of declaracaoTente.caminhoPegue.corpo) {
resultado += this.dicionarioDeclaracoes[corpo.constructor.name](corpo) + '\n';
}
}
resultado += ' '.repeat(this.indentacao);
resultado += '}';
}
if (declaracaoTente.caminhoFinalmente !== null) {
resultado += '\nfinally {\n';
for (let finalmente of declaracaoTente.caminhoFinalmente) {
resultado +=
this.dicionarioDeclaracoes[finalmente.constructor.name](finalmente) + '\n';
}
resultado += ' '.repeat(this.indentacao);
resultado += '}';
}
return resultado;
}
traduzirDeclaracaoVarMultiplo(declaracaoVarMultiplo) {
const variaveis = declaracaoVarMultiplo.simbolos.map((s) => s.lexema).join(', ');
let resultado = 'let ';
resultado += variaveis;
resultado += this.resolveTipoDeclaracaoVarEContante(declaracaoVarMultiplo.tipo);
if (!(declaracaoVarMultiplo === null || declaracaoVarMultiplo === void 0 ? void 0 : declaracaoVarMultiplo.inicializador))
resultado += ';';
else {
resultado += ' = ';
if (this.dicionarioConstrutos[declaracaoVarMultiplo.inicializador.constructor.name]) {
resultado += this.dicionarioConstrutos[declaracaoVarMultiplo.inicializador.constructor.name](declaracaoVarMultiplo.inicializador);
}
else {
resultado += this.dicionarioDeclaracoes[declaracaoVarMultiplo.inicializador.constructor.name](declaracaoVarMultiplo.inicializador);
}
resultado += ';';
}
return resultado;
}
traduzirDeclaracaoConstMultiplo(declaracaoConstMultiplo) {
const constantes = declaracaoConstMultiplo.simbolos.map((s) => s.lexema).join(', ');
let resultado = 'const ';
resultado += constantes;
resultado += this.resolveTipoDeclaracaoVarEContante(declaracaoConstMultiplo.tipo);
if (!(declaracaoConstMultiplo === null || declaracaoConstMultiplo === void 0 ? void 0 : declaracaoConstMultiplo.inicializador))
resultado += ';';
else {
resultado += ' = ';
if (this.dicionarioConstrutos[declaracaoConstMultiplo.inicializador.constructor.name]) {
resultado += this.dicionarioConstrutos[declaracaoConstMultiplo.inicializador.constructor.name](declaracaoConstMultiplo.inicializador);
}
else {
resultado += this.dicionarioDeclaracoes[declaracaoConstMultiplo.inicializador.constructor.name](declaracaoConstMultiplo.inicializador);
}
resultado += ';';
}
return resultado;
}
traduzirDeclaracaoEscrevaMesmaLinha(declaracaoEscrevaMesmaLinha) {
let resultado = 'trace(';
for (const argumento of declaracaoEscrevaMesmaLinha.argumentos) {
const valor = this.dicionarioConstrutos[argumento.constructor.name](argumento);
resultado += valor + ', ';
}
resultado = resultado.slice(0, -2);
resultado += ')';
return resultado;
}
traduzirDeclaracaoTendoComo(declaracaoTendoComo) {
// TendoComo is a resource management pattern (like try-with-resources in Java)
// AssemblyScript doesn't have built-in support, so we'll just treat it as a scope
let resultado = `// tendo ${declaracaoTendoComo.simboloVariavel.lexema} como recurso\n`;
resultado += ' '.repeat(this.indentacao);
resultado += `let ${declaracaoTendoComo.simboloVariavel.lexema} = `;
if (this.dicionarioConstrutos[declaracaoTendoComo.inicializacaoVariavel.constructor.name]) {
resultado += this.dicionarioConstrutos[declaracaoTendoComo.inicializacaoVariavel.constructor.name](declaracaoTendoComo.inicializacaoVariavel);
}
else {
resultado += this.dicionarioDeclaracoes[declaracaoTendoComo.inicializacaoVariavel.constructor.name](declaracaoTendoComo.inicializacaoVariavel);
}
resultado += ';\n';
resultado += ' '.repeat(this.indentacao);
resultado += this.dicionarioDeclaracoes[declaracaoTendoComo.corpo.constructor.name](declaracaoTendoComo.corpo);
return resultado;
}
traduzirDeclaracaoAjuda(declaracaoAjuda) {
// Ajuda is a help/documentation statement
// In AssemblyScript, we'll just comment it out
return '// ajuda' + '\n';
}
traduzirDeclaracaoTextoDocumentacao(declaracaoTextoDoc) {
// TextoDocumentacao is documentation text
// We'll convert it to a comment
return `/** ${declaracaoTextoDoc} */\n`;
}
logicaComumBlocoEscopo(declaracoes) {
let resultado = '{\n';
this.indentacao += 4;
if (typeof declaracoes[Symbol.iterator] === 'function') {
for (const declaracaoOuConstruto of declaracoes) {
resultado += ' '.repeat(this.indentacao);
const nomeConstrutor = declaracaoOuConstruto.constructor.name;
if (this.dicionarioConstrutos.hasOwnProperty(nomeConstrutor)) {
resultado += this.dicionarioConstrutos[nomeConstrutor](declaracaoOuConstruto);
}
else {
resultado += this.dicionarioDeclaracoes[nomeConstrutor](declaracaoOuConstruto);
}
resultado += '\n';
}
}
this.indentacao -= 4;
resultado += ' '.repeat(this.indentacao) + '}\n';
return resultado;
}
logicaTraducaoMetodoClasse(metodoClasse) {
this.indentacao += 4;
let resultado = ' '.repeat(this.indentacao);
resultado +=
metodoClasse.simbolo.lexema === 'construtor'
? 'constructor('
: metodoClasse.simbolo.lexema + '(';
for (let parametro of metodoClasse.funcao.parametros) {
resultado += parametro.nome.lexema + ', ';
}
if (metodoClasse.funcao.parametros.length > 0) {
resultado = resultado.slice(0, -2);
}
resultado += ') ';
resultado += this.logicaComumBlocoEscopo(metodoClasse.funcao.corpo);
resultado += ' '.repeat(this.indentacao) + '\n';
this.indentacao -= 4;
return resultado;
}
traduzirDeclaracaoClasse(declaracaoClasse) {
let resultado = 'export class ';
if (declaracaoClasse.superClasse)
resultado += `${declaracaoClasse.simbolo.lexema} extends ${declaracaoClasse.superClasse.simbolo.lexema} {\n`;
else
resultado += declaracaoClasse.simbolo.lexema + ' {\n';
for (let metodo of declaracaoClasse.metodos) {
resultado += this.logicaTraducaoMetodoClasse(metodo);
}
resultado += '}';
return resultado;
}
traduzirDeclaracaoSe(declaracaoSe) {
let resultado = 'if (';
const condicao = this.dicionarioConstrutos[declaracaoSe.condicao.constructor.name](declaracaoSe.condicao);
resultado += condicao;
resultado += ')';
resultado += this.dicionarioDeclaracoes[declaracaoSe.caminhoEntao.constructor.name](declaracaoSe.caminhoEntao);
if (declaracaoSe.caminhoSenao !== null) {
resultado += ' '.repeat(this.indentacao);
resultado += 'else ';
const se = declaracaoSe === null || declaracaoSe === void 0 ? void 0 : declaracaoSe.caminhoSenao;
if (se === null || se === void 0 ? void 0 : se.caminhoEntao) {
resultado += 'if (';
resultado += this.dicionarioConstrutos[se.condicao.constructor.name](se.condicao);
resultado += ')';
resultado += this.dicionarioDeclaracoes[se.caminhoEntao.constructor.name](se.caminhoEntao);
resultado += ' '.repeat(this.indentacao);
if (se === null || se === void 0 ? void 0 : se.caminhoSenao) {
resultado += 'else ';
resultado += this.dicionarioDeclaracoes[se.caminhoSenao.constructor.name](se.caminhoSenao);
return resultado;
}
}
resultado += this.dicionarioDeclaracoes[declaracaoSe.caminhoSenao.constructor.name](declaracaoSe.caminhoSenao);
}
return resultado;
}
traduzirDeclaracaoRetorna(declaracaoRetorna) {
let resultado = 'return ';
const nomeConstrutor = declaracaoRetorna.valor.constructor.name;
return (resultado += this.dicionarioConstrutos[nomeConstrutor](declaracaoRetorna === null || declaracaoRetorna === void 0 ? void 0 : declaracaoRetorna.valor));
}
traduzirDeclaracaoParaCada(declaracaoParaCada) {
// AssemblyScript não suporta for...of. Convertendo para loop baseado em índice.
if (declaracaoParaCada.variavelIteracao.constructor.name !== 'Variavel') {
throw new Error('Desestruturação em paraCada não é suportada no AssemblyScript. Use uma variável simples.');
}
const nomeVariavel = declaracaoParaCada.variavelIteracao.simbolo.lexema;
const nomeVetor = `__arr_${nomeVariavel}`;
let resultado = `const ${nomeVetor} = `;
resultado +=
this.dicionarioConstrutos[declaracaoParaCada.vetorOuDicionario.constructor.name](declaracaoParaCada.vetorOuDicionario) + ';';
resultado += '\n';
resultado += ' '.repeat(this.indentacao);
resultado += `for (let __i_${nomeVariavel} = 0; __i_${nomeVariavel} < ${nomeVetor}.length; __i_${nomeVariavel}++) `;
// Injeta a atribuição da variável de iteração no início do corpo do bloco
const corpoBloco = declaracaoParaCada.corpo;
const declaracoesCorpo = corpoBloco.declaracoes || [];
let resultadoCorpo = '{\n';
this.indentacao += 4;
resultadoCorpo +=
' '.repeat(this.indentacao) +
`const ${nomeVariavel} = ${nomeVetor}[__i_${nomeVariavel}];\n`;
for (const declaracaoOuConstruto of declaracoesCorpo) {
resultadoCorpo += ' '.repeat(this.indentacao);
const nomeConstrutor = declaracaoOuConstruto.constructor.name;
if (this.dicionarioConstrutos.hasOwnProperty(nomeConstrutor)) {
resultadoCorpo += this.dicionarioConstrutos[nomeConstrutor](declaracaoOuConstruto);
}
else {
resultadoCorpo += this.dicionarioDeclaracoes[nomeConstrutor](declaracaoOuConstruto);
}
resultadoCorpo += '\n';
}
this.indentacao -= 4;
resultadoCorpo += ' '.repeat(this.indentacao) + '}\n';
resultado += resultadoCorpo;
return resultado;
}
traduzirDeclaracaoPara(declaracaoPara) {
let resultado = 'for (';
if (declaracaoPara.inicializador.constructor.name === 'Array') {
resultado +=
this.dicionarioDeclaracoes[declaracaoPara.inicializador[0].constructor.name](declaracaoPara.inicializador[0]) + ' ';
}
else {
resultado +=
this.dicionarioDeclaracoes[declaracaoPara.inicializador.constructor.name](declaracaoPara.inicializador) + ' ';
}
resultado += !resultado.includes(';') ? ';' : '';
resultado +=
this.dicionarioConstrutos[declaracaoPara.condicao.constructor.name](declaracaoPara.condicao) + '; ';
resultado +=
this.dicionarioConstrutos[declaracaoPara.incrementar.constructor.name](declaracaoPara.incrementar) + ') ';
resultado += this.dicionarioDeclaracoes[declaracaoPara.corpo.constructor.name](declaracaoPara.corpo);
return resultado;
}
traduzirDeclaracaoImportar(declaracaoImportar) {
return `'importar() não é suportado por este padrão de JavaScript'`;
}
traduzirDeclaracaoLeia(declaracaoLeia) {
return `'leia() não é suportado por este padrão de JavaScript.'`;
}
traduzirDeclaracaoFuncao(declaracaoFuncao) {
let resultado = 'function ';
resultado += declaracaoFuncao.simbolo.lexema + '(';
// Adiciona parâmetros com tipos
for (const parametro of declaracaoFuncao.funcao.parametros) {
resultado += parametro.nome.lexema;
// Adiciona tipo do parâmetro se disponível
if (parametro.tipoDado) {
try {
resultado += this.resolveTipoDeclaracaoVarEContante(parametro.tipoDado);
}
catch (e) {
// Se não conseguir resolver o tipo, lança erro mais específico
throw new Error(`Parâmetro '${parametro.nome.lexema}' da função '${declaracaoFuncao.simbolo.lexema}' tem tipo não suportado: '${parametro.tipoDado}'`);
}
}
else {
// AssemblyScript requer tipos explícitos em todos os parâmetros
throw new Error(`Parâmetro '${parametro.nome.lexema}' da função '${declaracaoFuncao.simbolo.lexema}' não tem tipo definido. AssemblyScript requer tipos explícitos.`);
}
resultado += ', ';
}
if (declaracaoFuncao.funcao.parametros.length > 0) {
resultado = resultado.slice(0, -2);
}
resultado += ')';
// Adiciona tipo de retorno
const tipoRetorno = this.inferirTipoRetornoFuncao(declaracaoFuncao.funcao);
resultado += tipoRetorno;
resultado += ' ';
resultado += this.logicaComumBlocoEscopo(declaracaoFuncao.funcao.corpo);
return resultado;
}
inferirTipoRetornoFuncao(funcao) {
// Se a função tem tipo de retorno explícito, usa ele
if (funcao.tipo && funcao.tipo !== 'qualquer') {
try {
return this.resolveTipoDeclaracaoVarEContante(funcao.tipo);
}
catch (e) {
// Se não conseguir resolver, retorna void por padrão
return ': void';
}
}
// Procura por declarações de retorno no corpo e infere tipo a partir delas
const tipoInferido = this.inferirTipoDeRetorno(funcao.corpo);
if (tipoInferido) {
try {
return this.resolveTipoDeclaracaoVarEContante(tipoInferido);
}
catch (e) {
return ': void';
}
}
return ': void';
}
inferirTipoDeRetorno(corpo) {
if (!corpo)
return null;
for (const declaracao of corpo) {
if (declaracao.constructor.name === 'Retorna') {
const retorna = declaracao;
if (retorna.tipo && retorna.tipo !== 'vazio') {
return retorna.tipo;
}
}
// Verifica recursivamente em blocos aninhados
if (declaracao.corpo) {
const corpoInterno = declaracao.corpo;
if (Array.isArray(corpoInterno)) {
const tipo = this.inferirTipoDeRetorno(corpoInterno);
if (tipo)
return tipo;
}
else if (corpoInterno.declaracoes) {
const tipo = this.inferirTipoDeRetorno(corpoInterno.declaracoes);
if (tipo)
return tipo;
}
}
}
return null;
}
traduzirDeclaracaoFalhar(falhar) {
return `abort('${falhar.explicacao.valor}')`;
}
traduzirDeclaracaoFazer(declaracaoFazer) {
let resultado = 'do ';
resultado += this.dicionarioDeclaracoes[declaracaoFazer.caminhoFazer.constructor.name](declaracaoFazer.caminhoFazer);
resultado +=
'while (' +
this.dicionarioConstrutos[declaracaoFazer.condicaoEnquanto.constructor.name](declaracaoFazer.condicaoEnquanto) +
') ';
return resultado;
}
traduzirDeclaracaoExpressao(declaracaoExpressao) {
return this.dicionarioConstrutos[declaracaoExpressao.expressao.constructor.name](declaracaoExpressao.expressao);
}
logicaComumCaminhosEscolha(caminho) {
let resultado = '';
this.indentacao += 4;
resultado += ' '.repeat(this.indentacao);
for (let condicao of caminho.condicoes || []) {
resultado +=
'case ' + this.dicionarioConstrutos[condicao.constructor.name](condicao) + ':\n';
resultado += ' '.repeat(this.indentacao);
}
for (let declaracao of caminho.declaracoes) {
resultado += ' '.repeat(this.indentacao + 4);
switch (declaracao.constructor.name) {
case 'Retorna':
const declaracaoRetorna = declaracao;
resultado +=
'return ' +
this.dicionarioConstrutos[declaracaoRetorna.valor.constructor.name](declaracaoRetorna.valor);
break;
default:
resultado +=
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao) + '\n';
break;
}
resultado += ' '.repeat(this.indentacao + 4);
resultado += 'break' + '\n';
}
this.indentacao -= 4;
return resultado;
}
traduzirDeclaracaoEscolha(declaracaoEscolha) {
let resultado = 'switch (';
resultado +=
this.dicionarioConstrutos[declaracaoEscolha.identificadorOuLiteral.constructor.name](declaracaoEscolha.identificadorOuLiteral) + ') {\n';
for (let caminho of declaracaoEscolha.caminhos) {
resultado += this.logicaComumCaminhosEscolha(caminho);
}
if (declaracaoEscolha.caminhoPadrao) {
resultado += ' '.repeat(4);
resultado += 'default:\n';
resultado += this.logicaComumCaminhosEscolha(declaracaoEscolha.caminhoPadrao);
}
resultado += '}\n';
return resultado;
}
traduzirDeclaracaoEnquanto(declaracaoEnquanto) {
let resultado = 'while (';
resultado +=
this.dicionarioConstrutos[declaracaoEnquanto.condicao.constructor.name](declaracaoEnquanto.condicao) + ') ';
resultado += this.dicionarioDeclaracoes[declaracaoEnquanto.corpo.constructor.name](declaracaoEnquanto.corpo);
return resultado;
}
traduzirDeclaracaoBloco(declaracaoBloco) {
return this.logicaComumBlocoEscopo(declaracaoBloco.declaracoes);
}
traduzirConstrutoVetor(vetor) {
if (!vetor.valores.length) {
return '[]';
}
let resultado = '[';
for (let valor of vetor.valores) {
resultado += `${this.dicionarioConstrutos[valor.constructor.name](valor)}`;
}
resultado += ']';
return resultado;
}
traduzirConstrutoDicionario(dicionario) {
// AssemblyScript Maps são inicializados via construtor
// Map<K, V>() requer: new Map<string, ValueType>()
if (!dicionario.chaves.length) {
return 'new Map<string, i32>()';
}
// AssemblyScript não suporta literal syntax para Map, precisa usar constructor
// Gerar algo como: { let m = new Map<string, i32>(); m.set("key", value); ... return m; }
let resultado = '(() => { let m = new Map<string, i32>(); ';
for (let i = 0; i < dicionario.chaves.length; i++) {
const chave = dicionario.chaves[i];
const valor = dicionario.valores[i];
// A chave pode ser um Construto (como Literal) ou um valor simples
let chaveStr;
if (typeof chave === 'string') {
chaveStr = `"${chave}"`;
}
else if (chave &&
chave.constructor &&
this.dicionarioConstrutos[chave.constructor.name]) {
// Se for um Construto, traduzi-lo
chaveStr = this.dicionarioConstrutos[chave.constructor.name](chave);
}
else {
// Fallback: converter para string
chaveStr = `"${String(chave)}"`;
}
resultado += `m.set(${chaveStr}, ${this.dicionarioConstrutos[valor.constructor.name](valor)}); `;
}
resultado += 'return m; })()';
return resultado;
}
traduzirConstrutoDupla(dupla) {
const primeiro = this.dicionarioConstrutos[dupla.primeiro.constructor.name](dupla.primeiro);
const segundo = this.dicionarioConstrutos[dupla.segundo.constructor.name](dupla.segundo);
return `[${primeiro}, ${segundo}]`;
}
traduzirConstrutoTrio(trio) {
const primeiro = this.dicionarioConstrutos[trio.primeiro.constructor.name](trio.primeiro);
const segundo = this.dicionarioConstrutos[trio.segundo.constructor.name](trio.segundo);
const terceiro = this.dicionarioConstrutos[trio.terceiro.constructor.name](trio.terceiro);
return `[${primeiro}, ${segundo}, ${terceiro}]`;
}
traduzirConstrutoQuarteto(quarteto) {
const primeiro = this.dicionarioConstrutos[quarteto.primeiro.constructor.name](quarteto.primeiro);
const segundo = this.dicionarioConstrutos[quarteto.segundo.constructor.name](quarteto.segundo);
const terceiro = this.dicionarioConstrutos[quarteto.terceiro.constructor.name](quarteto.terceiro);
const quarto = this.dicionarioConstrutos[quarteto.quarto.constructor.name](quarteto.quarto);
return `[${primeiro}, ${segundo}, ${terceiro}, ${quarto}]`;
}
traduzirConstrutoQuinteto(quinteto) {
const primeiro = this.dicionarioConstrutos[quinteto.primeiro.constructor.name](quinteto.primeiro);
const segundo = this.dicionarioConstrutos[quinteto.segundo.constructor.name](quinteto.segundo);
const terceiro = this.dicionarioConstrutos[quinteto.terceiro.constructor.name](quinteto.terceiro);
const quarto = this.dicionarioConstrutos[quinteto.quarto.constructor.name](quinteto.quarto);
const quinto = this.dicionarioConstrutos[quinteto.quinto.constructor.name](quinteto.quinto);
return `[${primeiro}, ${segundo}, ${terceiro}, ${quarto}, ${quinto}]`;
}
traduzirConstrutoSexteto(sexteto) {
const primeiro = this.dicionarioConstrutos[sexteto.primeiro.constructor.name](sexteto.primeiro);
const segundo = this.dicionarioConstrutos[sexteto.segundo.constructor.name](sexteto.segundo);
const terceiro = this.dicionarioConstrutos[sexteto.terceiro.constructor.name](sexteto.terceiro);
const quarto = this.dicionarioConstrutos[sexteto.quarto.constructor.name](sexteto.quarto);
const quinto = this.dicionarioConstrutos[sexteto.quinto.constructor.name](sexteto.quinto);
const sexto = this.dicionarioConstrutos[sexteto.sexto.constructor.name](sexteto.sexto);
return `[${primeiro}, ${segundo}, ${terceiro}, ${quarto}, ${quinto}, ${sexto}]`;
}
traduzirConstrutoSepteto(septeto) {
const primeiro = this.dicionarioConstrutos[septeto.primeiro.constructor.name](septeto.primeiro);
const segundo = this.dicionarioConstrutos[septeto.segundo.constructor.name](septeto.segundo);
const terceiro = this.dicionarioConstrutos[septeto.terceiro.constructor.name](septeto.terceiro);
const quarto = this.dicionarioConstrutos[septeto.quarto.constructor.name](septeto.quarto);
const quinto = this.dicionarioConstrutos[septeto.quinto.constructor.name](septeto.quinto);
const sexto = this.dicionarioConstrutos[septeto.sexto.constructor.name](septeto.sexto);
const setimo = this.dicionarioConstrutos[septeto.setimo.constructor.name](septeto.setimo);
return `[${primeiro}, ${segundo}, ${terceiro}, ${quarto}, ${quinto}, ${sexto}, ${setimo}]`;
}
traduzirConstrutoOcteto(octeto) {
const primeiro = this.dicionarioConstrutos[octeto.primeiro.constructor.name](octeto.primeiro);
const segundo = this.dicionarioConstrutos[octeto.segundo.constructor.name](octeto.segundo);
const terceiro = this.dicionarioConstrutos[octeto.terceiro.constructor.name](octeto.terceiro);
const quarto = this.dicionarioConstrutos[octeto.quarto.constructor.name](octeto.quarto);
const quinto = this.dicionarioConstrutos[octeto.quinto.constructor.name](octeto.quinto);
const sexto = this.dicionarioConstrutos[octeto.sexto.constructor.name](octeto.sexto);
const setimo = this.dicionarioConstrutos[octeto.setimo.constructor.name](octeto.setimo);
const oitavo = this.dicionarioConstrutos[octeto.oitavo.constructor.name](octeto.oitavo);
return `[${primeiro}, ${segundo}, ${terceiro}, ${quarto}, ${quinto}, ${sexto}, ${setimo}, ${oitavo}]`;
}
traduzirConstrutoNoneto(noneto) {
const primeiro = this.dicionarioConstrutos[noneto.primeiro.constructor.name](noneto.primeiro);
const segundo = this.dicionarioConstrutos[noneto.segundo.constructor.name](noneto.segundo);
const terceiro = this.dicionarioConstrutos[noneto.terceiro.constructor.name](noneto.terceiro);
const quarto = this.dicionarioConstrutos[noneto.quarto.constructor.name](noneto.quarto);
const quinto = this.dicionarioConstrutos[noneto.quinto.constructor.name](noneto.quinto);
const sexto = this.dicionarioConstrutos[noneto.sexto.constructor.name](noneto.sexto);
const setimo = this.dicionarioConstrutos[noneto.setimo.constructor.name](noneto.setimo);
const oitavo = this.dicionarioConstrutos[noneto.oitavo.constructor.name](noneto.oitavo);
const nono = this.dicionarioConstrutos[noneto.nono.constructor.name](noneto.nono);
return `[${primeiro}, ${segundo}, ${terceiro}, ${quarto}, ${quinto}, ${sexto}, ${setimo}, ${oitavo}, ${nono}]`;
}
traduzirConstrutoDeceto(deceto) {
const primeiro = this.dicionarioConstrutos[deceto.primeiro.constructor.name](deceto.primeiro);
const segundo = this.dicionarioConstrutos[deceto.segundo.constructor.name](deceto.segundo);
const terceiro = this.dicionarioConstrutos[deceto.terceiro.constructor.name](deceto.terceiro);
const quarto = this.dicionarioConstrutos[deceto.quarto.constructor.name](deceto.quarto);
const quinto = this.dicionarioConstrutos[deceto.quinto.constructor.name](deceto.quinto);
const sexto = this.dicionarioConstrutos[deceto.sexto.constructor.name](deceto.sexto);
const setimo = this.dicionarioConstrutos[deceto.setimo.constructor.name](deceto.setimo);
const oitavo = this.dicionarioConstrutos[deceto.oitavo.constructor.name](deceto.oitavo);
const nono = this.dicionarioConstrutos[deceto.nono.constructor.name](deceto.nono);
const decimo = this.dicionarioConstrutos[deceto.decimo.constructor.name](deceto.decimo);
return `[${primeiro}, ${segundo}, ${terceiro}, ${quarto}, ${quinto}, ${sexto}, ${setimo}, ${oitavo}, ${nono}, ${decimo}]`;
}
traduzirConstrutoTuplaN(tuplaN) {
const elementos = tuplaN.elementos.map((elemento) => this.dicionarioConstrutos[elemento.constructor.name](elemento));
return `[${elementos.join(', ')}]`;
}
traduzirConstrutoSeTernario(seTernario) {
const condicao = this.dicionarioConstrutos[seTernario.condicao.constructor.name](seTernario.condicao);
const expressaoSe = this.dicionarioConstrutos[seTernario.expressaoSe.constructor.name](seTernario.expressaoSe);
const expressaoSenao = this.dicionarioConstrutos[seTernario.expressaoSenao.constructor.name](seTernario.expressaoSenao);
return `${condicao} ? ${expressaoSe} : ${expressaoSenao}`;
}
traduzirConstrutoElvis(elvis) {
const esquerda = this.dicionarioConstrutos[elvis.esquerda.constructor.name](elvis.esquerda);
const direita = this.dicionarioConstrutos[elvis.direita.constructor.name](elvis.direita);
// Elvis operator (?:) is equivalent to || in JavaScript for null-coalescing
return `${esquerda} || ${direita}`;
}
traduzirConstrutoAcessoPropriedade(acessoPropriedade) {
const objeto = this.dicionarioConstrutos[acessoPropriedade.objeto.constructor.name](acessoPropriedade.objeto);
return `${objeto}.${acessoPropriedade.nomePropriedade}`;
}
traduzirConstrutoExpressaoRegular(expressaoRegular) {
// AssemblyScript doesn't have native regex support like JavaScript
// Return the pattern as a string for now
const valor = expressaoRegular.valor;
if (typeof valor === 'string') {
return `"${valor}"`;
}
return String(valor);
}
traduzirConstrutoVariavel(variavel) {
return variavel.simbolo.lexema;
}
traduzirConstrutoUnario(unario) {
var _a, _b;
let resultado = '';
if ([delegua_1.default.INCREMENTAR, delegua_1.default.DECREMENTAR].includes(unario.operador.tipo)) {
resultado += (_a = unario.operando.valor) !== null && _a !== void 0 ? _a : unario.operando.simbolo.lexema;
resultado += unario.operador.tipo === delegua_1.default.INCREMENTAR ? '++' : '--';
}
else {
resultado += this.traduzirSimboloOperador(unario.operador);
resultado += (_b = unario.operando.valor) !== null && _b !== void 0 ? _b : unario.operando.simbolo.lexema;
}
return resultado;
}
traduzirConstrutoTipoDe(tipoDe) {
throw new Error('O operador typeof não é suportado no AssemblyScript. Use verificações de tipo em tempo de compilação como instanceof ou is<T>() em vez disso.');
}
traduzirConstrutoLogico(logico) {
let esquerda = this.dicionarioConstrutos[logico.esquerda.constructor.name](logico.esquerda);
let operador = this.traduzirSimboloOperador(logico.operador);
let direita = this.dicionarioConstrutos[logico.direita.constructor.name](logico.direita);
return `${esquerda} ${operador} ${direita}`;
}
traduzirFuncaoConstruto(funcaoConstruto) {
let resultado = 'function(';
for (const parametro of funcaoConstruto.parametros) {
const tipoParametro = this.resolveTipoDeclaracaoVarEContante(parametro.tipoDado);
resultado += `${parametro.nome.lexema}${tipoParametro}, `;
}
if (funcaoConstruto.parametros.length > 0) {
resultado = resultado.slice(0, -2);
}
resultado += ') ';
resultado += this.logicaComumBlocoEscopo(funcaoConstruto.corpo);
return resultado;
}
traduzirConstrutoDefinirValor(definirValor) {
let resultado = '';
if (definirValor.objeto instanceof construtos_1.Isto) {
resultado = 'this.' + definirValor.nome.lexema + ' = ';
}
resultado += definirValor.valor.simbolo.lexema;
return resultado;
}
traduzirConstrutoChamada(chamada) {
let resultado = '';
// Check if this is a native library function call
if (chamada.entidadeChamada instanceof construtos_1.Variavel) {
const nomeVariavel = chamada.entidadeChamada.simbolo.lexema;
const argumentosTexto = chamada.argumentos.map((arg) => this.dicionarioConstrutos[arg.constructor.name](arg));
const funcaoNativa = this.traduzirFuncaoNativaGlobal(nomeVariavel, argumentosTexto);
if (funcaoNativa) {
return funcaoNativa;
}
}
const retorno = `${this.dicionarioConstrutos[chamada.entidadeChamada.constructor.name](chamada.entidadeCha