UNPKG

@designliquido/delegua

Version:

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

774 lines 29.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TradutorAssemblyX64 = void 0; const construtos_1 = require("../construtos"); const declaracoes_1 = require("../declaracoes"); class TradutorAssemblyX64 { constructor(alvo = 'linux') { this.alvo = alvo; this.indentacao = 0; this.contadorLabels = 0; this.variaveis = new Map(); this.registradoresDisponiveis = ['rbx', 'r12', 'r13', 'r14', 'r15']; this.pilhaRegistradores = []; this.helperPrintIntEmitido = false; this.fmtIntWindowsEmitido = false; this.helpers = ''; this.bss = 'section .bss\n'; this.data = 'section .data\n'; this.dicionarioConstrutos = { AcessoIndiceVariavel: this.traduzirAcessoIndiceVariavel.bind(this), AcessoMetodoOuPropriedade: this.trazudirConstrutoAcessoMetodo.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), DefinirValor: this.traduzirConstrutoDefinirValor.bind(this), FuncaoConstruto: this.traduzirFuncaoConstruto.bind(this), Isto: () => 'this', Literal: this.traduzirConstrutoLiteral.bind(this), Logico: this.traduzirConstrutoLogico.bind(this), TipoDe: this.traduzirConstrutoTipoDe.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), 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), Var: this.traduzirDeclaracaoVar.bind(this), Escreva: this.traduzirDeclaracaoEscreva.bind(this), }; this.indentacao = 0; this.textoSaida = ` section .text ${this.alvo === 'linux' ? 'global _start' : 'global main'} ${this.alvo === 'linux' ? '_start:' : 'main:'}`; if (this.alvo === 'windows') { this.textoSaida = ` extern printf ` + this.textoSaida; } } gerarDigitoAleatorio() { let result = ''; const digits = '0123456789'; for (let i = 0; i < 5; i++) { const randomIndex = Math.floor(Math.random() * digits.length); result += digits.charAt(randomIndex); } return result; } gerarLabel() { return `L${this.contadorLabels++}`; } obterRegistrador() { if (this.registradoresDisponiveis.length > 0) { const reg = this.registradoresDisponiveis.pop(); this.pilhaRegistradores.push(reg); return reg; } return 'rax'; // fallback } liberarRegistrador(reg) { const index = this.pilhaRegistradores.indexOf(reg); if (index > -1) { this.pilhaRegistradores.splice(index, 1); this.registradoresDisponiveis.push(reg); } } // Implementação dos Construtos traduzirAcessoIndiceVariavel(construto) { let nomeVar; if (construto.entidadeChamada instanceof construtos_1.Variavel) { nomeVar = construto.entidadeChamada.simbolo?.lexema; } if (!nomeVar) { nomeVar = 'unknown'; } const indice = this.dicionarioConstrutos[construto.indice.constructor.name](construto.indice); return `[${nomeVar} + ${indice} * 8]`; } trazudirConstrutoAcessoMetodo(construto) { const objeto = this.dicionarioConstrutos[construto.objeto.constructor.name](construto.objeto); return `${objeto}.${construto.nomeMetodo}`; } traduzirConstrutoAgrupamento(construto) { return this.dicionarioConstrutos[construto.expressao.constructor.name](construto.expressao); } traduzirConstrutoAtribuicaoPorIndice(construto) { let nomeVar; if (construto.objeto instanceof construtos_1.Variavel) { nomeVar = construto.objeto.simbolo?.lexema; } if (!nomeVar) { nomeVar = 'unknown'; } const indice = this.dicionarioConstrutos[construto.indice.constructor.name](construto.indice); const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor); this.textoSaida += ` mov rax, ${valor} mov [${nomeVar} + ${indice} * 8], rax`; } traduzirConstrutoAtribuir(construto) { // Atribuir tem a estrutura: { alvo, valor } let nomeVar; if (construto.alvo instanceof construtos_1.Variavel) { nomeVar = construto.alvo.simbolo?.lexema; } if (!nomeVar) { return; } const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor); if (!this.variaveis.has(nomeVar)) { const varLabel = `var_${nomeVar}`; this.bss += ` ${varLabel} resq 1\n`; this.variaveis.set(nomeVar, varLabel); } this.textoSaida += ` mov rax, ${valor} mov [${this.variaveis.get(nomeVar)}], rax`; } traduzirConstrutoBinario(construto) { const esquerda = this.dicionarioConstrutos[construto.esquerda.constructor.name](construto.esquerda); const direita = this.dicionarioConstrutos[construto.direita.constructor.name](construto.direita); const operador = construto.operador.lexema; const registrador = this.obterRegistrador(); this.textoSaida += ` mov rax, ${esquerda} mov ${registrador}, ${direita}`; switch (operador) { case '+': this.textoSaida += ` add rax, ${registrador}`; break; case '-': this.textoSaida += ` sub rax, ${registrador}`; break; case '*': this.textoSaida += ` imul rax, ${registrador}`; break; case '/': this.textoSaida += ` xor rdx, rdx idiv ${registrador}`; break; case '%': this.textoSaida += ` xor rdx, rdx idiv ${registrador} mov rax, rdx`; break; case '<': this.textoSaida += ` cmp rax, ${registrador} setl al movzx rax, al`; break; case '>': this.textoSaida += ` cmp rax, ${registrador} setg al movzx rax, al`; break; case '<=': this.textoSaida += ` cmp rax, ${registrador} setle al movzx rax, al`; break; case '>=': this.textoSaida += ` cmp rax, ${registrador} setge al movzx rax, al`; break; case '==': this.textoSaida += ` cmp rax, ${registrador} sete al movzx rax, al`; break; case '!=': this.textoSaida += ` cmp rax, ${registrador} setne al movzx rax, al`; break; default: this.textoSaida += ` ; Operador ${operador} não implementado`; } this.liberarRegistrador(registrador); return 'rax'; } traduzirConstrutoChamada(construto) { let nomeFuncao = 'funcao'; if (construto.entidadeChamada instanceof construtos_1.Variavel) { nomeFuncao = construto.entidadeChamada.simbolo?.lexema || 'funcao'; } // Preparar argumentos (convenção de chamada System V AMD64) const registrosArgs = this.alvo === 'linux' ? ['rdi', 'rsi', 'rdx', 'rcx', 'r8', 'r9'] // System V AMD64 [web:8] : ['rcx', 'rdx', 'r8', 'r9']; // Windows x64 [web:2] construto.argumentos.forEach((argumento, indice) => { if (indice < registrosArgs.length) { const valorArg = this.dicionarioConstrutos[argumento.constructor.name](argumento); this.textoSaida += ` mov ${registrosArgs[indice]}, ${valorArg}`; } else { // TODO: empurrar argumentos extras na pilha de acordo com o ABI alvo } }); this.textoSaida += ` call ${nomeFuncao}`; } traduzirConstrutoDefinirValor(construto) { const objeto = this.dicionarioConstrutos[construto.objeto.constructor.name](construto.objeto); const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor); this.textoSaida += ` mov rax, ${valor} mov [${objeto}], rax`; } traduzirFuncaoConstruto(construto) { const labelFuncao = `func_${this.gerarDigitoAleatorio()}`; this.textoSaida += ` ${labelFuncao}: push rbp mov rbp, rsp`; // Traduzir corpo da função if (construto.corpo && Array.isArray(construto.corpo)) { construto.corpo.forEach((declaracao) => { if (this.dicionarioDeclaracoes[declaracao.constructor.name]) { this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao); } }); } this.textoSaida += ` pop rbp ret`; } traduzirConstrutoLiteral(construto) { if (typeof construto.valor === 'string') { return this.criaStringLiteral(construto); } return String(construto.valor); } traduzirConstrutoLogico(construto) { const esquerda = this.dicionarioConstrutos[construto.esquerda.constructor.name](construto.esquerda); const direita = this.dicionarioConstrutos[construto.direita.constructor.name](construto.direita); const operador = construto.operador.lexema; const labelVerdadeiro = this.gerarLabel(); const labelFim = this.gerarLabel(); this.textoSaida += ` mov rax, ${esquerda} cmp rax, 0`; if (operador === 'e' || operador === '&&') { this.textoSaida += ` je ${labelFim} mov rax, ${direita} cmp rax, 0 je ${labelFim} ${labelVerdadeiro}: mov rax, 1 ${labelFim}:`; } else if (operador === 'ou' || operador === '||') { this.textoSaida += ` jne ${labelVerdadeiro} mov rax, ${direita} cmp rax, 0 jne ${labelVerdadeiro} mov rax, 0 jmp ${labelFim} ${labelVerdadeiro}: mov rax, 1 ${labelFim}:`; } return 'rax'; } traduzirConstrutoTipoDe(construto) { // Simplificado - retorna tipo como número const expressao = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor); return expressao; } traduzirConstrutoUnario(construto) { const operando = this.dicionarioConstrutos[construto.operando.constructor.name](construto.operando); const operador = construto.operador.lexema; this.textoSaida += ` mov rax, ${operando}`; if (operador === '-') { this.textoSaida += ` neg rax`; } else if (operador === '!' || operador === 'nao') { this.textoSaida += ` cmp rax, 0 sete al movzx rax, al`; } else if (operador === '++') { this.textoSaida += ` inc rax mov ${operando}, rax`; } else if (operador === '--') { this.textoSaida += ` dec rax mov ${operando}, rax`; } return 'rax'; } traduzirConstrutoVariavel(construto) { const nomeVar = construto.simbolo?.lexema; if (nomeVar && this.variaveis.has(nomeVar)) { return `[${this.variaveis.get(nomeVar)}]`; } return nomeVar || 'unknown'; } traduzirConstrutoVetor(construto) { const rotuloVetor = `vetor_${this.gerarDigitoAleatorio()}`; const tamanho = construto.valores?.length || 0; this.bss += ` ${rotuloVetor} resq ${tamanho}\n`; if (construto.valores && Array.isArray(construto.valores)) { construto.valores.forEach((valor, index) => { if (this.dicionarioConstrutos[valor.constructor.name]) { const valorTraduzido = this.dicionarioConstrutos[valor.constructor.name](valor); this.textoSaida += ` mov rax, ${valorTraduzido} mov [${rotuloVetor} + ${index * 8}], rax`; } }); } return rotuloVetor; } // Implementação das Declarações traduzirDeclaracaoBloco(declaracao) { if (declaracao.declaracoes && Array.isArray(declaracao.declaracoes)) { declaracao.declaracoes.forEach((declaracao) => { if (this.dicionarioDeclaracoes[declaracao.constructor.name]) { this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao); } }); } } traduzirDeclaracaoEnquanto(declaracao) { const labelInicio = this.gerarLabel(); const labelFim = this.gerarLabel(); this.textoSaida += ` ${labelInicio}:`; const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao); this.textoSaida += ` cmp ${condicao}, 0 je ${labelFim}`; if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) { this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo); } this.textoSaida += ` jmp ${labelInicio} ${labelFim}:`; } traduzirDeclaracaoEscolha(declaracao) { const labelFim = this.gerarLabel(); const valorEscolha = this.dicionarioConstrutos[declaracao.identificadorOuLiteral.constructor.name](declaracao.identificadorOuLiteral); if (declaracao.caminhos && Array.isArray(declaracao.caminhos)) { declaracao.caminhos.forEach((caminho) => { const labelProximo = this.gerarLabel(); if (caminho.condicoes && caminho.condicoes[0]) { const valorCaso = this.dicionarioConstrutos[caminho.condicoes[0].constructor.name](caminho.condicoes[0]); this.textoSaida += ` mov rax, ${valorEscolha} cmp rax, ${valorCaso} jne ${labelProximo}`; if (caminho.declaracoes && Array.isArray(caminho.declaracoes)) { caminho.declaracoes.forEach((declaracao) => { if (this.dicionarioDeclaracoes[declaracao.constructor.name]) { this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao); } }); } this.textoSaida += ` jmp ${labelFim} ${labelProximo}:`; } }); } this.textoSaida += ` ${labelFim}:`; } traduzirDeclaracaoExpressao(declaracao) { if (declaracao.expressao && this.dicionarioConstrutos[declaracao.expressao.constructor.name]) { this.dicionarioConstrutos[declaracao.expressao.constructor.name](declaracao.expressao); } } traduzirDeclaracaoFazer(declaracao) { const labelInicio = this.gerarLabel(); this.textoSaida += ` ${labelInicio}:`; // Em Delégua, fazer-enquanto tem caminhoFazer que é um Bloco if (declaracao.caminhoFazer && declaracao.caminhoFazer.declaracoes) { declaracao.caminhoFazer.declaracoes.forEach((declaracao) => { if (this.dicionarioDeclaracoes[declaracao.constructor.name]) { this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao); } }); } if (declaracao.condicaoEnquanto) { const condicao = this.dicionarioConstrutos[declaracao.condicaoEnquanto.constructor.name](declaracao.condicaoEnquanto); this.textoSaida += ` cmp ${condicao}, 0 jne ${labelInicio}`; } } traduzirDeclaracaoFalhar(declaracao) { let mensagem = '"Erro"'; if (declaracao.explicacao && typeof declaracao.explicacao === 'object' && 'constructor' in declaracao.explicacao) { const explicacao = declaracao.explicacao; if (explicacao.constructor && this.dicionarioConstrutos[explicacao.constructor.name]) { mensagem = this.dicionarioConstrutos[explicacao.constructor.name](explicacao); } } if (this.alvo === 'linux') { this.textoSaida += ` ; Falhar com mensagem: ${mensagem} mov eax, 1 mov ebx, 1 int 0x80`; } else { this.textoSaida += ` ; Falhar com mensagem: ${mensagem} mov eax, 1 ret`; } } traduzirDeclaracaoFuncao(declaracao) { const nomeFuncao = declaracao.simbolo?.lexema || 'funcao'; this.textoSaida += ` ${nomeFuncao}: push rbp mov rbp, rsp`; if (declaracao.funcao && declaracao.funcao.corpo && Array.isArray(declaracao.funcao.corpo)) { declaracao.funcao.corpo.forEach((decl) => { if (this.dicionarioDeclaracoes[decl.constructor.name]) { this.dicionarioDeclaracoes[decl.constructor.name](decl); } }); } this.textoSaida += ` pop rbp ret`; } traduzirDeclaracaoImportar(declaracao) { // Importação é tratada em tempo de linkagem this.textoSaida += ` ; Importar: ${declaracao.caminho || 'unknown'}`; } traduzirDeclaracaoLeia(declaracao) { let nomeVar; if (declaracao.argumentos && declaracao.argumentos[0] && declaracao.argumentos[0] instanceof construtos_1.Variavel) { nomeVar = declaracao.argumentos[0].simbolo?.lexema; } if (!nomeVar) return; if (!this.variaveis.has(nomeVar)) { const varLabel = `var_${nomeVar}`; this.bss += ` ${varLabel} resb 256\n`; this.variaveis.set(nomeVar, varLabel); } this.textoSaida += ` mov eax, 3 mov ebx, 0 mov ecx, ${this.variaveis.get(nomeVar)} mov edx, 256 int 0x80`; } traduzirDeclaracaoPara(declaracao) { const labelInicio = this.gerarLabel(); const labelFim = this.gerarLabel(); // Inicializador pode ser um array de declarações, uma declaração ou um construto if (declaracao.inicializador) { if (Array.isArray(declaracao.inicializador)) { for (const decl of declaracao.inicializador) { const tipo = decl.constructor.name; if (this.dicionarioDeclaracoes[tipo]) { this.dicionarioDeclaracoes[tipo](decl); } } } else { const tipoInicializador = declaracao.inicializador.constructor.name; if (this.dicionarioDeclaracoes[tipoInicializador]) { this.dicionarioDeclaracoes[tipoInicializador](declaracao.inicializador); } else if (this.dicionarioConstrutos[tipoInicializador]) { this.dicionarioConstrutos[tipoInicializador](declaracao.inicializador); } } } this.textoSaida += ` ${labelInicio}:`; if (declaracao.condicao) { const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao); this.textoSaida += ` cmp ${condicao}, 0 je ${labelFim}`; } if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) { this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo); } if (declaracao.incrementar) { if (this.dicionarioConstrutos[declaracao.incrementar.constructor.name]) { this.dicionarioConstrutos[declaracao.incrementar.constructor.name](declaracao.incrementar); } } this.textoSaida += ` jmp ${labelInicio} ${labelFim}:`; } traduzirDeclaracaoParaCada(declaracao) { const rotuloInicio = this.gerarLabel(); const rotuloFim = this.gerarLabel(); let nomeVar; if (declaracao.variavelIteracao instanceof construtos_1.Variavel) { nomeVar = declaracao.variavelIteracao.simbolo?.lexema; } const vetor = declaracao.vetorOuDicionario; let tamanhoVetor = 0; if (vetor instanceof construtos_1.Vetor) { tamanhoVetor = vetor.tamanho || 0; } this.textoSaida += ` xor rcx, rcx ${rotuloInicio}: cmp rcx, ${tamanhoVetor} jge ${rotuloFim}`; if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) { this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo); } this.textoSaida += ` inc rcx jmp ${rotuloInicio} ${rotuloFim}:`; } traduzirDeclaracaoRetorna(declaracao) { if (declaracao.valor) { const valor = this.dicionarioConstrutos[declaracao.valor.constructor.name](declaracao.valor); this.textoSaida += ` mov rax, ${valor}`; } this.textoSaida += ` pop rbp ret`; } traduzirDeclaracaoSe(declaracao) { const rotuloSenao = this.gerarLabel(); const rotuloFim = this.gerarLabel(); const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao); this.textoSaida += ` cmp ${condicao}, 0 je ${rotuloSenao}`; if (this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name]) { this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name](declaracao.caminhoEntao); } this.textoSaida += ` jmp ${rotuloFim} ${rotuloSenao}:`; if (declaracao.caminhoSenao && this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name]) { this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name](declaracao.caminhoSenao); } this.textoSaida += ` ${rotuloFim}:`; } traduzirDeclaracaoClasse(declaracao) { // Classes em assembly são complexas - implementação básica this.textoSaida += ` ; Classe: ${declaracao.simbolo?.lexema || 'unknown'}`; } traduzirDeclaracaoTente(declaracao) { // Try-catch em assembly requer handler complexo this.textoSaida += ` ; Tente-pegue`; if (declaracao.caminhoTente && Array.isArray(declaracao.caminhoTente)) { declaracao.caminhoTente.forEach((declaracao) => { if (this.dicionarioDeclaracoes[declaracao.constructor.name]) { this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao); } }); } } traduzirDeclaracaoConst(declaracao) { const nomeVar = declaracao.simbolo?.lexema; if (!nomeVar) return; const valor = this.dicionarioConstrutos[declaracao.inicializador.constructor.name](declaracao.inicializador); const varLabel = `const_${nomeVar}`; this.data += ` ${varLabel} dq ${valor}\n`; this.variaveis.set(nomeVar, varLabel); } traduzirDeclaracaoVar(declaracao) { const nomeVar = declaracao.simbolo?.lexema; if (!nomeVar) return; const varLabel = `var_${nomeVar}`; this.bss += ` ${varLabel} resq 1\n`; this.variaveis.set(nomeVar, varLabel); if (declaracao.inicializador) { const tipoInicializador = declaracao.inicializador.constructor.name; // Verificar se é um vetor if (declaracao.inicializador instanceof construtos_1.Vetor) { // Vetor precisa de tratamento especial const labelVetor = this.traduzirConstrutoVetor(declaracao.inicializador); // Associar o nome da variável com o label do vetor this.variaveis.set(nomeVar, labelVetor); } else if (this.dicionarioConstrutos[tipoInicializador]) { const valor = this.dicionarioConstrutos[tipoInicializador](declaracao.inicializador); this.textoSaida += ` mov rax, ${valor} mov [${varLabel}], rax`; } } } criaStringLiteral(literal) { const varLiteral = `Delegua_${this.gerarDigitoAleatorio()}`; this.data += ` ${varLiteral} db '${literal.valor}', 0\n`; return varLiteral; } criaTamanhoNaMemoriaReferenteAVar(nomeStringLiteral) { const varTamanho = `tam_${nomeStringLiteral}`; this.data += ` ${varTamanho} equ $ - ${nomeStringLiteral}\n`; return varTamanho; } emitirHelperPrintInt() { if (this.helperPrintIntEmitido) return; this.helperPrintIntEmitido = true; this.bss += ` __print_buf resb 24\n`; this.helpers += ` __delegua_print_int: push rbx push rcx push rdx push rsi mov rcx, 10 lea rsi, [__print_buf + 22] mov byte [rsi], 10 .print_digitloop: xor rdx, rdx div rcx add dl, '0' dec rsi mov [rsi], dl test rax, rax jnz .print_digitloop lea rdx, [__print_buf + 23] sub rdx, rsi mov ecx, esi mov ebx, 1 mov eax, 4 int 0x80 pop rsi pop rdx pop rcx pop rbx ret`; } traduzirDeclaracaoEscreva(declaracaoEscreva) { const arg = declaracaoEscreva.argumentos[0]; if (arg instanceof construtos_1.Literal) { const nome_string_literal = this.criaStringLiteral(arg); const tam_string_literal = this.criaTamanhoNaMemoriaReferenteAVar(nome_string_literal); if (this.alvo === 'linux') { this.textoSaida += ` mov edx, ${tam_string_literal} mov ecx, ${nome_string_literal} mov ebx, 1 ; fd stdout mov eax, 4 ; sys_write int 0x80`; } else { this.textoSaida += ` lea rcx, [rel ${nome_string_literal}] call printf`; } } else { const valor = this.dicionarioConstrutos[arg.constructor.name](arg); if (this.alvo === 'linux') { this.emitirHelperPrintInt(); this.textoSaida += ` mov rax, ${valor} call __delegua_print_int`; } else { if (!this.fmtIntWindowsEmitido) { this.data += ` __fmt_int db '%d', 10, 0\n`; this.fmtIntWindowsEmitido = true; } this.textoSaida += ` mov rdx, ${valor} lea rcx, [rel __fmt_int] call printf`; } } } saidaSistema() { if (this.alvo === 'linux') { this.textoSaida += ` mov eax, 1 ; sys_exit xor ebx, ebx ; status 0 int 0x80`; } else { // Windows: return from main with 0 in EAX this.textoSaida += ` xor eax, eax ret`; } } traduzir(declaracoes) { let resultado = ''; this.declaracoesDeClasses = declaracoes.filter((declaracao) => declaracao instanceof declaracoes_1.Classe); for (const declaracao of declaracoes) { if (this.dicionarioDeclaracoes[declaracao.constructor.name]) { this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao); } } this.saidaSistema(); this.textoSaida += this.helpers; resultado += this.bss + '\n' + this.data + '\n' + this.textoSaida; return resultado; } } exports.TradutorAssemblyX64 = TradutorAssemblyX64; //# sourceMappingURL=tradutor-assembly-x64.js.map