@designliquido/delegua 1.13.1 → 1.14.0
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/bin/package.json +1 -1
- package/construtos/vetor.d.ts.map +1 -1
- package/construtos/vetor.js +2 -1
- package/construtos/vetor.js.map +1 -1
- package/interpretador/interpretador-base.js +3 -3
- package/interpretador/interpretador-base.js.map +1 -1
- package/package.json +1 -1
- package/tradutores/index.d.ts +2 -0
- package/tradutores/index.d.ts.map +1 -1
- package/tradutores/index.js +2 -0
- package/tradutores/index.js.map +1 -1
- package/tradutores/tradutor-assembly-risc-v.d.ts +99 -0
- package/tradutores/tradutor-assembly-risc-v.d.ts.map +1 -0
- package/tradutores/tradutor-assembly-risc-v.js +685 -0
- package/tradutores/tradutor-assembly-risc-v.js.map +1 -0
- package/tradutores/tradutor-assembly-x64.d.ts +5 -1
- package/tradutores/tradutor-assembly-x64.d.ts.map +1 -1
- package/tradutores/tradutor-assembly-x64.js +218 -108
- package/tradutores/tradutor-assembly-x64.js.map +1 -1
- package/tradutores/tradutor-assemblyscript.js +1 -1
- package/tradutores/tradutor-assemblyscript.js.map +1 -1
- package/tradutores/tradutor-webassembly.d.ts +159 -0
- package/tradutores/tradutor-webassembly.d.ts.map +1 -0
- package/tradutores/tradutor-webassembly.js +895 -0
- package/tradutores/tradutor-webassembly.js.map +1 -0
- package/umd/delegua.js +2057 -362
|
@@ -11,6 +11,9 @@ class TradutorAssemblyX64 {
|
|
|
11
11
|
this.variaveis = new Map();
|
|
12
12
|
this.registradoresDisponiveis = ['rbx', 'r12', 'r13', 'r14', 'r15'];
|
|
13
13
|
this.pilhaRegistradores = [];
|
|
14
|
+
this.helperPrintIntEmitido = false;
|
|
15
|
+
this.fmtIntWindowsEmitido = false;
|
|
16
|
+
this.helpers = '';
|
|
14
17
|
this.bss = 'section .bss\n';
|
|
15
18
|
this.data = 'section .data\n';
|
|
16
19
|
this.dicionarioConstrutos = {
|
|
@@ -54,15 +57,15 @@ class TradutorAssemblyX64 {
|
|
|
54
57
|
Escreva: this.traduzirDeclaracaoEscreva.bind(this),
|
|
55
58
|
};
|
|
56
59
|
this.indentacao = 0;
|
|
57
|
-
this.
|
|
60
|
+
this.textoSaida = `
|
|
58
61
|
section .text
|
|
59
62
|
${this.alvo === 'linux' ? 'global _start' : 'global main'}
|
|
60
63
|
${this.alvo === 'linux' ? '_start:' : 'main:'}`;
|
|
61
64
|
if (this.alvo === 'windows') {
|
|
62
|
-
this.
|
|
65
|
+
this.textoSaida =
|
|
63
66
|
`
|
|
64
67
|
extern printf
|
|
65
|
-
` + this.
|
|
68
|
+
` + this.textoSaida;
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
71
|
gerarDigitoAleatorio() {
|
|
@@ -123,7 +126,7 @@ extern printf
|
|
|
123
126
|
}
|
|
124
127
|
const indice = this.dicionarioConstrutos[construto.indice.constructor.name](construto.indice);
|
|
125
128
|
const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
126
|
-
this.
|
|
129
|
+
this.textoSaida += `
|
|
127
130
|
mov rax, ${valor}
|
|
128
131
|
mov [${nomeVar} + ${indice} * 8], rax`;
|
|
129
132
|
}
|
|
@@ -143,7 +146,7 @@ extern printf
|
|
|
143
146
|
this.bss += ` ${varLabel} resq 1\n`;
|
|
144
147
|
this.variaveis.set(nomeVar, varLabel);
|
|
145
148
|
}
|
|
146
|
-
this.
|
|
149
|
+
this.textoSaida += `
|
|
147
150
|
mov rax, ${valor}
|
|
148
151
|
mov [${this.variaveis.get(nomeVar)}], rax`;
|
|
149
152
|
}
|
|
@@ -151,39 +154,75 @@ extern printf
|
|
|
151
154
|
const esquerda = this.dicionarioConstrutos[construto.esquerda.constructor.name](construto.esquerda);
|
|
152
155
|
const direita = this.dicionarioConstrutos[construto.direita.constructor.name](construto.direita);
|
|
153
156
|
const operador = construto.operador.lexema;
|
|
154
|
-
const
|
|
155
|
-
this.
|
|
157
|
+
const registrador = this.obterRegistrador();
|
|
158
|
+
this.textoSaida += `
|
|
156
159
|
mov rax, ${esquerda}
|
|
157
|
-
mov ${
|
|
160
|
+
mov ${registrador}, ${direita}`;
|
|
158
161
|
switch (operador) {
|
|
159
162
|
case '+':
|
|
160
|
-
this.
|
|
161
|
-
add rax, ${
|
|
163
|
+
this.textoSaida += `
|
|
164
|
+
add rax, ${registrador}`;
|
|
162
165
|
break;
|
|
163
166
|
case '-':
|
|
164
|
-
this.
|
|
165
|
-
sub rax, ${
|
|
167
|
+
this.textoSaida += `
|
|
168
|
+
sub rax, ${registrador}`;
|
|
166
169
|
break;
|
|
167
170
|
case '*':
|
|
168
|
-
this.
|
|
169
|
-
imul rax, ${
|
|
171
|
+
this.textoSaida += `
|
|
172
|
+
imul rax, ${registrador}`;
|
|
170
173
|
break;
|
|
171
174
|
case '/':
|
|
172
|
-
this.
|
|
175
|
+
this.textoSaida += `
|
|
173
176
|
xor rdx, rdx
|
|
174
|
-
idiv ${
|
|
177
|
+
idiv ${registrador}`;
|
|
175
178
|
break;
|
|
176
179
|
case '%':
|
|
177
|
-
this.
|
|
180
|
+
this.textoSaida += `
|
|
178
181
|
xor rdx, rdx
|
|
179
|
-
idiv ${
|
|
182
|
+
idiv ${registrador}
|
|
180
183
|
mov rax, rdx`;
|
|
181
184
|
break;
|
|
185
|
+
case '<':
|
|
186
|
+
this.textoSaida += `
|
|
187
|
+
cmp rax, ${registrador}
|
|
188
|
+
setl al
|
|
189
|
+
movzx rax, al`;
|
|
190
|
+
break;
|
|
191
|
+
case '>':
|
|
192
|
+
this.textoSaida += `
|
|
193
|
+
cmp rax, ${registrador}
|
|
194
|
+
setg al
|
|
195
|
+
movzx rax, al`;
|
|
196
|
+
break;
|
|
197
|
+
case '<=':
|
|
198
|
+
this.textoSaida += `
|
|
199
|
+
cmp rax, ${registrador}
|
|
200
|
+
setle al
|
|
201
|
+
movzx rax, al`;
|
|
202
|
+
break;
|
|
203
|
+
case '>=':
|
|
204
|
+
this.textoSaida += `
|
|
205
|
+
cmp rax, ${registrador}
|
|
206
|
+
setge al
|
|
207
|
+
movzx rax, al`;
|
|
208
|
+
break;
|
|
209
|
+
case '==':
|
|
210
|
+
this.textoSaida += `
|
|
211
|
+
cmp rax, ${registrador}
|
|
212
|
+
sete al
|
|
213
|
+
movzx rax, al`;
|
|
214
|
+
break;
|
|
215
|
+
case '!=':
|
|
216
|
+
this.textoSaida += `
|
|
217
|
+
cmp rax, ${registrador}
|
|
218
|
+
setne al
|
|
219
|
+
movzx rax, al`;
|
|
220
|
+
break;
|
|
182
221
|
default:
|
|
183
|
-
this.
|
|
222
|
+
this.textoSaida += `
|
|
184
223
|
; Operador ${operador} não implementado`;
|
|
185
224
|
}
|
|
186
|
-
this.liberarRegistrador(
|
|
225
|
+
this.liberarRegistrador(registrador);
|
|
187
226
|
return 'rax';
|
|
188
227
|
}
|
|
189
228
|
traduzirConstrutoChamada(construto) {
|
|
@@ -199,26 +238,26 @@ extern printf
|
|
|
199
238
|
construto.argumentos.forEach((arg, index) => {
|
|
200
239
|
if (index < registrosArgs.length) {
|
|
201
240
|
const valorArg = this.dicionarioConstrutos[arg.constructor.name](arg);
|
|
202
|
-
this.
|
|
241
|
+
this.textoSaida += `
|
|
203
242
|
mov ${registrosArgs[index]}, ${valorArg}`;
|
|
204
243
|
}
|
|
205
244
|
else {
|
|
206
245
|
// TODO: push extra args on stack according to target ABI
|
|
207
246
|
}
|
|
208
247
|
});
|
|
209
|
-
this.
|
|
248
|
+
this.textoSaida += `
|
|
210
249
|
call ${nomeFuncao}`;
|
|
211
250
|
}
|
|
212
251
|
traduzirConstrutoDefinirValor(construto) {
|
|
213
252
|
const objeto = this.dicionarioConstrutos[construto.objeto.constructor.name](construto.objeto);
|
|
214
253
|
const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
215
|
-
this.
|
|
254
|
+
this.textoSaida += `
|
|
216
255
|
mov rax, ${valor}
|
|
217
256
|
mov [${objeto}], rax`;
|
|
218
257
|
}
|
|
219
258
|
traduzirFuncaoConstruto(construto) {
|
|
220
259
|
const labelFuncao = `func_${this.gerarDigitoAleatorio()}`;
|
|
221
|
-
this.
|
|
260
|
+
this.textoSaida += `
|
|
222
261
|
${labelFuncao}:
|
|
223
262
|
push rbp
|
|
224
263
|
mov rbp, rsp`;
|
|
@@ -230,7 +269,7 @@ ${labelFuncao}:
|
|
|
230
269
|
}
|
|
231
270
|
});
|
|
232
271
|
}
|
|
233
|
-
this.
|
|
272
|
+
this.textoSaida += `
|
|
234
273
|
pop rbp
|
|
235
274
|
ret`;
|
|
236
275
|
}
|
|
@@ -246,11 +285,11 @@ ${labelFuncao}:
|
|
|
246
285
|
const operador = construto.operador.lexema;
|
|
247
286
|
const labelVerdadeiro = this.gerarLabel();
|
|
248
287
|
const labelFim = this.gerarLabel();
|
|
249
|
-
this.
|
|
288
|
+
this.textoSaida += `
|
|
250
289
|
mov rax, ${esquerda}
|
|
251
290
|
cmp rax, 0`;
|
|
252
291
|
if (operador === 'e' || operador === '&&') {
|
|
253
|
-
this.
|
|
292
|
+
this.textoSaida += `
|
|
254
293
|
je ${labelFim}
|
|
255
294
|
mov rax, ${direita}
|
|
256
295
|
cmp rax, 0
|
|
@@ -260,7 +299,7 @@ ${labelVerdadeiro}:
|
|
|
260
299
|
${labelFim}:`;
|
|
261
300
|
}
|
|
262
301
|
else if (operador === 'ou' || operador === '||') {
|
|
263
|
-
this.
|
|
302
|
+
this.textoSaida += `
|
|
264
303
|
jne ${labelVerdadeiro}
|
|
265
304
|
mov rax, ${direita}
|
|
266
305
|
cmp rax, 0
|
|
@@ -281,17 +320,27 @@ ${labelFim}:`;
|
|
|
281
320
|
traduzirConstrutoUnario(construto) {
|
|
282
321
|
const operando = this.dicionarioConstrutos[construto.operando.constructor.name](construto.operando);
|
|
283
322
|
const operador = construto.operador.lexema;
|
|
284
|
-
this.
|
|
323
|
+
this.textoSaida += `
|
|
285
324
|
mov rax, ${operando}`;
|
|
286
325
|
if (operador === '-') {
|
|
287
|
-
this.
|
|
326
|
+
this.textoSaida += `
|
|
288
327
|
neg rax`;
|
|
289
328
|
}
|
|
290
329
|
else if (operador === '!' || operador === 'nao') {
|
|
291
|
-
this.
|
|
330
|
+
this.textoSaida += `
|
|
292
331
|
cmp rax, 0
|
|
293
332
|
sete al
|
|
294
333
|
movzx rax, al`;
|
|
334
|
+
}
|
|
335
|
+
else if (operador === '++') {
|
|
336
|
+
this.textoSaida += `
|
|
337
|
+
inc rax
|
|
338
|
+
mov ${operando}, rax`;
|
|
339
|
+
}
|
|
340
|
+
else if (operador === '--') {
|
|
341
|
+
this.textoSaida += `
|
|
342
|
+
dec rax
|
|
343
|
+
mov ${operando}, rax`;
|
|
295
344
|
}
|
|
296
345
|
return 'rax';
|
|
297
346
|
}
|
|
@@ -305,27 +354,27 @@ ${labelFim}:`;
|
|
|
305
354
|
}
|
|
306
355
|
traduzirConstrutoVetor(construto) {
|
|
307
356
|
var _a;
|
|
308
|
-
const
|
|
357
|
+
const rotuloVetor = `vetor_${this.gerarDigitoAleatorio()}`;
|
|
309
358
|
const tamanho = ((_a = construto.valores) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
310
|
-
this.bss += ` ${
|
|
359
|
+
this.bss += ` ${rotuloVetor} resq ${tamanho}\n`;
|
|
311
360
|
if (construto.valores && Array.isArray(construto.valores)) {
|
|
312
361
|
construto.valores.forEach((valor, index) => {
|
|
313
362
|
if (this.dicionarioConstrutos[valor.constructor.name]) {
|
|
314
363
|
const valorTraduzido = this.dicionarioConstrutos[valor.constructor.name](valor);
|
|
315
|
-
this.
|
|
364
|
+
this.textoSaida += `
|
|
316
365
|
mov rax, ${valorTraduzido}
|
|
317
|
-
mov [${
|
|
366
|
+
mov [${rotuloVetor} + ${index * 8}], rax`;
|
|
318
367
|
}
|
|
319
368
|
});
|
|
320
369
|
}
|
|
321
|
-
return
|
|
370
|
+
return rotuloVetor;
|
|
322
371
|
}
|
|
323
372
|
// Implementação das Declarações
|
|
324
373
|
traduzirDeclaracaoBloco(declaracao) {
|
|
325
374
|
if (declaracao.declaracoes && Array.isArray(declaracao.declaracoes)) {
|
|
326
|
-
declaracao.declaracoes.forEach((
|
|
327
|
-
if (this.dicionarioDeclaracoes[
|
|
328
|
-
this.dicionarioDeclaracoes[
|
|
375
|
+
declaracao.declaracoes.forEach((declaracao) => {
|
|
376
|
+
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
377
|
+
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
329
378
|
}
|
|
330
379
|
});
|
|
331
380
|
}
|
|
@@ -333,16 +382,16 @@ ${labelFim}:`;
|
|
|
333
382
|
traduzirDeclaracaoEnquanto(declaracao) {
|
|
334
383
|
const labelInicio = this.gerarLabel();
|
|
335
384
|
const labelFim = this.gerarLabel();
|
|
336
|
-
this.
|
|
385
|
+
this.textoSaida += `
|
|
337
386
|
${labelInicio}:`;
|
|
338
387
|
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
|
|
339
|
-
this.
|
|
388
|
+
this.textoSaida += `
|
|
340
389
|
cmp ${condicao}, 0
|
|
341
390
|
je ${labelFim}`;
|
|
342
391
|
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
|
|
343
392
|
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
|
|
344
393
|
}
|
|
345
|
-
this.
|
|
394
|
+
this.textoSaida += `
|
|
346
395
|
jmp ${labelInicio}
|
|
347
396
|
${labelFim}:`;
|
|
348
397
|
}
|
|
@@ -354,24 +403,24 @@ ${labelFim}:`;
|
|
|
354
403
|
const labelProximo = this.gerarLabel();
|
|
355
404
|
if (caminho.condicoes && caminho.condicoes[0]) {
|
|
356
405
|
const valorCaso = this.dicionarioConstrutos[caminho.condicoes[0].constructor.name](caminho.condicoes[0]);
|
|
357
|
-
this.
|
|
406
|
+
this.textoSaida += `
|
|
358
407
|
mov rax, ${valorEscolha}
|
|
359
408
|
cmp rax, ${valorCaso}
|
|
360
409
|
jne ${labelProximo}`;
|
|
361
410
|
if (caminho.declaracoes && Array.isArray(caminho.declaracoes)) {
|
|
362
|
-
caminho.declaracoes.forEach((
|
|
363
|
-
if (this.dicionarioDeclaracoes[
|
|
364
|
-
this.dicionarioDeclaracoes[
|
|
411
|
+
caminho.declaracoes.forEach((declaracao) => {
|
|
412
|
+
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
413
|
+
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
365
414
|
}
|
|
366
415
|
});
|
|
367
416
|
}
|
|
368
|
-
this.
|
|
417
|
+
this.textoSaida += `
|
|
369
418
|
jmp ${labelFim}
|
|
370
419
|
${labelProximo}:`;
|
|
371
420
|
}
|
|
372
421
|
});
|
|
373
422
|
}
|
|
374
|
-
this.
|
|
423
|
+
this.textoSaida += `
|
|
375
424
|
${labelFim}:`;
|
|
376
425
|
}
|
|
377
426
|
traduzirDeclaracaoExpressao(declaracao) {
|
|
@@ -382,19 +431,19 @@ ${labelFim}:`;
|
|
|
382
431
|
}
|
|
383
432
|
traduzirDeclaracaoFazer(declaracao) {
|
|
384
433
|
const labelInicio = this.gerarLabel();
|
|
385
|
-
this.
|
|
434
|
+
this.textoSaida += `
|
|
386
435
|
${labelInicio}:`;
|
|
387
436
|
// Em Delégua, fazer-enquanto tem caminhoFazer que é um Bloco
|
|
388
437
|
if (declaracao.caminhoFazer && declaracao.caminhoFazer.declaracoes) {
|
|
389
|
-
declaracao.caminhoFazer.declaracoes.forEach((
|
|
390
|
-
if (this.dicionarioDeclaracoes[
|
|
391
|
-
this.dicionarioDeclaracoes[
|
|
438
|
+
declaracao.caminhoFazer.declaracoes.forEach((declaracao) => {
|
|
439
|
+
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
440
|
+
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
392
441
|
}
|
|
393
442
|
});
|
|
394
443
|
}
|
|
395
444
|
if (declaracao.condicaoEnquanto) {
|
|
396
445
|
const condicao = this.dicionarioConstrutos[declaracao.condicaoEnquanto.constructor.name](declaracao.condicaoEnquanto);
|
|
397
|
-
this.
|
|
446
|
+
this.textoSaida += `
|
|
398
447
|
cmp ${condicao}, 0
|
|
399
448
|
jne ${labelInicio}`;
|
|
400
449
|
}
|
|
@@ -410,14 +459,14 @@ ${labelInicio}:`;
|
|
|
410
459
|
}
|
|
411
460
|
}
|
|
412
461
|
if (this.alvo === 'linux') {
|
|
413
|
-
this.
|
|
462
|
+
this.textoSaida += `
|
|
414
463
|
; Falhar com mensagem: ${mensagem}
|
|
415
464
|
mov eax, 1
|
|
416
465
|
mov ebx, 1
|
|
417
466
|
int 0x80`;
|
|
418
467
|
}
|
|
419
468
|
else {
|
|
420
|
-
this.
|
|
469
|
+
this.textoSaida += `
|
|
421
470
|
; Falhar com mensagem: ${mensagem}
|
|
422
471
|
mov eax, 1
|
|
423
472
|
ret`;
|
|
@@ -426,7 +475,7 @@ ${labelInicio}:`;
|
|
|
426
475
|
traduzirDeclaracaoFuncao(declaracao) {
|
|
427
476
|
var _a;
|
|
428
477
|
const nomeFuncao = ((_a = declaracao.simbolo) === null || _a === void 0 ? void 0 : _a.lexema) || 'funcao';
|
|
429
|
-
this.
|
|
478
|
+
this.textoSaida += `
|
|
430
479
|
${nomeFuncao}:
|
|
431
480
|
push rbp
|
|
432
481
|
mov rbp, rsp`;
|
|
@@ -439,13 +488,13 @@ ${nomeFuncao}:
|
|
|
439
488
|
}
|
|
440
489
|
});
|
|
441
490
|
}
|
|
442
|
-
this.
|
|
491
|
+
this.textoSaida += `
|
|
443
492
|
pop rbp
|
|
444
493
|
ret`;
|
|
445
494
|
}
|
|
446
495
|
traduzirDeclaracaoImportar(declaracao) {
|
|
447
496
|
// Importação é tratada em tempo de linkagem
|
|
448
|
-
this.
|
|
497
|
+
this.textoSaida += `
|
|
449
498
|
; Importar: ${declaracao.caminho || 'unknown'}`;
|
|
450
499
|
}
|
|
451
500
|
traduzirDeclaracaoLeia(declaracao) {
|
|
@@ -463,7 +512,7 @@ ${nomeFuncao}:
|
|
|
463
512
|
this.bss += ` ${varLabel} resb 256\n`;
|
|
464
513
|
this.variaveis.set(nomeVar, varLabel);
|
|
465
514
|
}
|
|
466
|
-
this.
|
|
515
|
+
this.textoSaida += `
|
|
467
516
|
mov eax, 3
|
|
468
517
|
mov ebx, 0
|
|
469
518
|
mov ecx, ${this.variaveis.get(nomeVar)}
|
|
@@ -473,21 +522,31 @@ ${nomeFuncao}:
|
|
|
473
522
|
traduzirDeclaracaoPara(declaracao) {
|
|
474
523
|
const labelInicio = this.gerarLabel();
|
|
475
524
|
const labelFim = this.gerarLabel();
|
|
476
|
-
// Inicializador pode ser uma declaração ou construto
|
|
525
|
+
// Inicializador pode ser um array de declarações, uma declaração ou um construto
|
|
477
526
|
if (declaracao.inicializador) {
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
527
|
+
if (Array.isArray(declaracao.inicializador)) {
|
|
528
|
+
for (const decl of declaracao.inicializador) {
|
|
529
|
+
const tipo = decl.constructor.name;
|
|
530
|
+
if (this.dicionarioDeclaracoes[tipo]) {
|
|
531
|
+
this.dicionarioDeclaracoes[tipo](decl);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
481
534
|
}
|
|
482
|
-
else
|
|
483
|
-
|
|
535
|
+
else {
|
|
536
|
+
const tipoInicializador = declaracao.inicializador.constructor.name;
|
|
537
|
+
if (this.dicionarioDeclaracoes[tipoInicializador]) {
|
|
538
|
+
this.dicionarioDeclaracoes[tipoInicializador](declaracao.inicializador);
|
|
539
|
+
}
|
|
540
|
+
else if (this.dicionarioConstrutos[tipoInicializador]) {
|
|
541
|
+
this.dicionarioConstrutos[tipoInicializador](declaracao.inicializador);
|
|
542
|
+
}
|
|
484
543
|
}
|
|
485
544
|
}
|
|
486
|
-
this.
|
|
545
|
+
this.textoSaida += `
|
|
487
546
|
${labelInicio}:`;
|
|
488
547
|
if (declaracao.condicao) {
|
|
489
548
|
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
|
|
490
|
-
this.
|
|
549
|
+
this.textoSaida += `
|
|
491
550
|
cmp ${condicao}, 0
|
|
492
551
|
je ${labelFim}`;
|
|
493
552
|
}
|
|
@@ -499,14 +558,14 @@ ${labelInicio}:`;
|
|
|
499
558
|
this.dicionarioConstrutos[declaracao.incrementar.constructor.name](declaracao.incrementar);
|
|
500
559
|
}
|
|
501
560
|
}
|
|
502
|
-
this.
|
|
561
|
+
this.textoSaida += `
|
|
503
562
|
jmp ${labelInicio}
|
|
504
563
|
${labelFim}:`;
|
|
505
564
|
}
|
|
506
565
|
traduzirDeclaracaoParaCada(declaracao) {
|
|
507
566
|
var _a;
|
|
508
|
-
const
|
|
509
|
-
const
|
|
567
|
+
const rotuloInicio = this.gerarLabel();
|
|
568
|
+
const rotuloFim = this.gerarLabel();
|
|
510
569
|
let nomeVar;
|
|
511
570
|
if (declaracao.variavelIteracao instanceof construtos_1.Variavel) {
|
|
512
571
|
nomeVar = (_a = declaracao.variavelIteracao.simbolo) === null || _a === void 0 ? void 0 : _a.lexema;
|
|
@@ -516,63 +575,63 @@ ${labelFim}:`;
|
|
|
516
575
|
if (vetor instanceof construtos_1.Vetor) {
|
|
517
576
|
tamanhoVetor = vetor.tamanho || 0;
|
|
518
577
|
}
|
|
519
|
-
this.
|
|
578
|
+
this.textoSaida += `
|
|
520
579
|
xor rcx, rcx
|
|
521
|
-
${
|
|
580
|
+
${rotuloInicio}:
|
|
522
581
|
cmp rcx, ${tamanhoVetor}
|
|
523
|
-
jge ${
|
|
582
|
+
jge ${rotuloFim}`;
|
|
524
583
|
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
|
|
525
584
|
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
|
|
526
585
|
}
|
|
527
|
-
this.
|
|
586
|
+
this.textoSaida += `
|
|
528
587
|
inc rcx
|
|
529
|
-
jmp ${
|
|
530
|
-
${
|
|
588
|
+
jmp ${rotuloInicio}
|
|
589
|
+
${rotuloFim}:`;
|
|
531
590
|
}
|
|
532
591
|
traduzirDeclaracaoRetorna(declaracao) {
|
|
533
592
|
if (declaracao.valor) {
|
|
534
593
|
const valor = this.dicionarioConstrutos[declaracao.valor.constructor.name](declaracao.valor);
|
|
535
|
-
this.
|
|
594
|
+
this.textoSaida += `
|
|
536
595
|
mov rax, ${valor}`;
|
|
537
596
|
}
|
|
538
|
-
this.
|
|
597
|
+
this.textoSaida += `
|
|
539
598
|
pop rbp
|
|
540
599
|
ret`;
|
|
541
600
|
}
|
|
542
601
|
traduzirDeclaracaoSe(declaracao) {
|
|
543
|
-
const
|
|
544
|
-
const
|
|
602
|
+
const rotuloSenao = this.gerarLabel();
|
|
603
|
+
const rotuloFim = this.gerarLabel();
|
|
545
604
|
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
|
|
546
|
-
this.
|
|
605
|
+
this.textoSaida += `
|
|
547
606
|
cmp ${condicao}, 0
|
|
548
|
-
je ${
|
|
607
|
+
je ${rotuloSenao}`;
|
|
549
608
|
if (this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name]) {
|
|
550
609
|
this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name](declaracao.caminhoEntao);
|
|
551
610
|
}
|
|
552
|
-
this.
|
|
553
|
-
jmp ${
|
|
554
|
-
${
|
|
611
|
+
this.textoSaida += `
|
|
612
|
+
jmp ${rotuloFim}
|
|
613
|
+
${rotuloSenao}:`;
|
|
555
614
|
if (declaracao.caminhoSenao &&
|
|
556
615
|
this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name]) {
|
|
557
616
|
this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name](declaracao.caminhoSenao);
|
|
558
617
|
}
|
|
559
|
-
this.
|
|
560
|
-
${
|
|
618
|
+
this.textoSaida += `
|
|
619
|
+
${rotuloFim}:`;
|
|
561
620
|
}
|
|
562
621
|
traduzirDeclaracaoClasse(declaracao) {
|
|
563
622
|
var _a;
|
|
564
623
|
// Classes em assembly são complexas - implementação básica
|
|
565
|
-
this.
|
|
624
|
+
this.textoSaida += `
|
|
566
625
|
; Classe: ${((_a = declaracao.simbolo) === null || _a === void 0 ? void 0 : _a.lexema) || 'unknown'}`;
|
|
567
626
|
}
|
|
568
627
|
traduzirDeclaracaoTente(declaracao) {
|
|
569
628
|
// Try-catch em assembly requer handler complexo
|
|
570
|
-
this.
|
|
629
|
+
this.textoSaida += `
|
|
571
630
|
; Tente-pegue`;
|
|
572
631
|
if (declaracao.caminhoTente && Array.isArray(declaracao.caminhoTente)) {
|
|
573
|
-
declaracao.caminhoTente.forEach((
|
|
574
|
-
if (this.dicionarioDeclaracoes[
|
|
575
|
-
this.dicionarioDeclaracoes[
|
|
632
|
+
declaracao.caminhoTente.forEach((declaracao) => {
|
|
633
|
+
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
634
|
+
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
576
635
|
}
|
|
577
636
|
});
|
|
578
637
|
}
|
|
@@ -606,7 +665,7 @@ ${labelFim}:`;
|
|
|
606
665
|
}
|
|
607
666
|
else if (this.dicionarioConstrutos[tipoInicializador]) {
|
|
608
667
|
const valor = this.dicionarioConstrutos[tipoInicializador](declaracao.inicializador);
|
|
609
|
-
this.
|
|
668
|
+
this.textoSaida += `
|
|
610
669
|
mov rax, ${valor}
|
|
611
670
|
mov [${varLabel}], rax`;
|
|
612
671
|
}
|
|
@@ -622,39 +681,89 @@ ${labelFim}:`;
|
|
|
622
681
|
this.data += ` ${varTamanho} equ $ - ${nomeStringLiteral}\n`;
|
|
623
682
|
return varTamanho;
|
|
624
683
|
}
|
|
684
|
+
emitirHelperPrintInt() {
|
|
685
|
+
if (this.helperPrintIntEmitido)
|
|
686
|
+
return;
|
|
687
|
+
this.helperPrintIntEmitido = true;
|
|
688
|
+
this.bss += ` __print_buf resb 24\n`;
|
|
689
|
+
this.helpers += `
|
|
690
|
+
__delegua_print_int:
|
|
691
|
+
push rbx
|
|
692
|
+
push rcx
|
|
693
|
+
push rdx
|
|
694
|
+
push rsi
|
|
695
|
+
mov rcx, 10
|
|
696
|
+
lea rsi, [__print_buf + 22]
|
|
697
|
+
mov byte [rsi], 10
|
|
698
|
+
.print_digitloop:
|
|
699
|
+
xor rdx, rdx
|
|
700
|
+
div rcx
|
|
701
|
+
add dl, '0'
|
|
702
|
+
dec rsi
|
|
703
|
+
mov [rsi], dl
|
|
704
|
+
test rax, rax
|
|
705
|
+
jnz .print_digitloop
|
|
706
|
+
lea rdx, [__print_buf + 23]
|
|
707
|
+
sub rdx, rsi
|
|
708
|
+
mov ecx, esi
|
|
709
|
+
mov ebx, 1
|
|
710
|
+
mov eax, 4
|
|
711
|
+
int 0x80
|
|
712
|
+
pop rsi
|
|
713
|
+
pop rdx
|
|
714
|
+
pop rcx
|
|
715
|
+
pop rbx
|
|
716
|
+
ret`;
|
|
717
|
+
}
|
|
625
718
|
traduzirDeclaracaoEscreva(declaracaoEscreva) {
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
if (this.alvo === 'linux') {
|
|
633
|
-
this.text += `
|
|
719
|
+
const arg = declaracaoEscreva.argumentos[0];
|
|
720
|
+
if (arg instanceof construtos_1.Literal) {
|
|
721
|
+
const nome_string_literal = this.criaStringLiteral(arg);
|
|
722
|
+
const tam_string_literal = this.criaTamanhoNaMemoriaReferenteAVar(nome_string_literal);
|
|
723
|
+
if (this.alvo === 'linux') {
|
|
724
|
+
this.textoSaida += `
|
|
634
725
|
mov edx, ${tam_string_literal}
|
|
635
726
|
mov ecx, ${nome_string_literal}
|
|
636
727
|
mov ebx, 1 ; fd stdout
|
|
637
728
|
mov eax, 4 ; sys_write
|
|
638
729
|
int 0x80`;
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
this.textoSaida += `
|
|
733
|
+
lea rcx, [rel ${nome_string_literal}]
|
|
734
|
+
call printf`;
|
|
735
|
+
}
|
|
639
736
|
}
|
|
640
737
|
else {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
738
|
+
const valor = this.dicionarioConstrutos[arg.constructor.name](arg);
|
|
739
|
+
if (this.alvo === 'linux') {
|
|
740
|
+
this.emitirHelperPrintInt();
|
|
741
|
+
this.textoSaida += `
|
|
742
|
+
mov rax, ${valor}
|
|
743
|
+
call __delegua_print_int`;
|
|
744
|
+
}
|
|
745
|
+
else {
|
|
746
|
+
if (!this.fmtIntWindowsEmitido) {
|
|
747
|
+
this.data += ` __fmt_int db '%d', 10, 0\n`;
|
|
748
|
+
this.fmtIntWindowsEmitido = true;
|
|
749
|
+
}
|
|
750
|
+
this.textoSaida += `
|
|
751
|
+
mov rdx, ${valor}
|
|
752
|
+
lea rcx, [rel __fmt_int]
|
|
645
753
|
call printf`;
|
|
754
|
+
}
|
|
646
755
|
}
|
|
647
756
|
}
|
|
648
757
|
saidaSistema() {
|
|
649
758
|
if (this.alvo === 'linux') {
|
|
650
|
-
this.
|
|
759
|
+
this.textoSaida += `
|
|
651
760
|
mov eax, 1 ; sys_exit
|
|
652
761
|
xor ebx, ebx ; status 0
|
|
653
762
|
int 0x80`;
|
|
654
763
|
}
|
|
655
764
|
else {
|
|
656
765
|
// Windows: return from main with 0 in EAX
|
|
657
|
-
this.
|
|
766
|
+
this.textoSaida += `
|
|
658
767
|
xor eax, eax
|
|
659
768
|
ret`;
|
|
660
769
|
}
|
|
@@ -668,7 +777,8 @@ ${labelFim}:`;
|
|
|
668
777
|
}
|
|
669
778
|
}
|
|
670
779
|
this.saidaSistema();
|
|
671
|
-
|
|
780
|
+
this.textoSaida += this.helpers;
|
|
781
|
+
resultado += this.bss + '\n' + this.data + '\n' + this.textoSaida;
|
|
672
782
|
return resultado;
|
|
673
783
|
}
|
|
674
784
|
}
|