@designliquido/delegua 0.61.3 → 0.63.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/README.md +17 -9
- package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
- package/analisador-semantico/analisador-semantico.js +22 -24
- package/analisador-semantico/analisador-semantico.js.map +1 -1
- package/avaliador-sintatico/avaliador-sintatico.js +7 -7
- package/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
- package/avaliador-sintatico/comum.js +11 -10
- package/avaliador-sintatico/comum.js.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts +13 -2
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +43 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.d.ts.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.js +32 -34
- package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.js.map +1 -1
- package/bibliotecas/biblioteca-global.d.ts.map +1 -1
- package/bibliotecas/biblioteca-global.js +11 -13
- package/bibliotecas/biblioteca-global.js.map +1 -1
- package/bibliotecas/dialetos/egua-classico/biblioteca-global.js +9 -9
- package/bibliotecas/dialetos/egua-classico/biblioteca-global.js.map +1 -1
- package/bibliotecas/dialetos/pitugues/biblioteca-global.d.ts.map +1 -1
- package/bibliotecas/dialetos/pitugues/biblioteca-global.js +9 -11
- package/bibliotecas/dialetos/pitugues/biblioteca-global.js.map +1 -1
- package/bin/package.json +1 -1
- package/formatadores/formatador-delegua.js +1 -1
- package/formatadores/formatador-delegua.js.map +1 -1
- package/interfaces/retornos/retorno-lexador.d.ts +2 -2
- package/interfaces/retornos/retorno-lexador.d.ts.map +1 -1
- package/interpretador/dialetos/pitugues/comum.js +2 -2
- package/interpretador/dialetos/pitugues/comum.js.map +1 -1
- package/interpretador/interpretador-base.js +10 -10
- package/interpretador/interpretador-base.js.map +1 -1
- package/interpretador/interpretador.d.ts.map +1 -1
- package/interpretador/interpretador.js +7 -8
- package/interpretador/interpretador.js.map +1 -1
- package/lexador/dialetos/lexador-pitugues.d.ts +3 -3
- package/lexador/dialetos/lexador-pitugues.d.ts.map +1 -1
- package/lexador/dialetos/lexador-pitugues.js +7 -6
- package/lexador/dialetos/lexador-pitugues.js.map +1 -1
- package/lexador/dialetos/lexador-tenda.d.ts +2 -2
- package/lexador/dialetos/lexador-tenda.d.ts.map +1 -1
- package/lexador/dialetos/localizacao.d.ts +9 -0
- package/lexador/dialetos/localizacao.d.ts.map +1 -0
- package/lexador/dialetos/{pragma.js → localizacao.js} +1 -1
- package/lexador/dialetos/localizacao.js.map +1 -0
- 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/mermaid/aresta-fluxograma.d.ts +7 -0
- package/tradutores/mermaid/aresta-fluxograma.d.ts.map +1 -0
- package/tradutores/mermaid/aresta-fluxograma.js +11 -0
- package/tradutores/mermaid/aresta-fluxograma.js.map +1 -0
- package/tradutores/mermaid/diagrama-classe.d.ts +16 -0
- package/tradutores/mermaid/diagrama-classe.d.ts.map +1 -0
- package/tradutores/mermaid/diagrama-classe.js +33 -0
- package/tradutores/mermaid/diagrama-classe.js.map +1 -0
- package/tradutores/mermaid/index.d.ts +5 -0
- package/tradutores/mermaid/index.d.ts.map +1 -0
- package/tradutores/mermaid/index.js +21 -0
- package/tradutores/mermaid/index.js.map +1 -0
- package/tradutores/mermaid/subgrafo-classe.d.ts +14 -0
- package/tradutores/mermaid/subgrafo-classe.d.ts.map +1 -0
- package/tradutores/mermaid/subgrafo-classe.js +45 -0
- package/tradutores/mermaid/subgrafo-classe.js.map +1 -0
- package/tradutores/mermaid/vertice-fluxograma.d.ts +9 -0
- package/tradutores/mermaid/vertice-fluxograma.d.ts.map +1 -0
- package/tradutores/mermaid/vertice-fluxograma.js +16 -0
- package/tradutores/mermaid/vertice-fluxograma.js.map +1 -0
- package/tradutores/tradutor-assembly-arm.d.ts +98 -0
- package/tradutores/tradutor-assembly-arm.d.ts.map +1 -0
- package/tradutores/tradutor-assembly-arm.js +715 -0
- package/tradutores/tradutor-assembly-arm.js.map +1 -0
- package/tradutores/tradutor-assembly-x64.d.ts +82 -4
- package/tradutores/tradutor-assembly-x64.d.ts.map +1 -1
- package/tradutores/tradutor-assembly-x64.js +612 -87
- package/tradutores/tradutor-assembly-x64.js.map +1 -1
- package/tradutores/tradutor-mermaidjs.d.ts +10 -16
- package/tradutores/tradutor-mermaidjs.d.ts.map +1 -1
- package/tradutores/tradutor-mermaidjs.js +107 -43
- package/tradutores/tradutor-mermaidjs.js.map +1 -1
- package/umd/delegua.js +1998 -378
- package/lexador/dialetos/pragma.d.ts +0 -9
- package/lexador/dialetos/pragma.d.ts.map +0 -1
- package/lexador/dialetos/pragma.js.map +0 -1
|
@@ -4,55 +4,65 @@ exports.TradutorAssemblyX64 = void 0;
|
|
|
4
4
|
const construtos_1 = require("../construtos");
|
|
5
5
|
const declaracoes_1 = require("../declaracoes");
|
|
6
6
|
class TradutorAssemblyX64 {
|
|
7
|
-
constructor() {
|
|
7
|
+
constructor(alvo = 'linux') {
|
|
8
|
+
this.alvo = alvo;
|
|
8
9
|
this.indentacao = 0;
|
|
10
|
+
this.contadorLabels = 0;
|
|
11
|
+
this.variaveis = new Map();
|
|
12
|
+
this.registradoresDisponiveis = ['rbx', 'r12', 'r13', 'r14', 'r15'];
|
|
13
|
+
this.pilhaRegistradores = [];
|
|
9
14
|
this.bss = 'section .bss\n';
|
|
10
15
|
this.data = 'section .data\n';
|
|
11
|
-
this.text = `
|
|
12
|
-
section .text
|
|
13
|
-
global _start
|
|
14
|
-
|
|
15
|
-
_start:`;
|
|
16
16
|
this.dicionarioConstrutos = {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
17
|
+
AcessoIndiceVariavel: this.traduzirAcessoIndiceVariavel.bind(this),
|
|
18
|
+
AcessoMetodoOuPropriedade: this.trazudirConstrutoAcessoMetodo.bind(this),
|
|
19
|
+
Agrupamento: this.traduzirConstrutoAgrupamento.bind(this),
|
|
20
|
+
AtribuicaoPorIndice: this.traduzirConstrutoAtribuicaoPorIndice.bind(this),
|
|
21
|
+
Atribuir: this.traduzirConstrutoAtribuir.bind(this),
|
|
22
|
+
Binario: this.traduzirConstrutoBinario.bind(this),
|
|
23
|
+
Chamada: this.traduzirConstrutoChamada.bind(this),
|
|
24
|
+
DefinirValor: this.traduzirConstrutoDefinirValor.bind(this),
|
|
25
|
+
FuncaoConstruto: this.traduzirFuncaoConstruto.bind(this),
|
|
26
|
+
Isto: () => 'this',
|
|
27
|
+
Literal: this.traduzirConstrutoLiteral.bind(this),
|
|
28
|
+
Logico: this.traduzirConstrutoLogico.bind(this),
|
|
29
|
+
TipoDe: this.traduzirConstrutoTipoDe.bind(this),
|
|
30
|
+
Unario: this.traduzirConstrutoUnario.bind(this),
|
|
31
|
+
Variavel: this.traduzirConstrutoVariavel.bind(this),
|
|
32
|
+
Vetor: this.traduzirConstrutoVetor.bind(this),
|
|
33
33
|
};
|
|
34
34
|
this.dicionarioDeclaracoes = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
35
|
+
Bloco: this.traduzirDeclaracaoBloco.bind(this),
|
|
36
|
+
Enquanto: this.traduzirDeclaracaoEnquanto.bind(this),
|
|
37
|
+
Continua: () => 'continue',
|
|
38
|
+
Escolha: this.traduzirDeclaracaoEscolha.bind(this),
|
|
39
|
+
Expressao: this.traduzirDeclaracaoExpressao.bind(this),
|
|
40
|
+
Fazer: this.traduzirDeclaracaoFazer.bind(this),
|
|
41
|
+
Falhar: this.traduzirDeclaracaoFalhar.bind(this),
|
|
42
|
+
FuncaoDeclaracao: this.traduzirDeclaracaoFuncao.bind(this),
|
|
43
|
+
Importar: this.traduzirDeclaracaoImportar.bind(this),
|
|
44
|
+
Leia: this.traduzirDeclaracaoLeia.bind(this),
|
|
45
|
+
Para: this.traduzirDeclaracaoPara.bind(this),
|
|
46
|
+
ParaCada: this.traduzirDeclaracaoParaCada.bind(this),
|
|
47
|
+
Retorna: this.traduzirDeclaracaoRetorna.bind(this),
|
|
48
|
+
Se: this.traduzirDeclaracaoSe.bind(this),
|
|
49
|
+
Sustar: () => 'break',
|
|
50
|
+
Classe: this.traduzirDeclaracaoClasse.bind(this),
|
|
51
|
+
Tente: this.traduzirDeclaracaoTente.bind(this),
|
|
52
|
+
Const: this.traduzirDeclaracaoConst.bind(this),
|
|
53
|
+
Var: this.traduzirDeclaracaoVar.bind(this),
|
|
54
54
|
Escreva: this.traduzirDeclaracaoEscreva.bind(this),
|
|
55
55
|
};
|
|
56
|
+
this.indentacao = 0;
|
|
57
|
+
this.text = `
|
|
58
|
+
section .text
|
|
59
|
+
${this.alvo === 'linux' ? 'global _start' : 'global main'}
|
|
60
|
+
${this.alvo === 'linux' ? '_start:' : 'main:'}`;
|
|
61
|
+
if (this.alvo === 'windows') {
|
|
62
|
+
this.text = `
|
|
63
|
+
extern printf
|
|
64
|
+
` + this.text;
|
|
65
|
+
}
|
|
56
66
|
}
|
|
57
67
|
gerarDigitoAleatorio() {
|
|
58
68
|
let result = '';
|
|
@@ -63,38 +73,536 @@ _start:`;
|
|
|
63
73
|
}
|
|
64
74
|
return result;
|
|
65
75
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
76
|
+
gerarLabel() {
|
|
77
|
+
return `L${this.contadorLabels++}`;
|
|
78
|
+
}
|
|
79
|
+
obterRegistrador() {
|
|
80
|
+
if (this.registradoresDisponiveis.length > 0) {
|
|
81
|
+
const reg = this.registradoresDisponiveis.pop();
|
|
82
|
+
this.pilhaRegistradores.push(reg);
|
|
83
|
+
return reg;
|
|
84
|
+
}
|
|
85
|
+
return 'rax'; // fallback
|
|
86
|
+
}
|
|
87
|
+
liberarRegistrador(reg) {
|
|
88
|
+
const index = this.pilhaRegistradores.indexOf(reg);
|
|
89
|
+
if (index > -1) {
|
|
90
|
+
this.pilhaRegistradores.splice(index, 1);
|
|
91
|
+
this.registradoresDisponiveis.push(reg);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Implementação dos Construtos
|
|
95
|
+
traduzirAcessoIndiceVariavel(construto) {
|
|
96
|
+
var _a;
|
|
97
|
+
let nomeVar;
|
|
98
|
+
if (construto.entidadeChamada instanceof construtos_1.Variavel) {
|
|
99
|
+
nomeVar = (_a = construto.entidadeChamada.simbolo) === null || _a === void 0 ? void 0 : _a.lexema;
|
|
100
|
+
}
|
|
101
|
+
if (!nomeVar) {
|
|
102
|
+
nomeVar = 'unknown';
|
|
103
|
+
}
|
|
104
|
+
const indice = this.dicionarioConstrutos[construto.indice.constructor.name](construto.indice);
|
|
105
|
+
return `[${nomeVar} + ${indice} * 8]`;
|
|
106
|
+
}
|
|
107
|
+
trazudirConstrutoAcessoMetodo(construto) {
|
|
108
|
+
const objeto = this.dicionarioConstrutos[construto.objeto.constructor.name](construto.objeto);
|
|
109
|
+
return `${objeto}.${construto.nomeMetodo}`;
|
|
110
|
+
}
|
|
111
|
+
traduzirConstrutoAgrupamento(construto) {
|
|
112
|
+
return this.dicionarioConstrutos[construto.expressao.constructor.name](construto.expressao);
|
|
113
|
+
}
|
|
114
|
+
traduzirConstrutoAtribuicaoPorIndice(construto) {
|
|
115
|
+
var _a;
|
|
116
|
+
let nomeVar;
|
|
117
|
+
if (construto.objeto instanceof construtos_1.Variavel) {
|
|
118
|
+
nomeVar = (_a = construto.objeto.simbolo) === null || _a === void 0 ? void 0 : _a.lexema;
|
|
119
|
+
}
|
|
120
|
+
if (!nomeVar) {
|
|
121
|
+
nomeVar = 'unknown';
|
|
122
|
+
}
|
|
123
|
+
const indice = this.dicionarioConstrutos[construto.indice.constructor.name](construto.indice);
|
|
124
|
+
const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
125
|
+
this.text += `
|
|
126
|
+
mov rax, ${valor}
|
|
127
|
+
mov [${nomeVar} + ${indice} * 8], rax`;
|
|
128
|
+
}
|
|
129
|
+
traduzirConstrutoAtribuir(construto) {
|
|
130
|
+
var _a;
|
|
131
|
+
// Atribuir tem a estrutura: { alvo, valor }
|
|
132
|
+
let nomeVar;
|
|
133
|
+
if (construto.alvo instanceof construtos_1.Variavel) {
|
|
134
|
+
nomeVar = (_a = construto.alvo.simbolo) === null || _a === void 0 ? void 0 : _a.lexema;
|
|
135
|
+
}
|
|
136
|
+
if (!nomeVar) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
140
|
+
if (!this.variaveis.has(nomeVar)) {
|
|
141
|
+
const varLabel = `var_${nomeVar}`;
|
|
142
|
+
this.bss += ` ${varLabel} resq 1\n`;
|
|
143
|
+
this.variaveis.set(nomeVar, varLabel);
|
|
144
|
+
}
|
|
145
|
+
this.text += `
|
|
146
|
+
mov rax, ${valor}
|
|
147
|
+
mov [${this.variaveis.get(nomeVar)}], rax`;
|
|
148
|
+
}
|
|
149
|
+
traduzirConstrutoBinario(construto) {
|
|
150
|
+
const esquerda = this.dicionarioConstrutos[construto.esquerda.constructor.name](construto.esquerda);
|
|
151
|
+
const direita = this.dicionarioConstrutos[construto.direita.constructor.name](construto.direita);
|
|
152
|
+
const operador = construto.operador.lexema;
|
|
153
|
+
const reg = this.obterRegistrador();
|
|
154
|
+
this.text += `
|
|
155
|
+
mov rax, ${esquerda}
|
|
156
|
+
mov ${reg}, ${direita}`;
|
|
157
|
+
switch (operador) {
|
|
158
|
+
case '+':
|
|
159
|
+
this.text += `
|
|
160
|
+
add rax, ${reg}`;
|
|
161
|
+
break;
|
|
162
|
+
case '-':
|
|
163
|
+
this.text += `
|
|
164
|
+
sub rax, ${reg}`;
|
|
165
|
+
break;
|
|
166
|
+
case '*':
|
|
167
|
+
this.text += `
|
|
168
|
+
imul rax, ${reg}`;
|
|
169
|
+
break;
|
|
170
|
+
case '/':
|
|
171
|
+
this.text += `
|
|
172
|
+
xor rdx, rdx
|
|
173
|
+
idiv ${reg}`;
|
|
174
|
+
break;
|
|
175
|
+
case '%':
|
|
176
|
+
this.text += `
|
|
177
|
+
xor rdx, rdx
|
|
178
|
+
idiv ${reg}
|
|
179
|
+
mov rax, rdx`;
|
|
180
|
+
break;
|
|
181
|
+
default:
|
|
182
|
+
this.text += `
|
|
183
|
+
; Operador ${operador} não implementado`;
|
|
184
|
+
}
|
|
185
|
+
this.liberarRegistrador(reg);
|
|
186
|
+
return 'rax';
|
|
187
|
+
}
|
|
188
|
+
traduzirConstrutoChamada(construto) {
|
|
189
|
+
var _a;
|
|
190
|
+
let nomeFuncao = 'funcao';
|
|
191
|
+
if (construto.entidadeChamada instanceof construtos_1.Variavel) {
|
|
192
|
+
nomeFuncao = ((_a = construto.entidadeChamada.simbolo) === null || _a === void 0 ? void 0 : _a.lexema) || 'funcao';
|
|
193
|
+
}
|
|
194
|
+
// Preparar argumentos (convenção de chamada System V AMD64)
|
|
195
|
+
const registrosArgs = this.alvo === 'linux'
|
|
196
|
+
? ['rdi', 'rsi', 'rdx', 'rcx', 'r8', 'r9'] // System V AMD64 [web:8]
|
|
197
|
+
: ['rcx', 'rdx', 'r8', 'r9']; // Windows x64 [web:2]
|
|
198
|
+
construto.argumentos.forEach((arg, index) => {
|
|
199
|
+
if (index < registrosArgs.length) {
|
|
200
|
+
const valorArg = this.dicionarioConstrutos[arg.constructor.name](arg);
|
|
201
|
+
this.text += `
|
|
202
|
+
mov ${registrosArgs[index]}, ${valorArg}`;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
// TODO: push extra args on stack according to target ABI
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
this.text += `
|
|
209
|
+
call ${nomeFuncao}`;
|
|
210
|
+
}
|
|
211
|
+
traduzirConstrutoDefinirValor(construto) {
|
|
212
|
+
const objeto = this.dicionarioConstrutos[construto.objeto.constructor.name](construto.objeto);
|
|
213
|
+
const valor = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
214
|
+
this.text += `
|
|
215
|
+
mov rax, ${valor}
|
|
216
|
+
mov [${objeto}], rax`;
|
|
217
|
+
}
|
|
218
|
+
traduzirFuncaoConstruto(construto) {
|
|
219
|
+
const labelFuncao = `func_${this.gerarDigitoAleatorio()}`;
|
|
220
|
+
this.text += `
|
|
221
|
+
${labelFuncao}:
|
|
222
|
+
push rbp
|
|
223
|
+
mov rbp, rsp`;
|
|
224
|
+
// Traduzir corpo da função
|
|
225
|
+
if (construto.corpo && Array.isArray(construto.corpo)) {
|
|
226
|
+
construto.corpo.forEach((declaracao) => {
|
|
227
|
+
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
228
|
+
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
this.text += `
|
|
233
|
+
pop rbp
|
|
234
|
+
ret`;
|
|
235
|
+
}
|
|
236
|
+
traduzirConstrutoLiteral(construto) {
|
|
237
|
+
if (typeof construto.valor === 'string') {
|
|
238
|
+
return this.criaStringLiteral(construto);
|
|
239
|
+
}
|
|
240
|
+
return String(construto.valor);
|
|
241
|
+
}
|
|
242
|
+
traduzirConstrutoLogico(construto) {
|
|
243
|
+
const esquerda = this.dicionarioConstrutos[construto.esquerda.constructor.name](construto.esquerda);
|
|
244
|
+
const direita = this.dicionarioConstrutos[construto.direita.constructor.name](construto.direita);
|
|
245
|
+
const operador = construto.operador.lexema;
|
|
246
|
+
const labelVerdadeiro = this.gerarLabel();
|
|
247
|
+
const labelFim = this.gerarLabel();
|
|
248
|
+
this.text += `
|
|
249
|
+
mov rax, ${esquerda}
|
|
250
|
+
cmp rax, 0`;
|
|
251
|
+
if (operador === 'e' || operador === '&&') {
|
|
252
|
+
this.text += `
|
|
253
|
+
je ${labelFim}
|
|
254
|
+
mov rax, ${direita}
|
|
255
|
+
cmp rax, 0
|
|
256
|
+
je ${labelFim}
|
|
257
|
+
${labelVerdadeiro}:
|
|
258
|
+
mov rax, 1
|
|
259
|
+
${labelFim}:`;
|
|
260
|
+
}
|
|
261
|
+
else if (operador === 'ou' || operador === '||') {
|
|
262
|
+
this.text += `
|
|
263
|
+
jne ${labelVerdadeiro}
|
|
264
|
+
mov rax, ${direita}
|
|
265
|
+
cmp rax, 0
|
|
266
|
+
jne ${labelVerdadeiro}
|
|
267
|
+
mov rax, 0
|
|
268
|
+
jmp ${labelFim}
|
|
269
|
+
${labelVerdadeiro}:
|
|
270
|
+
mov rax, 1
|
|
271
|
+
${labelFim}:`;
|
|
272
|
+
}
|
|
273
|
+
return 'rax';
|
|
274
|
+
}
|
|
275
|
+
traduzirConstrutoTipoDe(construto) {
|
|
276
|
+
// Simplificado - retorna tipo como número
|
|
277
|
+
const expressao = this.dicionarioConstrutos[construto.valor.constructor.name](construto.valor);
|
|
278
|
+
return expressao;
|
|
279
|
+
}
|
|
280
|
+
traduzirConstrutoUnario(construto) {
|
|
281
|
+
const operando = this.dicionarioConstrutos[construto.operando.constructor.name](construto.operando);
|
|
282
|
+
const operador = construto.operador.lexema;
|
|
283
|
+
this.text += `
|
|
284
|
+
mov rax, ${operando}`;
|
|
285
|
+
if (operador === '-') {
|
|
286
|
+
this.text += `
|
|
287
|
+
neg rax`;
|
|
288
|
+
}
|
|
289
|
+
else if (operador === '!' || operador === 'nao') {
|
|
290
|
+
this.text += `
|
|
291
|
+
cmp rax, 0
|
|
292
|
+
sete al
|
|
293
|
+
movzx rax, al`;
|
|
294
|
+
}
|
|
295
|
+
return 'rax';
|
|
296
|
+
}
|
|
297
|
+
traduzirConstrutoVariavel(construto) {
|
|
298
|
+
var _a;
|
|
299
|
+
const nomeVar = (_a = construto.simbolo) === null || _a === void 0 ? void 0 : _a.lexema;
|
|
300
|
+
if (nomeVar && this.variaveis.has(nomeVar)) {
|
|
301
|
+
return `[${this.variaveis.get(nomeVar)}]`;
|
|
302
|
+
}
|
|
303
|
+
return nomeVar || 'unknown';
|
|
304
|
+
}
|
|
305
|
+
traduzirConstrutoVetor(construto) {
|
|
306
|
+
var _a;
|
|
307
|
+
const labelVetor = `vetor_${this.gerarDigitoAleatorio()}`;
|
|
308
|
+
const tamanho = ((_a = construto.valores) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
309
|
+
this.bss += ` ${labelVetor} resq ${tamanho}\n`;
|
|
310
|
+
if (construto.valores && Array.isArray(construto.valores)) {
|
|
311
|
+
construto.valores.forEach((valor, index) => {
|
|
312
|
+
if (this.dicionarioConstrutos[valor.constructor.name]) {
|
|
313
|
+
const valorTraduzido = this.dicionarioConstrutos[valor.constructor.name](valor);
|
|
314
|
+
this.text += `
|
|
315
|
+
mov rax, ${valorTraduzido}
|
|
316
|
+
mov [${labelVetor} + ${index * 8}], rax`;
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
return labelVetor;
|
|
321
|
+
}
|
|
322
|
+
// Implementação das Declarações
|
|
323
|
+
traduzirDeclaracaoBloco(declaracao) {
|
|
324
|
+
if (declaracao.declaracoes && Array.isArray(declaracao.declaracoes)) {
|
|
325
|
+
declaracao.declaracoes.forEach((decl) => {
|
|
326
|
+
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
|
|
327
|
+
this.dicionarioDeclaracoes[decl.constructor.name](decl);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
traduzirDeclaracaoEnquanto(declaracao) {
|
|
333
|
+
const labelInicio = this.gerarLabel();
|
|
334
|
+
const labelFim = this.gerarLabel();
|
|
335
|
+
this.text += `
|
|
336
|
+
${labelInicio}:`;
|
|
337
|
+
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
|
|
338
|
+
this.text += `
|
|
339
|
+
cmp ${condicao}, 0
|
|
340
|
+
je ${labelFim}`;
|
|
341
|
+
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
|
|
342
|
+
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
|
|
343
|
+
}
|
|
344
|
+
this.text += `
|
|
345
|
+
jmp ${labelInicio}
|
|
346
|
+
${labelFim}:`;
|
|
347
|
+
}
|
|
348
|
+
traduzirDeclaracaoEscolha(declaracao) {
|
|
349
|
+
const labelFim = this.gerarLabel();
|
|
350
|
+
const valorEscolha = this.dicionarioConstrutos[declaracao.identificadorOuLiteral.constructor.name](declaracao.identificadorOuLiteral);
|
|
351
|
+
if (declaracao.caminhos && Array.isArray(declaracao.caminhos)) {
|
|
352
|
+
declaracao.caminhos.forEach((caminho) => {
|
|
353
|
+
const labelProximo = this.gerarLabel();
|
|
354
|
+
if (caminho.condicoes && caminho.condicoes[0]) {
|
|
355
|
+
const valorCaso = this.dicionarioConstrutos[caminho.condicoes[0].constructor.name](caminho.condicoes[0]);
|
|
356
|
+
this.text += `
|
|
357
|
+
mov rax, ${valorEscolha}
|
|
358
|
+
cmp rax, ${valorCaso}
|
|
359
|
+
jne ${labelProximo}`;
|
|
360
|
+
if (caminho.declaracoes && Array.isArray(caminho.declaracoes)) {
|
|
361
|
+
caminho.declaracoes.forEach((decl) => {
|
|
362
|
+
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
|
|
363
|
+
this.dicionarioDeclaracoes[decl.constructor.name](decl);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
this.text += `
|
|
368
|
+
jmp ${labelFim}
|
|
369
|
+
${labelProximo}:`;
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
this.text += `
|
|
374
|
+
${labelFim}:`;
|
|
375
|
+
}
|
|
376
|
+
traduzirDeclaracaoExpressao(declaracao) {
|
|
377
|
+
if (declaracao.expressao && this.dicionarioConstrutos[declaracao.expressao.constructor.name]) {
|
|
378
|
+
this.dicionarioConstrutos[declaracao.expressao.constructor.name](declaracao.expressao);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
traduzirDeclaracaoFazer(declaracao) {
|
|
382
|
+
const labelInicio = this.gerarLabel();
|
|
383
|
+
this.text += `
|
|
384
|
+
${labelInicio}:`;
|
|
385
|
+
// Em Delégua, fazer-enquanto tem caminhoFazer que é um Bloco
|
|
386
|
+
if (declaracao.caminhoFazer && declaracao.caminhoFazer.declaracoes) {
|
|
387
|
+
declaracao.caminhoFazer.declaracoes.forEach((decl) => {
|
|
388
|
+
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
|
|
389
|
+
this.dicionarioDeclaracoes[decl.constructor.name](decl);
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
if (declaracao.condicaoEnquanto) {
|
|
394
|
+
const condicao = this.dicionarioConstrutos[declaracao.condicaoEnquanto.constructor.name](declaracao.condicaoEnquanto);
|
|
395
|
+
this.text += `
|
|
396
|
+
cmp ${condicao}, 0
|
|
397
|
+
jne ${labelInicio}`;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
traduzirDeclaracaoFalhar(declaracao) {
|
|
401
|
+
let mensagem = '"Erro"';
|
|
402
|
+
if (declaracao.explicacao && typeof declaracao.explicacao === 'object' && 'constructor' in declaracao.explicacao) {
|
|
403
|
+
const explicacao = declaracao.explicacao;
|
|
404
|
+
if (explicacao.constructor && this.dicionarioConstrutos[explicacao.constructor.name]) {
|
|
405
|
+
mensagem = this.dicionarioConstrutos[explicacao.constructor.name](explicacao);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (this.alvo === 'linux') {
|
|
409
|
+
this.text += `
|
|
410
|
+
; Falhar com mensagem: ${mensagem}
|
|
411
|
+
mov eax, 1
|
|
412
|
+
mov ebx, 1
|
|
413
|
+
int 0x80`;
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
this.text += `
|
|
417
|
+
; Falhar com mensagem: ${mensagem}
|
|
418
|
+
mov eax, 1
|
|
419
|
+
ret`;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
traduzirDeclaracaoFuncao(declaracao) {
|
|
423
|
+
var _a;
|
|
424
|
+
const nomeFuncao = ((_a = declaracao.simbolo) === null || _a === void 0 ? void 0 : _a.lexema) || 'funcao';
|
|
425
|
+
this.text += `
|
|
426
|
+
${nomeFuncao}:
|
|
427
|
+
push rbp
|
|
428
|
+
mov rbp, rsp`;
|
|
429
|
+
if (declaracao.funcao && declaracao.funcao.corpo && Array.isArray(declaracao.funcao.corpo)) {
|
|
430
|
+
declaracao.funcao.corpo.forEach((decl) => {
|
|
431
|
+
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
|
|
432
|
+
this.dicionarioDeclaracoes[decl.constructor.name](decl);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
this.text += `
|
|
437
|
+
pop rbp
|
|
438
|
+
ret`;
|
|
439
|
+
}
|
|
440
|
+
traduzirDeclaracaoImportar(declaracao) {
|
|
441
|
+
// Importação é tratada em tempo de linkagem
|
|
442
|
+
this.text += `
|
|
443
|
+
; Importar: ${declaracao.caminho || 'unknown'}`;
|
|
444
|
+
}
|
|
445
|
+
traduzirDeclaracaoLeia(declaracao) {
|
|
446
|
+
var _a;
|
|
447
|
+
let nomeVar;
|
|
448
|
+
if (declaracao.argumentos && declaracao.argumentos[0] && declaracao.argumentos[0] instanceof construtos_1.Variavel) {
|
|
449
|
+
nomeVar = (_a = declaracao.argumentos[0].simbolo) === null || _a === void 0 ? void 0 : _a.lexema;
|
|
450
|
+
}
|
|
451
|
+
if (!nomeVar)
|
|
452
|
+
return;
|
|
453
|
+
if (!this.variaveis.has(nomeVar)) {
|
|
454
|
+
const varLabel = `var_${nomeVar}`;
|
|
455
|
+
this.bss += ` ${varLabel} resb 256\n`;
|
|
456
|
+
this.variaveis.set(nomeVar, varLabel);
|
|
457
|
+
}
|
|
458
|
+
this.text += `
|
|
459
|
+
mov eax, 3
|
|
460
|
+
mov ebx, 0
|
|
461
|
+
mov ecx, ${this.variaveis.get(nomeVar)}
|
|
462
|
+
mov edx, 256
|
|
463
|
+
int 0x80`;
|
|
464
|
+
}
|
|
465
|
+
traduzirDeclaracaoPara(declaracao) {
|
|
466
|
+
const labelInicio = this.gerarLabel();
|
|
467
|
+
const labelFim = this.gerarLabel();
|
|
468
|
+
// Inicializador pode ser uma declaração ou construto
|
|
469
|
+
if (declaracao.inicializador) {
|
|
470
|
+
const tipoInicializador = declaracao.inicializador.constructor.name;
|
|
471
|
+
if (this.dicionarioDeclaracoes[tipoInicializador]) {
|
|
472
|
+
this.dicionarioDeclaracoes[tipoInicializador](declaracao.inicializador);
|
|
473
|
+
}
|
|
474
|
+
else if (this.dicionarioConstrutos[tipoInicializador]) {
|
|
475
|
+
this.dicionarioConstrutos[tipoInicializador](declaracao.inicializador);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
this.text += `
|
|
479
|
+
${labelInicio}:`;
|
|
480
|
+
if (declaracao.condicao) {
|
|
481
|
+
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
|
|
482
|
+
this.text += `
|
|
483
|
+
cmp ${condicao}, 0
|
|
484
|
+
je ${labelFim}`;
|
|
485
|
+
}
|
|
486
|
+
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
|
|
487
|
+
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
|
|
488
|
+
}
|
|
489
|
+
if (declaracao.incrementar) {
|
|
490
|
+
if (this.dicionarioConstrutos[declaracao.incrementar.constructor.name]) {
|
|
491
|
+
this.dicionarioConstrutos[declaracao.incrementar.constructor.name](declaracao.incrementar);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
this.text += `
|
|
495
|
+
jmp ${labelInicio}
|
|
496
|
+
${labelFim}:`;
|
|
497
|
+
}
|
|
498
|
+
traduzirDeclaracaoParaCada(declaracao) {
|
|
499
|
+
var _a;
|
|
500
|
+
const labelInicio = this.gerarLabel();
|
|
501
|
+
const labelFim = this.gerarLabel();
|
|
502
|
+
let nomeVar;
|
|
503
|
+
if (declaracao.variavelIteracao instanceof construtos_1.Variavel) {
|
|
504
|
+
nomeVar = (_a = declaracao.variavelIteracao.simbolo) === null || _a === void 0 ? void 0 : _a.lexema;
|
|
505
|
+
}
|
|
506
|
+
const vetor = declaracao.vetorOuDicionario;
|
|
507
|
+
let tamanhoVetor = 0;
|
|
508
|
+
if (vetor instanceof construtos_1.Vetor) {
|
|
509
|
+
tamanhoVetor = vetor.tamanho || 0;
|
|
510
|
+
}
|
|
511
|
+
this.text += `
|
|
512
|
+
xor rcx, rcx
|
|
513
|
+
${labelInicio}:
|
|
514
|
+
cmp rcx, ${tamanhoVetor}
|
|
515
|
+
jge ${labelFim}`;
|
|
516
|
+
if (this.dicionarioDeclaracoes[declaracao.corpo.constructor.name]) {
|
|
517
|
+
this.dicionarioDeclaracoes[declaracao.corpo.constructor.name](declaracao.corpo);
|
|
518
|
+
}
|
|
519
|
+
this.text += `
|
|
520
|
+
inc rcx
|
|
521
|
+
jmp ${labelInicio}
|
|
522
|
+
${labelFim}:`;
|
|
523
|
+
}
|
|
524
|
+
traduzirDeclaracaoRetorna(declaracao) {
|
|
525
|
+
if (declaracao.valor) {
|
|
526
|
+
const valor = this.dicionarioConstrutos[declaracao.valor.constructor.name](declaracao.valor);
|
|
527
|
+
this.text += `
|
|
528
|
+
mov rax, ${valor}`;
|
|
529
|
+
}
|
|
530
|
+
this.text += `
|
|
531
|
+
pop rbp
|
|
532
|
+
ret`;
|
|
533
|
+
}
|
|
534
|
+
traduzirDeclaracaoSe(declaracao) {
|
|
535
|
+
const labelSenao = this.gerarLabel();
|
|
536
|
+
const labelFim = this.gerarLabel();
|
|
537
|
+
const condicao = this.dicionarioConstrutos[declaracao.condicao.constructor.name](declaracao.condicao);
|
|
538
|
+
this.text += `
|
|
539
|
+
cmp ${condicao}, 0
|
|
540
|
+
je ${labelSenao}`;
|
|
541
|
+
if (this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name]) {
|
|
542
|
+
this.dicionarioDeclaracoes[declaracao.caminhoEntao.constructor.name](declaracao.caminhoEntao);
|
|
543
|
+
}
|
|
544
|
+
this.text += `
|
|
545
|
+
jmp ${labelFim}
|
|
546
|
+
${labelSenao}:`;
|
|
547
|
+
if (declaracao.caminhoSenao && this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name]) {
|
|
548
|
+
this.dicionarioDeclaracoes[declaracao.caminhoSenao.constructor.name](declaracao.caminhoSenao);
|
|
549
|
+
}
|
|
550
|
+
this.text += `
|
|
551
|
+
${labelFim}:`;
|
|
552
|
+
}
|
|
553
|
+
traduzirDeclaracaoClasse(declaracao) {
|
|
554
|
+
var _a;
|
|
555
|
+
// Classes em assembly são complexas - implementação básica
|
|
556
|
+
this.text += `
|
|
557
|
+
; Classe: ${((_a = declaracao.simbolo) === null || _a === void 0 ? void 0 : _a.lexema) || 'unknown'}`;
|
|
558
|
+
}
|
|
559
|
+
traduzirDeclaracaoTente(declaracao) {
|
|
560
|
+
// Try-catch em assembly requer handler complexo
|
|
561
|
+
this.text += `
|
|
562
|
+
; Tente-pegue`;
|
|
563
|
+
if (declaracao.caminhoTente && Array.isArray(declaracao.caminhoTente)) {
|
|
564
|
+
declaracao.caminhoTente.forEach((decl) => {
|
|
565
|
+
if (this.dicionarioDeclaracoes[decl.constructor.name]) {
|
|
566
|
+
this.dicionarioDeclaracoes[decl.constructor.name](decl);
|
|
567
|
+
}
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
traduzirDeclaracaoConst(declaracao) {
|
|
572
|
+
var _a;
|
|
573
|
+
const nomeVar = (_a = declaracao.simbolo) === null || _a === void 0 ? void 0 : _a.lexema;
|
|
574
|
+
if (!nomeVar)
|
|
575
|
+
return;
|
|
576
|
+
const valor = this.dicionarioConstrutos[declaracao.inicializador.constructor.name](declaracao.inicializador);
|
|
577
|
+
const varLabel = `const_${nomeVar}`;
|
|
578
|
+
this.data += ` ${varLabel} dq ${valor}\n`;
|
|
579
|
+
this.variaveis.set(nomeVar, varLabel);
|
|
580
|
+
}
|
|
581
|
+
traduzirDeclaracaoVar(declaracao) {
|
|
582
|
+
var _a;
|
|
583
|
+
const nomeVar = (_a = declaracao.simbolo) === null || _a === void 0 ? void 0 : _a.lexema;
|
|
584
|
+
if (!nomeVar)
|
|
585
|
+
return;
|
|
586
|
+
const varLabel = `var_${nomeVar}`;
|
|
587
|
+
this.bss += ` ${varLabel} resq 1\n`;
|
|
588
|
+
this.variaveis.set(nomeVar, varLabel);
|
|
589
|
+
if (declaracao.inicializador) {
|
|
590
|
+
const tipoInicializador = declaracao.inicializador.constructor.name;
|
|
591
|
+
// Verificar se é um vetor
|
|
592
|
+
if (declaracao.inicializador instanceof construtos_1.Vetor) {
|
|
593
|
+
// Vetor precisa de tratamento especial
|
|
594
|
+
const labelVetor = this.traduzirConstrutoVetor(declaracao.inicializador);
|
|
595
|
+
// Associar o nome da variável com o label do vetor
|
|
596
|
+
this.variaveis.set(nomeVar, labelVetor);
|
|
597
|
+
}
|
|
598
|
+
else if (this.dicionarioConstrutos[tipoInicializador]) {
|
|
599
|
+
const valor = this.dicionarioConstrutos[tipoInicializador](declaracao.inicializador);
|
|
600
|
+
this.text += `
|
|
601
|
+
mov rax, ${valor}
|
|
602
|
+
mov [${varLabel}], rax`;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
98
606
|
criaStringLiteral(literal) {
|
|
99
607
|
const varLiteral = `Delegua_${this.gerarDigitoAleatorio()}`;
|
|
100
608
|
this.data += ` ${varLiteral} db '${literal.valor}', 0\n`;
|
|
@@ -102,7 +610,7 @@ _start:`;
|
|
|
102
610
|
}
|
|
103
611
|
criaTamanhoNaMemoriaReferenteAVar(nomeStringLiteral) {
|
|
104
612
|
const varTamanho = `tam_${nomeStringLiteral}`;
|
|
105
|
-
this.data += ` ${varTamanho} equ $ - ${nomeStringLiteral}`;
|
|
613
|
+
this.data += ` ${varTamanho} equ $ - ${nomeStringLiteral}\n`;
|
|
106
614
|
return varTamanho;
|
|
107
615
|
}
|
|
108
616
|
traduzirDeclaracaoEscreva(declaracaoEscreva) {
|
|
@@ -112,29 +620,46 @@ _start:`;
|
|
|
112
620
|
nome_string_literal = this.criaStringLiteral(declaracaoEscreva.argumentos[0]);
|
|
113
621
|
tam_string_literal = this.criaTamanhoNaMemoriaReferenteAVar(nome_string_literal);
|
|
114
622
|
}
|
|
115
|
-
this.
|
|
623
|
+
if (this.alvo === 'linux') {
|
|
624
|
+
this.text += `
|
|
116
625
|
mov edx, ${tam_string_literal}
|
|
117
626
|
mov ecx, ${nome_string_literal}
|
|
118
|
-
mov ebx, 1
|
|
119
|
-
mov eax, 4
|
|
120
|
-
int 0x80
|
|
121
|
-
|
|
627
|
+
mov ebx, 1 ; fd stdout
|
|
628
|
+
mov eax, 4 ; sys_write
|
|
629
|
+
int 0x80`;
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
// Windows: prototype `extern printf` and follow Win64 calling convention
|
|
633
|
+
// RCX = format pointer; here we use the literal directly as a C string
|
|
634
|
+
this.text += `
|
|
635
|
+
lea rcx, [rel ${nome_string_literal}]
|
|
636
|
+
call printf`;
|
|
637
|
+
}
|
|
122
638
|
}
|
|
123
|
-
|
|
124
|
-
this.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
639
|
+
saidaSistema() {
|
|
640
|
+
if (this.alvo === 'linux') {
|
|
641
|
+
this.text += `
|
|
642
|
+
mov eax, 1 ; sys_exit
|
|
643
|
+
xor ebx, ebx ; status 0
|
|
644
|
+
int 0x80`;
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
// Windows: return from main with 0 in EAX
|
|
648
|
+
this.text += `
|
|
649
|
+
xor eax, eax
|
|
650
|
+
ret`;
|
|
651
|
+
}
|
|
128
652
|
}
|
|
129
653
|
traduzir(declaracoes) {
|
|
130
654
|
let resultado = '';
|
|
131
655
|
this.declaracoesDeClasses = declaracoes.filter((declaracao) => declaracao instanceof declaracoes_1.Classe);
|
|
132
656
|
for (const declaracao of declaracoes) {
|
|
133
|
-
|
|
657
|
+
if (this.dicionarioDeclaracoes[declaracao.constructor.name]) {
|
|
658
|
+
this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
|
|
659
|
+
}
|
|
134
660
|
}
|
|
135
|
-
this.
|
|
661
|
+
this.saidaSistema();
|
|
136
662
|
resultado += this.bss + '\n' + this.data + '\n' + this.text;
|
|
137
|
-
console.log(resultado);
|
|
138
663
|
return resultado;
|
|
139
664
|
}
|
|
140
665
|
}
|