@designliquido/delegua 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/analisador-semantico/dialetos/analisador-semantico-pitugues.d.ts.map +1 -1
  2. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js +5 -0
  3. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js.map +1 -1
  4. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
  5. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +11 -8
  6. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
  7. package/bibliotecas/biblioteca-global.d.ts +1 -1
  8. package/bibliotecas/biblioteca-global.d.ts.map +1 -1
  9. package/bibliotecas/biblioteca-global.js +3 -17
  10. package/bibliotecas/biblioteca-global.js.map +1 -1
  11. package/bibliotecas/dialetos/pitugues/biblioteca-global.d.ts.map +1 -1
  12. package/bibliotecas/dialetos/pitugues/biblioteca-global.js +8 -6
  13. package/bibliotecas/dialetos/pitugues/biblioteca-global.js.map +1 -1
  14. package/bin/package.json +1 -1
  15. package/interfaces/tradutor-interface.d.ts +1 -1
  16. package/interfaces/tradutor-interface.d.ts.map +1 -1
  17. package/interfaces/visitante-comum-interface.d.ts +4 -5
  18. package/interfaces/visitante-comum-interface.d.ts.map +1 -1
  19. package/interpretador/comum.d.ts.map +1 -1
  20. package/interpretador/comum.js +1 -0
  21. package/interpretador/comum.js.map +1 -1
  22. package/interpretador/depuracao/comum.d.ts +2 -0
  23. package/interpretador/depuracao/comum.d.ts.map +1 -1
  24. package/interpretador/depuracao/comum.js +15 -2
  25. package/interpretador/depuracao/comum.js.map +1 -1
  26. package/interpretador/depuracao/interpretador-base-com-depuracao.d.ts +2 -0
  27. package/interpretador/depuracao/interpretador-base-com-depuracao.d.ts.map +1 -1
  28. package/interpretador/depuracao/interpretador-base-com-depuracao.js +6 -0
  29. package/interpretador/depuracao/interpretador-base-com-depuracao.js.map +1 -1
  30. package/interpretador/dialetos/pitugues/comum.d.ts.map +1 -1
  31. package/interpretador/dialetos/pitugues/comum.js +13 -0
  32. package/interpretador/dialetos/pitugues/comum.js.map +1 -1
  33. package/interpretador/interpretador-base.d.ts +2 -2
  34. package/interpretador/interpretador-base.d.ts.map +1 -1
  35. package/interpretador/interpretador-base.js +9 -17
  36. package/interpretador/interpretador-base.js.map +1 -1
  37. package/interpretador/interpretador.d.ts +3 -4
  38. package/interpretador/interpretador.d.ts.map +1 -1
  39. package/interpretador/interpretador.js +14 -8
  40. package/interpretador/interpretador.js.map +1 -1
  41. package/package.json +1 -1
  42. package/tradutores/index.d.ts +1 -0
  43. package/tradutores/index.d.ts.map +1 -1
  44. package/tradutores/index.js +1 -0
  45. package/tradutores/index.js.map +1 -1
  46. package/tradutores/tradutor-elixir.d.ts +141 -0
  47. package/tradutores/tradutor-elixir.d.ts.map +1 -0
  48. package/tradutores/tradutor-elixir.js +926 -0
  49. package/tradutores/tradutor-elixir.js.map +1 -0
  50. package/tradutores/tradutor-mermaidjs.d.ts +68 -78
  51. package/tradutores/tradutor-mermaidjs.d.ts.map +1 -1
  52. package/tradutores/tradutor-mermaidjs.js +596 -404
  53. package/tradutores/tradutor-mermaidjs.js.map +1 -1
  54. package/umd/delegua.js +1806 -698
@@ -4,8 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.TradutorMermaidJs = void 0;
7
- const delegua_1 = __importDefault(require("../tipos-de-simbolos/delegua"));
7
+ const construtos_1 = require("../construtos");
8
8
  const mermaid_1 = require("./mermaid");
9
+ const delegua_1 = __importDefault(require("../tipos-de-simbolos/delegua"));
9
10
  /**
10
11
  * [MermaidJs](https://mermaid.js.org/) é uma especificação que nos permite
11
12
  * criar fluxogramas através de uma notação por texto.
@@ -19,249 +20,28 @@ const mermaid_1 = require("./mermaid");
19
20
  * @see VerticeFluxograma
20
21
  */
