@designliquido/delegua 1.2.0 → 1.3.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/dialetos/analisador-semantico-pitugues.d.ts.map +1 -1
- package/analisador-semantico/dialetos/analisador-semantico-pitugues.js +5 -0
- package/analisador-semantico/dialetos/analisador-semantico-pitugues.js.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +11 -8
- package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
- package/bibliotecas/biblioteca-global.d.ts +1 -1
- package/bibliotecas/biblioteca-global.d.ts.map +1 -1
- package/bibliotecas/biblioteca-global.js +3 -17
- package/bibliotecas/biblioteca-global.js.map +1 -1
- package/bibliotecas/dialetos/pitugues/biblioteca-global.d.ts.map +1 -1
- package/bibliotecas/dialetos/pitugues/biblioteca-global.js +8 -6
- package/bibliotecas/dialetos/pitugues/biblioteca-global.js.map +1 -1
- package/bin/package.json +1 -1
- package/interfaces/tradutor-interface.d.ts +1 -1
- package/interfaces/tradutor-interface.d.ts.map +1 -1
- package/interfaces/visitante-comum-interface.d.ts +2 -2
- package/interfaces/visitante-comum-interface.d.ts.map +1 -1
- package/interpretador/comum.d.ts.map +1 -1
- package/interpretador/comum.js +1 -0
- package/interpretador/comum.js.map +1 -1
- package/interpretador/dialetos/pitugues/comum.d.ts.map +1 -1
- package/interpretador/dialetos/pitugues/comum.js +13 -0
- package/interpretador/dialetos/pitugues/comum.js.map +1 -1
- package/interpretador/interpretador-base.d.ts.map +1 -1
- package/interpretador/interpretador-base.js +1 -12
- package/interpretador/interpretador-base.js.map +1 -1
- package/interpretador/interpretador.d.ts +2 -1
- package/interpretador/interpretador.d.ts.map +1 -1
- package/interpretador/interpretador.js +14 -0
- package/interpretador/interpretador.js.map +1 -1
- package/package.json +1 -1
- package/tradutores/index.d.ts +1 -0
- package/tradutores/index.d.ts.map +1 -1
- package/tradutores/index.js +1 -0
- package/tradutores/index.js.map +1 -1
- package/tradutores/tradutor-elixir.d.ts +141 -0
- package/tradutores/tradutor-elixir.d.ts.map +1 -0
- package/tradutores/tradutor-elixir.js +926 -0
- package/tradutores/tradutor-elixir.js.map +1 -0
- package/tradutores/tradutor-mermaidjs.d.ts +69 -78
- package/tradutores/tradutor-mermaidjs.d.ts.map +1 -1
- package/tradutores/tradutor-mermaidjs.js +440 -404
- package/tradutores/tradutor-mermaidjs.js.map +1 -1
- package/umd/delegua.js +1642 -685
|
@@ -4,8 +4,8 @@ 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"));
|
|
8
7
|
const mermaid_1 = require("./mermaid");
|
|
8
|
+
const delegua_1 = __importDefault(require("../tipos-de-simbolos/delegua"));
|
|
9
9
|
/**
|
|
10
10
|
* [MermaidJs](https://mermaid.js.org/) é uma especificação que nos permite
|
|
11
11
|
* criar fluxogramas através de uma notação por texto.
|
|
@@ -19,249 +19,28 @@ const mermaid_1 = require("./mermaid");
|
|
|
19
19
|
* @see VerticeFluxograma
|
|
20
20
|
*/
|
|
21
21
|
class TradutorMermaidJs {
|
|
22
|
-
|
|
23
|
-
|
|
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;
|
|
22
|
+
visitarDeclaracaoCabecalhoPrograma(declaracao) {
|
|
23
|
+
throw new Error('Método não implementado.');
|
|
110
24
|
}
|
|
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}`;
|
|
141
|
-
}
|
|
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) {
|
|
25
|
+
async visitarDeclaracaoClasse(declaracao) {
|
|
247
26
|
var _a, _b;
|
|
248
|
-
const nomeClasse =
|
|
249
|
-
const superClasse =
|
|
250
|
-
? (((_a =
|
|
27
|
+
const nomeClasse = declaracao.simbolo.lexema;
|
|
28
|
+
const superClasse = declaracao.superClasse
|
|
29
|
+
? (((_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
30
|
: undefined;
|
|
252
|
-
const linha =
|
|
31
|
+
const linha = declaracao.linha;
|
|
253
32
|
// Cria arestas de entrada e saída para a classe
|
|
254
33
|
const textoInicio = `Classe${nomeClasse}Inicio[Início: Classe ${nomeClasse}]`;
|
|
255
|
-
const arestaInicial = new mermaid_1.ArestaFluxograma(
|
|
34
|
+
const arestaInicial = new mermaid_1.ArestaFluxograma(declaracao, textoInicio);
|
|
256
35
|
const textoFim = `Classe${nomeClasse}Fim[Fim: Classe ${nomeClasse}]`;
|
|
257
|
-
const arestaFinal = new mermaid_1.ArestaFluxograma(
|
|
36
|
+
const arestaFinal = new mermaid_1.ArestaFluxograma(declaracao, textoFim);
|
|
258
37
|
// Cria o subgrafo da classe
|
|
259
38
|
const subgrafo = new mermaid_1.SubgrafoClasse(nomeClasse, linha, arestaInicial, arestaFinal, superClasse);
|
|
260
39
|
// Salva o estado anterior
|
|
261
40
|
const anterioresAntes = [...this.anteriores];
|
|
262
41
|
// Processa métodos
|
|
263
|
-
if (
|
|
264
|
-
for (const metodoDeclaracao of
|
|
42
|
+
if (declaracao.metodos && declaracao.metodos.length > 0) {
|
|
43
|
+
for (const metodoDeclaracao of declaracao.metodos) {
|
|
265
44
|
const nomeMetodo = metodoDeclaracao.simbolo.lexema;
|
|
266
45
|
const linhaMetodo = metodoDeclaracao.linha;
|
|
267
46
|
const ehConstrutor = nomeMetodo === 'construtor' || nomeMetodo === 'iniciar';
|
|
@@ -276,7 +55,7 @@ class TradutorMermaidJs {
|
|
|
276
55
|
this.anteriores = [arestaInicialMetodo];
|
|
277
56
|
if (metodoDeclaracao.funcao.corpo && metodoDeclaracao.funcao.corpo.length > 0) {
|
|
278
57
|
for (const declaracaoCorpo of metodoDeclaracao.funcao.corpo) {
|
|
279
|
-
const verticesCorpo =
|
|
58
|
+
const verticesCorpo = await declaracaoCorpo.aceitar(this);
|
|
280
59
|
subgrafoMetodo.vertices = subgrafoMetodo.vertices.concat(verticesCorpo);
|
|
281
60
|
}
|
|
282
61
|
}
|
|
@@ -299,73 +78,101 @@ class TradutorMermaidJs {
|
|
|
299
78
|
this.anteriores = anterioresAntes;
|
|
300
79
|
// Armazena o subgrafo da classe
|
|
301
80
|
this.declaracoesClasses[nomeClasse] = subgrafo;
|
|
302
|
-
return [];
|
|
81
|
+
return Promise.resolve([]);
|
|
82
|
+
}
|
|
83
|
+
async visitarDeclaracaoComentario(declaracao) {
|
|
84
|
+
return Promise.resolve('');
|
|
303
85
|
}
|
|
304
|
-
|
|
305
|
-
let texto = `Linha${
|
|
306
|
-
texto += this.logicaComumTraducaoVarEConst(
|
|
307
|
-
const aresta = new mermaid_1.ArestaFluxograma(
|
|
86
|
+
async visitarDeclaracaoConst(declaracao) {
|
|
87
|
+
let texto = `Linha${declaracao.linha}(variável: ${declaracao.simbolo.lexema}`;
|
|
88
|
+
texto += await this.logicaComumTraducaoVarEConst(declaracao, texto);
|
|
89
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
308
90
|
const vertices = this.logicaComumConexaoArestas(aresta);
|
|
309
91
|
this.anteriores.push(aresta);
|
|
310
|
-
return vertices;
|
|
92
|
+
return Promise.resolve(vertices);
|
|
93
|
+
}
|
|
94
|
+
visitarDeclaracaoConstMultiplo(declaracao) {
|
|
95
|
+
throw new Error('Método não implementado.');
|
|
96
|
+
}
|
|
97
|
+
async visitarDeclaracaoDeExpressao(declaracao) {
|
|
98
|
+
// Verifica se é uma chamada de função
|
|
99
|
+
if (declaracao.expressao.constructor.name === 'Chamada') {
|
|
100
|
+
const chamada = declaracao.expressao;
|
|
101
|
+
const verticesChamada = await this.traduzirChamadaFuncao(declaracao, chamada);
|
|
102
|
+
if (verticesChamada.length > 0) {
|
|
103
|
+
return Promise.resolve(verticesChamada);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Se não for uma chamada de função ou não for uma função conhecida,
|
|
107
|
+
// trata como expressão normal
|
|
108
|
+
let texto = `Linha${declaracao.linha}(`;
|
|
109
|
+
const textoConstruto = await declaracao.expressao.aceitar(this);
|
|
110
|
+
texto += textoConstruto + ')';
|
|
111
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
112
|
+
const vertices = this.logicaComumConexaoArestas(aresta);
|
|
113
|
+
this.anteriores.push(aresta);
|
|
114
|
+
return Promise.resolve(vertices);
|
|
115
|
+
}
|
|
116
|
+
async visitarDeclaracaoDefinicaoFuncao(declaracao) {
|
|
117
|
+
const nomeFuncao = declaracao.simbolo.lexema;
|
|
118
|
+
const linha = declaracao.linha;
|
|
119
|
+
// Cria arestas de entrada e saída para a função
|
|
120
|
+
const textoInicio = `Func${nomeFuncao}Inicio[Início: ${nomeFuncao}()]`;
|
|
121
|
+
const arestaInicial = new mermaid_1.ArestaFluxograma(declaracao, textoInicio);
|
|
122
|
+
const textoFim = `Func${nomeFuncao}Fim[Fim: ${nomeFuncao}()]`;
|
|
123
|
+
const arestaFinal = new mermaid_1.ArestaFluxograma(declaracao, textoFim);
|
|
124
|
+
// Cria o subgrafo da função
|
|
125
|
+
const subgrafo = new mermaid_1.SubgrafoFuncao(nomeFuncao, linha, arestaInicial, arestaFinal);
|
|
126
|
+
// Salva o estado atual de anteriores
|
|
127
|
+
const anterioresAntes = [...this.anteriores];
|
|
128
|
+
this.anteriores = [arestaInicial];
|
|
129
|
+
// Processa o corpo da função
|
|
130
|
+
if (declaracao.funcao.corpo && declaracao.funcao.corpo.length > 0) {
|
|
131
|
+
for (const declaracaoCorpo of declaracao.funcao.corpo) {
|
|
132
|
+
const verticesCorpo = await declaracaoCorpo.aceitar(this);
|
|
133
|
+
subgrafo.vertices = subgrafo.vertices.concat(verticesCorpo);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Conecta o fim do corpo à aresta final
|
|
137
|
+
if (this.anteriores.length > 0) {
|
|
138
|
+
for (const anterior of this.anteriores) {
|
|
139
|
+
subgrafo.vertices.push(new mermaid_1.VerticeFluxograma(anterior, arestaFinal));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Restaura o estado anterior
|
|
143
|
+
this.anteriores = anterioresAntes;
|
|
144
|
+
// Armazena o subgrafo
|
|
145
|
+
this.declaracoesFuncoes[nomeFuncao] = subgrafo;
|
|
146
|
+
// Não adiciona ao fluxo principal
|
|
147
|
+
return Promise.resolve([]);
|
|
311
148
|
}
|
|
312
|
-
|
|
313
|
-
let texto = `Linha${
|
|
314
|
-
const condicao =
|
|
149
|
+
async visitarDeclaracaoEnquanto(declaracao) {
|
|
150
|
+
let texto = `Linha${declaracao.linha}(enquanto `;
|
|
151
|
+
const condicao = await declaracao.condicao.aceitar(this);
|
|
315
152
|
texto += condicao + ')';
|
|
316
|
-
const aresta = new mermaid_1.ArestaFluxograma(
|
|
153
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
317
154
|
let vertices = this.logicaComumConexaoArestas(aresta);
|
|
318
155
|
this.anteriores.push(aresta);
|
|
319
156
|
// Corpo, normalmente um `Bloco`.
|
|
320
|
-
const verticesCorpo =
|
|
157
|
+
const verticesCorpo = await declaracao.corpo.aceitar(this);
|
|
321
158
|
vertices = vertices.concat(verticesCorpo);
|
|
322
159
|
const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
|
|
323
160
|
const verticeLaco = new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, aresta);
|
|
324
161
|
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
|
-
};
|
|
162
|
+
return Promise.resolve(vertices);
|
|
356
163
|
}
|
|
357
|
-
|
|
358
|
-
let texto = `Linha${
|
|
359
|
-
const textoIdentificadorOuLiteral =
|
|
164
|
+
async visitarDeclaracaoEscolha(declaracao) {
|
|
165
|
+
let texto = `Linha${declaracao.linha}(escolha um caminho pelo valor de `;
|
|
166
|
+
const textoIdentificadorOuLiteral = await declaracao.identificadorOuLiteral.aceitar(this);
|
|
360
167
|
texto += textoIdentificadorOuLiteral + ')';
|
|
361
|
-
const aresta = new mermaid_1.ArestaFluxograma(
|
|
168
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
362
169
|
let vertices = this.logicaComumConexaoArestas(aresta);
|
|
363
170
|
const arestasCaminho = [];
|
|
364
|
-
for (const caminho of
|
|
365
|
-
arestasCaminho.push(this.logicaComumCaminhoEscolha(
|
|
171
|
+
for (const caminho of declaracao.caminhos) {
|
|
172
|
+
arestasCaminho.push(await this.logicaComumCaminhoEscolha(declaracao, caminho, caminho.condicoes[0].linha, textoIdentificadorOuLiteral, false));
|
|
366
173
|
}
|
|
367
|
-
if (
|
|
368
|
-
arestasCaminho.push(this.logicaComumCaminhoEscolha(
|
|
174
|
+
if (declaracao.caminhoPadrao) {
|
|
175
|
+
arestasCaminho.push(await this.logicaComumCaminhoEscolha(declaracao, declaracao.caminhoPadrao, declaracao.caminhoPadrao.declaracoes[0].linha - 1, textoIdentificadorOuLiteral, true));
|
|
369
176
|
}
|
|
370
177
|
for (const conjunto of Object.values(arestasCaminho)) {
|
|
371
178
|
const verticeEscolhaECaminho = new mermaid_1.VerticeFluxograma(aresta, conjunto.caminho);
|
|
@@ -373,122 +180,91 @@ class TradutorMermaidJs {
|
|
|
373
180
|
vertices = vertices.concat(conjunto.declaracoesCaminho);
|
|
374
181
|
this.anteriores.push(conjunto.declaracoesCaminho[conjunto.declaracoesCaminho.length - 1].destino);
|
|
375
182
|
}
|
|
376
|
-
return vertices;
|
|
183
|
+
return Promise.resolve(vertices);
|
|
377
184
|
}
|
|
378
|
-
|
|
379
|
-
let texto = `Linha${
|
|
380
|
-
for (const argumento of
|
|
381
|
-
const valor =
|
|
185
|
+
async visitarDeclaracaoEscreva(declaracao) {
|
|
186
|
+
let texto = `Linha${declaracao.linha}(escreva: `;
|
|
187
|
+
for (const argumento of declaracao.argumentos) {
|
|
188
|
+
const valor = await argumento.aceitar(this);
|
|
382
189
|
texto += valor + ', ';
|
|
383
190
|
}
|
|
384
191
|
texto = texto.slice(0, -2);
|
|
385
192
|
texto += ')';
|
|
386
|
-
const aresta = new mermaid_1.ArestaFluxograma(
|
|
193
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
387
194
|
const vertices = this.logicaComumConexaoArestas(aresta);
|
|
388
195
|
this.anteriores.push(aresta);
|
|
389
|
-
return vertices;
|
|
196
|
+
return Promise.resolve(vertices);
|
|
390
197
|
}
|
|
391
|
-
|
|
392
|
-
|
|
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;
|
|
198
|
+
visitarDeclaracaoEscrevaMesmaLinha(declaracao) {
|
|
199
|
+
throw new Error('Método não implementado.');
|
|
409
200
|
}
|
|
410
|
-
|
|
411
|
-
const texto = `Linha${
|
|
412
|
-
const aresta = new mermaid_1.ArestaFluxograma(
|
|
201
|
+
async visitarDeclaracaoFazer(declaracao) {
|
|
202
|
+
const texto = `Linha${declaracao.linha}(fazer)`;
|
|
203
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
413
204
|
let vertices = this.logicaComumConexaoArestas(aresta);
|
|
414
205
|
this.anteriores.push(aresta);
|
|
415
206
|
// Corpo, normalmente um `Bloco`.
|
|
416
|
-
const verticesCorpo =
|
|
207
|
+
const verticesCorpo = await declaracao.caminhoFazer.aceitar(this);
|
|
417
208
|
vertices = vertices.concat(verticesCorpo);
|
|
418
209
|
const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
|
|
419
|
-
const condicao =
|
|
420
|
-
let textoEnquanto = `Linha${
|
|
421
|
-
const arestaEnquanto = new mermaid_1.ArestaFluxograma(
|
|
210
|
+
const condicao = await declaracao.condicaoEnquanto.aceitar(this);
|
|
211
|
+
let textoEnquanto = `Linha${declaracao.condicaoEnquanto.linha}(enquanto ${condicao})`;
|
|
212
|
+
const arestaEnquanto = new mermaid_1.ArestaFluxograma(declaracao, textoEnquanto);
|
|
422
213
|
const verticeEnquanto = new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, arestaEnquanto);
|
|
423
214
|
vertices.push(verticeEnquanto);
|
|
424
215
|
const verticeCondicaoComFazer = new mermaid_1.VerticeFluxograma(arestaEnquanto, aresta);
|
|
425
216
|
vertices.push(verticeCondicaoComFazer);
|
|
426
217
|
this.anteriores.pop();
|
|
427
218
|
this.anteriores.push(arestaEnquanto);
|
|
428
|
-
return vertices;
|
|
219
|
+
return Promise.resolve(vertices);
|
|
429
220
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
const
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
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 [];
|
|
221
|
+
visitarDeclaracaoInicioAlgoritmo(declaracao) {
|
|
222
|
+
throw new Error('Método não implementado.');
|
|
223
|
+
}
|
|
224
|
+
async visitarDeclaracaoParaCada(declaracao) {
|
|
225
|
+
const textoVariavelIteracao = await declaracao.variavelIteracao.aceitar(this);
|
|
226
|
+
let texto = `Linha${declaracao.linha}(para cada ${textoVariavelIteracao} em `;
|
|
227
|
+
const textoVariavelIterada = await declaracao.vetorOuDicionario.aceitar(this);
|
|
228
|
+
texto += textoVariavelIterada + ')';
|
|
229
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
230
|
+
let vertices = this.logicaComumConexaoArestas(aresta);
|
|
231
|
+
this.anteriores.push(aresta);
|
|
232
|
+
// Corpo, normalmente um `Bloco`.
|
|
233
|
+
const verticesCorpo = await declaracao.corpo.aceitar(this);
|
|
234
|
+
vertices = vertices.concat(verticesCorpo);
|
|
235
|
+
const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
|
|
236
|
+
vertices.push(new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, aresta));
|
|
237
|
+
return Promise.resolve(vertices);
|
|
462
238
|
}
|
|
463
|
-
|
|
464
|
-
let texto = `Linha${
|
|
465
|
-
if (
|
|
466
|
-
for (const declaracaoInicializadora of
|
|
239
|
+
async visitarDeclaracaoPara(declaracao) {
|
|
240
|
+
let texto = `Linha${declaracao.linha}(para `;
|
|
241
|
+
if (declaracao.inicializador) {
|
|
242
|
+
for (const declaracaoInicializadora of declaracao.inicializador) {
|
|
467
243
|
// Normalmente é `Var`.
|
|
468
244
|
const declaracaoVar = declaracaoInicializadora;
|
|
469
|
-
const valorInicializacao =
|
|
245
|
+
const valorInicializacao = await declaracaoVar.inicializador.aceitar(this);
|
|
470
246
|
texto += `uma variável ${declaracaoVar.simbolo.lexema} inicializada com ${valorInicializacao}, `;
|
|
471
247
|
}
|
|
472
248
|
texto = texto.slice(0, -2);
|
|
473
249
|
}
|
|
474
250
|
texto += ')';
|
|
475
|
-
const aresta = new mermaid_1.ArestaFluxograma(
|
|
251
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
476
252
|
let vertices = this.logicaComumConexaoArestas(aresta);
|
|
477
253
|
this.anteriores.push(aresta);
|
|
478
254
|
// Condição
|
|
479
|
-
const textoCondicao =
|
|
480
|
-
const textoArestaCondicao = `Linha${
|
|
481
|
-
const arestaCondicao = new mermaid_1.ArestaFluxograma(
|
|
255
|
+
const textoCondicao = await declaracao.condicao.aceitar(this);
|
|
256
|
+
const textoArestaCondicao = `Linha${declaracao.linha}Condicao{se ${textoCondicao}}`;
|
|
257
|
+
const arestaCondicao = new mermaid_1.ArestaFluxograma(declaracao, textoArestaCondicao);
|
|
482
258
|
vertices = vertices.concat(this.logicaComumConexaoArestas(arestaCondicao));
|
|
483
259
|
this.anteriores.push(arestaCondicao);
|
|
484
260
|
this.ultimaDicaVertice = 'Sim';
|
|
485
261
|
// Corpo, normalmente um `Bloco`.
|
|
486
|
-
const verticesCorpo =
|
|
262
|
+
const verticesCorpo = await declaracao.corpo.aceitar(this);
|
|
487
263
|
vertices = vertices.concat(verticesCorpo);
|
|
488
264
|
// Incremento
|
|
489
265
|
const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
|
|
490
|
-
const textoIncremento =
|
|
491
|
-
const arestaIncremento = new mermaid_1.ArestaFluxograma(
|
|
266
|
+
const textoIncremento = await declaracao.incrementar.aceitar(this);
|
|
267
|
+
const arestaIncremento = new mermaid_1.ArestaFluxograma(declaracao, `Linha${declaracao.linha}Incremento(${textoIncremento})`);
|
|
492
268
|
const verticeIncremento = new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, arestaIncremento);
|
|
493
269
|
vertices.push(verticeIncremento);
|
|
494
270
|
const verticeLaco = new mermaid_1.VerticeFluxograma(arestaIncremento, arestaCondicao);
|
|
@@ -497,80 +273,340 @@ class TradutorMermaidJs {
|
|
|
497
273
|
this.anteriores.pop();
|
|
498
274
|
this.anteriores.push(arestaCondicao);
|
|
499
275
|
this.ultimaDicaVertice = 'Não';
|
|
500
|
-
return vertices;
|
|
276
|
+
return Promise.resolve(vertices);
|
|
501
277
|
}
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
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);
|
|
278
|
+
async visitarDeclaracaoSe(declaracao) {
|
|
279
|
+
let texto = `Linha${declaracao.linha}{se `;
|
|
280
|
+
const condicao = await declaracao.condicao.aceitar(this);
|
|
520
281
|
texto += condicao;
|
|
521
282
|
texto += `}`;
|
|
522
|
-
const aresta = new mermaid_1.ArestaFluxograma(
|
|
283
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
523
284
|
let vertices = this.logicaComumConexaoArestas(aresta);
|
|
524
285
|
this.anteriores.push(aresta);
|
|
525
286
|
this.ultimaDicaVertice = 'Sim';
|
|
526
287
|
// Caminho então, normalmente um `Bloco`.
|
|
527
|
-
const verticesEntao =
|
|
288
|
+
const verticesEntao = await declaracao.caminhoEntao.aceitar(this);
|
|
528
289
|
vertices = vertices.concat(verticesEntao);
|
|
529
290
|
const ultimaArestaEntao = verticesEntao[verticesEntao.length - 1].destino;
|
|
530
|
-
if (
|
|
291
|
+
if (declaracao.caminhoSenao) {
|
|
531
292
|
this.anteriores = [];
|
|
532
|
-
const arestaSenao = new mermaid_1.ArestaFluxograma(
|
|
293
|
+
const arestaSenao = new mermaid_1.ArestaFluxograma(declaracao, `Linha${declaracao.caminhoSenao.linha}(senão)`);
|
|
533
294
|
vertices.push(new mermaid_1.VerticeFluxograma(aresta, arestaSenao, 'Não'));
|
|
534
295
|
this.anteriores.push(arestaSenao);
|
|
535
|
-
const verticesSenao =
|
|
296
|
+
const verticesSenao = await declaracao.caminhoSenao.aceitar(this);
|
|
536
297
|
vertices = vertices.concat(verticesSenao);
|
|
537
298
|
}
|
|
538
299
|
this.anteriores.push(ultimaArestaEntao);
|
|
539
|
-
return vertices;
|
|
300
|
+
return Promise.resolve(vertices);
|
|
540
301
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
302
|
+
async visitarDeclaracaoTendoComo(declaracao) {
|
|
303
|
+
const textoVariavelIteracao = await declaracao.inicializacaoVariavel.aceitar(this);
|
|
304
|
+
let texto = `Linha${declaracao.linha}(tendo ${textoVariavelIteracao} como `;
|
|
305
|
+
texto += declaracao.simboloVariavel.lexema + ')';
|
|
306
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
307
|
+
let vertices = this.logicaComumConexaoArestas(aresta);
|
|
308
|
+
this.anteriores.push(aresta);
|
|
309
|
+
// Corpo, normalmente um `Bloco`.
|
|
310
|
+
const verticesCorpo = await declaracao.corpo.aceitar(this);
|
|
311
|
+
vertices = vertices.concat(verticesCorpo);
|
|
312
|
+
const ultimaArestaCorpo = verticesCorpo[verticesCorpo.length - 1].destino;
|
|
313
|
+
vertices.push(new mermaid_1.VerticeFluxograma(ultimaArestaCorpo, aresta));
|
|
314
|
+
return Promise.resolve(vertices);
|
|
547
315
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
316
|
+
visitarDeclaracaoTente(declaracao) {
|
|
317
|
+
throw new Error('Método não implementado.');
|
|
318
|
+
}
|
|
319
|
+
visitarDeclaracaoTextoDocumentacao(declaracao) {
|
|
320
|
+
throw new Error('Método não implementado.');
|
|
321
|
+
}
|
|
322
|
+
async visitarDeclaracaoVar(declaracao) {
|
|
323
|
+
let texto = `Linha${declaracao.linha}(variável: ${declaracao.simbolo.lexema}`;
|
|
324
|
+
texto += await this.logicaComumTraducaoVarEConst(declaracao, texto);
|
|
325
|
+
const aresta = new mermaid_1.ArestaFluxograma(declaracao, texto);
|
|
552
326
|
const vertices = this.logicaComumConexaoArestas(aresta);
|
|
553
327
|
this.anteriores.push(aresta);
|
|
554
|
-
return vertices;
|
|
328
|
+
return Promise.resolve(vertices);
|
|
329
|
+
}
|
|
330
|
+
visitarDeclaracaoVarMultiplo(declaracao) {
|
|
331
|
+
throw new Error('Método não implementado.');
|
|
332
|
+
}
|
|
333
|
+
async visitarExpressaoDeAtribuicao(expressao) {
|
|
334
|
+
const textoAlvo = await expressao.alvo.aceitar(this);
|
|
335
|
+
const textoValor = await expressao.valor.aceitar(this);
|
|
336
|
+
return Promise.resolve(`${textoAlvo} recebe: ${textoValor}`);
|
|
337
|
+
}
|
|
338
|
+
async visitarExpressaoAcessoIndiceVariavel(expressao) {
|
|
339
|
+
const textoIndice = await expressao.indice.aceitar(this);
|
|
340
|
+
return Promise.resolve(`no índice ${textoIndice}`);
|
|
341
|
+
}
|
|
342
|
+
visitarExpressaoAcessoIntervaloVariavel(expressao) {
|
|
343
|
+
throw new Error('Método não implementado.');
|
|
344
|
+
}
|
|
345
|
+
visitarExpressaoAcessoElementoMatriz(expressao) {
|
|
346
|
+
throw new Error('Método não implementado.');
|
|
555
347
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
348
|
+
async visitarExpressaoAcessoMetodo(expressao) {
|
|
349
|
+
return Promise.resolve(`método ${expressao.nomeMetodo}`);
|
|
350
|
+
}
|
|
351
|
+
async visitarExpressaoAcessoMetodoOuPropriedade(expressao) {
|
|
352
|
+
return Promise.resolve(`método ou propriedade ${expressao.simbolo.lexema}`);
|
|
353
|
+
}
|
|
354
|
+
async visitarExpressaoAcessoPropriedade(expressao) {
|
|
355
|
+
return Promise.resolve(`propriedade ${expressao.nomePropriedade}`);
|
|
356
|
+
}
|
|
357
|
+
async visitarExpressaoAgrupamento(expressao) {
|
|
358
|
+
return await expressao.expressao.aceitar(this);
|
|
359
|
+
}
|
|
360
|
+
visitarExpressaoArgumentoReferenciaFuncao(expressao) {
|
|
361
|
+
throw new Error('Método não implementado.');
|
|
362
|
+
}
|
|
363
|
+
visitarExpressaoAtribuicaoPorIndice(expressao) {
|
|
364
|
+
throw new Error('Método não implementado.');
|
|
365
|
+
}
|
|
366
|
+
visitarExpressaoAtribuicaoPorIndicesMatriz(expressao) {
|
|
367
|
+
throw new Error('Método não implementado.');
|
|
368
|
+
}
|
|
369
|
+
async visitarExpressaoBinaria(expressao) {
|
|
370
|
+
const operandoEsquerdo = await expressao.esquerda.aceitar(this);
|
|
371
|
+
const operandoDireito = await expressao.direita.aceitar(this);
|
|
372
|
+
switch (expressao.operador.tipo) {
|
|
373
|
+
case delegua_1.default.ADICAO:
|
|
374
|
+
return Promise.resolve(`somar ${operandoEsquerdo} e ${operandoDireito}`);
|
|
375
|
+
case delegua_1.default.MENOR:
|
|
376
|
+
return Promise.resolve(`${operandoEsquerdo} for menor que ${operandoDireito}`);
|
|
377
|
+
}
|
|
378
|
+
return Promise.resolve('');
|
|
379
|
+
}
|
|
380
|
+
async visitarExpressaoBloco(bloco) {
|
|
381
|
+
let vertices = [];
|
|
382
|
+
for (const declaracao of bloco.declaracoes) {
|
|
383
|
+
const verticesDeclaracao = await declaracao.aceitar(this);
|
|
384
|
+
vertices = vertices.concat(verticesDeclaracao);
|
|
385
|
+
}
|
|
386
|
+
return Promise.resolve(vertices);
|
|
387
|
+
}
|
|
388
|
+
async visitarExpressaoComentario(expressao) {
|
|
389
|
+
return Promise.resolve('');
|
|
390
|
+
}
|
|
391
|
+
visitarExpressaoContinua(declaracao) {
|
|
392
|
+
throw new Error('Método não implementado.');
|
|
393
|
+
}
|
|
394
|
+
async visitarExpressaoDeChamada(expressao) {
|
|
395
|
+
const textoEntidadeChamada = await expressao.entidadeChamada.aceitar(this);
|
|
396
|
+
let texto = `chamada a ${textoEntidadeChamada}`;
|
|
397
|
+
if (expressao.argumentos.length > 0) {
|
|
398
|
+
texto += `, com argumentos: `;
|
|
399
|
+
for (const argumento of expressao.argumentos) {
|
|
400
|
+
const textoArgumento = await argumento.aceitar(this);
|
|
401
|
+
texto += `${textoArgumento}, `;
|
|
402
|
+
}
|
|
403
|
+
texto = texto.slice(0, -2);
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
texto += `, sem argumentos`;
|
|
407
|
+
}
|
|
408
|
+
return Promise.resolve(texto);
|
|
409
|
+
}
|
|
410
|
+
async visitarExpressaoDefinirValor(expressao) {
|
|
411
|
+
const textoObjeto = await expressao.objeto.aceitar(this);
|
|
412
|
+
const textoValor = await expressao.valor.aceitar(this);
|
|
413
|
+
return Promise.resolve(`${expressao.nome.lexema} em ${textoObjeto} recebe ${textoValor}`);
|
|
414
|
+
}
|
|
415
|
+
visitarExpressaoFuncaoConstruto(expressao) {
|
|
416
|
+
throw new Error('Método não implementado.');
|
|
417
|
+
}
|
|
418
|
+
async visitarExpressaoDeVariavel(expressao) {
|
|
419
|
+
return Promise.resolve(expressao.simbolo.lexema);
|
|
420
|
+
}
|
|
421
|
+
async visitarExpressaoDicionario(expressao) {
|
|
422
|
+
let texto = `dicionário`;
|
|
423
|
+
if (expressao.chaves.length > 0) {
|
|
424
|
+
texto += `, com `;
|
|
425
|
+
for (const [chave, indice] of Object.entries(expressao.chaves)) {
|
|
426
|
+
texto += `chave ${chave} definida com o valor ${expressao.valores[0]}`;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
texto += ' vazio';
|
|
431
|
+
}
|
|
432
|
+
return Promise.resolve(texto);
|
|
433
|
+
}
|
|
434
|
+
visitarExpressaoExpressaoRegular(expressao) {
|
|
435
|
+
throw new Error('Método não implementado.');
|
|
436
|
+
}
|
|
437
|
+
visitarExpressaoFalhar(expressao) {
|
|
438
|
+
throw new Error('Método não implementado.');
|
|
439
|
+
}
|
|
440
|
+
visitarExpressaoFimPara(declaracao) {
|
|
441
|
+
throw new Error('Método não implementado.');
|
|
442
|
+
}
|
|
443
|
+
visitarExpressaoFormatacaoEscrita(declaracao) {
|
|
444
|
+
throw new Error('Método não implementado.');
|
|
445
|
+
}
|
|
446
|
+
async visitarExpressaoIsto(expressao) {
|
|
447
|
+
return Promise.resolve('this');
|
|
448
|
+
}
|
|
449
|
+
async visitarExpressaoLeia(expressao) {
|
|
450
|
+
let texto = 'leia da entrada';
|
|
451
|
+
if (expressao.argumentos && expressao.argumentos.length > 0) {
|
|
452
|
+
const textoArgumento = await expressao.argumentos[0].aceitar(this);
|
|
453
|
+
texto += `, imprimindo antes: \\'${textoArgumento}\\'`;
|
|
454
|
+
}
|
|
455
|
+
return Promise.resolve(texto);
|
|
456
|
+
}
|
|
457
|
+
async visitarExpressaoLiteral(expressao) {
|
|
458
|
+
switch (expressao.tipo) {
|
|
459
|
+
case 'lógico':
|
|
460
|
+
return Promise.resolve(expressao.valor ? 'verdadeiro' : 'falso');
|
|
461
|
+
case 'texto':
|
|
462
|
+
return Promise.resolve(`\\'${expressao.valor}\\'`);
|
|
463
|
+
default:
|
|
464
|
+
return Promise.resolve(String(expressao.valor));
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
visitarExpressaoLogica(expressao) {
|
|
468
|
+
throw new Error('Método não implementado.');
|
|
469
|
+
}
|
|
470
|
+
visitarExpressaoReferenciaFuncao(expressao) {
|
|
471
|
+
throw new Error('Método não implementado.');
|
|
472
|
+
}
|
|
473
|
+
async visitarExpressaoRetornar(expressao) {
|
|
474
|
+
let texto = `Linha${expressao.linha}(retorna`;
|
|
475
|
+
if (expressao.valor) {
|
|
476
|
+
texto += `: ${await expressao.valor.aceitar(this)}`;
|
|
560
477
|
}
|
|
561
478
|
texto += ')';
|
|
562
|
-
const aresta = new mermaid_1.ArestaFluxograma(
|
|
479
|
+
const aresta = new mermaid_1.ArestaFluxograma(expressao, texto);
|
|
563
480
|
const vertices = this.logicaComumConexaoArestas(aresta);
|
|
564
481
|
this.anteriores.push(aresta);
|
|
482
|
+
return Promise.resolve(vertices);
|
|
483
|
+
}
|
|
484
|
+
async visitarExpressaoSeparador(expressao) {
|
|
485
|
+
return Promise.resolve(`${expressao.conteudo} `);
|
|
486
|
+
}
|
|
487
|
+
visitarExpressaoSuper(expressao) {
|
|
488
|
+
throw new Error('Método não implementado.');
|
|
489
|
+
}
|
|
490
|
+
visitarExpressaoSustar(declaracao) {
|
|
491
|
+
throw new Error('Método não implementado.');
|
|
492
|
+
}
|
|
493
|
+
visitarExpressaoTupla(expressao) {
|
|
494
|
+
throw new Error('Método não implementado.');
|
|
495
|
+
}
|
|
496
|
+
visitarExpressaoTuplaN(expressao) {
|
|
497
|
+
throw new Error('Método não implementado.');
|
|
498
|
+
}
|
|
499
|
+
visitarExpressaoTipoDe(expressao) {
|
|
500
|
+
throw new Error('Método não implementado.');
|
|
501
|
+
}
|
|
502
|
+
async visitarExpressaoUnaria(expressao) {
|
|
503
|
+
const textoOperando = await expressao.operando.aceitar(this);
|
|
504
|
+
let textoOperador = '';
|
|
505
|
+
switch (expressao.operador.tipo) {
|
|
506
|
+
case delegua_1.default.INCREMENTAR:
|
|
507
|
+
textoOperador = `incrementar ${textoOperando} em 1`;
|
|
508
|
+
break;
|
|
509
|
+
case delegua_1.default.DECREMENTAR:
|
|
510
|
+
textoOperador = `decrementar ${textoOperando} de 1`;
|
|
511
|
+
break;
|
|
512
|
+
}
|
|
513
|
+
switch (expressao.incidenciaOperador) {
|
|
514
|
+
case 'ANTES':
|
|
515
|
+
return Promise.resolve(`${textoOperador}, devolver valor de ${textoOperando}`);
|
|
516
|
+
case 'DEPOIS':
|
|
517
|
+
return Promise.resolve(`devolver valor de ${textoOperando}, ${textoOperador}`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
async visitarExpressaoVetor(expressao) {
|
|
521
|
+
let texto = `vetor: `;
|
|
522
|
+
for (const elemento of expressao.valores) {
|
|
523
|
+
texto += await elemento.aceitar(this);
|
|
524
|
+
}
|
|
525
|
+
return Promise.resolve(texto);
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Traduz uma declaração de Expressao que contém uma chamada de função,
|
|
529
|
+
* criando os vértices necessários para conectar ao subgrafo da função.
|
|
530
|
+
*/
|
|
531
|
+
async traduzirChamadaFuncao(declaracaoExpressao, chamada) {
|
|
532
|
+
// Verifica se é uma chamada a uma função conhecida
|
|
533
|
+
if (chamada.entidadeChamada.constructor.name === 'Variavel') {
|
|
534
|
+
const variavel = chamada.entidadeChamada;
|
|
535
|
+
const nomeFuncao = variavel.simbolo.lexema;
|
|
536
|
+
if (this.declaracoesFuncoes[nomeFuncao]) {
|
|
537
|
+
const subgrafo = this.declaracoesFuncoes[nomeFuncao];
|
|
538
|
+
let vertices = [];
|
|
539
|
+
// Conecta do fluxo atual para a entrada da função
|
|
540
|
+
const textoPreChamada = `Linha${declaracaoExpressao.linha}(${await chamada.aceitar(this)})`;
|
|
541
|
+
const arestaPreChamada = new mermaid_1.ArestaFluxograma(declaracaoExpressao, textoPreChamada);
|
|
542
|
+
vertices = vertices.concat(this.logicaComumConexaoArestas(arestaPreChamada));
|
|
543
|
+
// Conecta a pré-chamada ao início da função
|
|
544
|
+
vertices.push(new mermaid_1.VerticeFluxograma(arestaPreChamada, subgrafo.arestaInicial));
|
|
545
|
+
// A saída da função volta para o fluxo principal
|
|
546
|
+
this.anteriores = [subgrafo.arestaFinal];
|
|
547
|
+
return Promise.resolve(vertices);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
// Se não for uma função conhecida, trata como expressão normal
|
|
551
|
+
return Promise.resolve([]);
|
|
552
|
+
}
|
|
553
|
+
logicaComumConexaoArestas(aresta) {
|
|
554
|
+
const vertices = [];
|
|
555
|
+
while (this.anteriores.length > 0) {
|
|
556
|
+
const anterior = this.anteriores.shift();
|
|
557
|
+
let textoVertice = undefined;
|
|
558
|
+
if (this.ultimaDicaVertice) {
|
|
559
|
+
textoVertice = String(this.ultimaDicaVertice);
|
|
560
|
+
this.ultimaDicaVertice = undefined;
|
|
561
|
+
}
|
|
562
|
+
vertices.push(new mermaid_1.VerticeFluxograma(anterior, aresta, textoVertice));
|
|
563
|
+
}
|
|
565
564
|
return vertices;
|
|
566
565
|
}
|
|
566
|
+
async logicaComumCaminhoEscolha(declaracaoEscolha, caminhoEscolha, linha, textoIdentificadorOuLiteral, caminhoPadrao) {
|
|
567
|
+
let textoCaso = '';
|
|
568
|
+
if (!caminhoPadrao) {
|
|
569
|
+
textoCaso = `caso ${textoIdentificadorOuLiteral} seja igual a `;
|
|
570
|
+
for (const condicao of caminhoEscolha.condicoes) {
|
|
571
|
+
const textoCondicao = await condicao.aceitar(this);
|
|
572
|
+
textoCaso += `${textoCondicao} ou `;
|
|
573
|
+
}
|
|
574
|
+
textoCaso = textoCaso.slice(0, -4);
|
|
575
|
+
textoCaso += ':';
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
textoCaso = `caso ${textoIdentificadorOuLiteral} tenha qualquer outro valor:`;
|
|
579
|
+
}
|
|
580
|
+
let textoCaminho = `Linha${linha}(${textoCaso})`;
|
|
581
|
+
const arestaCondicaoCaminho = new mermaid_1.ArestaFluxograma(declaracaoEscolha, textoCaminho);
|
|
582
|
+
this.anteriores.push(arestaCondicaoCaminho);
|
|
583
|
+
let verticesResolvidos = [];
|
|
584
|
+
for (const declaracaoCaminho of caminhoEscolha.declaracoes) {
|
|
585
|
+
const verticesDeclaracoes = await declaracaoCaminho.aceitar(this);
|
|
586
|
+
verticesResolvidos = verticesResolvidos.concat(verticesDeclaracoes);
|
|
587
|
+
this.anteriores.pop();
|
|
588
|
+
this.anteriores.push(verticesDeclaracoes[verticesDeclaracoes.length - 1].destino);
|
|
589
|
+
}
|
|
590
|
+
this.anteriores.pop();
|
|
591
|
+
return Promise.resolve({
|
|
592
|
+
caminho: arestaCondicaoCaminho,
|
|
593
|
+
declaracoesCaminho: verticesResolvidos,
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
async logicaComumTraducaoVarEConst(declaracaoVarOuConst, textoInicial) {
|
|
597
|
+
if (declaracaoVarOuConst.inicializador) {
|
|
598
|
+
textoInicial += `, iniciada com: ${await declaracaoVarOuConst.inicializador.aceitar(this)}`;
|
|
599
|
+
}
|
|
600
|
+
textoInicial += ')';
|
|
601
|
+
return Promise.resolve(textoInicial);
|
|
602
|
+
}
|
|
567
603
|
/**
|
|
568
604
|
* Ponto de entrada para a tradução de declarações em um fluxograma
|
|
569
605
|
* no formato MermaidJs.
|
|
570
606
|
* @param {Declaracao[]} declaracoes As declarações a serem traduzidas.
|
|
571
607
|
* @returns {string} Texto no formato MermaidJs representando o fluxograma.
|
|
572
608
|
*/
|
|
573
|
-
traduzir(declaracoes) {
|
|
609
|
+
async traduzir(declaracoes) {
|
|
574
610
|
this.anteriores = [];
|
|
575
611
|
this.vertices = [];
|
|
576
612
|
let resultado = 'graph TD;\n';
|
|
@@ -578,7 +614,7 @@ class TradutorMermaidJs {
|
|
|
578
614
|
this.declaracoesFuncoes = {};
|
|
579
615
|
this.declaracoesClasses = {};
|
|
580
616
|
for (const declaracao of declaracoes) {
|
|
581
|
-
this.vertices = this.vertices.concat(
|
|
617
|
+
this.vertices = this.vertices.concat(await declaracao.aceitar(this));
|
|
582
618
|
}
|
|
583
619
|
// Renderiza os subgrafos de funções
|
|
584
620
|
if (Object.keys(this.declaracoesFuncoes).length > 0) {
|