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