@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.
@@ -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.text = `
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.text =
65
+ this.textoSaida =
63
66
  `
64
67
  extern printf
65
- ` + this.text;
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.text += `
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.text += `
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 reg = this.obterRegistrador();
155
- this.text += `
157
+ const registrador = this.obterRegistrador();
158
+ this.textoSaida += `
156
159
  mov rax, ${esquerda}
157
- mov ${reg}, ${direita}`;
160
+ mov ${registrador}, ${direita}`;
158
161
  switch (operador) {
159
162
  case '+':
160
- this.text += `
161
- add rax, ${reg}`;
163
+ this.textoSaida += `
164
+ add rax, ${registrador}`;
162
165
  break;
163
166
  case '-':
164
- this.text += `
165
- sub rax, ${reg}`;
167
+ this.textoSaida += `
168
+ sub rax, ${registrador}`;
166
169
  break;
167
170
  case '*':
168
- this.text += `
169
- imul rax, ${reg}`;
171
+ this.textoSaida += `
172
+ imul rax, ${registrador}`;
170
173
  break;
171
174
  case '/':
172
- this.text += `
175
+ this.textoSaida += `
173
176
  xor rdx, rdx
174
- idiv ${reg}`;
177
+ idiv ${registrador}`;
175
178
  break;
176
179
  case '%':
177
- this.text += `
180
+ this.textoSaida += `
178
181
  xor rdx, rdx
179
- idiv ${reg}
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.text += `
222
+ this.textoSaida += `
184
223
  ; Operador ${operador} não implementado`;
185
224
  }
186
- this.liberarRegistrador(reg);
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.text += `
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.text += `
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.text += `
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.text += `
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.text += `
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.text += `
288
+ this.textoSaida += `
250
289
  mov rax, ${esquerda}
251
290
  cmp rax, 0`;
252
291
  if (operador === 'e' || operador === '&&') {
253
- this.text += `
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.text += `
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.text += `
323
+ this.textoSaida += `
285
324
  mov rax, ${operando}`;
286
325
  if (operador === '-') {
287
- this.text += `
326
+ this.textoSaida += `
288
327
  neg rax`;
289
328
  }
290
329
  else if (operador === '!' || operador === 'nao') {
291
- this.text += `
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 labelVetor = `vetor_${this.gerarDigitoAleatorio()}`;
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 += ` ${labelVetor} resq ${tamanho}\n`;
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.text += `
364
+ this.textoSaida += `
316
365
  mov rax, ${valorTraduzido}
317
- mov [${labelVetor} + ${index * 8}], rax`;
366
+ mov [${rotuloVetor} + ${index * 8}], rax`;
318
367
  }
319
368
  });
320
369
  }
321
- return labelVetor;
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((decl) => {
327
- if (this.dicionarioDeclaracoes[decl.constructor.name]) {
328
- this.dicionarioDeclaracoes[decl.constructor.name](decl);
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.text += `
385
+ this.textoSaida += `
337
386
  ${labelInicio}:`;
338
387
  const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
339
- this.text += `
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.text += `
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.text += `
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((decl) => {
363
- if (this.dicionarioDeclaracoes[decl.constructor.name]) {
364
- this.dicionarioDeclaracoes[decl.constructor.name](decl);
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.text += `
417
+ this.textoSaida += `
369
418
  jmp ${labelFim}
370
419
  ${labelProximo}:`;
371
420
  }
372
421
  });
373
422
  }
374
- this.text += `
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.text += `
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((decl) => {
390
- if (this.dicionarioDeclaracoes[decl.constructor.name]) {
391
- this.dicionarioDeclaracoes[decl.constructor.name](decl);
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.text += `
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.text += `
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.text += `
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.text += `
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.text += `
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.text += `
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.text += `
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
- const tipoInicializador = declaracao.inicializador.constructor.name;
479
- if (this.dicionarioDeclaracoes[tipoInicializador]) {
480
- this.dicionarioDeclaracoes[tipoInicializador](declaracao.inicializador);
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 if (this.dicionarioConstrutos[tipoInicializador]) {
483
- this.dicionarioConstrutos[tipoInicializador](declaracao.inicializador);
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.text += `
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.text += `
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.text += `
561
+ this.textoSaida += `
503
562
  jmp ${labelInicio}
504
563
  ${labelFim}:`;
505
564
  }
506
565
  traduzirDeclaracaoParaCada(declaracao) {
507
566
  var _a;
508
- const labelInicio = this.gerarLabel();
509
- const labelFim = this.gerarLabel();
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.text += `
578
+ this.textoSaida += `
520
579
  xor rcx, rcx
521
- ${labelInicio}:
580
+ ${rotuloInicio}:
522
581
  cmp rcx, ${tamanhoVetor}
523
- jge ${labelFim}`;
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.text += `
586
+ this.textoSaida += `
528
587
  inc rcx
529
- jmp ${labelInicio}
530
- ${labelFim}:`;
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.text += `
594
+ this.textoSaida += `
536
595
  mov rax, ${valor}`;
537
596
  }
538
- this.text += `
597
+ this.textoSaida += `
539
598
  pop rbp
540
599
  ret`;
541
600
  }
542
601
  traduzirDeclaracaoSe(declaracao) {
543
- const labelSenao = this.gerarLabel();
544
- const labelFim = this.gerarLabel();
602
+ const rotuloSenao = this.gerarLabel();
603
+ const rotuloFim = this.gerarLabel();
545
604
  const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
546
- this.text += `
605
+ this.textoSaida += `
547
606
  cmp ${condicao}, 0
548
- je ${labelSenao}`;
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.text += `
553
- jmp ${labelFim}
554
- ${labelSenao}:`;
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.text += `
560
- ${labelFim}:`;
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.text += `
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.text += `
629
+ this.textoSaida += `
571
630
  ; Tente-pegue`;
572
631
  if (declaracao.caminhoTente && Array.isArray(declaracao.caminhoTente)) {
573
- declaracao.caminhoTente.forEach((decl) => {
574
- if (this.dicionarioDeclaracoes[decl.constructor.name]) {
575
- this.dicionarioDeclaracoes[decl.constructor.name](decl);
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.text += `
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
- let tam_string_literal = '';
627
- let nome_string_literal = '';
628
- if (declaracaoEscreva.argumentos[0] instanceof construtos_1.Literal) {
629
- nome_string_literal = this.criaStringLiteral(declaracaoEscreva.argumentos[0]);
630
- tam_string_literal = this.criaTamanhoNaMemoriaReferenteAVar(nome_string_literal);
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
- // Windows: prototype `extern printf` and follow Win64 calling convention
642
- // RCX = format pointer; here we use the literal directly as a C string
643
- this.text += `
644
- lea rcx, [rel ${nome_string_literal}]
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.text += `
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.text += `
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
- resultado += this.bss + '\n' + this.data + '\n' + this.text;
780
+ this.textoSaida += this.helpers;
781
+ resultado += this.bss + '\n' + this.data + '\n' + this.textoSaida;
672
782
  return resultado;
673
783
  }
674
784
  }