@designliquido/delegua
Version:
Linguagem de programação simples e moderna usando português estruturado.
711 lines (708 loc) • 27.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TradutorAssemblyARM = void 0;
const construtos_1 = require("../construtos");
const declaracoes_1 = require("../declaracoes");
class TradutorAssemblyARM {
constructor(alvo = 'linux-arm') {
this.alvo = alvo;
this.indentacao = 0;
this.contadorLabels = 0;
this.variaveis = new Map();
this.registradoresDisponiveis = ['r4', 'r5', 'r6', 'r7', 'r8', 'r9', 'r10'];
this.pilhaRegistradores = [];
this.bss = '.bss\n';
this.data = '.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: () => 'b .continue_label',
Escolha: this.traduzirDeclaracaoEscolha.bind(this),
Escreva: this.traduzirDeclaracaoEscreva.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: () => 'b .break_label',
Classe: this.traduzirDeclaracaoClasse.bind(this),
Tente: this.traduzirDeclaracaoTente.bind(this),
Const: this.traduzirDeclaracaoConst.bind(this),
Var: this.traduzirDeclaracaoVar.bind(this),
};
this.indentacao = 0;
// Seleciona o símbolo de entrada conforme a plataforma alvo.
// Para linux-arm: programa standalone com _start.
// Para android: ainda é um binário standalone, mas com rótulo Delegua_main
// para deixar claro que não é o _start do CRT padrão.
const entryLabel = this.alvo === 'android' ? 'Delegua_main' : '_start';
this.text = `
.text
.global ${entryLabel}
${entryLabel}:`;
}
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 'r0'; // 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);
const reg = this.obterRegistrador();
this.text += `
ldr ${reg}, =${nomeVar}
ldr r0, =${indice}
lsl r0, r0, #2 @ multiply index by 4 (word size)
add ${reg}, ${reg}, r0
ldr r0, [${reg}]`;
this.liberarRegistrador(reg);
return 'r0';
}
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);
const reg = this.obterRegistrador();
this.text += `
ldr ${reg}, =${nomeVar}
ldr r1, =${indice}
lsl r1, r1, #2 @ multiply by 4
add ${reg}, ${reg}, r1
ldr r1, =${valor}
str r1, [${reg}]`;
this.liberarRegistrador(reg);
}
traduzirConstrutoAtribuir(construto) {
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}: .space 4\n`;
this.variaveis.set(nomeVar, varLabel);
}
this.text += `
ldr r0, =${valor}
ldr r1, =${this.variaveis.get(nomeVar)}
str r0, [r1]`;
}
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 reg = this.obterRegistrador();
// Load left operand into r0
if (esquerda !== 'r0') {
this.text += `
ldr r0, =${esquerda}`;
}
// Load right operand into reg
this.text += `
ldr ${reg}, =${direita}`;
switch (operador) {
case '+':
this.text += `
add r0, r0, ${reg}`;
break;
case '-':
this.text += `
sub r0, r0, ${reg}`;
break;
case '*':
this.text += `
mul r0, r0, ${reg}`;
break;
case '/':
this.text += `
sdiv r0, r0, ${reg}`;
break;
case '%':
this.text += `
sdiv r1, r0, ${reg}
mul r1, r1, ${reg}
sub r0, r0, r1 @ r0 = r0 - (r0/reg)*reg`;
break;
case '<':
this.text += `
cmp r0, ${reg}
movlt r0, #1
movge r0, #0`;
break;
case '>':
this.text += `
cmp r0, ${reg}
movgt r0, #1
movle r0, #0`;
break;
case '<=':
this.text += `
cmp r0, ${reg}
movle r0, #1
movgt r0, #0`;
break;
case '>=':
this.text += `
cmp r0, ${reg}
movge r0, #1
movlt r0, #0`;
break;
case '==':
case '===':
this.text += `
cmp r0, ${reg}
moveq r0, #1
movne r0, #0`;
break;
case '!=':
case '!==':
this.text += `
cmp r0, ${reg}
movne r0, #1
moveq r0, #0`;
break;
default:
this.text += `
@ Operador ${operador} não implementado`;
}
this.liberarRegistrador(reg);
return 'r0';
}
traduzirConstrutoChamada(construto) {
let nomeFuncao = 'funcao';
if (construto.entidadeChamada instanceof construtos_1.Variavel) {
nomeFuncao = construto.entidadeChamada.simbolo?.lexema || 'funcao';
}
// ARM calling convention: r0-r3 for first 4 args, rest on stack
const registrosArgs = ['r0', 'r1', 'r2', 'r3'];
construto.argumentos.forEach((argumento, indice) => {
if (indice < registrosArgs.length) {
const valorArg = this.dicionarioConstrutos[argumento.constructor.name](argumento);
if (valorArg !== registrosArgs[indice]) {
this.text += `
ldr ${registrosArgs[indice]}, =${valorArg}`;
}
}
else {
// Push extra args on stack
const valorArg = this.dicionarioConstrutos[argumento.constructor.name](argumento);
this.text += `
ldr r0, =${valorArg}
push {r0}`;
}
});
this.text += `
bl ${nomeFuncao}`;
}
traduzirConstrutoDefinirValor(construto) {
const objeto = this.dicionarioConstrutos[construto.objeto.constructor.name](construto.objeto);
const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
this.text += `
ldr r0, =${valor}
ldr r1, =${objeto}
str r0, [r1]`;
}
traduzirFuncaoConstruto(construto) {
const labelFuncao = `func_${this.gerarDigitoAleatorio()}`;
this.text += `
${labelFuncao}:
push {fp, lr}
mov fp, sp`;
// 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.text += `
mov sp, fp
pop {fp, pc}`;
}
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.text += `
ldr r0, =${esquerda}
cmp r0, #0`;
if (operador === 'e' || operador === '&&') {
this.text += `
beq ${labelFim}
ldr r0, =${direita}
cmp r0, #0
beq ${labelFim}
${labelVerdadeiro}:
mov r0, #1
${labelFim}:`;
}
else if (operador === 'ou' || operador === '||') {
this.text += `
bne ${labelVerdadeiro}
ldr r0, =${direita}
cmp r0, #0
bne ${labelVerdadeiro}
mov r0, #0
b ${labelFim}
${labelVerdadeiro}:
mov r0, #1
${labelFim}:`;
}
return 'r0';
}
traduzirConstrutoTipoDe(construto) {
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.text += `
ldr r0, =${operando}`;
if (operador === '-') {
this.text += `
neg r0, r0`;
}
else if (operador === '!' || operador === 'nao') {
this.text += `
cmp r0, #0
moveq r0, #1
movne r0, #0`;
}
return 'r0';
}
traduzirConstrutoVariavel(construto) {
const nomeVar = construto.simbolo?.lexema;
if (nomeVar && this.variaveis.has(nomeVar)) {
const varLabel = this.variaveis.get(nomeVar);
this.text += `
ldr r0, =${varLabel}
ldr r0, [r0]`;
return 'r0';
}
return nomeVar || 'unknown';
}
traduzirConstrutoVetor(construto) {
const labelVetor = `vetor_${this.gerarDigitoAleatorio()}`;
const tamanho = construto.valores?.length || 0;
this.bss += ` ${labelVetor}: .space ${tamanho * 4}\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.text += `
ldr r0, =${valorTraduzido}
ldr r1, =${labelVetor}
str r0, [r1, #${index * 4}]`;
}
});
}
return labelVetor;
}
// Implementação das Declarações
traduzirDeclaracaoBloco(declaracao) {
if (declaracao.declaracoes && Array.isArray(declaracao.declaracoes)) {
declaracao.declaracoes.forEach((decl) => {
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
this.dicionarioDeclaracoes[decl.constructor.name](decl);
}
});
}
}
traduzirDeclaracaoEnquanto(declaracao) {
const labelInicio = this.gerarLabel();
const labelFim = this.gerarLabel();
this.text += `
${labelInicio}:`;
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
this.text += `
cmp ${condicao}, #0
beq ${labelFim}`;
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
}
this.text += `
b ${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.text += `
ldr r0, =${valorEscolha}
ldr r1, =${valorCaso}
cmp r0, r1
bne ${labelProximo}`;
if (caminho.declaracoes && Array.isArray(caminho.declaracoes)) {
caminho.declaracoes.forEach((decl) => {
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
this.dicionarioDeclaracoes[decl.constructor.name](decl);
}
});
}
this.text += `
b ${labelFim}
${labelProximo}:`;
}
});
}
this.text += `
${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.text += `
${labelInicio}:`;
if (declaracao.caminhoFazer && declaracao.caminhoFazer.declaracoes) {
declaracao.caminhoFazer.declaracoes.forEach((decl) => {
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
this.dicionarioDeclaracoes[decl.constructor.name](decl);
}
});
}
if (declaracao.condicaoEnquanto) {
const condicao = this.dicionarioConstrutos[declaracao.condicaoEnquanto.constructor.name](declaracao.condicaoEnquanto);
this.text += `
cmp ${condicao}, #0
bne ${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);
}
}
this.text += `
@ Falhar com mensagem: ${mensagem}
mov r0, #1
mov r7, #1 @ sys_exit
swi 0`;
}
traduzirDeclaracaoFuncao(declaracao) {
const nomeFuncao = declaracao.simbolo?.lexema || 'funcao';
this.text += `
${nomeFuncao}:
push {fp, lr}
mov fp, sp`;
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.text += `
mov sp, fp
pop {fp, pc}`;
}
traduzirDeclaracaoImportar(declaracao) {
this.text += `
@ 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}: .space 256\n`;
this.variaveis.set(nomeVar, varLabel);
}
this.text += `
ldr r1, =${this.variaveis.get(nomeVar)}
mov r2, #256
mov r0, #0 @ stdin
mov r7, #3 @ sys_read
swi 0`;
}
traduzirDeclaracaoPara(declaracao) {
const labelInicio = this.gerarLabel();
const labelFim = this.gerarLabel();
if (declaracao.inicializador) {
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.text += `
${labelInicio}:`;
if (declaracao.condicao) {
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
this.text += `
cmp ${condicao}, #0
beq ${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.text += `
b ${labelInicio}
${labelFim}:`;
}
traduzirDeclaracaoParaCada(declaracao) {
const labelInicio = this.gerarLabel();
const labelFim = 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.text += `
mov r4, #0 @ counter
${labelInicio}:
cmp r4, #${tamanhoVetor}
bge ${labelFim}`;
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
}
this.text += `
add r4, r4, #1
b ${labelInicio}
${labelFim}:`;
}
traduzirDeclaracaoRetorna(declaracao) {
if (declaracao.valor) {
const valor = this.dicionarioConstrutos[declaracao.valor.constructor.name](declaracao.valor);
this.text += `
ldr r0, =${valor}`;
}
this.text += `
mov sp, fp
pop {fp, pc}`;
}
traduzirDeclaracaoSe(declaracao) {
const labelSenao = this.gerarLabel();
const labelFim = this.gerarLabel();
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
this.text += `
cmp ${condicao}, #0
beq ${labelSenao}`;
if (this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name]) {
this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name](declaracao.caminhoEntao);
}
this.text += `
b ${labelFim}
${labelSenao}:`;
if (declaracao.caminhoSenao &&
this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name]) {
this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name](declaracao.caminhoSenao);
}
this.text += `
${labelFim}:`;
}
traduzirDeclaracaoClasse(declaracao) {
this.text += `
@ Classe: ${declaracao.simbolo?.lexema || 'unknown'}`;
}
traduzirDeclaracaoTente(declaracao) {
this.text += `
@ Tente-pegue`;
if (declaracao.caminhoTente && Array.isArray(declaracao.caminhoTente)) {
declaracao.caminhoTente.forEach((decl) => {
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
this.dicionarioDeclaracoes[decl.constructor.name](decl);
}
});
}
}
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}: .word ${valor}\n`;
this.variaveis.set(nomeVar, varLabel);
}
traduzirDeclaracaoVar(declaracao) {
const nomeVar = declaracao.simbolo?.lexema;
if (!nomeVar)
return;
const varLabel = `var_${nomeVar}`;
this.bss += ` ${varLabel}: .space 4\n`;
this.variaveis.set(nomeVar, varLabel);
if (declaracao.inicializador && declaracao.inicializador.valor !== null) {
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.text += `
ldr r0, =${valor}
ldr r1, =${varLabel}
str r0, [r1]`;
}
}
}
criaStringLiteral(literal) {
const varLiteral = `Delegua_${this.gerarDigitoAleatorio()}`;
this.data += ` ${varLiteral}: .asciz "${literal.valor}"\n`;
return varLiteral;
}
criaTamanhoNaMemoriaReferenteAVar(nomeStringLiteral) {
const varTamanho = `tam_${nomeStringLiteral}`;
// Em ARM, calculamos o tamanho de forma diferente
// Podemos usar uma diretiva ou calcular em tempo de execução
return varTamanho;
}
traduzirDeclaracaoEscreva(declaracaoEscreva) {
let tam_string_literal = '';
let nome_string_literal = '';
if (declaracaoEscreva.argumentos[0] instanceof construtos_1.Literal) {
nome_string_literal = this.criaStringLiteral(declaracaoEscreva.argumentos[0]);
const stringValue = declaracaoEscreva.argumentos[0].valor;
tam_string_literal = String(stringValue.length);
}
// Para ambos linux-arm e android, continuamos usando a convenção
// de syscall Linux ARM (write). Em Android típico, esse binário
// seria executado via adb/Termux, onde essa convenção ainda é válida.
this.text += `
ldr r1, =${nome_string_literal}
mov r2, #${tam_string_literal}
mov r0, #1 @ fd stdout
mov r7, #4 @ sys_write
swi 0`;
}
saidaSistema() {
// Mesmo comentário da função Escreva: usamos sys_exit Linux.
// Em um futuro modo Android "NDK/JNI", esta função deveria
// apenas retornar ao chamador em vez de fazer syscall direta.
this.text += `
mov r0, #1 @ exit status
mov r7, #1 @ sys_exit
swi 0`;
}
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();
resultado += this.bss + '\n' + this.data + '\n' + this.text;
return resultado;
}
}
exports.TradutorAssemblyARM = TradutorAssemblyARM;
//# sourceMappingURL=tradutor-assembly-arm.js.map