@designliquido/delegua 1.26.0 → 1.26.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/analisador-semantico/analisador-semantico.d.ts +4 -1
- package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
- package/analisador-semantico/analisador-semantico.js +36 -8
- package/analisador-semantico/analisador-semantico.js.map +1 -1
- package/analisador-semantico/dialetos/analisador-semantico-pitugues.d.ts.map +1 -1
- package/analisador-semantico/dialetos/analisador-semantico-pitugues.js +11 -12
- package/analisador-semantico/dialetos/analisador-semantico-pitugues.js.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +14 -12
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
- package/avaliador-sintatico/dialetos/micro-avaliador-sintatico-pitugues.d.ts.map +1 -1
- package/avaliador-sintatico/dialetos/micro-avaliador-sintatico-pitugues.js +5 -3
- package/avaliador-sintatico/dialetos/micro-avaliador-sintatico-pitugues.js.map +1 -1
- package/bibliotecas/dialetos/pitugues/biblioteca-global.d.ts.map +1 -1
- package/bibliotecas/dialetos/pitugues/biblioteca-global.js +1 -1
- package/bibliotecas/dialetos/pitugues/biblioteca-global.js.map +1 -1
- package/bibliotecas/dialetos/pitugues/primitivas-dicionario.js +3 -3
- package/bibliotecas/dialetos/pitugues/primitivas-dicionario.js.map +1 -1
- package/bibliotecas/dialetos/pitugues/primitivas-numero.js +8 -8
- package/bibliotecas/dialetos/pitugues/primitivas-numero.js.map +1 -1
- package/bibliotecas/dialetos/pitugues/primitivas-texto.js +22 -22
- package/bibliotecas/dialetos/pitugues/primitivas-texto.js.map +1 -1
- package/bibliotecas/dialetos/pitugues/primitivas-vetor.d.ts.map +1 -1
- package/bibliotecas/dialetos/pitugues/primitivas-vetor.js +16 -16
- package/bibliotecas/dialetos/pitugues/primitivas-vetor.js.map +1 -1
- package/bin/package.json +2 -2
- package/excecoes/index.d.ts +1 -0
- package/excecoes/index.d.ts.map +1 -1
- package/excecoes/index.js +1 -0
- package/excecoes/index.js.map +1 -1
- package/excecoes/mensagem-erro.d.ts +17 -0
- package/excecoes/mensagem-erro.d.ts.map +1 -0
- package/excecoes/mensagem-erro.js +31 -0
- package/excecoes/mensagem-erro.js.map +1 -0
- package/interpretador/depuracao/avaliador-expressao-depuracao.d.ts.map +1 -1
- package/interpretador/depuracao/avaliador-expressao-depuracao.js +2 -1
- package/interpretador/depuracao/avaliador-expressao-depuracao.js.map +1 -1
- package/interpretador/depuracao/comum.d.ts.map +1 -1
- package/interpretador/depuracao/comum.js +6 -1
- package/interpretador/depuracao/comum.js.map +1 -1
- package/interpretador/dialetos/pitugues/comum.d.ts +3 -3
- package/interpretador/dialetos/pitugues/comum.d.ts.map +1 -1
- package/interpretador/dialetos/pitugues/comum.js +18 -4
- package/interpretador/dialetos/pitugues/comum.js.map +1 -1
- package/interpretador/dialetos/pitugues/interpretador-pitugues.js +2 -2
- package/interpretador/dialetos/pitugues/interpretador-pitugues.js.map +1 -1
- package/interpretador/interpretador-base.d.ts.map +1 -1
- package/interpretador/interpretador-base.js +2 -1
- package/interpretador/interpretador-base.js.map +1 -1
- package/interpretador/interpretador.js +3 -3
- package/interpretador/interpretador.js.map +1 -1
- package/lexador/lexador.d.ts.map +1 -1
- package/lexador/lexador.js.map +1 -1
- package/package.json +2 -2
- package/tipos-de-dados/dialetos/pitugues.d.ts +0 -4
- package/tipos-de-dados/dialetos/pitugues.d.ts.map +1 -1
- package/tipos-de-dados/dialetos/pitugues.js +0 -4
- package/tipos-de-dados/dialetos/pitugues.js.map +1 -1
- package/tradutores/tradutor-assembly-x64.d.ts +11 -96
- package/tradutores/tradutor-assembly-x64.d.ts.map +1 -1
- package/tradutores/tradutor-assembly-x64.js +25 -761
- package/tradutores/tradutor-assembly-x64.js.map +1 -1
- package/tradutores/tradutor-javascript.d.ts +1 -1
- package/tradutores/tradutor-javascript.d.ts.map +1 -1
- package/tradutores/tradutor-javascript.js +7 -0
- package/tradutores/tradutor-javascript.js.map +1 -1
- package/tradutores/tradutor-python.d.ts +8 -0
- package/tradutores/tradutor-python.d.ts.map +1 -1
- package/tradutores/tradutor-python.js +35 -4
- package/tradutores/tradutor-python.js.map +1 -1
- package/tradutores/tradutor-reverso-javascript.d.ts.map +1 -1
- package/tradutores/tradutor-reverso-javascript.js +3 -0
- package/tradutores/tradutor-reverso-javascript.js.map +1 -1
- package/tradutores/x64/alocador-registradores.d.ts +29 -0
- package/tradutores/x64/alocador-registradores.d.ts.map +1 -0
- package/tradutores/x64/alocador-registradores.js +192 -0
- package/tradutores/x64/alocador-registradores.js.map +1 -0
- package/tradutores/x64/codegen.d.ts +43 -0
- package/tradutores/x64/codegen.d.ts.map +1 -0
- package/tradutores/x64/codegen.js +416 -0
- package/tradutores/x64/codegen.js.map +1 -0
- package/tradutores/x64/dessa.d.ts +9 -0
- package/tradutores/x64/dessa.d.ts.map +1 -0
- package/tradutores/x64/dessa.js +124 -0
- package/tradutores/x64/dessa.js.map +1 -0
- package/tradutores/x64/dominancia.d.ts +25 -0
- package/tradutores/x64/dominancia.d.ts.map +1 -0
- package/tradutores/x64/dominancia.js +129 -0
- package/tradutores/x64/dominancia.js.map +1 -0
- package/tradutores/x64/ir.d.ts +144 -0
- package/tradutores/x64/ir.d.ts.map +1 -0
- package/tradutores/x64/ir.js +44 -0
- package/tradutores/x64/ir.js.map +1 -0
- package/tradutores/x64/liveness.d.ts +12 -0
- package/tradutores/x64/liveness.d.ts.map +1 -0
- package/tradutores/x64/liveness.js +159 -0
- package/tradutores/x64/liveness.js.map +1 -0
- package/tradutores/x64/lowering.d.ts +7 -0
- package/tradutores/x64/lowering.d.ts.map +1 -0
- package/tradutores/x64/lowering.js +904 -0
- package/tradutores/x64/lowering.js.map +1 -0
- package/tradutores/x64/ssa.d.ts +9 -0
- package/tradutores/x64/ssa.d.ts.map +1 -0
- package/tradutores/x64/ssa.js +170 -0
- package/tradutores/x64/ssa.js.map +1 -0
- package/tradutores/x64/tipos-x64.d.ts +12 -0
- package/tradutores/x64/tipos-x64.d.ts.map +1 -0
- package/tradutores/x64/tipos-x64.js +59 -0
- package/tradutores/x64/tipos-x64.js.map +1 -0
- package/umd/delegua.js +6053 -4480
|
@@ -1,773 +1,37 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TradutorAssemblyX64 = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const alocador_registradores_1 = require("./x64/alocador-registradores");
|
|
5
|
+
const codegen_1 = require("./x64/codegen");
|
|
6
|
+
const dessa_1 = require("./x64/dessa");
|
|
7
|
+
const lowering_1 = require("./x64/lowering");
|
|
8
|
+
const ssa_1 = require("./x64/ssa");
|
|
9
|
+
const PALETA_LINUX = ['rbx', 'r12', 'r13', 'r14', 'r15'];
|
|
10
|
+
const PALETA_WINDOWS = ['rbx', 'rdi', 'rsi', 'r12', 'r13', 'r14', 'r15'];
|
|
11
|
+
/**
|
|
12
|
+
* Traduz Delégua para NASM x64. Pipeline: lowering (AST -> IR com CFG explícito) ->
|
|
13
|
+
* por função: construção de SSA (fronteira de dominância + phis) -> alocação de
|
|
14
|
+
* registradores (vivacidade + coloração de grafo) -> destruição de SSA (phis -> cópias,
|
|
15
|
+
* arestas críticas divididas) -> geração de código. Ver fontes/tradutores/x64/*.ts para
|
|
16
|
+
* cada etapa e issue #1400 para o desenho completo.
|
|
17
|
+
*/
|
|
6
18
|
class TradutorAssemblyX64 {
|
|
7
19
|
constructor(alvo = 'linux') {
|
|
8
20
|
this.alvo = alvo;
|
|
9
|
-
this.indentacao = 0;
|
|
10
|
-
this.contadorLabels = 0;
|
|
11
|
-
this.variaveis = new Map();
|
|
12
|
-
this.registradoresDisponiveis = ['rbx', 'r12', 'r13', 'r14', 'r15'];
|
|
13
|
-
this.pilhaRegistradores = [];
|
|
14
|
-
this.helperPrintIntEmitido = false;
|
|
15
|
-
this.fmtIntWindowsEmitido = false;
|
|
16
|
-
this.helpers = '';
|
|
17
|
-
this.bss = 'section .bss\n';
|
|
18
|
-
this.data = 'section .data\n';
|
|
19
|
-
this.dicionarioConstrutos = {
|
|
20
|
-
AcessoIndiceVariavel: this.traduzirAcessoIndiceVariavel.bind(this),
|
|
21
|
-
AcessoMetodoOuPropriedade: this.trazudirConstrutoAcessoMetodo.bind(this),
|
|
22
|
-
Agrupamento: this.traduzirConstrutoAgrupamento.bind(this),
|
|
23
|
-
AtribuicaoPorIndice: this.traduzirConstrutoAtribuicaoPorIndice.bind(this),
|
|
24
|
-
Atribuir: this.traduzirConstrutoAtribuir.bind(this),
|
|
25
|
-
Binario: this.traduzirConstrutoBinario.bind(this),
|
|
26
|
-
Chamada: this.traduzirConstrutoChamada.bind(this),
|
|
27
|
-
DefinirValor: this.traduzirConstrutoDefinirValor.bind(this),
|
|
28
|
-
FuncaoConstruto: this.traduzirFuncaoConstruto.bind(this),
|
|
29
|
-
Isto: () => 'this',
|
|
30
|
-
Literal: this.traduzirConstrutoLiteral.bind(this),
|
|
31
|
-
Logico: this.traduzirConstrutoLogico.bind(this),
|
|
32
|
-
TipoDe: this.traduzirConstrutoTipoDe.bind(this),
|
|
33
|
-
Unario: this.traduzirConstrutoUnario.bind(this),
|
|
34
|
-
Variavel: this.traduzirConstrutoVariavel.bind(this),
|
|
35
|
-
Vetor: this.traduzirConstrutoVetor.bind(this),
|
|
36
|
-
};
|
|
37
|
-
this.dicionarioDeclaracoes = {
|
|
38
|
-
Bloco: this.traduzirDeclaracaoBloco.bind(this),
|
|
39
|
-
Enquanto: this.traduzirDeclaracaoEnquanto.bind(this),
|
|
40
|
-
Continua: () => 'continue',
|
|
41
|
-
Escolha: this.traduzirDeclaracaoEscolha.bind(this),
|
|
42
|
-
Expressao: this.traduzirDeclaracaoExpressao.bind(this),
|
|
43
|
-
Fazer: this.traduzirDeclaracaoFazer.bind(this),
|
|
44
|
-
Falhar: this.traduzirDeclaracaoFalhar.bind(this),
|
|
45
|
-
FuncaoDeclaracao: this.traduzirDeclaracaoFuncao.bind(this),
|
|
46
|
-
Importar: this.traduzirDeclaracaoImportar.bind(this),
|
|
47
|
-
Leia: this.traduzirDeclaracaoLeia.bind(this),
|
|
48
|
-
Para: this.traduzirDeclaracaoPara.bind(this),
|
|
49
|
-
ParaCada: this.traduzirDeclaracaoParaCada.bind(this),
|
|
50
|
-
Retorna: this.traduzirDeclaracaoRetorna.bind(this),
|
|
51
|
-
Se: this.traduzirDeclaracaoSe.bind(this),
|
|
52
|
-
Sustar: () => 'break',
|
|
53
|
-
Classe: this.traduzirDeclaracaoClasse.bind(this),
|
|
54
|
-
Tente: this.traduzirDeclaracaoTente.bind(this),
|
|
55
|
-
Const: this.traduzirDeclaracaoConst.bind(this),
|
|
56
|
-
Var: this.traduzirDeclaracaoVar.bind(this),
|
|
57
|
-
Escreva: this.traduzirDeclaracaoEscreva.bind(this),
|
|
58
|
-
};
|
|
59
|
-
this.indentacao = 0;
|
|
60
|
-
this.textoSaida = `
|
|
61
|
-
section .text
|
|
62
|
-
${this.alvo === 'linux' ? 'global _start' : 'global main'}
|
|
63
|
-
${this.alvo === 'linux' ? '_start:' : 'main:'}`;
|
|
64
|
-
if (this.alvo === 'windows') {
|
|
65
|
-
this.textoSaida =
|
|
66
|
-
`
|
|
67
|
-
extern printf
|
|
68
|
-
` + this.textoSaida;
|
|
69
|
-
}
|
|
70
21
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const digits = '0123456789';
|
|
74
|
-
for (let i = 0; i < 5; i++) {
|
|
75
|
-
const randomIndex = Math.floor(Math.random() * digits.length);
|
|
76
|
-
result += digits.charAt(randomIndex);
|
|
77
|
-
}
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
gerarLabel() {
|
|
81
|
-
return `L${this.contadorLabels++}`;
|
|
82
|
-
}
|
|
83
|
-
obterRegistrador() {
|
|
84
|
-
if (this.registradoresDisponiveis.length > 0) {
|
|
85
|
-
const reg = this.registradoresDisponiveis.pop();
|
|
86
|
-
this.pilhaRegistradores.push(reg);
|
|
87
|
-
return reg;
|
|
88
|
-
}
|
|
89
|
-
return 'rax'; // fallback
|
|
90
|
-
}
|
|
91
|
-
liberarRegistrador(reg) {
|
|
92
|
-
const index = this.pilhaRegistradores.indexOf(reg);
|
|
93
|
-
if (index > -1) {
|
|
94
|
-
this.pilhaRegistradores.splice(index, 1);
|
|
95
|
-
this.registradoresDisponiveis.push(reg);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// Implementação dos Construtos
|
|
99
|
-
traduzirAcessoIndiceVariavel(construto) {
|
|
100
|
-
let nomeVar;
|
|
101
|
-
if (construto.entidadeChamada instanceof construtos_1.Variavel) {
|
|
102
|
-
nomeVar = construto.entidadeChamada.simbolo?.lexema;
|
|
103
|
-
}
|
|
104
|
-
if (!nomeVar) {
|
|
105
|
-
nomeVar = 'unknown';
|
|
106
|
-
}
|
|
107
|
-
const indice = this.dicionarioConstrutos[construto.indice.constructor.name](construto.indice);
|
|
108
|
-
return `[${nomeVar} + ${indice} * 8]`;
|
|
109
|
-
}
|
|
110
|
-
trazudirConstrutoAcessoMetodo(construto) {
|
|
111
|
-
const objeto = this.dicionarioConstrutos[construto.objeto.constructor.name](construto.objeto);
|
|
112
|
-
return `${objeto}.${construto.nomeMetodo}`;
|
|
113
|
-
}
|
|
114
|
-
traduzirConstrutoAgrupamento(construto) {
|
|
115
|
-
return this.dicionarioConstrutos[construto.expressao.constructor.name](construto.expressao);
|
|
116
|
-
}
|
|
117
|
-
traduzirConstrutoAtribuicaoPorIndice(construto) {
|
|
118
|
-
let nomeVar;
|
|
119
|
-
if (construto.objeto instanceof construtos_1.Variavel) {
|
|
120
|
-
nomeVar = construto.objeto.simbolo?.lexema;
|
|
121
|
-
}
|
|
122
|
-
if (!nomeVar) {
|
|
123
|
-
nomeVar = 'unknown';
|
|
124
|
-
}
|
|
125
|
-
const indice = this.dicionarioConstrutos[construto.indice.constructor.name](construto.indice);
|
|
126
|
-
const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
127
|
-
this.textoSaida += `
|
|
128
|
-
mov rax, ${valor}
|
|
129
|
-
mov [${nomeVar} + ${indice} * 8], rax`;
|
|
130
|
-
}
|
|
131
|
-
traduzirConstrutoAtribuir(construto) {
|
|
132
|
-
// Atribuir tem a estrutura: { alvo, valor }
|
|
133
|
-
let nomeVar;
|
|
134
|
-
if (construto.alvo instanceof construtos_1.Variavel) {
|
|
135
|
-
nomeVar = construto.alvo.simbolo?.lexema;
|
|
136
|
-
}
|
|
137
|
-
if (!nomeVar) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
141
|
-
if (!this.variaveis.has(nomeVar)) {
|
|
142
|
-
const varLabel = `var_${nomeVar}`;
|
|
143
|
-
this.bss += ` ${varLabel} resq 1\n`;
|
|
144
|
-
this.variaveis.set(nomeVar, varLabel);
|
|
145
|
-
}
|
|
146
|
-
this.textoSaida += `
|
|
147
|
-
mov rax, ${valor}
|
|
148
|
-
mov [${this.variaveis.get(nomeVar)}], rax`;
|
|
149
|
-
}
|
|
150
|
-
traduzirConstrutoBinario(construto) {
|
|
151
|
-
const esquerda = this.dicionarioConstrutos[construto.esquerda.constructor.name](construto.esquerda);
|
|
152
|
-
const direita = this.dicionarioConstrutos[construto.direita.constructor.name](construto.direita);
|
|
153
|
-
const operador = construto.operador.lexema;
|
|
154
|
-
const registrador = this.obterRegistrador();
|
|
155
|
-
this.textoSaida += `
|
|
156
|
-
mov rax, ${esquerda}
|
|
157
|
-
mov ${registrador}, ${direita}`;
|
|
158
|
-
switch (operador) {
|
|
159
|
-
case '+':
|
|
160
|
-
this.textoSaida += `
|
|
161
|
-
add rax, ${registrador}`;
|
|
162
|
-
break;
|
|
163
|
-
case '-':
|
|
164
|
-
this.textoSaida += `
|
|
165
|
-
sub rax, ${registrador}`;
|
|
166
|
-
break;
|
|
167
|
-
case '*':
|
|
168
|
-
this.textoSaida += `
|
|
169
|
-
imul rax, ${registrador}`;
|
|
170
|
-
break;
|
|
171
|
-
case '/':
|
|
172
|
-
this.textoSaida += `
|
|
173
|
-
xor rdx, rdx
|
|
174
|
-
idiv ${registrador}`;
|
|
175
|
-
break;
|
|
176
|
-
case '%':
|
|
177
|
-
this.textoSaida += `
|
|
178
|
-
xor rdx, rdx
|
|
179
|
-
idiv ${registrador}
|
|
180
|
-
mov rax, rdx`;
|
|
181
|
-
break;
|
|
182
|
-
case '<':
|
|
183
|
-
this.textoSaida += `
|
|
184
|
-
cmp rax, ${registrador}
|
|
185
|
-
setl al
|
|
186
|
-
movzx rax, al`;
|
|
187
|
-
break;
|
|
188
|
-
case '>':
|
|
189
|
-
this.textoSaida += `
|
|
190
|
-
cmp rax, ${registrador}
|
|
191
|
-
setg al
|
|
192
|
-
movzx rax, al`;
|
|
193
|
-
break;
|
|
194
|
-
case '<=':
|
|
195
|
-
this.textoSaida += `
|
|
196
|
-
cmp rax, ${registrador}
|
|
197
|
-
setle al
|
|
198
|
-
movzx rax, al`;
|
|
199
|
-
break;
|
|
200
|
-
case '>=':
|
|
201
|
-
this.textoSaida += `
|
|
202
|
-
cmp rax, ${registrador}
|
|
203
|
-
setge al
|
|
204
|
-
movzx rax, al`;
|
|
205
|
-
break;
|
|
206
|
-
case '==':
|
|
207
|
-
this.textoSaida += `
|
|
208
|
-
cmp rax, ${registrador}
|
|
209
|
-
sete al
|
|
210
|
-
movzx rax, al`;
|
|
211
|
-
break;
|
|
212
|
-
case '!=':
|
|
213
|
-
this.textoSaida += `
|
|
214
|
-
cmp rax, ${registrador}
|
|
215
|
-
setne al
|
|
216
|
-
movzx rax, al`;
|
|
217
|
-
break;
|
|
218
|
-
default:
|
|
219
|
-
this.textoSaida += `
|
|
220
|
-
; Operador ${operador} não implementado`;
|
|
221
|
-
}
|
|
222
|
-
this.liberarRegistrador(registrador);
|
|
223
|
-
return 'rax';
|
|
224
|
-
}
|
|
225
|
-
traduzirConstrutoChamada(construto) {
|
|
226
|
-
let nomeFuncao = 'funcao';
|
|
227
|
-
if (construto.entidadeChamada instanceof construtos_1.Variavel) {
|
|
228
|
-
nomeFuncao = construto.entidadeChamada.simbolo?.lexema || 'funcao';
|
|
229
|
-
}
|
|
230
|
-
// Preparar argumentos (convenção de chamada System V AMD64)
|
|
231
|
-
const registrosArgs = this.alvo === 'linux'
|
|
232
|
-
? ['rdi', 'rsi', 'rdx', 'rcx', 'r8', 'r9'] // System V AMD64 [web:8]
|
|
233
|
-
: ['rcx', 'rdx', 'r8', 'r9']; // Windows x64 [web:2]
|
|
234
|
-
construto.argumentos.forEach((argumento, indice) => {
|
|
235
|
-
if (indice < registrosArgs.length) {
|
|
236
|
-
const valorArg = this.dicionarioConstrutos[argumento.constructor.name](argumento);
|
|
237
|
-
this.textoSaida += `
|
|
238
|
-
mov ${registrosArgs[indice]}, ${valorArg}`;
|
|
239
|
-
}
|
|
240
|
-
else {
|
|
241
|
-
// TODO: empurrar argumentos extras na pilha de acordo com o ABI alvo
|
|
242
|
-
}
|
|
243
|
-
});
|
|
244
|
-
this.textoSaida += `
|
|
245
|
-
call ${nomeFuncao}`;
|
|
246
|
-
}
|
|
247
|
-
traduzirConstrutoDefinirValor(construto) {
|
|
248
|
-
const objeto = this.dicionarioConstrutos[construto.objeto.constructor.name](construto.objeto);
|
|
249
|
-
const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
250
|
-
this.textoSaida += `
|
|
251
|
-
mov rax, ${valor}
|
|
252
|
-
mov [${objeto}], rax`;
|
|
253
|
-
}
|
|
254
|
-
traduzirFuncaoConstruto(construto) {
|
|
255
|
-
const labelFuncao = `func_${this.gerarDigitoAleatorio()}`;
|
|
256
|
-
this.textoSaida += `
|
|
257
|
-
${labelFuncao}:
|
|
258
|
-
push rbp
|
|
259
|
-
mov rbp, rsp`;
|
|
260
|
-
// Traduzir corpo da função
|
|
261
|
-
if (construto.corpo && Array.isArray(construto.corpo)) {
|
|
262
|
-
construto.corpo.forEach((declaracao) => {
|
|
263
|
-
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
264
|
-
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
this.textoSaida += `
|
|
269
|
-
pop rbp
|
|
270
|
-
ret`;
|
|
271
|
-
}
|
|
272
|
-
traduzirConstrutoLiteral(construto) {
|
|
273
|
-
if (typeof construto.valor === 'string') {
|
|
274
|
-
return this.criaStringLiteral(construto);
|
|
275
|
-
}
|
|
276
|
-
return String(construto.valor);
|
|
277
|
-
}
|
|
278
|
-
traduzirConstrutoLogico(construto) {
|
|
279
|
-
const esquerda = this.dicionarioConstrutos[construto.esquerda.constructor.name](construto.esquerda);
|
|
280
|
-
const direita = this.dicionarioConstrutos[construto.direita.constructor.name](construto.direita);
|
|
281
|
-
const operador = construto.operador.lexema;
|
|
282
|
-
const labelVerdadeiro = this.gerarLabel();
|
|
283
|
-
const labelFim = this.gerarLabel();
|
|
284
|
-
this.textoSaida += `
|
|
285
|
-
mov rax, ${esquerda}
|
|
286
|
-
cmp rax, 0`;
|
|
287
|
-
if (operador === 'e' || operador === '&&') {
|
|
288
|
-
this.textoSaida += `
|
|
289
|
-
je ${labelFim}
|
|
290
|
-
mov rax, ${direita}
|
|
291
|
-
cmp rax, 0
|
|
292
|
-
je ${labelFim}
|
|
293
|
-
${labelVerdadeiro}:
|
|
294
|
-
mov rax, 1
|
|
295
|
-
${labelFim}:`;
|
|
296
|
-
}
|
|
297
|
-
else if (operador === 'ou' || operador === '||') {
|
|
298
|
-
this.textoSaida += `
|
|
299
|
-
jne ${labelVerdadeiro}
|
|
300
|
-
mov rax, ${direita}
|
|
301
|
-
cmp rax, 0
|
|
302
|
-
jne ${labelVerdadeiro}
|
|
303
|
-
mov rax, 0
|
|
304
|
-
jmp ${labelFim}
|
|
305
|
-
${labelVerdadeiro}:
|
|
306
|
-
mov rax, 1
|
|
307
|
-
${labelFim}:`;
|
|
308
|
-
}
|
|
309
|
-
return 'rax';
|
|
310
|
-
}
|
|
311
|
-
traduzirConstrutoTipoDe(construto) {
|
|
312
|
-
// Simplificado - retorna tipo como número
|
|
313
|
-
const expressao = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
314
|
-
return expressao;
|
|
315
|
-
}
|
|
316
|
-
traduzirConstrutoUnario(construto) {
|
|
317
|
-
const operando = this.dicionarioConstrutos[construto.operando.constructor.name](construto.operando);
|
|
318
|
-
const operador = construto.operador.lexema;
|
|
319
|
-
this.textoSaida += `
|
|
320
|
-
mov rax, ${operando}`;
|
|
321
|
-
if (operador === '-') {
|
|
322
|
-
this.textoSaida += `
|
|
323
|
-
neg rax`;
|
|
324
|
-
}
|
|
325
|
-
else if (operador === '!' || operador === 'nao') {
|
|
326
|
-
this.textoSaida += `
|
|
327
|
-
cmp rax, 0
|
|
328
|
-
sete al
|
|
329
|
-
movzx rax, al`;
|
|
330
|
-
}
|
|
331
|
-
else if (operador === '++') {
|
|
332
|
-
this.textoSaida += `
|
|
333
|
-
inc rax
|
|
334
|
-
mov ${operando}, rax`;
|
|
335
|
-
}
|
|
336
|
-
else if (operador === '--') {
|
|
337
|
-
this.textoSaida += `
|
|
338
|
-
dec rax
|
|
339
|
-
mov ${operando}, rax`;
|
|
340
|
-
}
|
|
341
|
-
return 'rax';
|
|
342
|
-
}
|
|
343
|
-
traduzirConstrutoVariavel(construto) {
|
|
344
|
-
const nomeVar = construto.simbolo?.lexema;
|
|
345
|
-
if (nomeVar && this.variaveis.has(nomeVar)) {
|
|
346
|
-
return `[${this.variaveis.get(nomeVar)}]`;
|
|
347
|
-
}
|
|
348
|
-
return nomeVar || 'unknown';
|
|
349
|
-
}
|
|
350
|
-
traduzirConstrutoVetor(construto) {
|
|
351
|
-
const rotuloVetor = `vetor_${this.gerarDigitoAleatorio()}`;
|
|
352
|
-
const tamanho = construto.valores?.length || 0;
|
|
353
|
-
this.bss += ` ${rotuloVetor} resq ${tamanho}\n`;
|
|
354
|
-
if (construto.valores && Array.isArray(construto.valores)) {
|
|
355
|
-
construto.valores.forEach((valor, index) => {
|
|
356
|
-
if (this.dicionarioConstrutos[valor.constructor.name]) {
|
|
357
|
-
const valorTraduzido = this.dicionarioConstrutos[valor.constructor.name](valor);
|
|
358
|
-
this.textoSaida += `
|
|
359
|
-
mov rax, ${valorTraduzido}
|
|
360
|
-
mov [${rotuloVetor} + ${index * 8}], rax`;
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
return rotuloVetor;
|
|
365
|
-
}
|
|
366
|
-
// Implementação das Declarações
|
|
367
|
-
traduzirDeclaracaoBloco(declaracao) {
|
|
368
|
-
if (declaracao.declaracoes && Array.isArray(declaracao.declaracoes)) {
|
|
369
|
-
declaracao.declaracoes.forEach((declaracao) => {
|
|
370
|
-
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
371
|
-
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
traduzirDeclaracaoEnquanto(declaracao) {
|
|
377
|
-
const labelInicio = this.gerarLabel();
|
|
378
|
-
const labelFim = this.gerarLabel();
|
|
379
|
-
this.textoSaida += `
|
|
380
|
-
${labelInicio}:`;
|
|
381
|
-
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
|
|
382
|
-
this.textoSaida += `
|
|
383
|
-
cmp ${condicao}, 0
|
|
384
|
-
je ${labelFim}`;
|
|
385
|
-
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
|
|
386
|
-
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
|
|
387
|
-
}
|
|
388
|
-
this.textoSaida += `
|
|
389
|
-
jmp ${labelInicio}
|
|
390
|
-
${labelFim}:`;
|
|
391
|
-
}
|
|
392
|
-
traduzirDeclaracaoEscolha(declaracao) {
|
|
393
|
-
const labelFim = this.gerarLabel();
|
|
394
|
-
const valorEscolha = this.dicionarioConstrutos[declaracao.identificadorOuLiteral.constructor.name](declaracao.identificadorOuLiteral);
|
|
395
|
-
if (declaracao.caminhos && Array.isArray(declaracao.caminhos)) {
|
|
396
|
-
declaracao.caminhos.forEach((caminho) => {
|
|
397
|
-
const labelProximo = this.gerarLabel();
|
|
398
|
-
if (caminho.condicoes && caminho.condicoes[0]) {
|
|
399
|
-
const valorCaso = this.dicionarioConstrutos[caminho.condicoes[0].constructor.name](caminho.condicoes[0]);
|
|
400
|
-
this.textoSaida += `
|
|
401
|
-
mov rax, ${valorEscolha}
|
|
402
|
-
cmp rax, ${valorCaso}
|
|
403
|
-
jne ${labelProximo}`;
|
|
404
|
-
if (caminho.declaracoes && Array.isArray(caminho.declaracoes)) {
|
|
405
|
-
caminho.declaracoes.forEach((declaracao) => {
|
|
406
|
-
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
407
|
-
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
this.textoSaida += `
|
|
412
|
-
jmp ${labelFim}
|
|
413
|
-
${labelProximo}:`;
|
|
414
|
-
}
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
this.textoSaida += `
|
|
418
|
-
${labelFim}:`;
|
|
419
|
-
}
|
|
420
|
-
traduzirDeclaracaoExpressao(declaracao) {
|
|
421
|
-
if (declaracao.expressao &&
|
|
422
|
-
this.dicionarioConstrutos[declaracao.expressao.constructor.name]) {
|
|
423
|
-
this.dicionarioConstrutos[declaracao.expressao.constructor.name](declaracao.expressao);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
traduzirDeclaracaoFazer(declaracao) {
|
|
427
|
-
const labelInicio = this.gerarLabel();
|
|
428
|
-
this.textoSaida += `
|
|
429
|
-
${labelInicio}:`;
|
|
430
|
-
// Em Delégua, fazer-enquanto tem caminhoFazer que é um Bloco
|
|
431
|
-
if (declaracao.caminhoFazer && declaracao.caminhoFazer.declaracoes) {
|
|
432
|
-
declaracao.caminhoFazer.declaracoes.forEach((declaracao) => {
|
|
433
|
-
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
434
|
-
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
if (declaracao.condicaoEnquanto) {
|
|
439
|
-
const condicao = this.dicionarioConstrutos[declaracao.condicaoEnquanto.constructor.name](declaracao.condicaoEnquanto);
|
|
440
|
-
this.textoSaida += `
|
|
441
|
-
cmp ${condicao}, 0
|
|
442
|
-
jne ${labelInicio}`;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
traduzirDeclaracaoFalhar(declaracao) {
|
|
446
|
-
let mensagem = '"Erro"';
|
|
447
|
-
if (declaracao.explicacao &&
|
|
448
|
-
typeof declaracao.explicacao === 'object' &&
|
|
449
|
-
'constructor' in declaracao.explicacao) {
|
|
450
|
-
const explicacao = declaracao.explicacao;
|
|
451
|
-
if (explicacao.constructor && this.dicionarioConstrutos[explicacao.constructor.name]) {
|
|
452
|
-
mensagem = this.dicionarioConstrutos[explicacao.constructor.name](explicacao);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
if (this.alvo === 'linux') {
|
|
456
|
-
this.textoSaida += `
|
|
457
|
-
; Falhar com mensagem: ${mensagem}
|
|
458
|
-
mov eax, 1
|
|
459
|
-
mov ebx, 1
|
|
460
|
-
int 0x80`;
|
|
461
|
-
}
|
|
462
|
-
else {
|
|
463
|
-
this.textoSaida += `
|
|
464
|
-
; Falhar com mensagem: ${mensagem}
|
|
465
|
-
mov eax, 1
|
|
466
|
-
ret`;
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
traduzirDeclaracaoFuncao(declaracao) {
|
|
470
|
-
const nomeFuncao = declaracao.simbolo?.lexema || 'funcao';
|
|
471
|
-
this.textoSaida += `
|
|
472
|
-
${nomeFuncao}:
|
|
473
|
-
push rbp
|
|
474
|
-
mov rbp, rsp`;
|
|
475
|
-
if (declaracao.funcao &&
|
|
476
|
-
declaracao.funcao.corpo &&
|
|
477
|
-
Array.isArray(declaracao.funcao.corpo)) {
|
|
478
|
-
declaracao.funcao.corpo.forEach((decl) => {
|
|
479
|
-
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
|
|
480
|
-
this.dicionarioDeclaracoes[decl.constructor.name](decl);
|
|
481
|
-
}
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
this.textoSaida += `
|
|
485
|
-
pop rbp
|
|
486
|
-
ret`;
|
|
487
|
-
}
|
|
488
|
-
traduzirDeclaracaoImportar(declaracao) {
|
|
489
|
-
// Importação é tratada em tempo de linkagem
|
|
490
|
-
this.textoSaida += `
|
|
491
|
-
; Importar: ${declaracao.caminho || 'unknown'}`;
|
|
492
|
-
}
|
|
493
|
-
traduzirDeclaracaoLeia(declaracao) {
|
|
494
|
-
let nomeVar;
|
|
495
|
-
if (declaracao.argumentos &&
|
|
496
|
-
declaracao.argumentos[0] &&
|
|
497
|
-
declaracao.argumentos[0] instanceof construtos_1.Variavel) {
|
|
498
|
-
nomeVar = declaracao.argumentos[0].simbolo?.lexema;
|
|
499
|
-
}
|
|
500
|
-
if (!nomeVar)
|
|
501
|
-
return;
|
|
502
|
-
if (!this.variaveis.has(nomeVar)) {
|
|
503
|
-
const varLabel = `var_${nomeVar}`;
|
|
504
|
-
this.bss += ` ${varLabel} resb 256\n`;
|
|
505
|
-
this.variaveis.set(nomeVar, varLabel);
|
|
506
|
-
}
|
|
507
|
-
this.textoSaida += `
|
|
508
|
-
mov eax, 3
|
|
509
|
-
mov ebx, 0
|
|
510
|
-
mov ecx, ${this.variaveis.get(nomeVar)}
|
|
511
|
-
mov edx, 256
|
|
512
|
-
int 0x80`;
|
|
513
|
-
}
|
|
514
|
-
traduzirDeclaracaoPara(declaracao) {
|
|
515
|
-
const labelInicio = this.gerarLabel();
|
|
516
|
-
const labelFim = this.gerarLabel();
|
|
517
|
-
// Inicializador pode ser um array de declarações, uma declaração ou um construto
|
|
518
|
-
if (declaracao.inicializador) {
|
|
519
|
-
if (Array.isArray(declaracao.inicializador)) {
|
|
520
|
-
for (const decl of declaracao.inicializador) {
|
|
521
|
-
const tipo = decl.constructor.name;
|
|
522
|
-
if (this.dicionarioDeclaracoes[tipo]) {
|
|
523
|
-
this.dicionarioDeclaracoes[tipo](decl);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
const tipoInicializador = declaracao.inicializador.constructor.name;
|
|
529
|
-
if (this.dicionarioDeclaracoes[tipoInicializador]) {
|
|
530
|
-
this.dicionarioDeclaracoes[tipoInicializador](declaracao.inicializador);
|
|
531
|
-
}
|
|
532
|
-
else if (this.dicionarioConstrutos[tipoInicializador]) {
|
|
533
|
-
this.dicionarioConstrutos[tipoInicializador](declaracao.inicializador);
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
this.textoSaida += `
|
|
538
|
-
${labelInicio}:`;
|
|
539
|
-
if (declaracao.condicao) {
|
|
540
|
-
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
|
|
541
|
-
this.textoSaida += `
|
|
542
|
-
cmp ${condicao}, 0
|
|
543
|
-
je ${labelFim}`;
|
|
544
|
-
}
|
|
545
|
-
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
|
|
546
|
-
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
|
|
547
|
-
}
|
|
548
|
-
if (declaracao.incrementar) {
|
|
549
|
-
if (this.dicionarioConstrutos[declaracao.incrementar.constructor.name]) {
|
|
550
|
-
this.dicionarioConstrutos[declaracao.incrementar.constructor.name](declaracao.incrementar);
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
this.textoSaida += `
|
|
554
|
-
jmp ${labelInicio}
|
|
555
|
-
${labelFim}:`;
|
|
556
|
-
}
|
|
557
|
-
traduzirDeclaracaoParaCada(declaracao) {
|
|
558
|
-
const rotuloInicio = this.gerarLabel();
|
|
559
|
-
const rotuloFim = this.gerarLabel();
|
|
560
|
-
let nomeVar;
|
|
561
|
-
if (declaracao.variavelIteracao instanceof construtos_1.Variavel) {
|
|
562
|
-
nomeVar = declaracao.variavelIteracao.simbolo?.lexema;
|
|
563
|
-
}
|
|
564
|
-
const vetor = declaracao.vetorOuDicionario;
|
|
565
|
-
let tamanhoVetor = 0;
|
|
566
|
-
if (vetor instanceof construtos_1.Vetor) {
|
|
567
|
-
tamanhoVetor = vetor.tamanho || 0;
|
|
568
|
-
}
|
|
569
|
-
this.textoSaida += `
|
|
570
|
-
xor rcx, rcx
|
|
571
|
-
${rotuloInicio}:
|
|
572
|
-
cmp rcx, ${tamanhoVetor}
|
|
573
|
-
jge ${rotuloFim}`;
|
|
574
|
-
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
|
|
575
|
-
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
|
|
576
|
-
}
|
|
577
|
-
this.textoSaida += `
|
|
578
|
-
inc rcx
|
|
579
|
-
jmp ${rotuloInicio}
|
|
580
|
-
${rotuloFim}:`;
|
|
581
|
-
}
|
|
582
|
-
traduzirDeclaracaoRetorna(declaracao) {
|
|
583
|
-
if (declaracao.valor) {
|
|
584
|
-
const valor = this.dicionarioConstrutos[declaracao.valor.constructor.name](declaracao.valor);
|
|
585
|
-
this.textoSaida += `
|
|
586
|
-
mov rax, ${valor}`;
|
|
587
|
-
}
|
|
588
|
-
this.textoSaida += `
|
|
589
|
-
pop rbp
|
|
590
|
-
ret`;
|
|
591
|
-
}
|
|
592
|
-
traduzirDeclaracaoSe(declaracao) {
|
|
593
|
-
const rotuloSenao = this.gerarLabel();
|
|
594
|
-
const rotuloFim = this.gerarLabel();
|
|
595
|
-
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
|
|
596
|
-
this.textoSaida += `
|
|
597
|
-
cmp ${condicao}, 0
|
|
598
|
-
je ${rotuloSenao}`;
|
|
599
|
-
if (this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name]) {
|
|
600
|
-
this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name](declaracao.caminhoEntao);
|
|
601
|
-
}
|
|
602
|
-
this.textoSaida += `
|
|
603
|
-
jmp ${rotuloFim}
|
|
604
|
-
${rotuloSenao}:`;
|
|
605
|
-
if (declaracao.caminhoSenao &&
|
|
606
|
-
this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name]) {
|
|
607
|
-
this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name](declaracao.caminhoSenao);
|
|
608
|
-
}
|
|
609
|
-
this.textoSaida += `
|
|
610
|
-
${rotuloFim}:`;
|
|
611
|
-
}
|
|
612
|
-
traduzirDeclaracaoClasse(declaracao) {
|
|
613
|
-
// Classes em assembly são complexas - implementação básica
|
|
614
|
-
this.textoSaida += `
|
|
615
|
-
; Classe: ${declaracao.simbolo?.lexema || 'unknown'}`;
|
|
616
|
-
}
|
|
617
|
-
traduzirDeclaracaoTente(declaracao) {
|
|
618
|
-
// Try-catch em assembly requer handler complexo
|
|
619
|
-
this.textoSaida += `
|
|
620
|
-
; Tente-pegue`;
|
|
621
|
-
if (declaracao.caminhoTente && Array.isArray(declaracao.caminhoTente)) {
|
|
622
|
-
declaracao.caminhoTente.forEach((declaracao) => {
|
|
623
|
-
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
624
|
-
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
625
|
-
}
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
traduzirDeclaracaoConst(declaracao) {
|
|
630
|
-
const nomeVar = declaracao.simbolo?.lexema;
|
|
631
|
-
if (!nomeVar)
|
|
632
|
-
return;
|
|
633
|
-
const valor = this.dicionarioConstrutos[declaracao.inicializador.constructor.name](declaracao.inicializador);
|
|
634
|
-
const varLabel = `const_${nomeVar}`;
|
|
635
|
-
this.data += ` ${varLabel} dq ${valor}\n`;
|
|
636
|
-
this.variaveis.set(nomeVar, varLabel);
|
|
637
|
-
}
|
|
638
|
-
traduzirDeclaracaoVar(declaracao) {
|
|
639
|
-
const nomeVar = declaracao.simbolo?.lexema;
|
|
640
|
-
if (!nomeVar)
|
|
641
|
-
return;
|
|
642
|
-
const varLabel = `var_${nomeVar}`;
|
|
643
|
-
this.bss += ` ${varLabel} resq 1\n`;
|
|
644
|
-
this.variaveis.set(nomeVar, varLabel);
|
|
645
|
-
if (declaracao.inicializador) {
|
|
646
|
-
const tipoInicializador = declaracao.inicializador.constructor.name;
|
|
647
|
-
// Verificar se é um vetor
|
|
648
|
-
if (declaracao.inicializador instanceof construtos_1.Vetor) {
|
|
649
|
-
// Vetor precisa de tratamento especial
|
|
650
|
-
const labelVetor = this.traduzirConstrutoVetor(declaracao.inicializador);
|
|
651
|
-
// Associar o nome da variável com o label do vetor
|
|
652
|
-
this.variaveis.set(nomeVar, labelVetor);
|
|
653
|
-
}
|
|
654
|
-
else if (this.dicionarioConstrutos[tipoInicializador]) {
|
|
655
|
-
const valor = this.dicionarioConstrutos[tipoInicializador](declaracao.inicializador);
|
|
656
|
-
this.textoSaida += `
|
|
657
|
-
mov rax, ${valor}
|
|
658
|
-
mov [${varLabel}], rax`;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
criaStringLiteral(literal) {
|
|
663
|
-
const varLiteral = `Delegua_${this.gerarDigitoAleatorio()}`;
|
|
664
|
-
this.data += ` ${varLiteral} db '${literal.valor}', 0\n`;
|
|
665
|
-
return varLiteral;
|
|
666
|
-
}
|
|
667
|
-
criaTamanhoNaMemoriaReferenteAVar(nomeStringLiteral) {
|
|
668
|
-
const varTamanho = `tam_${nomeStringLiteral}`;
|
|
669
|
-
this.data += ` ${varTamanho} equ $ - ${nomeStringLiteral}\n`;
|
|
670
|
-
return varTamanho;
|
|
671
|
-
}
|
|
672
|
-
emitirHelperPrintInt() {
|
|
673
|
-
if (this.helperPrintIntEmitido)
|
|
674
|
-
return;
|
|
675
|
-
this.helperPrintIntEmitido = true;
|
|
676
|
-
this.bss += ` __print_buf resb 24\n`;
|
|
677
|
-
this.helpers += `
|
|
678
|
-
__delegua_print_int:
|
|
679
|
-
push rbx
|
|
680
|
-
push rcx
|
|
681
|
-
push rdx
|
|
682
|
-
push rsi
|
|
683
|
-
mov rcx, 10
|
|
684
|
-
lea rsi, [__print_buf + 22]
|
|
685
|
-
mov byte [rsi], 10
|
|
686
|
-
.print_digitloop:
|
|
687
|
-
xor rdx, rdx
|
|
688
|
-
div rcx
|
|
689
|
-
add dl, '0'
|
|
690
|
-
dec rsi
|
|
691
|
-
mov [rsi], dl
|
|
692
|
-
test rax, rax
|
|
693
|
-
jnz .print_digitloop
|
|
694
|
-
lea rdx, [__print_buf + 23]
|
|
695
|
-
sub rdx, rsi
|
|
696
|
-
mov ecx, esi
|
|
697
|
-
mov ebx, 1
|
|
698
|
-
mov eax, 4
|
|
699
|
-
int 0x80
|
|
700
|
-
pop rsi
|
|
701
|
-
pop rdx
|
|
702
|
-
pop rcx
|
|
703
|
-
pop rbx
|
|
704
|
-
ret`;
|
|
705
|
-
}
|
|
706
|
-
traduzirDeclaracaoEscreva(declaracaoEscreva) {
|
|
707
|
-
const arg = declaracaoEscreva.argumentos[0];
|
|
708
|
-
if (arg instanceof construtos_1.Literal) {
|
|
709
|
-
const nome_string_literal = this.criaStringLiteral(arg);
|
|
710
|
-
const tam_string_literal = this.criaTamanhoNaMemoriaReferenteAVar(nome_string_literal);
|
|
711
|
-
if (this.alvo === 'linux') {
|
|
712
|
-
this.textoSaida += `
|
|
713
|
-
mov edx, ${tam_string_literal}
|
|
714
|
-
mov ecx, ${nome_string_literal}
|
|
715
|
-
mov ebx, 1 ; fd stdout
|
|
716
|
-
mov eax, 4 ; sys_write
|
|
717
|
-
int 0x80`;
|
|
718
|
-
}
|
|
719
|
-
else {
|
|
720
|
-
this.textoSaida += `
|
|
721
|
-
lea rcx, [rel ${nome_string_literal}]
|
|
722
|
-
call printf`;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
else {
|
|
726
|
-
const valor = this.dicionarioConstrutos[arg.constructor.name](arg);
|
|
727
|
-
if (this.alvo === 'linux') {
|
|
728
|
-
this.emitirHelperPrintInt();
|
|
729
|
-
this.textoSaida += `
|
|
730
|
-
mov rax, ${valor}
|
|
731
|
-
call __delegua_print_int`;
|
|
732
|
-
}
|
|
733
|
-
else {
|
|
734
|
-
if (!this.fmtIntWindowsEmitido) {
|
|
735
|
-
this.data += ` __fmt_int db '%d', 10, 0\n`;
|
|
736
|
-
this.fmtIntWindowsEmitido = true;
|
|
737
|
-
}
|
|
738
|
-
this.textoSaida += `
|
|
739
|
-
mov rdx, ${valor}
|
|
740
|
-
lea rcx, [rel __fmt_int]
|
|
741
|
-
call printf`;
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
saidaSistema() {
|
|
746
|
-
if (this.alvo === 'linux') {
|
|
747
|
-
this.textoSaida += `
|
|
748
|
-
mov eax, 1 ; sys_exit
|
|
749
|
-
xor ebx, ebx ; status 0
|
|
750
|
-
int 0x80`;
|
|
751
|
-
}
|
|
752
|
-
else {
|
|
753
|
-
// Windows: return from main with 0 in EAX
|
|
754
|
-
this.textoSaida += `
|
|
755
|
-
xor eax, eax
|
|
756
|
-
ret`;
|
|
757
|
-
}
|
|
22
|
+
paleta() {
|
|
23
|
+
return this.alvo === 'linux' ? PALETA_LINUX : PALETA_WINDOWS;
|
|
758
24
|
}
|
|
759
25
|
traduzir(declaracoes) {
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
this.
|
|
769
|
-
resultado += this.bss + '\n' + this.data + '\n' + this.textoSaida;
|
|
770
|
-
return resultado;
|
|
26
|
+
const programa = new lowering_1.LoweringX64().lowerPrograma(declaracoes);
|
|
27
|
+
const paleta = this.paleta();
|
|
28
|
+
const funcoesProcessadas = programa.funcoes.map((funcao) => {
|
|
29
|
+
(0, ssa_1.construirSSA)(funcao);
|
|
30
|
+
const { alocacao } = (0, alocador_registradores_1.alocarRegistradores)(funcao, paleta);
|
|
31
|
+
(0, dessa_1.destruirSSA)(funcao, alocacao);
|
|
32
|
+
return { funcao, alocacao };
|
|
33
|
+
});
|
|
34
|
+
return new codegen_1.CodegenX64(this.alvo, paleta).gerar(programa, funcoesProcessadas);
|
|
771
35
|
}
|
|
772
36
|
}
|
|
773
37
|
exports.TradutorAssemblyX64 = TradutorAssemblyX64;
|