21
22
  class TradutorMermaidJs {
22
- constructor() {
23
- this.dicionarioConstrutos = {
24
- AcessoIndiceVariavel: this.traduzirConstrutoAcessoIndiceVariavel.bind(this),
25
- AcessoMetodo: this.traduzirConstrutoAcessoMetodo.bind(this),
26
- AcessoMetodoOuPropriedade: this.traduzirConstrutoAcessoMetodoOuPropriedade.bind(this),
27
- AcessoPropriedade: this.traduzirConstrutoAcessoPropriedade.bind(this),
28
- Agrupamento: this.traduzirConstrutoAgrupamento.bind(this),
29
- Atribuir: this.traduzirConstrutoAtribuir.bind(this),
30
- Binario: this.traduzirConstrutoBinario.bind(this),
31
- Chamada: this.traduzirConstrutoChamada.bind(this),
32
- ComentarioComoConstruto: () => '',
33
- DefinirValor: this.traduzirConstrutoDefinirValor.bind(this),
34
- Dicionario: this.traduzirConstrutoDicionario.bind(this),
35
- // FuncaoConstruto: this.traduzirFuncaoConstruto.bind(this),
36
- FuncaoConstruto: () => { throw new Error("Fluxogramas de funções ainda não é suportado."); },
37
- Isto: () => 'this',
38
- Leia: this.traduzirConstrutoLeia.bind(this),
39
- Literal: this.traduzirConstrutoLiteral.bind(this),
40
- Separador: this.traduzirConstrutoSeparador.bind(this),
41
- Unario: this.traduzirConstrutoUnario.bind(this),
42
- Variavel: this.traduzirConstrutoVariavel.bind(this),
43
- Vetor: this.traduzirConstrutoVetor.bind(this),
44
- };
45
- this.dicionarioDeclaracoes = {
46
- Bloco: this.traduzirDeclaracaoBloco.bind(this),
47
- Classe: this.traduzirDeclaracaoClasse.bind(this),
48
- Comentario: () => '',
49
- Const: this.traduzirDeclaracaoConst.bind(this),
50
- Enquanto: this.traduzirDeclaracaoEnquanto.bind(this),
51
- Escolha: this.traduzirDeclaracaoEscolha.bind(this),
52
- Expressao: this.traduzirDeclaracaoExpressao.bind(this),
53
- Escreva: this.traduzirDeclaracaoEscreva.bind(this),
54
- Fazer: this.traduzirDeclaracaoFazerEnquanto.bind(this),
55
- FuncaoDeclaracao: this.traduzirDeclaracaoFuncao.bind(this),
56
- Para: this.traduzirDeclaracaoPara.bind(this),
57
- ParaCada: this.traduzirDeclaracaoParaCada.bind(this),
58
- Retorna: this.traduzirDeclaracaoRetorna.bind(this),
59
- Se: this.traduzirDeclaracaoSe.bind(this),
60
- Var: this.traduzirDeclaracaoVar.bind(this),
61
- };
62
- }
63
- traduzirConstrutoAcessoIndiceVariavel(acessoIndiceVariavel) {
64
- const textoIndice = this.dicionarioConstrutos[acessoIndiceVariavel.indice.constructor.name](acessoIndiceVariavel.indice);
65
- return `no índice ${textoIndice}`;
66
- }
67
- traduzirConstrutoAcessoMetodo(acessoMetodo) {
68
- return `método ${acessoMetodo.nomeMetodo}`;
69
- }
70
- traduzirConstrutoAcessoMetodoOuPropriedade(acessoMetodoOuPropriedade) {
71
- return `método ou propriedade ${acessoMetodoOuPropriedade.simbolo.lexema}`;
72
- }
73
- traduzirConstrutoAcessoPropriedade(acessoPropriedade) {
74
- return `propriedade ${acessoPropriedade.nomePropriedade}`;
75
- }
76
- traduzirConstrutoAgrupamento(agrupamento) {
77
- return this.dicionarioConstrutos[agrupamento.expressao.constructor.name](agrupamento.expressao);
78
- }
79
- traduzirConstrutoAtribuir(atribuir) {
80
- const textoAlvo = this.dicionarioConstrutos[atribuir.alvo.constructor.name](atribuir.alvo);
81
- const textoValor = this.dicionarioConstrutos[atribuir.valor.constructor.name](atribuir.valor);
82
- return `${textoAlvo} recebe: ${textoValor}`;
83
- }
84
- traduzirConstrutoBinario(binario) {
85
- const operandoEsquerdo = this.dicionarioConstrutos[binario.esquerda.constructor.name](binario.esquerda);
86
- const operandoDireito = this.dicionarioConstrutos[binario.direita.constructor.name](binario.direita);
87
- switch (binario.operador.tipo) {
88
- case delegua_1.default.ADICAO:
89
- return `somar ${operandoEsquerdo} e ${operandoDireito}`;
90
- case delegua_1.default.MENOR:
91
- return `${operandoEsquerdo} for menor que ${operandoDireito}`;
92
- }
93
- return '';
94
- }
95
- traduzirConstrutoChamada(chamada) {
96
- const textoEntidadeChamada = this.dicionarioConstrutos[chamada.entidadeChamada.constructor.name](chamada.entidadeChamada);
97
- let texto = `chamada a ${textoEntidadeChamada}`;
98
- if (chamada.argumentos.length > 0) {
99
- texto += `, com argumentos: `;
100
- for (const argumento of chamada.argumentos) {
101
- const textoArgumento = this.dicionarioConstrutos[argumento.constructor.name](argumento);
102
- texto += `${textoArgumento}, `;
103
- }
104
- texto = texto.slice(0, -2);
105
- }
106
- else {
107
- texto += `, sem argumentos`;
108
- }
109
- return texto;
110
- }
111
- /**
112
- * Traduz uma declaração de Expressao que contém uma chamada de função,
113
- * criando os vértices necessários para conectar ao subgrafo da função.
114
- */
115
- traduzirChamadaFuncao(declaracaoExpressao, chamada) {
116
- // Verifica se é uma chamada a uma função conhecida
117
- if (chamada.entidadeChamada.constructor.name === 'Variavel') {
118
- const variavel = chamada.entidadeChamada;
119
- const nomeFuncao = variavel.simbolo.lexema;
120
- if (this.declaracoesFuncoes[nomeFuncao]) {
121
- const subgrafo = this.declaracoesFuncoes[nomeFuncao];
122
- let vertices = [];
123
- // Conecta do fluxo atual para a entrada da função
124
- const textoPreChamada = `Linha${declaracaoExpressao.linha}(${this.traduzirConstrutoChamada(chamada)})`;
125
- const arestaPreChamada = new mermaid_1.ArestaFluxograma(declaracaoExpressao, textoPreChamada);
126
- vertices = vertices.concat(this.logicaComumConexaoArestas(arestaPreChamada));
127
- // Conecta a pré-chamada ao início da função
128
- vertices.push(new mermaid_1.VerticeFluxograma(arestaPreChamada, subgrafo.arestaInicial));
129
- // A saída da função volta para o fluxo principal
130
- this.anteriores = [subgrafo.arestaFinal];
131
- return vertices;
132
- }
133
- }
134
- // Se não for uma função conhecida, trata como expressão normal
135
- return [];
136
- }
137
- traduzirConstrutoDefinirValor(definirValor) {
138
- const textoObjeto = this.dicionarioConstrutos[definirValor.objeto.constructor.name](definirValor.objeto);
139
- const textoValor = this.dicionarioConstrutos[definirValor.valor.constructor.name](definirValor.valor);
140
- return `${definirValor.nome.lexema} em ${textoObjeto} recebe ${textoValor}`;
23
+ visitarDeclaracaoCabecalhoPrograma(declaracao) {
24
+ throw new Error('Método não implementado.');
141
25
  }
142
- traduzirConstrutoDicionario(dicionario) {
143
- let texto = `dicionário`;
144
- if (dicionario.chaves.length > 0) {
145
- texto += `, com `;
146
- for (const [chave, indice] of Object.entries(dicionario.chaves)) {
147
- texto += `chave ${chave} definida com o valor ${dicionario.valores[0]}`;
148
- }
149
- }
150
- else {
151
- texto += ' vazio';
152
- }
153
- return texto;
154
- }
155
- traduzirFuncaoConstruto(funcaoConstruto) {
156
- let vertices = [];
157
- let arestas = [];
158
- if (funcaoConstruto.corpo && funcaoConstruto.corpo.length > 0) {
159
- for (const declaracaoCorpo of funcaoConstruto.corpo) {
160
- // Usa o mesmo caminho de outras declarações,
161
- // então todas as arestas passam por logicaComumConexaoArestas.
162
- const verticesCorpo = this.dicionarioDeclaracoes[declaracaoCorpo.constructor.name](declaracaoCorpo);
163
- vertices = vertices.concat(verticesCorpo);
164
- arestas = arestas.concat(this.anteriores);
165
- this.anteriores = [];
166
- }
167
- }
168
- let primeiraAresta = undefined;
169
- if (this.anteriores.length > 0) {
170
- primeiraAresta = this.anteriores[0];
171
- const verticesRestantes = this.logicaComumConexaoArestas(primeiraAresta);
172
- console.log(verticesRestantes);
173
- }
174
- return vertices;
175
- }
176
- traduzirConstrutoLeia(leia) {
177
- let texto = 'leia da entrada';
178
- if (leia.argumentos && leia.argumentos.length > 0) {
179
- const textoArgumento = this.dicionarioConstrutos[leia.argumentos[0].constructor.name](leia.argumentos[0]);
180
- texto += `, imprimindo antes: \\'${textoArgumento}\\'`;
181
- }
182
- return texto;
183
- }
184
- traduzirConstrutoLiteral(literal) {
185
- switch (literal.tipo) {
186
- case 'lógico':
187
- return literal.valor ? 'verdadeiro' : 'falso';
188
- case 'texto':
189
- return `\\'${literal.valor}\\'`;
190
- default:
191
- return String(literal.valor);
192
- }
193
- }
194
- traduzirConstrutoSeparador(separador) {
195
- return `${separador.conteudo} `;
196
- }
197
- traduzirConstrutoUnario(unario) {
198
- const textoOperando = this.dicionarioConstrutos[unario.operando.constructor.name](unario.operando);
199
- let textoOperador = '';
200
- switch (unario.operador.tipo) {
201
- case delegua_1.default.INCREMENTAR:
202
- textoOperador = `incrementar ${textoOperando} em 1`;
203
- break;
204
- case delegua_1.default.DECREMENTAR:
205
- textoOperador = `decrementar ${textoOperando} de 1`;
206
- break;
207
- }
208
- switch (unario.incidenciaOperador) {
209
- case 'ANTES':
210
- return `${textoOperador}, devolver valor de ${textoOperando}`;
211
- case 'DEPOIS':
212
- return `devolver valor de ${textoOperando}, ${textoOperador}`;
213
- }
214
- }
215
- traduzirConstrutoVariavel(variavel) {
216
- return variavel.simbolo.lexema;
217
- }
218
- traduzirConstrutoVetor(vetor) {
219
- let texto = `vetor: `;
220
- for (const elemento of vetor.valores) {
221
- texto += this.dicionarioConstrutos[elemento.constructor.name](elemento);
222
- }
223
- return texto;
224
- }
225
- logicaComumConexaoArestas(aresta) {
226
- const vertices = [];
227
- while (this.anteriores.length > 0) {
228
- const anterior = this.anteriores.shift();
229
- let textoVertice = undefined;
230
- if (this.ultimaDicaVertice) {
231
- textoVertice = String(this.ultimaDicaVertice);
232
- this.ultimaDicaVertice = undefined;
233
- }
234
- vertices.push(new mermaid_1.VerticeFluxograma(anterior, aresta, textoVertice));
235
- }
236
- return vertices;
237
- }
238
- traduzirDeclaracaoBloco(declaracaoBloco) {
239
- let vertices = [];
240
- for (const declaracao of declaracaoBloco.declaracoes) {
241
- const verticesDeclaracao = this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao);
242
- vertices = vertices.concat(verticesDeclaracao);
243
- }
244
- return vertices;
245
- }
246
- traduzirDeclaracaoClasse(declaracaoClasse) {
26
+ async visitarDeclaracaoClasse(declaracao) {
247
27
  var _a, _b;
248
- const nomeClasse = declaracaoClasse.simbolo.lexema;
249
- const superClasse = declaracaoClasse.superClasse
250
- ? (((_a = declaracaoClasse.superClasse.simbolo) === null || _a === void 0 ? void 0 : _a.lexema) || ((_b = declaracaoClasse.superClasse.nome) === null || _b === void 0 ? void 0 : _b.lexema))
28
+ const nomeClasse = declaracao.simbolo.lexema;
29
+ const superClasse = declaracao.superClasse
30
+ ? (((_a = declaracao.superClasse.simbolo) === null || _a === void 0 ? void 0 : _a.lexema) || ((_b = declaracao.superClasse.nome) === null || _b === void 0 ? void 0 : _b.lexema))
251
31
  : undefined;
252
- const linha = declaracaoClasse.linha;
32
+ const linha = declaracao.linha;
253
33
  // Cria arestas de entrada e saída para a classe
254
34
  const textoInicio = `Classe${nomeClasse}Inicio[Início: Classe ${nomeClasse}]`;
255
- const arestaInicial = new mermaid_1.ArestaFluxograma(declaracaoClasse, textoInicio);
35
+ const arestaInicial = new mermaid_1.ArestaFluxograma(declaracao, textoInicio);
256
36
  const textoFim = `Classe${nomeClasse}Fim[Fim: Classe ${nomeClasse}]`;
257
- const arestaFinal = new mermaid_1.ArestaFluxograma(declaracaoClasse, textoFim);
37
+ const arestaFinal = new mermaid_1.ArestaFluxograma(declaracao, textoFim);
258
38
  // Cria o subgrafo da classe
259
39
  const subgrafo = new mermaid_1.SubgrafoClasse(nomeClasse, linha, arestaInicial, arestaFinal, superClasse);
260
40
  // Salva o estado anterior
261
41
  const anterioresAntes = [...this.anteriores];
262
42
  // Processa métodos
263
- if (declaracaoClasse.metodos && declaracaoClasse.metodos.length > 0) {
264
- for (const metodoDeclaracao of declaracaoClasse.metodos) {
43
+ if (declaracao.metodos && declaracao.metodos.length > 0) {
44
+ for (const metodoDeclaracao of declaracao.metodos) {
265
45
  const nomeMetodo = metodoDeclaracao.simbolo.lexema;
266
46
  const linhaMetodo = metodoDeclaracao.linha;
267
47
  const ehConstrutor = nomeMetodo === 'construtor' || nomeMetodo === 'iniciar';
@@ -276,7 +56,7 @@ class TradutorMermaidJs {
276
56
  this.anteriores = [arestaInicialMetodo];
277
57
  if (metodoDeclaracao.funcao.corpo && metodoDeclaracao.funcao.corpo.length > 0) {
278
58
  for (const declaracaoCorpo of metodoDeclaracao.funcao.corpo) {
279
- const verticesCorpo = this.dicionarioDeclaracoes[declaracaoCorpo.constructor.name](declaracaoCorpo);
59
+ const verticesCorpo = await declaracaoCorpo.aceitar(this);
280
60
  subgrafoMetodo.vertices = subgrafoMetodo.vertices.concat(verticesCorpo);
281
61
  }
282
62
  }
@@ -299,73 +79,101 @@ class TradutorMermaidJs {
299
79
  this.anteriores = anterioresAntes;
300
80
  // Armazena o subgrafo da classe
301
81
  this.declaracoesClasses[nomeClasse] = subgrafo;
302
- return [];
82
+ return Promise.resolve([]);
303
83
  }
304
- traduzirDeclaracaoConst(declaracaoConst) {
305
- let texto = `Linha${declaracaoConst.linha}(variável: ${declaracaoConst.simbolo.lexema}`;
306
- texto += this.logicaComumTraducaoVarEConst(declaracaoConst, texto);
307
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoConst, texto);
84
+ async visitarDeclaracaoComentario(declaracao) {
85
+ return Promise.resolve('');
86
+ }
87
+ async visitarDeclaracaoConst(declaracao) {
88
+ let texto = `Linha${declaracao.linha}(variável: ${declaracao.simbolo.lexema}`;
89
+ texto += await this.logicaComumTraducaoVarEConst(declaracao, texto);
90
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
308
91
  const vertices = this.logicaComumConexaoArestas(aresta);
309
92
  this.anteriores.push(aresta);
310
- return vertices;
93
+ return Promise.resolve(vertices);
94
+ }
95
+ visitarDeclaracaoConstMultiplo(declaracao) {
96
+ throw new Error('Método não implementado.');
311
97
  }
312
- traduzirDeclaracaoEnquanto(declaracaoEnquanto) {
313
- let texto = `Linha${declaracaoEnquanto.linha}(enquanto `;
314
- const condicao = this.dicionarioConstrutos[declaracaoEnquanto.condicao.constructor.name](declaracaoEnquanto.condicao);
98
+ async visitarDeclaracaoDeExpressao(declaracao) {
99
+ // Verifica se é uma chamada de função
100
+ if (declaracao.expressao.constructor === construtos_1.Chamada) {
101
+ const chamada = declaracao.expressao;
102
+ const verticesChamada = await this.traduzirChamadaFuncao(declaracao, chamada);
103
+ if (verticesChamada.length > 0) {
104
+ return Promise.resolve(verticesChamada);
105
+ }
106
+ }
107
+ // Se não for uma chamada de função ou não for uma função conhecida,
108
+ // trata como expressão normal
109
+ let texto = `Linha${declaracao.linha}(`;
110
+ const textoConstruto = await declaracao.expressao.aceitar(this);
111
+ texto += textoConstruto + ')';
112
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
113
+ const vertices = this.logicaComumConexaoArestas(aresta);
114
+ this.anteriores.push(aresta);
115
+ return Promise.resolve(vertices);
116
+ }
117
+ async visitarDeclaracaoDefinicaoFuncao(declaracao) {
118
+ const nomeFuncao = declaracao.simbolo.lexema;
119
+ const linha = declaracao.linha;
120
+ // Cria arestas de entrada e saída para a função
121
+ const textoInicio = `Func${nomeFuncao}Inicio[Início: ${nomeFuncao}()]`;
122
+ const arestaInicial = new mermaid_1.ArestaFluxograma(declaracao, textoInicio);
123
+ const textoFim = `Func${nomeFuncao}Fim[Fim: ${nomeFuncao}()]`;
124
+ const arestaFinal = new mermaid_1.ArestaFluxograma(declaracao, textoFim);
125
+ // Cria o subgrafo da função
126
+ const subgrafo = new mermaid_1.SubgrafoFuncao(nomeFuncao, linha, arestaInicial, arestaFinal);
127
+ // Salva o estado atual de anteriores
128
+ const anterioresAntes = [...this.anteriores];
129
+ this.anteriores = [arestaInicial];
130
+ // Processa o corpo da função
131
+ if (declaracao.funcao.corpo && declaracao.funcao.corpo.length > 0) {
132
+ for (const declaracaoCorpo of declaracao.funcao.corpo) {
133
+ const verticesCorpo = await declaracaoCorpo.aceitar(this);
134
+ subgrafo.vertices = subgrafo.vertices.concat(verticesCorpo);
135
+ }
136
+ }
137
+ // Conecta o fim do corpo à aresta final
138
+ if (this.anteriores.length > 0) {
139
+ for (const anterior of this.anteriores) {
140
+ subgrafo.vertices.push(new mermaid_1.VerticeFluxograma(anterior, arestaFinal));
141
+ }
142
+ }
143
+ // Restaura o estado anterior
144
+ this.anteriores = anterioresAntes;
145
+ // Armazena o subgrafo
146
+ this.declaracoesFuncoes[nomeFuncao] = subgrafo;
147
+ // Não adiciona ao fluxo principal
148
+ return Promise.resolve([]);
149
+ }
150
+ async visitarDeclaracaoEnquanto(declaracao) {
151
+ let texto = `Linha${declaracao.linha}(enquanto `;
152
+ const condicao = await declaracao.condicao.aceitar(this);
315
153
  texto += condicao + ')';
316
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoEnquanto, texto);
154
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
317
155
  let vertices = this.logicaComumConexaoArestas(aresta);
318
156
  this.anteriores.push(aresta);
319
157
  // Corpo, normalmente um `Bloco`.
320
- const verticesCorpo = this.dicionarioDeclaracoes[declaracaoEnquanto.corpo.constructor.name](declaracaoEnquanto.corpo);
158
+ const verticesCorpo = await declaracao.corpo.aceitar(this);
321
159
  vertices = vertices.concat(verticesCorpo);
322
160
  const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
323
161
  const verticeLaco = new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, aresta);
324
162
  vertices.push(verticeLaco);
325
- return vertices;
326
- }
327
- logicaComumCaminhoEscolha(declaracaoEscolha, caminhoEscolha, linha, textoIdentificadorOuLiteral, caminhoPadrao) {
328
- let textoCaso = '';
329
- if (!caminhoPadrao) {
330
- textoCaso = `caso ${textoIdentificadorOuLiteral} seja igual a `;
331
- for (const condicao of caminhoEscolha.condicoes) {
332
- const textoCondicao = this.dicionarioConstrutos[condicao.constructor.name](condicao);
333
- textoCaso += `${textoCondicao} ou `;
334
- }
335
- textoCaso = textoCaso.slice(0, -4);
336
- textoCaso += ':';
337
- }
338
- else {
339
- textoCaso = `caso ${textoIdentificadorOuLiteral} tenha qualquer outro valor:`;
340
- }
341
- let textoCaminho = `Linha${linha}(${textoCaso})`;
342
- const arestaCondicaoCaminho = new mermaid_1.ArestaFluxograma(declaracaoEscolha, textoCaminho);
343
- this.anteriores.push(arestaCondicaoCaminho);
344
- let verticesResolvidos = [];
345
- for (const declaracaoCaminho of caminhoEscolha.declaracoes) {
346
- const verticesDeclaracoes = this.dicionarioDeclaracoes[declaracaoCaminho.constructor.name](declaracaoCaminho);
347
- verticesResolvidos = verticesResolvidos.concat(verticesDeclaracoes);
348
- this.anteriores.pop();
349
- this.anteriores.push(verticesDeclaracoes[verticesDeclaracoes.length - 1].destino);
350
- }
351
- this.anteriores.pop();
352
- return {
353
- caminho: arestaCondicaoCaminho,
354
- declaracoesCaminho: verticesResolvidos,
355
- };
163
+ return Promise.resolve(vertices);
356
164
  }
357
- traduzirDeclaracaoEscolha(declaracaoEscolha) {
358
- let texto = `Linha${declaracaoEscolha.linha}(escolha um caminho pelo valor de `;
359
- const textoIdentificadorOuLiteral = this.dicionarioConstrutos[declaracaoEscolha.identificadorOuLiteral.constructor.name](declaracaoEscolha.identificadorOuLiteral);
165
+ async visitarDeclaracaoEscolha(declaracao) {
166
+ let texto = `Linha${declaracao.linha}(escolha um caminho pelo valor de `;
167
+ const textoIdentificadorOuLiteral = await declaracao.identificadorOuLiteral.aceitar(this);
360
168
  texto += textoIdentificadorOuLiteral + ')';
361
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoEscolha, texto);
169
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
362
170
  let vertices = this.logicaComumConexaoArestas(aresta);
363
171
  const arestasCaminho = [];
364
- for (const caminho of declaracaoEscolha.caminhos) {
365
- arestasCaminho.push(this.logicaComumCaminhoEscolha(declaracaoEscolha, caminho, caminho.condicoes[0].linha, textoIdentificadorOuLiteral, false));
172
+ for (const caminho of declaracao.caminhos) {
173
+ arestasCaminho.push(await this.logicaComumCaminhoEscolha(declaracao, caminho, caminho.condicoes[0].linha, textoIdentificadorOuLiteral, false));
366
174
  }
367
- if (declaracaoEscolha.caminhoPadrao) {
368
- arestasCaminho.push(this.logicaComumCaminhoEscolha(declaracaoEscolha, declaracaoEscolha.caminhoPadrao, declaracaoEscolha.caminhoPadrao.declaracoes[0].linha - 1, textoIdentificadorOuLiteral, true));
175
+ if (declaracao.caminhoPadrao) {
176
+ arestasCaminho.push(await this.logicaComumCaminhoEscolha(declaracao, declaracao.caminhoPadrao, declaracao.caminhoPadrao.declaracoes[0].linha - 1, textoIdentificadorOuLiteral, true));
369
177
  }
370
178
  for (const conjunto of Object.values(arestasCaminho)) {
371
179
  const verticeEscolhaECaminho = new mermaid_1.VerticeFluxograma(aresta, conjunto.caminho);
@@ -373,122 +181,91 @@ class TradutorMermaidJs {
373
181
  vertices = vertices.concat(conjunto.declaracoesCaminho);
374
182
  this.anteriores.push(conjunto.declaracoesCaminho[conjunto.declaracoesCaminho.length - 1].destino);
375
183
  }
376
- return vertices;
184
+ return Promise.resolve(vertices);
377
185
  }
378
- traduzirDeclaracaoEscreva(declaracaoEscreva) {
379
- let texto = `Linha${declaracaoEscreva.linha}(escreva: `;
380
- for (const argumento of declaracaoEscreva.argumentos) {
381
- const valor = this.dicionarioConstrutos[argumento.constructor.name](argumento);
186
+ async visitarDeclaracaoEscreva(declaracao) {
187
+ let texto = `Linha${declaracao.linha}(escreva: `;
188
+ for (const argumento of declaracao.argumentos) {
189
+ const valor = await argumento.aceitar(this);
382
190
  texto += valor + ', ';
383
191
  }
384
192
  texto = texto.slice(0, -2);
385
193
  texto += ')';
386
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoEscreva, texto);
194
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
387
195
  const vertices = this.logicaComumConexaoArestas(aresta);
388
196
  this.anteriores.push(aresta);
389
- return vertices;
197
+ return Promise.resolve(vertices);
390
198
  }
391
- traduzirDeclaracaoExpressao(declaracaoExpressao) {
392
- // Verifica se é uma chamada de função
393
- if (declaracaoExpressao.expressao.constructor.name === 'Chamada') {
394
- const chamada = declaracaoExpressao.expressao;
395
- const verticesChamada = this.traduzirChamadaFuncao(declaracaoExpressao, chamada);
396
- if (verticesChamada.length > 0) {
397
- return verticesChamada;
398
- }
399
- }
400
- // Se não for uma chamada de função ou não for uma função conhecida,
401
- // trata como expressão normal
402
- let texto = `Linha${declaracaoExpressao.linha}(`;
403
- const textoConstruto = this.dicionarioConstrutos[declaracaoExpressao.expressao.constructor.name](declaracaoExpressao.expressao);
404
- texto += textoConstruto + ')';
405
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoExpressao, texto);
406
- const vertices = this.logicaComumConexaoArestas(aresta);
407
- this.anteriores.push(aresta);
408
- return vertices;
199
+ visitarDeclaracaoEscrevaMesmaLinha(declaracao) {
200
+ throw new Error('Método não implementado.');
409
201
  }
410
- traduzirDeclaracaoFazerEnquanto(declaracaoFazerEnquanto) {
411
- const texto = `Linha${declaracaoFazerEnquanto.linha}(fazer)`;
412
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoFazerEnquanto, texto);
202
+ async visitarDeclaracaoFazer(declaracao) {
203
+ const texto = `Linha${declaracao.linha}(fazer)`;
204
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
413
205
  let vertices = this.logicaComumConexaoArestas(aresta);
414
206
  this.anteriores.push(aresta);
415
207
  // Corpo, normalmente um `Bloco`.
416
- const verticesCorpo = this.dicionarioDeclaracoes[declaracaoFazerEnquanto.caminhoFazer.constructor.name](declaracaoFazerEnquanto.caminhoFazer);
208
+ const verticesCorpo = await declaracao.caminhoFazer.aceitar(this);
417
209
  vertices = vertices.concat(verticesCorpo);
418
210
  const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
419
- const condicao = this.dicionarioConstrutos[declaracaoFazerEnquanto.condicaoEnquanto.constructor.name](declaracaoFazerEnquanto.condicaoEnquanto);
420
- let textoEnquanto = `Linha${declaracaoFazerEnquanto.condicaoEnquanto.linha}(enquanto ${condicao})`;
421
- const arestaEnquanto = new mermaid_1.ArestaFluxograma(declaracaoFazerEnquanto, textoEnquanto);
211
+ const condicao = await declaracao.condicaoEnquanto.aceitar(this);
212
+ let textoEnquanto = `Linha${declaracao.condicaoEnquanto.linha}(enquanto ${condicao})`;
213
+ const arestaEnquanto = new mermaid_1.ArestaFluxograma(declaracao, textoEnquanto);
422
214
  const verticeEnquanto = new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, arestaEnquanto);
423
215
  vertices.push(verticeEnquanto);
424
216
  const verticeCondicaoComFazer = new mermaid_1.VerticeFluxograma(arestaEnquanto, aresta);
425
217
  vertices.push(verticeCondicaoComFazer);
426
218
  this.anteriores.pop();
427
219
  this.anteriores.push(arestaEnquanto);
428
- return vertices;
220
+ return Promise.resolve(vertices);
429
221
  }
430
- traduzirDeclaracaoFuncao(declaracaoFuncao) {
431
- const nomeFuncao = declaracaoFuncao.simbolo.lexema;
432
- const linha = declaracaoFuncao.linha;
433
- // Cria arestas de entrada e saída para a função
434
- const textoInicio = `Func${nomeFuncao}Inicio[Início: ${nomeFuncao}()]`;
435
- const arestaInicial = new mermaid_1.ArestaFluxograma(declaracaoFuncao, textoInicio);
436
- const textoFim = `Func${nomeFuncao}Fim[Fim: ${nomeFuncao}()]`;
437
- const arestaFinal = new mermaid_1.ArestaFluxograma(declaracaoFuncao, textoFim);
438
- // Cria o subgrafo da função
439
- const subgrafo = new mermaid_1.SubgrafoFuncao(nomeFuncao, linha, arestaInicial, arestaFinal);
440
- // Salva o estado atual de anteriores
441
- const anterioresAntes = [...this.anteriores];
442
- this.anteriores = [arestaInicial];
443
- // Processa o corpo da função
444
- if (declaracaoFuncao.funcao.corpo && declaracaoFuncao.funcao.corpo.length > 0) {
445
- for (const declaracaoCorpo of declaracaoFuncao.funcao.corpo) {
446
- const verticesCorpo = this.dicionarioDeclaracoes[declaracaoCorpo.constructor.name](declaracaoCorpo);
447
- subgrafo.vertices = subgrafo.vertices.concat(verticesCorpo);
448
- }
449
- }
450
- // Conecta o fim do corpo à aresta final
451
- if (this.anteriores.length > 0) {
452
- for (const anterior of this.anteriores) {
453
- subgrafo.vertices.push(new mermaid_1.VerticeFluxograma(anterior, arestaFinal));
454
- }
455
- }
456
- // Restaura o estado anterior
457
- this.anteriores = anterioresAntes;
458
- // Armazena o subgrafo
459
- this.declaracoesFuncoes[nomeFuncao] = subgrafo;
460
- // Não adiciona ao fluxo principal
461
- return [];
222
+ visitarDeclaracaoInicioAlgoritmo(declaracao) {
223
+ throw new Error('Método não implementado.');
224
+ }
225
+ async visitarDeclaracaoParaCada(declaracao) {
226
+ const textoVariavelIteracao = await declaracao.variavelIteracao.aceitar(this);
227
+ let texto = `Linha${declaracao.linha}(para cada ${textoVariavelIteracao} em `;
228
+ const textoVariavelIterada = await declaracao.vetorOuDicionario.aceitar(this);
229
+ texto += textoVariavelIterada + ')';
230
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
231
+ let vertices = this.logicaComumConexaoArestas(aresta);
232
+ this.anteriores.push(aresta);
233
+ // Corpo, normalmente um `Bloco`.
234
+ const verticesCorpo = await declaracao.corpo.aceitar(this);
235
+ vertices = vertices.concat(verticesCorpo);
236
+ const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
237
+ vertices.push(new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, aresta));
238
+ return Promise.resolve(vertices);
462
239
  }
463
- traduzirDeclaracaoPara(declaracaoPara) {
464
- let texto = `Linha${declaracaoPara.linha}(para `;
465
- if (declaracaoPara.inicializador) {
466
- for (const declaracaoInicializadora of declaracaoPara.inicializador) {
240
+ async visitarDeclaracaoPara(declaracao) {
241
+ let texto = `Linha${declaracao.linha}(para `;
242
+ if (declaracao.inicializador) {
243
+ for (const declaracaoInicializadora of declaracao.inicializador) {
467
244
  // Normalmente é `Var`.
468
245
  const declaracaoVar = declaracaoInicializadora;
469
- const valorInicializacao = this.dicionarioConstrutos[declaracaoVar.inicializador.constructor.name](declaracaoVar.inicializador);
246
+ const valorInicializacao = await declaracaoVar.inicializador.aceitar(this);
470
247
  texto += `uma variável ${declaracaoVar.simbolo.lexema} inicializada com ${valorInicializacao}, `;
471
248
  }
472
249
  texto = texto.slice(0, -2);
473
250
  }
474
251
  texto += ')';
475
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoPara, texto);
252
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
476
253
  let vertices = this.logicaComumConexaoArestas(aresta);
477
254
  this.anteriores.push(aresta);
478
255
  // Condição
479
- const textoCondicao = this.dicionarioConstrutos[declaracaoPara.condicao.constructor.name](declaracaoPara.condicao);
480
- const textoArestaCondicao = `Linha${declaracaoPara.linha}Condicao{se ${textoCondicao}}`;
481
- const arestaCondicao = new mermaid_1.ArestaFluxograma(declaracaoPara, textoArestaCondicao);
256
+ const textoCondicao = await declaracao.condicao.aceitar(this);
257
+ const textoArestaCondicao = `Linha${declaracao.linha}Condicao{se ${textoCondicao}}`;
258
+ const arestaCondicao = new mermaid_1.ArestaFluxograma(declaracao, textoArestaCondicao);
482
259
  vertices = vertices.concat(this.logicaComumConexaoArestas(arestaCondicao));
483
260
  this.anteriores.push(arestaCondicao);
484
261
  this.ultimaDicaVertice = 'Sim';
485
262
  // Corpo, normalmente um `Bloco`.
486
- const verticesCorpo = this.dicionarioDeclaracoes[declaracaoPara.corpo.constructor.name](declaracaoPara.corpo);
263
+ const verticesCorpo = await declaracao.corpo.aceitar(this);
487
264
  vertices = vertices.concat(verticesCorpo);
488
265
  // Incremento
489
266
  const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
490
- const textoIncremento = this.dicionarioConstrutos[declaracaoPara.incrementar.constructor.name](declaracaoPara.incrementar);
491
- const arestaIncremento = new mermaid_1.ArestaFluxograma(declaracaoPara, `Linha${declaracaoPara.linha}Incremento(${textoIncremento})`);
267
+ const textoIncremento = await declaracao.incrementar.aceitar(this);
268
+ const arestaIncremento = new mermaid_1.ArestaFluxograma(declaracao, `Linha${declaracao.linha}Incremento(${textoIncremento})`);
492
269
  const verticeIncremento = new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, arestaIncremento);
493
270
  vertices.push(verticeIncremento);
494
271
  const verticeLaco = new mermaid_1.VerticeFluxograma(arestaIncremento, arestaCondicao);
@@ -497,80 +274,495 @@ class TradutorMermaidJs {
497
274
  this.anteriores.pop();
498
275
  this.anteriores.push(arestaCondicao);
499
276
  this.ultimaDicaVertice = 'Não';
500
- return vertices;
277
+ return Promise.resolve(vertices);
501
278
  }
502
- traduzirDeclaracaoParaCada(declaracaoParaCada) {
503
- const textoVariavelIteracao = this.dicionarioConstrutos[declaracaoParaCada.variavelIteracao.constructor.name](declaracaoParaCada.variavelIteracao);
504
- let texto = `Linha${declaracaoParaCada.linha}(para cada ${textoVariavelIteracao} em `;
505
- const textoVariavelIterada = this.dicionarioConstrutos[declaracaoParaCada.vetorOuDicionario.constructor.name](declaracaoParaCada.vetorOuDicionario);
506
- texto += textoVariavelIterada + ')';
507
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoParaCada, texto);
508
- let vertices = this.logicaComumConexaoArestas(aresta);
509
- this.anteriores.push(aresta);
510
- // Corpo, normalmente um `Bloco`.
511
- const verticesCorpo = this.dicionarioDeclaracoes[declaracaoParaCada.corpo.constructor.name](declaracaoParaCada.corpo);
512
- vertices = vertices.concat(verticesCorpo);
513
- const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
514
- vertices.push(new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, aresta));
515
- return vertices;
516
- }
517
- traduzirDeclaracaoSe(declaracaoSe) {
518
- let texto = `Linha${declaracaoSe.linha}{se `;
519
- const condicao = this.dicionarioConstrutos[declaracaoSe.condicao.constructor.name](declaracaoSe.condicao);
279
+ async visitarDeclaracaoSe(declaracao) {
280
+ let texto = `Linha${declaracao.linha}{se `;
281
+ const condicao = await declaracao.condicao.aceitar(this);
520
282
  texto += condicao;
521
283
  texto += `}`;
522
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoSe, texto);
284
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
523
285
  let vertices = this.logicaComumConexaoArestas(aresta);
524
286
  this.anteriores.push(aresta);
525
287
  this.ultimaDicaVertice = 'Sim';
526
288
  // Caminho então, normalmente um `Bloco`.
527
- const verticesEntao = this.dicionarioDeclaracoes[declaracaoSe.caminhoEntao.constructor.name](declaracaoSe.caminhoEntao);
289
+ const verticesEntao = await declaracao.caminhoEntao.aceitar(this);
528
290
  vertices = vertices.concat(verticesEntao);
529
- const ultimaArestaEntao = verticesEntao[verticesEntao.length - 1].destino;
530
- if (declaracaoSe.caminhoSenao) {
291
+ const ultimaArestaEntao = verticesEntao.length > 0
292
+ ? verticesEntao[verticesEntao.length - 1].destino
293
+ : aresta;
294
+ if (declaracao.caminhoSenao) {
531
295
  this.anteriores = [];
532
- const arestaSenao = new mermaid_1.ArestaFluxograma(declaracaoSe, `Linha${declaracaoSe.caminhoSenao.linha}(senão)`);
296
+ const arestaSenao = new mermaid_1.ArestaFluxograma(declaracao, `Linha${declaracao.caminhoSenao.linha}(senão)`);
533
297
  vertices.push(new mermaid_1.VerticeFluxograma(aresta, arestaSenao, 'Não'));
534
298
  this.anteriores.push(arestaSenao);
535
- const verticesSenao = this.dicionarioDeclaracoes[declaracaoSe.caminhoSenao.constructor.name](declaracaoSe.caminhoSenao);
299
+ const verticesSenao = await declaracao.caminhoSenao.aceitar(this);
536
300
  vertices = vertices.concat(verticesSenao);
537
301
  }
538
302
  this.anteriores.push(ultimaArestaEntao);
539
- return vertices;
303
+ return Promise.resolve(vertices);
540
304
  }
541
- logicaComumTraducaoVarEConst(declaracaoVarOuConst, textoInicial) {
542
- if (declaracaoVarOuConst.inicializador) {
543
- textoInicial += `, iniciada com: ${this.dicionarioConstrutos[declaracaoVarOuConst.inicializador.constructor.name](declaracaoVarOuConst.inicializador)}`;
305
+ async visitarDeclaracaoTendoComo(declaracao) {
306
+ const textoVariavelIteracao = await declaracao.inicializacaoVariavel.aceitar(this);
307
+ let texto = `Linha${declaracao.linha}(tendo ${textoVariavelIteracao} como `;
308
+ texto += declaracao.simboloVariavel.lexema + ')';
309
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
310
+ let vertices = this.logicaComumConexaoArestas(aresta);
311
+ this.anteriores.push(aresta);
312
+ // Corpo, normalmente um `Bloco`.
313
+ const verticesCorpo = await declaracao.corpo.aceitar(this);
314
+ vertices = vertices.concat(verticesCorpo);
315
+ const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
316
+ vertices.push(new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, aresta));
317
+ return Promise.resolve(vertices);
318
+ }
319
+ async visitarDeclaracaoTente(declaracao) {
320
+ const texto = `Linha${declaracao.linha}(tente)`;
321
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
322
+ let vertices = this.logicaComumConexaoArestas(aresta);
323
+ this.anteriores.push(aresta);
324
+ // Caminho tente (try)
325
+ const verticesTente = [];
326
+ for (const declaracaoTente of declaracao.caminhoTente) {
327
+ const verticesDeclaracao = await declaracaoTente.aceitar(this);
328
+ verticesTente.push(...verticesDeclaracao);
329
+ }
330
+ vertices = vertices.concat(verticesTente);
331
+ const ultimaArestaTente = verticesTente.length > 0
332
+ ? verticesTente[verticesTente.length - 1].destino
333
+ : aresta;
334
+ const anterioresAposTente = [];
335
+ // Caminho pegue (catch) - se existir
336
+ if (declaracao.caminhoPegue) {
337
+ this.anteriores = [aresta];
338
+ const arestaPegue = new mermaid_1.ArestaFluxograma(declaracao, `Linha${declaracao.linha}Pegue(pegue)`);
339
+ vertices.push(new mermaid_1.VerticeFluxograma(aresta, arestaPegue, 'Erro'));
340
+ this.anteriores.push(arestaPegue);
341
+ const verticesPegue = [];
342
+ if (Array.isArray(declaracao.caminhoPegue)) {
343
+ for (const declaracaoPegue of declaracao.caminhoPegue) {
344
+ const verticesDeclaracao = await declaracaoPegue.aceitar(this);
345
+ verticesPegue.push(...verticesDeclaracao);
346
+ }
347
+ }
348
+ vertices = vertices.concat(verticesPegue);
349
+ const ultimaArestaPegue = verticesPegue.length > 0
350
+ ? verticesPegue[verticesPegue.length - 1].destino
351
+ : arestaPegue;
352
+ anterioresAposTente.push(ultimaArestaPegue);
353
+ }
354
+ // Caminho senão (else) - se existir
355
+ if (declaracao.caminhoSenao && declaracao.caminhoSenao.length > 0) {
356
+ this.anteriores = [ultimaArestaTente];
357
+ const arestaSenao = new mermaid_1.ArestaFluxograma(declaracao, `Linha${declaracao.linha}Senao(senão - sem erro)`);
358
+ vertices.push(new mermaid_1.VerticeFluxograma(ultimaArestaTente, arestaSenao, 'Sucesso'));
359
+ this.anteriores.push(arestaSenao);
360
+ const verticesSenao = [];
361
+ for (const declaracaoSenao of declaracao.caminhoSenao) {
362
+ const verticesDeclaracao = await declaracaoSenao.aceitar(this);
363
+ verticesSenao.push(...verticesDeclaracao);
364
+ }
365
+ vertices = vertices.concat(verticesSenao);
366
+ const ultimaArestaSenao = verticesSenao.length > 0
367
+ ? verticesSenao[verticesSenao.length - 1].destino
368
+ : arestaSenao;
369
+ anterioresAposTente.push(ultimaArestaSenao);
544
370
  }
545
- textoInicial += ')';
546
- return textoInicial;
371
+ else {
372
+ // Se não há senão, o caminho de sucesso também continua
373
+ anterioresAposTente.push(ultimaArestaTente);
374
+ }
375
+ // Caminho finalmente (finally) - se existir
376
+ if (declaracao.caminhoFinalmente && declaracao.caminhoFinalmente.length > 0) {
377
+ this.anteriores = anterioresAposTente;
378
+ const arestaFinalmente = new mermaid_1.ArestaFluxograma(declaracao, `Linha${declaracao.linha}Finalmente(finalmente)`);
379
+ vertices = vertices.concat(this.logicaComumConexaoArestas(arestaFinalmente));
380
+ this.anteriores.push(arestaFinalmente);
381
+ const verticesFinalmente = [];
382
+ for (const declaracaoFinalmente of declaracao.caminhoFinalmente) {
383
+ const verticesDeclaracao = await declaracaoFinalmente.aceitar(this);
384
+ verticesFinalmente.push(...verticesDeclaracao);
385
+ }
386
+ vertices = vertices.concat(verticesFinalmente);
387
+ }
388
+ else {
389
+ // Se não há finalmente, os anteriores são os caminhos após tente
390
+ this.anteriores = anterioresAposTente;
391
+ }
392
+ return Promise.resolve(vertices);
547
393
  }
548
- traduzirDeclaracaoVar(declaracaoVar) {
549
- let texto = `Linha${declaracaoVar.linha}(variável: ${declaracaoVar.simbolo.lexema}`;
550
- texto += this.logicaComumTraducaoVarEConst(declaracaoVar, texto);
551
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoVar, texto);
394
+ visitarDeclaracaoTextoDocumentacao(declaracao) {
395
+ throw new Error('Método não implementado.');
396
+ }
397
+ async visitarDeclaracaoVar(declaracao) {
398
+ let texto = `Linha${declaracao.linha}(variável: ${declaracao.simbolo.lexema}`;
399
+ texto += await this.logicaComumTraducaoVarEConst(declaracao, texto);
400
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
552
401
  const vertices = this.logicaComumConexaoArestas(aresta);
553
402
  this.anteriores.push(aresta);
554
- return vertices;
403
+ return Promise.resolve(vertices);
404
+ }
405
+ visitarDeclaracaoVarMultiplo(declaracao) {
406
+ throw new Error('Método não implementado.');
407
+ }
408
+ async visitarExpressaoDeAtribuicao(expressao) {
409
+ const textoAlvo = await expressao.alvo.aceitar(this);
410
+ const textoValor = await expressao.valor.aceitar(this);
411
+ return Promise.resolve(`${textoAlvo} recebe: ${textoValor}`);
412
+ }
413
+ async visitarExpressaoAcessoIndiceVariavel(expressao) {
414
+ const textoIndice = await expressao.indice.aceitar(this);
415
+ return Promise.resolve(`no índice ${textoIndice}`);
416
+ }
417
+ visitarExpressaoAcessoIntervaloVariavel(expressao) {
418
+ throw new Error('Método não implementado.');
419
+ }
420
+ visitarExpressaoAcessoElementoMatriz(expressao) {
421
+ throw new Error('Método não implementado.');
422
+ }
423
+ async visitarExpressaoAcessoMetodo(expressao) {
424
+ return Promise.resolve(`método ${expressao.nomeMetodo}`);
425
+ }
426
+ async visitarExpressaoAcessoMetodoOuPropriedade(expressao) {
427
+ return Promise.resolve(`método ou propriedade ${expressao.simbolo.lexema}`);
428
+ }
429
+ async visitarExpressaoAcessoPropriedade(expressao) {
430
+ return Promise.resolve(`propriedade ${expressao.nomePropriedade}`);
431
+ }
432
+ async visitarExpressaoAgrupamento(expressao) {
433
+ return await expressao.expressao.aceitar(this);
434
+ }
435
+ async visitarExpressaoArgumentoReferenciaFuncao(expressao) {
436
+ const nomeFuncao = expressao.simboloFuncao.lexema;
437
+ return Promise.resolve(`referência à função ${nomeFuncao}`);
555
438
  }
556
- traduzirDeclaracaoRetorna(declaracaoRetorna) {
557
- let texto = `Linha${declaracaoRetorna.linha}(retorna`;
558
- if (declaracaoRetorna.valor) {
559
- texto += `: ${this.dicionarioConstrutos[declaracaoRetorna.valor.constructor.name](declaracaoRetorna.valor)}`;
439
+ async visitarExpressaoAtribuicaoPorIndice(expressao) {
440
+ const textoObjeto = await expressao.objeto.aceitar(this);
441
+ const textoIndice = await expressao.indice.aceitar(this);
442
+ const textoValor = await expressao.valor.aceitar(this);
443
+ return Promise.resolve(`${textoObjeto} no índice ${textoIndice} recebe: ${textoValor}`);
444
+ }
445
+ visitarExpressaoAtribuicaoPorIndicesMatriz(expressao) {
446
+ throw new Error('Método não implementado.');
447
+ }
448
+ async visitarExpressaoBinaria(expressao) {
449
+ const operandoEsquerdo = await expressao.esquerda.aceitar(this);
450
+ const operandoDireito = await expressao.direita.aceitar(this);
451
+ switch (expressao.operador.tipo) {
452
+ case delegua_1.default.ADICAO:
453
+ return Promise.resolve(`somar ${operandoEsquerdo} e ${operandoDireito}`);
454
+ case delegua_1.default.SUBTRACAO:
455
+ return Promise.resolve(`subtrair ${operandoDireito} de ${operandoEsquerdo}`);
456
+ case delegua_1.default.MULTIPLICACAO:
457
+ return Promise.resolve(`multiplicar ${operandoEsquerdo} por ${operandoDireito}`);
458
+ case delegua_1.default.DIVISAO:
459
+ return Promise.resolve(`dividir ${operandoEsquerdo} por ${operandoDireito}`);
460
+ case delegua_1.default.MODULO:
461
+ return Promise.resolve(`resto de ${operandoEsquerdo} dividido por ${operandoDireito}`);
462
+ case delegua_1.default.MENOR:
463
+ return Promise.resolve(`${operandoEsquerdo} for menor que ${operandoDireito}`);
464
+ case delegua_1.default.MENOR_IGUAL:
465
+ return Promise.resolve(`${operandoEsquerdo} for menor ou igual a ${operandoDireito}`);
466
+ case delegua_1.default.MAIOR:
467
+ return Promise.resolve(`${operandoEsquerdo} for maior que ${operandoDireito}`);
468
+ case delegua_1.default.MAIOR_IGUAL:
469
+ return Promise.resolve(`${operandoEsquerdo} for maior ou igual a ${operandoDireito}`);
470
+ case delegua_1.default.IGUAL_IGUAL:
471
+ return Promise.resolve(`${operandoEsquerdo} for igual a ${operandoDireito}`);
472
+ case delegua_1.default.DIFERENTE:
473
+ return Promise.resolve(`${operandoEsquerdo} for diferente de ${operandoDireito}`);
474
+ }
475
+ return Promise.resolve('');
476
+ }
477
+ async visitarExpressaoBloco(bloco) {
478
+ let vertices = [];
479
+ for (const declaracao of bloco.declaracoes) {
480
+ const verticesDeclaracao = await declaracao.aceitar(this);
481
+ vertices = vertices.concat(verticesDeclaracao);
482
+ }
483
+ return Promise.resolve(vertices);
484
+ }
485
+ async visitarExpressaoComentario(expressao) {
486
+ return Promise.resolve('');
487
+ }
488
+ async visitarExpressaoContinua(declaracao) {
489
+ const texto = `Linha${declaracao.linha}(continua)`;
490
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
491
+ const vertices = this.logicaComumConexaoArestas(aresta);
492
+ this.anteriores.push(aresta);
493
+ return Promise.resolve(vertices);
494
+ }
495
+ async visitarExpressaoDeChamada(expressao) {
496
+ const textoEntidadeChamada = await expressao.entidadeChamada.aceitar(this);
497
+ let texto = `chamada a ${textoEntidadeChamada}`;
498
+ if (expressao.argumentos.length > 0) {
499
+ texto += `, com argumentos: `;
500
+ for (const argumento of expressao.argumentos) {
501
+ const textoArgumento = await argumento.aceitar(this);
502
+ texto += `${textoArgumento}, `;
503
+ }
504
+ texto = texto.slice(0, -2);
505
+ }
506
+ else {
507
+ texto += `, sem argumentos`;
508
+ }
509
+ return Promise.resolve(texto);
510
+ }
511
+ async visitarExpressaoDefinirValor(expressao) {
512
+ const textoObjeto = await expressao.objeto.aceitar(this);
513
+ const textoValor = await expressao.valor.aceitar(this);
514
+ return Promise.resolve(`${expressao.nome.lexema} em ${textoObjeto} recebe ${textoValor}`);
515
+ }
516
+ async visitarExpressaoFuncaoConstruto(expressao) {
517
+ let texto = 'função anônima';
518
+ if (expressao.parametros && expressao.parametros.length > 0) {
519
+ const parametros = expressao.parametros.map(p => p.nome.lexema).join(', ');
520
+ texto += `(${parametros})`;
521
+ }
522
+ else {
523
+ texto += '()';
524
+ }
525
+ return Promise.resolve(texto);
526
+ }
527
+ async visitarExpressaoDeVariavel(expressao) {
528
+ return Promise.resolve(expressao.simbolo.lexema);
529
+ }
530
+ async visitarExpressaoDicionario(expressao) {
531
+ let texto = `dicionário`;
532
+ if (expressao.chaves.length > 0) {
533
+ texto += `, com `;
534
+ for (const [chave, indice] of Object.entries(expressao.chaves)) {
535
+ texto += `chave ${chave} definida com o valor ${expressao.valores[0]}`;
536
+ }
537
+ }
538
+ else {
539
+ texto += ' vazio';
540
+ }
541
+ return Promise.resolve(texto);
542
+ }
543
+ async visitarExpressaoExpressaoRegular(expressao) {
544
+ // Representa a expressão regular como texto para o fluxograma
545
+ const padraoRegex = expressao.valor ? String(expressao.valor) : expressao.simbolo.lexema;
546
+ return Promise.resolve(`expressão regular: /${padraoRegex}/`);
547
+ }
548
+ async visitarExpressaoFalhar(expressao) {
549
+ let texto = `Linha${expressao.linha}(falhar`;
550
+ if (expressao.explicacao) {
551
+ const textoExplicacao = await expressao.explicacao.aceitar(this);
552
+ texto += `: ${textoExplicacao}`;
560
553
  }
561
554
  texto += ')';
562
- const aresta = new mermaid_1.ArestaFluxograma(declaracaoRetorna, texto);
555
+ const aresta = new mermaid_1.ArestaFluxograma(expressao, texto);
563
556
  const vertices = this.logicaComumConexaoArestas(aresta);
564
557
  this.anteriores.push(aresta);
558
+ return Promise.resolve(vertices);
559
+ }
560
+ visitarExpressaoFimPara(declaracao) {
561
+ throw new Error('Método não implementado.');
562
+ }
563
+ async visitarExpressaoFormatacaoEscrita(declaracao) {
564
+ const textoExpressao = await declaracao.expressao.aceitar(this);
565
+ let formato = textoExpressao;
566
+ // Adiciona informações de formatação se especificadas
567
+ const partes = [textoExpressao];
568
+ if (declaracao.espacos > 0) {
569
+ partes.push(`${declaracao.espacos} espaços`);
570
+ }
571
+ if (declaracao.casasDecimais > 0) {
572
+ partes.push(`${declaracao.casasDecimais} casas decimais`);
573
+ }
574
+ if (partes.length > 1) {
575
+ formato = `${partes[0]} (${partes.slice(1).join(', ')})`;
576
+ }
577
+ return Promise.resolve(formato);
578
+ }
579
+ async visitarExpressaoIsto(expressao) {
580
+ return Promise.resolve('this');
581
+ }
582
+ async visitarExpressaoLeia(expressao) {
583
+ let texto = 'leia da entrada';
584
+ if (expressao.argumentos && expressao.argumentos.length > 0) {
585
+ const textoArgumento = await expressao.argumentos[0].aceitar(this);
586
+ texto += `, imprimindo antes: \\'${textoArgumento}\\'`;
587
+ }
588
+ return Promise.resolve(texto);
589
+ }
590
+ async visitarExpressaoLiteral(expressao) {
591
+ switch (expressao.tipo) {
592
+ case 'lógico':
593
+ return Promise.resolve(expressao.valor ? 'verdadeiro' : 'falso');
594
+ case 'texto':
595
+ return Promise.resolve(`\\'${expressao.valor}\\'`);
596
+ default:
597
+ return Promise.resolve(String(expressao.valor));
598
+ }
599
+ }
600
+ async visitarExpressaoLogica(expressao) {
601
+ const operandoEsquerdo = await expressao.esquerda.aceitar(this);
602
+ const operandoDireito = await expressao.direita.aceitar(this);
603
+ switch (expressao.operador.tipo) {
604
+ case delegua_1.default.E:
605
+ return Promise.resolve(`${operandoEsquerdo} e ${operandoDireito}`);
606
+ case delegua_1.default.OU:
607
+ return Promise.resolve(`${operandoEsquerdo} ou ${operandoDireito}`);
608
+ }
609
+ return Promise.resolve('');
610
+ }
611
+ async visitarExpressaoReferenciaFuncao(expressao) {
612
+ const nomeFuncao = expressao.simboloFuncao.lexema;
613
+ return Promise.resolve(`@${nomeFuncao}`);
614
+ }
615
+ async visitarExpressaoRetornar(expressao) {
616
+ let texto = `Linha${expressao.linha}(retorna`;
617
+ if (expressao.valor) {
618
+ texto += `: ${await expressao.valor.aceitar(this)}`;
619
+ }
620
+ texto += ')';
621
+ const aresta = new mermaid_1.ArestaFluxograma(expressao, texto);
622
+ const vertices = this.logicaComumConexaoArestas(aresta);
623
+ this.anteriores.push(aresta);
624
+ return Promise.resolve(vertices);
625
+ }
626
+ async visitarExpressaoSeparador(expressao) {
627
+ return Promise.resolve(`${expressao.conteudo} `);
628
+ }
629
+ async visitarExpressaoSuper(expressao) {
630
+ return Promise.resolve('super');
631
+ }
632
+ async visitarExpressaoSustar(declaracao) {
633
+ const texto = `Linha${declaracao.linha}(sustar)`;
634
+ const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
635
+ const vertices = this.logicaComumConexaoArestas(aresta);
636
+ this.anteriores.push(aresta);
637
+ return Promise.resolve(vertices);
638
+ }
639
+ async visitarExpressaoTupla(expressao) {
640
+ // Tupla base pode ter um único valor
641
+ if (expressao.valor !== undefined) {
642
+ return Promise.resolve(`tupla(${expressao.valor})`);
643
+ }
644
+ // Se não houver valor, tupla vazia
645
+ return Promise.resolve('tupla()');
646
+ }
647
+ async visitarExpressaoTuplaN(expressao) {
648
+ const valores = [];
649
+ for (const elemento of expressao.elementos) {
650
+ const valorTraduzido = await elemento.aceitar(this);
651
+ valores.push(valorTraduzido);
652
+ }
653
+ return Promise.resolve(`tupla(${valores.join(', ')})`);
654
+ }
655
+ visitarExpressaoTipoDe(expressao) {
656
+ throw new Error('Método não implementado.');
657
+ }
658
+ async visitarExpressaoUnaria(expressao) {
659
+ const textoOperando = await expressao.operando.aceitar(this);
660
+ let textoOperador = '';
661
+ switch (expressao.operador.tipo) {
662
+ case delegua_1.default.INCREMENTAR:
663
+ textoOperador = `incrementar ${textoOperando} em 1`;
664
+ break;
665
+ case delegua_1.default.DECREMENTAR:
666
+ textoOperador = `decrementar ${textoOperando} de 1`;
667
+ break;
668
+ }
669
+ switch (expressao.incidenciaOperador) {
670
+ case 'ANTES':
671
+ return Promise.resolve(`${textoOperador}, devolver valor de ${textoOperando}`);
672
+ case 'DEPOIS':
673
+ return Promise.resolve(`devolver valor de ${textoOperando}, ${textoOperador}`);
674
+ }
675
+ }
676
+ async visitarExpressaoVetor(expressao) {
677
+ let texto = `vetor: `;
678
+ for (const elemento of expressao.valores) {
679
+ texto += await elemento.aceitar(this);
680
+ }
681
+ return Promise.resolve(texto);
682
+ }
683
+ /**
684
+ * Traduz uma declaração de Expressao que contém uma chamada de função,
685
+ * criando os vértices necessários para conectar ao subgrafo da função.
686
+ */
687
+ async traduzirChamadaFuncao(declaracaoExpressao, chamada) {
688
+ // Verifica se é uma chamada a uma função conhecida
689
+ if (chamada.entidadeChamada.constructor === construtos_1.Variavel) {
690
+ const variavel = chamada.entidadeChamada;
691
+ const nomeFuncao = variavel.simbolo.lexema;
692
+ if (this.declaracoesFuncoes[nomeFuncao]) {
693
+ const subgrafo = this.declaracoesFuncoes[nomeFuncao];
694
+ let vertices = [];
695
+ // Conecta do fluxo atual para a entrada da função
696
+ const textoPreChamada = `Linha${declaracaoExpressao.linha}(${await chamada.aceitar(this)})`;
697
+ const arestaPreChamada = new mermaid_1.ArestaFluxograma(declaracaoExpressao, textoPreChamada);
698
+ vertices = vertices.concat(this.logicaComumConexaoArestas(arestaPreChamada));
699
+ // Conecta a pré-chamada ao início da função
700
+ vertices.push(new mermaid_1.VerticeFluxograma(arestaPreChamada, subgrafo.arestaInicial));
701
+ // A saída da função volta para o fluxo principal
702
+ this.anteriores = [subgrafo.arestaFinal];
703
+ return Promise.resolve(vertices);
704
+ }
705
+ }
706
+ // Se não for uma função conhecida, trata como expressão normal
707
+ return Promise.resolve([]);
708
+ }
709
+ logicaComumConexaoArestas(aresta) {
710
+ const vertices = [];
711
+ while (this.anteriores.length > 0) {
712
+ const anterior = this.anteriores.shift();
713
+ let textoVertice = undefined;
714
+ if (this.ultimaDicaVertice) {
715
+ textoVertice = String(this.ultimaDicaVertice);
716
+ this.ultimaDicaVertice = undefined;
717
+ }
718
+ vertices.push(new mermaid_1.VerticeFluxograma(anterior, aresta, textoVertice));
719
+ }
565
720
  return vertices;
566
721
  }
722
+ async logicaComumCaminhoEscolha(declaracaoEscolha, caminhoEscolha, linha, textoIdentificadorOuLiteral, caminhoPadrao) {
723
+ let textoCaso = '';
724
+ if (!caminhoPadrao) {
725
+ textoCaso = `caso ${textoIdentificadorOuLiteral} seja igual a `;
726
+ for (const condicao of caminhoEscolha.condicoes) {
727
+ const textoCondicao = await condicao.aceitar(this);
728
+ textoCaso += `${textoCondicao} ou `;
729
+ }
730
+ textoCaso = textoCaso.slice(0, -4);
731
+ textoCaso += ':';
732
+ }
733
+ else {
734
+ textoCaso = `caso ${textoIdentificadorOuLiteral} tenha qualquer outro valor:`;
735
+ }
736
+ let textoCaminho = `Linha${linha}(${textoCaso})`;
737
+ const arestaCondicaoCaminho = new mermaid_1.ArestaFluxograma(declaracaoEscolha, textoCaminho);
738
+ this.anteriores.push(arestaCondicaoCaminho);
739
+ let verticesResolvidos = [];
740
+ for (const declaracaoCaminho of caminhoEscolha.declaracoes) {
741
+ const verticesDeclaracoes = await declaracaoCaminho.aceitar(this);
742
+ verticesResolvidos = verticesResolvidos.concat(verticesDeclaracoes);
743
+ this.anteriores.pop();
744
+ this.anteriores.push(verticesDeclaracoes[verticesDeclaracoes.length - 1].destino);
745
+ }
746
+ this.anteriores.pop();
747
+ return Promise.resolve({
748
+ caminho: arestaCondicaoCaminho,
749
+ declaracoesCaminho: verticesResolvidos,
750
+ });
751
+ }
752
+ async logicaComumTraducaoVarEConst(declaracaoVarOuConst, textoInicial) {
753
+ if (declaracaoVarOuConst.inicializador) {
754
+ textoInicial += `, iniciada com: ${await declaracaoVarOuConst.inicializador.aceitar(this)}`;
755
+ }
756
+ textoInicial += ')';
757
+ return Promise.resolve(textoInicial);
758
+ }
567
759
  /**
568
760
  * Ponto de entrada para a tradução de declarações em um fluxograma
569
761
  * no formato MermaidJs.
570
762
  * @param {Declaracao[]} declaracoes As declarações a serem traduzidas.
571
763
  * @returns {string} Texto no formato MermaidJs representando o fluxograma.
572
764
  */
573
- traduzir(declaracoes) {
765
+ async traduzir(declaracoes) {
574
766
  this.anteriores = [];
575
767
  this.vertices = [];
576
768
  let resultado = 'graph TD;\n';
@@ -578,7 +770,7 @@ class TradutorMermaidJs {
578
770
  this.declaracoesFuncoes = {};
579
771
  this.declaracoesClasses = {};
580
772
  for (const declaracao of declaracoes) {
581
- this.vertices = this.vertices.concat(this.dicionarioDeclaracoes[declaracao.constructor.name](declaracao));
773
+ this.vertices = this.vertices.concat(await declaracao.aceitar(this));
582
774
  }
583
775
  // Renderiza os subgrafos de funções
584
776
  if (Object.keys(this.declaracoesFuncoes).length > 0) {