UNPKG

@designliquido/delegua

Version:

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

1,028 lines 58.4 kB
"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