@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.
Files changed (110) hide show
  1. package/analisador-semantico/analisador-semantico.d.ts +4 -1
  2. package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
  3. package/analisador-semantico/analisador-semantico.js +36 -8
  4. package/analisador-semantico/analisador-semantico.js.map +1 -1
  5. package/analisador-semantico/dialetos/analisador-semantico-pitugues.d.ts.map +1 -1
  6. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js +11 -12
  7. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js.map +1 -1
  8. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
  9. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +14 -12
  10. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
  11. package/avaliador-sintatico/dialetos/micro-avaliador-sintatico-pitugues.d.ts.map +1 -1
  12. package/avaliador-sintatico/dialetos/micro-avaliador-sintatico-pitugues.js +5 -3
  13. package/avaliador-sintatico/dialetos/micro-avaliador-sintatico-pitugues.js.map +1 -1
  14. package/bibliotecas/dialetos/pitugues/biblioteca-global.d.ts.map +1 -1
  15. package/bibliotecas/dialetos/pitugues/biblioteca-global.js +1 -1
  16. package/bibliotecas/dialetos/pitugues/biblioteca-global.js.map +1 -1
  17. package/bibliotecas/dialetos/pitugues/primitivas-dicionario.js +3 -3
  18. package/bibliotecas/dialetos/pitugues/primitivas-dicionario.js.map +1 -1
  19. package/bibliotecas/dialetos/pitugues/primitivas-numero.js +8 -8
  20. package/bibliotecas/dialetos/pitugues/primitivas-numero.js.map +1 -1
  21. package/bibliotecas/dialetos/pitugues/primitivas-texto.js +22 -22
  22. package/bibliotecas/dialetos/pitugues/primitivas-texto.js.map +1 -1
  23. package/bibliotecas/dialetos/pitugues/primitivas-vetor.d.ts.map +1 -1
  24. package/bibliotecas/dialetos/pitugues/primitivas-vetor.js +16 -16
  25. package/bibliotecas/dialetos/pitugues/primitivas-vetor.js.map +1 -1
  26. package/bin/package.json +2 -2
  27. package/excecoes/index.d.ts +1 -0
  28. package/excecoes/index.d.ts.map +1 -1
  29. package/excecoes/index.js +1 -0
  30. package/excecoes/index.js.map +1 -1
  31. package/excecoes/mensagem-erro.d.ts +17 -0
  32. package/excecoes/mensagem-erro.d.ts.map +1 -0
  33. package/excecoes/mensagem-erro.js +31 -0
  34. package/excecoes/mensagem-erro.js.map +1 -0
  35. package/interpretador/depuracao/avaliador-expressao-depuracao.d.ts.map +1 -1
  36. package/interpretador/depuracao/avaliador-expressao-depuracao.js +2 -1
  37. package/interpretador/depuracao/avaliador-expressao-depuracao.js.map +1 -1
  38. package/interpretador/depuracao/comum.d.ts.map +1 -1
  39. package/interpretador/depuracao/comum.js +6 -1
  40. package/interpretador/depuracao/comum.js.map +1 -1
  41. package/interpretador/dialetos/pitugues/comum.d.ts +3 -3
  42. package/interpretador/dialetos/pitugues/comum.d.ts.map +1 -1
  43. package/interpretador/dialetos/pitugues/comum.js +18 -4
  44. package/interpretador/dialetos/pitugues/comum.js.map +1 -1
  45. package/interpretador/dialetos/pitugues/interpretador-pitugues.js +2 -2
  46. package/interpretador/dialetos/pitugues/interpretador-pitugues.js.map +1 -1
  47. package/interpretador/interpretador-base.d.ts.map +1 -1
  48. package/interpretador/interpretador-base.js +2 -1
  49. package/interpretador/interpretador-base.js.map +1 -1
  50. package/interpretador/interpretador.js +3 -3
  51. package/interpretador/interpretador.js.map +1 -1
  52. package/lexador/lexador.d.ts.map +1 -1
  53. package/lexador/lexador.js.map +1 -1
  54. package/package.json +2 -2
  55. package/tipos-de-dados/dialetos/pitugues.d.ts +0 -4
  56. package/tipos-de-dados/dialetos/pitugues.d.ts.map +1 -1
  57. package/tipos-de-dados/dialetos/pitugues.js +0 -4
  58. package/tipos-de-dados/dialetos/pitugues.js.map +1 -1
  59. package/tradutores/tradutor-assembly-x64.d.ts +11 -96
  60. package/tradutores/tradutor-assembly-x64.d.ts.map +1 -1
  61. package/tradutores/tradutor-assembly-x64.js +25 -761
  62. package/tradutores/tradutor-assembly-x64.js.map +1 -1
  63. package/tradutores/tradutor-javascript.d.ts +1 -1
  64. package/tradutores/tradutor-javascript.d.ts.map +1 -1
  65. package/tradutores/tradutor-javascript.js +7 -0
  66. package/tradutores/tradutor-javascript.js.map +1 -1
  67. package/tradutores/tradutor-python.d.ts +8 -0
  68. package/tradutores/tradutor-python.d.ts.map +1 -1
  69. package/tradutores/tradutor-python.js +35 -4
  70. package/tradutores/tradutor-python.js.map +1 -1
  71. package/tradutores/tradutor-reverso-javascript.d.ts.map +1 -1
  72. package/tradutores/tradutor-reverso-javascript.js +3 -0
  73. package/tradutores/tradutor-reverso-javascript.js.map +1 -1
  74. package/tradutores/x64/alocador-registradores.d.ts +29 -0
  75. package/tradutores/x64/alocador-registradores.d.ts.map +1 -0
  76. package/tradutores/x64/alocador-registradores.js +192 -0
  77. package/tradutores/x64/alocador-registradores.js.map +1 -0
  78. package/tradutores/x64/codegen.d.ts +43 -0
  79. package/tradutores/x64/codegen.d.ts.map +1 -0
  80. package/tradutores/x64/codegen.js +416 -0
  81. package/tradutores/x64/codegen.js.map +1 -0
  82. package/tradutores/x64/dessa.d.ts +9 -0
  83. package/tradutores/x64/dessa.d.ts.map +1 -0
  84. package/tradutores/x64/dessa.js +124 -0
  85. package/tradutores/x64/dessa.js.map +1 -0
  86. package/tradutores/x64/dominancia.d.ts +25 -0
  87. package/tradutores/x64/dominancia.d.ts.map +1 -0
  88. package/tradutores/x64/dominancia.js +129 -0
  89. package/tradutores/x64/dominancia.js.map +1 -0
  90. package/tradutores/x64/ir.d.ts +144 -0
  91. package/tradutores/x64/ir.d.ts.map +1 -0
  92. package/tradutores/x64/ir.js +44 -0
  93. package/tradutores/x64/ir.js.map +1 -0
  94. package/tradutores/x64/liveness.d.ts +12 -0
  95. package/tradutores/x64/liveness.d.ts.map +1 -0
  96. package/tradutores/x64/liveness.js +159 -0
  97. package/tradutores/x64/liveness.js.map +1 -0
  98. package/tradutores/x64/lowering.d.ts +7 -0
  99. package/tradutores/x64/lowering.d.ts.map +1 -0
  100. package/tradutores/x64/lowering.js +904 -0
  101. package/tradutores/x64/lowering.js.map +1 -0
  102. package/tradutores/x64/ssa.d.ts +9 -0
  103. package/tradutores/x64/ssa.d.ts.map +1 -0
  104. package/tradutores/x64/ssa.js +170 -0
  105. package/tradutores/x64/ssa.js.map +1 -0
  106. package/tradutores/x64/tipos-x64.d.ts +12 -0
  107. package/tradutores/x64/tipos-x64.d.ts.map +1 -0
  108. package/tradutores/x64/tipos-x64.js +59 -0
  109. package/tradutores/x64/tipos-x64.js.map +1 -0
  110. 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 construtos_1 = require("../construtos");
5
- const declaracoes_1 = require("../declaracoes");
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
- gerarDigitoAleatorio() {
72
- let result = '';
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
- let resultado = '';
761
- this.declaracoesDeClasses = declaracoes.filter((declaracao) => declaracao instanceof declaracoes_1.Classe);
762
- for (const declaracao of declaracoes) {
763
- if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
764
- this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
765
- }
766
- }
767
- this.saidaSistema();
768
- this.textoSaida += this.helpers;
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;