@designliquido/delegua 0.2.12 → 0.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.
Files changed (99) hide show
  1. package/bin/package.json +1 -1
  2. package/fontes/ambiente.d.ts +1 -14
  3. package/fontes/ambiente.js +1 -53
  4. package/fontes/ambiente.js.map +1 -1
  5. package/fontes/avaliador-sintatico/avaliador-sintatico.js +10 -10
  6. package/fontes/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
  7. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-egua-classico.js +7 -7
  8. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-egua-classico.js.map +1 -1
  9. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-eguap.js +7 -7
  10. package/fontes/avaliador-sintatico/dialetos/avaliador-sintatico-eguap.js.map +1 -1
  11. package/fontes/bibliotecas/biblioteca-global.d.ts +2 -2
  12. package/fontes/bibliotecas/biblioteca-global.js +15 -15
  13. package/fontes/bibliotecas/biblioteca-global.js.map +1 -1
  14. package/fontes/construtos/atribuir.d.ts +2 -2
  15. package/fontes/construtos/atribuir.js.map +1 -1
  16. package/fontes/construtos/chamada.d.ts +2 -1
  17. package/fontes/construtos/chamada.js.map +1 -1
  18. package/fontes/construtos/literal.d.ts +2 -1
  19. package/fontes/construtos/literal.js.map +1 -1
  20. package/fontes/construtos/variavel.d.ts +2 -2
  21. package/fontes/construtos/variavel.js.map +1 -1
  22. package/fontes/declaracoes/bloco.d.ts +2 -1
  23. package/fontes/declaracoes/bloco.js.map +1 -1
  24. package/fontes/declaracoes/escreva.d.ts +2 -1
  25. package/fontes/declaracoes/escreva.js.map +1 -1
  26. package/fontes/declaracoes/expressao.d.ts +2 -1
  27. package/fontes/declaracoes/expressao.js.map +1 -1
  28. package/fontes/declaracoes/funcao.d.ts +2 -2
  29. package/fontes/declaracoes/funcao.js.map +1 -1
  30. package/fontes/declaracoes/retorna.d.ts +2 -1
  31. package/fontes/declaracoes/retorna.js.map +1 -1
  32. package/fontes/declaracoes/se.d.ts +2 -1
  33. package/fontes/declaracoes/se.js.map +1 -1
  34. package/fontes/declaracoes/var.d.ts +2 -2
  35. package/fontes/declaracoes/var.js.map +1 -1
  36. package/fontes/delegua.d.ts +2 -1
  37. package/fontes/delegua.js +12 -7
  38. package/fontes/delegua.js.map +1 -1
  39. package/fontes/estruturas/delegua-classe.d.ts +14 -0
  40. package/fontes/estruturas/{classe.js → delegua-classe.js} +4 -4
  41. package/fontes/estruturas/delegua-classe.js.map +1 -0
  42. package/fontes/estruturas/funcao-padrao.d.ts +1 -1
  43. package/fontes/estruturas/funcao-padrao.js +1 -1
  44. package/fontes/estruturas/funcao-padrao.js.map +1 -1
  45. package/fontes/estruturas/funcao.d.ts +9 -7
  46. package/fontes/estruturas/funcao.js +20 -26
  47. package/fontes/estruturas/funcao.js.map +1 -1
  48. package/fontes/estruturas/index.d.ts +2 -2
  49. package/fontes/estruturas/index.js +2 -2
  50. package/fontes/estruturas/index.js.map +1 -1
  51. package/fontes/estruturas/{instancia.d.ts → objeto-delegua-classe.d.ts} +3 -2
  52. package/fontes/estruturas/objeto-delegua-classe.js +28 -0
  53. package/fontes/estruturas/objeto-delegua-classe.js.map +1 -0
  54. package/fontes/excecoes/index.d.ts +0 -3
  55. package/fontes/excecoes/index.js +0 -3
  56. package/fontes/excecoes/index.js.map +1 -1
  57. package/fontes/interfaces/escopo-execucao.d.ts +7 -0
  58. package/fontes/interfaces/escopo-execucao.js +3 -0
  59. package/fontes/interfaces/escopo-execucao.js.map +1 -0
  60. package/fontes/interfaces/interpretador-interface.d.ts +6 -4
  61. package/fontes/interfaces/pilha-interface.d.ts +2 -2
  62. package/fontes/interpretador/dialetos/egua-classico.d.ts +27 -19
  63. package/fontes/interpretador/dialetos/egua-classico.js +121 -139
  64. package/fontes/interpretador/dialetos/egua-classico.js.map +1 -1
  65. package/fontes/interpretador/interpretador.d.ts +38 -18
  66. package/fontes/interpretador/interpretador.js +142 -139
  67. package/fontes/interpretador/interpretador.js.map +1 -1
  68. package/fontes/interpretador/pilha-escopos-execucao.d.ts +20 -0
  69. package/fontes/interpretador/pilha-escopos-execucao.js +74 -0
  70. package/fontes/interpretador/pilha-escopos-execucao.js.map +1 -0
  71. package/fontes/quebras/index.d.ts +10 -0
  72. package/fontes/quebras/index.js +51 -0
  73. package/fontes/quebras/index.js.map +1 -0
  74. package/fontes/resolvedor/index.d.ts +4 -62
  75. package/fontes/resolvedor/index.js +18 -340
  76. package/fontes/resolvedor/index.js.map +1 -1
  77. package/fontes/resolvedor/resolvedor.d.ts +64 -0
  78. package/fontes/resolvedor/resolvedor.js +345 -0
  79. package/fontes/resolvedor/resolvedor.js.map +1 -0
  80. package/package.json +1 -1
  81. package/testes/biblioteca-global.test.js +15 -29
  82. package/testes/biblioteca-global.test.js.map +1 -1
  83. package/testes/egua-classico/interpretador.test.js +21 -41
  84. package/testes/egua-classico/interpretador.test.js.map +1 -1
  85. package/testes/interpretador.test.js +21 -41
  86. package/testes/interpretador.test.js.map +1 -1
  87. package/fontes/estruturas/classe.d.ts +0 -11
  88. package/fontes/estruturas/classe.js.map +0 -1
  89. package/fontes/estruturas/instancia.js +0 -28
  90. package/fontes/estruturas/instancia.js.map +0 -1
  91. package/fontes/excecoes/excecao-continuar.d.ts +0 -2
  92. package/fontes/excecoes/excecao-continuar.js +0 -27
  93. package/fontes/excecoes/excecao-continuar.js.map +0 -1
  94. package/fontes/excecoes/excecao-retornar.d.ts +0 -4
  95. package/fontes/excecoes/excecao-retornar.js +0 -30
  96. package/fontes/excecoes/excecao-retornar.js.map +0 -1
  97. package/fontes/excecoes/excecao-sustar.d.ts +0 -2
  98. package/fontes/excecoes/excecao-sustar.js +0 -27
  99. package/fontes/excecoes/excecao-sustar.js.map +0 -1
@@ -1,11 +1,13 @@
1
1
  import { Ambiente } from '../ambiente';
2
2
  import { InterpretadorInterface, ResolvedorInterface, SimboloInterface } from '../interfaces';
3
- import { Classe, Enquanto, Escolha, Escreva, Fazer, Funcao, Importar, Para, Se, Tente } from '../declaracoes';
3
+ import { Bloco, Classe, Declaracao, Enquanto, Escolha, Escreva, Fazer, Funcao, Importar, Para, Retorna, Se, Tente, Var } from '../declaracoes';
4
4
  import { DeleguaFuncao } from '../estruturas';
5
- import { Construto, Super } from '../construtos';
5
+ import { Atribuir, Construto, Super } from '../construtos';
6
6
  import { ErroInterpretador } from './erro-interpretador';
7
7
  import { RetornoInterpretador } from './retorno-interpretador';
8
8
  import { ImportadorInterface } from '../interfaces/importador-interface';
9
+ import { PilhaEscoposExecucao } from './pilha-escopos-execucao';
10
+ import { ContinuarQuebra, RetornoQuebra, SustarQuebra } from '../quebras';
9
11
  /**
10
12
  * O Interpretador visita todos os elementos complexos gerados pelo analisador sintático (Parser),
11
13
  * e de fato executa a lógica de programação descrita no código.
@@ -14,17 +16,16 @@ export declare class Interpretador implements InterpretadorInterface {
14
16
  importador: ImportadorInterface;
15
17
  resolvedor: ResolvedorInterface;
16
18
  diretorioBase: any;
17
- global: Ambiente;
18
- ambiente: Ambiente;
19
19
  locais: Map<Construto, number>;
20
20
  erros: ErroInterpretador[];
21
21
  performance: boolean;
22
22
  funcaoDeRetorno: Function;
23
23
  resultadoInterpretador: Array<String>;
24
+ pilhaEscoposExecucao: PilhaEscoposExecucao;
24
25
  constructor(importador: ImportadorInterface, resolvedor: ResolvedorInterface, diretorioBase: string, performance: boolean, funcaoDeRetorno: Function);
25
26
  resolver(expressao: any, profundidade: number): void;
26
27
  visitarExpressaoLiteral(expressao: any): any;
27
- avaliar(expressao: any): any;
28
+ avaliar(expressao: Construto): any;
28
29
  visitarExpressaoAgrupamento(expressao: any): any;
29
30
  eVerdadeiro(objeto: any): boolean;
30
31
  verificarOperandoNumero(operador: any, operando: any): void;
@@ -33,25 +34,31 @@ export declare class Interpretador implements InterpretadorInterface {
33
34
  verificarOperandosNumeros(operador: any, direita: any, esquerda: any): void;
34
35
  visitarExpressaoBinaria(expressao: any): string | number | boolean;
35
36
  visitarExpressaoDeChamada(expressao: any): any;
36
- visitarExpressaoDeAtribuicao(expressao: any): any;
37
+ visitarExpressaoDeAtribuicao(expressao: Atribuir): any;
37
38
  procurarVariavel(simbolo: SimboloInterface, expressao: any): any;
38
39
  visitarExpressaoDeVariavel(expressao: any): any;
39
40
  visitarDeclaracaoDeExpressao(declaracao: any): any;
40
41
  visitarExpressaoLogica(expressao: any): any;
41
42
  visitarExpressaoSe(declaracao: Se): any;
42
43
  visitarExpressaoPara(declaracao: Para): any;
43
- visitarExpressaoFazer(declaracao: Fazer): void;
44
- visitarExpressaoEscolha(declaracao: Escolha): void;
45
- visitarExpressaoTente(declaracao: Tente): void;
44
+ visitarExpressaoFazer(declaracao: Fazer): any;
45
+ visitarExpressaoEscolha(declaracao: Escolha): any;
46
+ visitarExpressaoTente(declaracao: Tente): any;
46
47
  visitarExpressaoEnquanto(declaracao: Enquanto): any;
47
- visitarExpressaoImportar(declaracao: Importar): {};
48
+ visitarExpressaoImportar(declaracao: Importar): any;
48
49
  visitarExpressaoEscreva(declaracao: Escreva): any;
49
- executarBloco(declaracoes: any, ambiente: any): void;
50
- visitarExpressaoBloco(declaracao: any): any;
51
- visitarExpressaoVar(declaracao: any): any;
52
- visitarExpressaoContinua(declaracao?: any): void;
53
- visitarExpressaoSustar(declaracao?: any): void;
54
- visitarExpressaoRetornar(declaracao: any): void;
50
+ /**
51
+ * Empilha declarações na pilha de escopos de execução, cria um novo ambiente e
52
+ * executa as declarações empilhadas.
53
+ * @param declaracoes Um vetor de declaracoes a ser executado.
54
+ * @param ambiente O ambiente de execução quando houver, como parâmetros, argumentos, etc.
55
+ */
56
+ executarBloco(declaracoes: Declaracao[], ambiente?: Ambiente): any;
57
+ visitarExpressaoBloco(declaracao: Bloco): any;
58
+ visitarExpressaoVar(declaracao: Var): any;
59
+ visitarExpressaoContinua(declaracao?: any): ContinuarQuebra;
60
+ visitarExpressaoSustar(declaracao?: any): SustarQuebra;
61
+ visitarExpressaoRetornar(declaracao: Retorna): RetornoQuebra;
55
62
  visitarExpressaoDeleguaFuncao(expressao: any): DeleguaFuncao;
56
63
  visitarExpressaoAtribuicaoSobrescrita(expressao: any): void;
57
64
  visitarExpressaoAcessoIndiceVariavel(expressao: any): any;
@@ -64,6 +71,19 @@ export declare class Interpretador implements InterpretadorInterface {
64
71
  visitarExpressaoVetor(expressao: any): any[];
65
72
  visitarExpressaoSuper(expressao: Super): any;
66
73
  paraTexto(objeto: any): any;
67
- executar(declaracao: any, mostrarResultado?: boolean): void;
68
- interpretar(objeto: any): RetornoInterpretador;
74
+ executar(declaracao: Declaracao, mostrarResultado?: boolean): any;
75
+ /**
76
+ * Executa o último escopo empilhado no topo na pilha de escopos do interpretador.
77
+ * @param manterAmbiente Se verdadeiro, ambiente do topo da pilha de escopo é copiado para o ambiente imediatamente abaixo.
78
+ * @returns O resultado da execução do escopo, se houver.
79
+ */
80
+ executarUltimoEscopo(manterAmbiente?: boolean): any;
81
+ /**
82
+ * Método que efetivamente inicia o processo de interpretação.
83
+ * @param declaracoes Um vetor de declarações gerado pelo Avaliador Sintático.
84
+ * @param manterAmbiente Se ambiente de execução (variáveis, classes, etc.) deve ser mantido. Normalmente usado
85
+ * pelo modo REPL (LEIA).
86
+ * @returns Um objeto com o resultado da interpretação.
87
+ */
88
+ interpretar(declaracoes: Declaracao[], manterAmbiente?: boolean): RetornoInterpretador;
69
89
  }
@@ -35,6 +35,8 @@ var biblioteca_global_1 = __importDefault(require("../bibliotecas/biblioteca-glo
35
35
  var importar_biblioteca_1 = __importDefault(require("../bibliotecas/importar-biblioteca"));
36
36
  var excecoes_1 = require("../excecoes");
37
37
  var estruturas_1 = require("../estruturas");
38
+ var pilha_escopos_execucao_1 = require("./pilha-escopos-execucao");
39
+ var quebras_1 = require("../quebras");
38
40
  /**
39
41
  * O Interpretador visita todos os elementos complexos gerados pelo analisador sintático (Parser),
40
42
  * e de fato executa a lógica de programação descrita no código.
@@ -49,11 +51,16 @@ var Interpretador = /** @class */ (function () {
49
51
  this.diretorioBase = diretorioBase;
50
52
  this.performance = performance;
51
53
  this.funcaoDeRetorno = funcaoDeRetorno || console.log;
52
- this.global = new ambiente_1.Ambiente();
53
- this.ambiente = this.global;
54
54
  this.locais = new Map();
55
55
  this.erros = [];
56
- this.global = (0, biblioteca_global_1.default)(this, this.global);
56
+ this.pilhaEscoposExecucao = new pilha_escopos_execucao_1.PilhaEscoposExecucao();
57
+ var escopoExecucao = {
58
+ declaracoes: [],
59
+ declaracaoAtual: 0,
60
+ ambiente: new ambiente_1.Ambiente()
61
+ };
62
+ this.pilhaEscoposExecucao.empilhar(escopoExecucao);
63
+ (0, biblioteca_global_1.default)(this, this.pilhaEscoposExecucao);
57
64
  }
58
65
  Interpretador.prototype.resolver = function (expressao, profundidade) {
59
66
  this.locais.set(expressao, profundidade);
@@ -62,9 +69,7 @@ var Interpretador = /** @class */ (function () {
62
69
  return expressao.valor;
63
70
  };
64
71
  Interpretador.prototype.avaliar = function (expressao) {
65
- if (expressao.aceitar) {
66
- return expressao.aceitar(this);
67
- }
72
+ return expressao.aceitar(this);
68
73
  };
69
74
  Interpretador.prototype.visitarExpressaoAgrupamento = function (expressao) {
70
75
  return this.avaliar(expressao.expressao);
@@ -198,36 +203,29 @@ var Interpretador = /** @class */ (function () {
198
203
  else {
199
204
  if (parametros &&
200
205
  parametros.length > 0 &&
201
- parametros[parametros.length - 1]['tipo'] === 'wildcard') {
206
+ parametros[parametros.length - 1]['tipo'] === 'estrela') {
202
207
  var novosArgumentos = argumentos.slice(0, parametros.length - 1);
203
208
  novosArgumentos.push(argumentos.slice(parametros.length - 1, argumentos.length));
204
209
  argumentos = novosArgumentos;
205
210
  }
206
211
  }
207
212
  if (entidadeChamada instanceof estruturas_1.FuncaoPadrao) {
208
- return entidadeChamada.chamar(this, argumentos, expressao.entidadeChamada.nome);
213
+ try {
214
+ return entidadeChamada.chamar(argumentos, expressao.entidadeChamada.nome);
215
+ }
216
+ catch (erro) {
217
+ this.erros.push(erro);
218
+ }
209
219
  }
210
220
  return entidadeChamada.chamar(this, argumentos);
211
221
  };
212
222
  Interpretador.prototype.visitarExpressaoDeAtribuicao = function (expressao) {
213
223
  var valor = this.avaliar(expressao.valor);
214
- var distancia = this.locais.get(expressao);
215
- if (distancia !== undefined) {
216
- this.ambiente.atribuirVariavelEm(distancia, expressao.simbolo, valor);
217
- }
218
- else {
219
- this.ambiente.atribuirVariavel(expressao.simbolo, valor);
220
- }
224
+ this.pilhaEscoposExecucao.atribuirVariavel(expressao.simbolo, valor);
221
225
  return valor;
222
226
  };
223
227
  Interpretador.prototype.procurarVariavel = function (simbolo, expressao) {
224
- var distancia = this.locais.get(expressao);
225
- if (distancia !== undefined) {
226
- return this.ambiente.obterVariavelEm(distancia, simbolo.lexema);
227
- }
228
- else {
229
- return this.global.obterVariavel(simbolo);
230
- }
228
+ return this.pilhaEscoposExecucao.obterVariavel(simbolo);
231
229
  };
232
230
  Interpretador.prototype.visitarExpressaoDeVariavel = function (expressao) {
233
231
  return this.procurarVariavel(expressao.simbolo, expressao);
@@ -263,8 +261,7 @@ var Interpretador = /** @class */ (function () {
263
261
  };
264
262
  Interpretador.prototype.visitarExpressaoSe = function (declaracao) {
265
263
  if (this.eVerdadeiro(this.avaliar(declaracao.condicao))) {
266
- this.executar(declaracao.caminhoEntao);
267
- return null;
264
+ return this.executar(declaracao.caminhoEntao);
268
265
  }
269
266
  for (var i = 0; i < declaracao.caminhosSeSenao.length; i++) {
270
267
  var atual = declaracao.caminhosSeSenao[i];
@@ -282,24 +279,16 @@ var Interpretador = /** @class */ (function () {
282
279
  if (declaracao.inicializador !== null) {
283
280
  this.avaliar(declaracao.inicializador);
284
281
  }
285
- while (true) {
286
- if (declaracao.condicao !== null) {
287
- if (!this.eVerdadeiro(this.avaliar(declaracao.condicao))) {
288
- break;
289
- }
282
+ var retornoExecucao;
283
+ while (!(retornoExecucao instanceof quebras_1.Quebra)) {
284
+ if (declaracao.condicao !== null && !this.eVerdadeiro(this.avaliar(declaracao.condicao))) {
285
+ break;
290
286
  }
291
287
  try {
292
- this.executar(declaracao.corpo);
288
+ retornoExecucao = this.executar(declaracao.corpo);
293
289
  }
294
290
  catch (erro) {
295
- if (erro instanceof excecoes_1.ExcecaoSustar) {
296
- break;
297
- }
298
- else if (erro instanceof excecoes_1.ExcecaoContinuar) {
299
- }
300
- else {
301
- throw erro;
302
- }
291
+ throw erro;
303
292
  }
304
293
  if (declaracao.incrementar !== null) {
305
294
  this.avaliar(declaracao.incrementar);
@@ -308,21 +297,15 @@ var Interpretador = /** @class */ (function () {
308
297
  return null;
309
298
  };
310
299
  Interpretador.prototype.visitarExpressaoFazer = function (declaracao) {
300
+ var retornoExecucao;
311
301
  do {
312
302
  try {
313
- this.executar(declaracao.caminhoFazer);
303
+ retornoExecucao = this.executar(declaracao.caminhoFazer);
314
304
  }
315
305
  catch (erro) {
316
- if (erro instanceof excecoes_1.ExcecaoSustar) {
317
- break;
318
- }
319
- else if (erro instanceof excecoes_1.ExcecaoContinuar) {
320
- }
321
- else {
322
- throw erro;
323
- }
306
+ throw erro;
324
307
  }
325
- } while (this.eVerdadeiro(this.avaliar(declaracao.condicaoEnquanto)));
308
+ } while (!(retornoExecucao instanceof quebras_1.Quebra) && this.eVerdadeiro(this.avaliar(declaracao.condicaoEnquanto)));
326
309
  };
327
310
  Interpretador.prototype.visitarExpressaoEscolha = function (declaracao) {
328
311
  var condicaoEscolha = this.avaliar(declaracao.condicao);
@@ -332,8 +315,8 @@ var Interpretador = /** @class */ (function () {
332
315
  try {
333
316
  for (var i = 0; i < caminhos.length; i++) {
334
317
  var caminho_1 = caminhos[i];
335
- for (var j = 0; j < caminho_1.conditions.length; j++) {
336
- if (this.avaliar(caminho_1.conditions[j]) === condicaoEscolha) {
318
+ for (var j = 0; j < caminho_1.condicoes.length; j++) {
319
+ if (this.avaliar(caminho_1.condicoes[j]) === condicaoEscolha) {
337
320
  encontrado = true;
338
321
  try {
339
322
  for (var k = 0; k < caminho_1.declaracoes.length; k++) {
@@ -341,11 +324,7 @@ var Interpretador = /** @class */ (function () {
341
324
  }
342
325
  }
343
326
  catch (erro) {
344
- if (erro instanceof excecoes_1.ExcecaoContinuar) {
345
- }
346
- else {
347
- throw erro;
348
- }
327
+ throw erro;
349
328
  }
350
329
  }
351
330
  }
@@ -357,48 +336,41 @@ var Interpretador = /** @class */ (function () {
357
336
  }
358
337
  }
359
338
  catch (erro) {
360
- if (erro instanceof excecoes_1.ExcecaoSustar) {
361
- }
362
- else {
363
- throw erro;
364
- }
339
+ throw erro;
365
340
  }
366
341
  };
367
342
  Interpretador.prototype.visitarExpressaoTente = function (declaracao) {
368
343
  try {
369
344
  var sucesso = true;
370
345
  try {
371
- this.executarBloco(declaracao.caminhoTente, new ambiente_1.Ambiente(this.ambiente));
346
+ this.executarBloco(declaracao.caminhoTente);
372
347
  }
373
348
  catch (erro) {
374
349
  sucesso = false;
375
350
  if (declaracao.caminhoPegue !== null) {
376
- this.executarBloco(declaracao.caminhoPegue, new ambiente_1.Ambiente(this.ambiente));
351
+ this.executarBloco(declaracao.caminhoPegue);
352
+ }
353
+ else {
354
+ this.erros.push(erro);
377
355
  }
378
356
  }
379
357
  if (sucesso && declaracao.caminhoSenao !== null) {
380
- this.executarBloco(declaracao.caminhoSenao, new ambiente_1.Ambiente(this.ambiente));
358
+ this.executarBloco(declaracao.caminhoSenao);
381
359
  }
382
360
  }
383
361
  finally {
384
362
  if (declaracao.caminhoFinalmente !== null)
385
- this.executarBloco(declaracao.caminhoFinalmente, new ambiente_1.Ambiente(this.ambiente));
363
+ this.executarBloco(declaracao.caminhoFinalmente);
386
364
  }
387
365
  };
388
366
  Interpretador.prototype.visitarExpressaoEnquanto = function (declaracao) {
389
- while (this.eVerdadeiro(this.avaliar(declaracao.condicao))) {
367
+ var retornoExecucao;
368
+ while (!(retornoExecucao instanceof quebras_1.Quebra) && this.eVerdadeiro(this.avaliar(declaracao.condicao))) {
390
369
  try {
391
- this.executar(declaracao.corpo);
370
+ retornoExecucao = this.executar(declaracao.corpo);
392
371
  }
393
372
  catch (erro) {
394
- if (erro instanceof excecoes_1.ExcecaoSustar) {
395
- break;
396
- }
397
- else if (erro instanceof excecoes_1.ExcecaoContinuar) {
398
- }
399
- else {
400
- throw erro;
401
- }
373
+ throw erro;
402
374
  }
403
375
  }
404
376
  return null;
@@ -407,74 +379,77 @@ var Interpretador = /** @class */ (function () {
407
379
  var caminhoRelativo = this.avaliar(declaracao.caminho);
408
380
  var caminhoTotal = caminho.join(this.diretorioBase, caminhoRelativo);
409
381
  var nomeArquivo = caminho.basename(caminhoTotal);
410
- if (!caminhoTotal.endsWith('.egua') && !caminhoTotal.endsWith('.delegua')) {
382
+ if (!caminhoTotal.endsWith('.egua') &&
383
+ !caminhoTotal.endsWith('.delegua')) {
411
384
  return (0, importar_biblioteca_1.default)(caminhoRelativo);
412
385
  }
413
386
  var conteudoImportacao = this.importador.importar(caminhoRelativo);
414
- var retornoInterpretador = this.interpretar(conteudoImportacao.retornoAvaliadorSintatico);
415
- var funcoesDeclaradas = this.global.obterTodasDeleguaFuncao();
387
+ var retornoInterpretador = this.interpretar(conteudoImportacao.retornoAvaliadorSintatico.declaracoes);
388
+ var funcoesDeclaradas = this.pilhaEscoposExecucao.obterTodasDeleguaFuncao();
416
389
  var eDicionario = function (objeto) { return objeto.constructor === Object; };
417
390
  if (eDicionario(funcoesDeclaradas)) {
418
391
  var novoModulo = new estruturas_1.DeleguaModulo();
419
392
  var chaves = Object.keys(funcoesDeclaradas);
420
393
  for (var i = 0; i < chaves.length; i++) {
421
- novoModulo.componentes[chaves[i]] = funcoesDeclaradas[chaves[i]];
394
+ novoModulo.componentes[chaves[i]] =
395
+ funcoesDeclaradas[chaves[i]];
422
396
  }
423
397
  return novoModulo;
424
398
  }
425
399
  return funcoesDeclaradas;
426
400
  };
427
401
  Interpretador.prototype.visitarExpressaoEscreva = function (declaracao) {
428
- var valor = this.avaliar(declaracao.expressao);
429
- var formatoTexto = this.paraTexto(valor);
430
- this.resultadoInterpretador.push(formatoTexto);
431
- this.funcaoDeRetorno(formatoTexto);
432
- return null;
433
- };
434
- Interpretador.prototype.executarBloco = function (declaracoes, ambiente) {
435
- var anterior = this.ambiente;
436
402
  try {
437
- this.ambiente = ambiente;
438
- if (declaracoes && declaracoes.length) {
439
- for (var i = 0; i < declaracoes.length; i++) {
440
- this.executar(declaracoes[i]);
441
- }
442
- }
403
+ var valor = this.avaliar(declaracao.expressao);
404
+ var formatoTexto = this.paraTexto(valor);
405
+ this.resultadoInterpretador.push(formatoTexto);
406
+ this.funcaoDeRetorno(formatoTexto);
407
+ return null;
443
408
  }
444
409
  catch (erro) {
445
- // TODO: try sem catch é uma roubada total. Implementar uma forma de quebra de fluxo sem exceção.
446
- throw erro;
447
- }
448
- finally {
449
- this.ambiente = anterior;
410
+ this.erros.push(erro);
450
411
  }
451
412
  };
413
+ /**
414
+ * Empilha declarações na pilha de escopos de execução, cria um novo ambiente e
415
+ * executa as declarações empilhadas.
416
+ * @param declaracoes Um vetor de declaracoes a ser executado.
417
+ * @param ambiente O ambiente de execução quando houver, como parâmetros, argumentos, etc.
418
+ */
419
+ Interpretador.prototype.executarBloco = function (declaracoes, ambiente) {
420
+ var escopoExecucao = {
421
+ declaracoes: declaracoes,
422
+ declaracaoAtual: 0,
423
+ ambiente: ambiente || new ambiente_1.Ambiente()
424
+ };
425
+ this.pilhaEscoposExecucao.empilhar(escopoExecucao);
426
+ return this.executarUltimoEscopo();
427
+ };
452
428
  Interpretador.prototype.visitarExpressaoBloco = function (declaracao) {
453
- this.executarBloco(declaracao.declaracoes, new ambiente_1.Ambiente(this.ambiente));
454
- return null;
429
+ return this.executarBloco(declaracao.declaracoes);
455
430
  };
456
431
  Interpretador.prototype.visitarExpressaoVar = function (declaracao) {
457
432
  var valor = null;
458
433
  if (declaracao.inicializador !== null) {
459
434
  valor = this.avaliar(declaracao.inicializador);
460
435
  }
461
- this.ambiente.definirVariavel(declaracao.simbolo.lexema, valor);
436
+ this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, valor);
462
437
  return null;
463
438
  };
464
439
  Interpretador.prototype.visitarExpressaoContinua = function (declaracao) {
465
- throw new excecoes_1.ExcecaoContinuar();
440
+ return new quebras_1.ContinuarQuebra();
466
441
  };
467
442
  Interpretador.prototype.visitarExpressaoSustar = function (declaracao) {
468
- throw new excecoes_1.ExcecaoSustar();
443
+ return new quebras_1.SustarQuebra();
469
444
  };
470
445
  Interpretador.prototype.visitarExpressaoRetornar = function (declaracao) {
471
446
  var valor = null;
472
447
  if (declaracao.valor != null)
473
448
  valor = this.avaliar(declaracao.valor);
474
- throw new excecoes_1.ExcecaoRetornar(valor);
449
+ return new quebras_1.RetornoQuebra(valor);
475
450
  };
476
451
  Interpretador.prototype.visitarExpressaoDeleguaFuncao = function (expressao) {
477
- return new estruturas_1.DeleguaFuncao(null, expressao, this.ambiente, false);
452
+ return new estruturas_1.DeleguaFuncao(null, expressao);
478
453
  };
479
454
  Interpretador.prototype.visitarExpressaoAtribuicaoSobrescrita = function (expressao) {
480
455
  var objeto = this.avaliar(expressao.objeto);
@@ -492,7 +467,7 @@ var Interpretador = /** @class */ (function () {
492
467
  objeto[indice] = valor;
493
468
  }
494
469
  else if (objeto.constructor === Object ||
495
- objeto instanceof estruturas_1.DeleguaInstancia ||
470
+ objeto instanceof estruturas_1.ObjetoDeleguaClasse ||
496
471
  objeto instanceof estruturas_1.DeleguaFuncao ||
497
472
  objeto instanceof estruturas_1.DeleguaClasse ||
498
473
  objeto instanceof estruturas_1.DeleguaModulo) {
@@ -520,7 +495,7 @@ var Interpretador = /** @class */ (function () {
520
495
  return objeto[indice];
521
496
  }
522
497
  else if (objeto.constructor === Object ||
523
- objeto instanceof estruturas_1.DeleguaInstancia ||
498
+ objeto instanceof estruturas_1.ObjetoDeleguaClasse ||
524
499
  objeto instanceof estruturas_1.DeleguaFuncao ||
525
500
  objeto instanceof estruturas_1.DeleguaClasse ||
526
501
  objeto instanceof estruturas_1.DeleguaModulo) {
@@ -546,12 +521,12 @@ var Interpretador = /** @class */ (function () {
546
521
  };
547
522
  Interpretador.prototype.visitarExpressaoDefinir = function (expressao) {
548
523
  var objeto = this.avaliar(expressao.objeto);
549
- if (!(objeto instanceof estruturas_1.DeleguaInstancia) &&
524
+ if (!(objeto instanceof estruturas_1.ObjetoDeleguaClasse) &&
550
525
  objeto.constructor !== Object) {
551
526
  throw new excecoes_1.ErroEmTempoDeExecucao(expressao.objeto.nome, 'Somente instâncias e dicionários podem possuir campos.', expressao.linha);
552
527
  }
553
528
  var valor = this.avaliar(expressao.valor);
554
- if (objeto instanceof estruturas_1.DeleguaInstancia) {
529
+ if (objeto instanceof estruturas_1.ObjetoDeleguaClasse) {
555
530
  objeto.set(expressao.nome, valor);
556
531
  return valor;
557
532
  }
@@ -560,8 +535,8 @@ var Interpretador = /** @class */ (function () {
560
535
  }
561
536
  };
562
537
  Interpretador.prototype.visitarExpressaoFuncao = function (declaracao) {
563
- var funcao = new estruturas_1.DeleguaFuncao(declaracao.simbolo.lexema, declaracao.funcao, this.ambiente, false);
564
- this.ambiente.definirVariavel(declaracao.simbolo.lexema, funcao);
538
+ var funcao = new estruturas_1.DeleguaFuncao(declaracao.simbolo.lexema, declaracao.funcao);
539
+ this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, funcao);
565
540
  };
566
541
  Interpretador.prototype.visitarExpressaoClasse = function (declaracao) {
567
542
  var superClasse = null;
@@ -571,29 +546,29 @@ var Interpretador = /** @class */ (function () {
571
546
  throw new excecoes_1.ErroEmTempoDeExecucao(declaracao.superClasse.nome, 'SuperClasse precisa ser uma classe.', declaracao.linha);
572
547
  }
573
548
  }
574
- this.ambiente.definirVariavel(declaracao.simbolo.lexema, null);
549
+ this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, null);
575
550
  if (declaracao.superClasse !== null) {
576
- this.ambiente = new ambiente_1.Ambiente(this.ambiente);
577
- this.ambiente.definirVariavel('super', superClasse);
551
+ this.pilhaEscoposExecucao.definirVariavel('super', superClasse);
578
552
  }
579
553
  var metodos = {};
580
554
  var definirMetodos = declaracao.metodos;
581
555
  for (var i = 0; i < declaracao.metodos.length; i++) {
582
556
  var metodoAtual = definirMetodos[i];
583
- var eInicializado = metodoAtual.simbolo.lexema === 'construtor';
584
- var funcao = new estruturas_1.DeleguaFuncao(metodoAtual.simbolo.lexema, metodoAtual.funcao, this.ambiente, eInicializado);
557
+ var eInicializador = metodoAtual.simbolo.lexema === 'construtor';
558
+ var funcao = new estruturas_1.DeleguaFuncao(metodoAtual.simbolo.lexema, metodoAtual.funcao, undefined, eInicializador);
585
559
  metodos[metodoAtual.simbolo.lexema] = funcao;
586
560
  }
587
561
  var criado = new estruturas_1.DeleguaClasse(declaracao.simbolo.lexema, superClasse, metodos);
588
- if (superClasse !== null) {
562
+ // TODO: Recolocar isso se for necessário.
563
+ /* if (superClasse !== null) {
589
564
  this.ambiente = this.ambiente.enclosing;
590
- }
591
- this.ambiente.atribuirVariavel(declaracao.simbolo, criado);
565
+ } */
566
+ this.pilhaEscoposExecucao.atribuirVariavel(declaracao.simbolo, criado);
592
567
  return null;
593
568
  };
594
569
  Interpretador.prototype.visitarExpressaoAcessoMetodo = function (expressao) {
595
570
  var objeto = this.avaliar(expressao.objeto);
596
- if (objeto instanceof estruturas_1.DeleguaInstancia) {
571
+ if (objeto instanceof estruturas_1.ObjetoDeleguaClasse) {
597
572
  return objeto.get(expressao.simbolo) || null;
598
573
  }
599
574
  else if (objeto.constructor === Object) {
@@ -623,13 +598,13 @@ var Interpretador = /** @class */ (function () {
623
598
  };
624
599
  Interpretador.prototype.visitarExpressaoSuper = function (expressao) {
625
600
  var distancia = this.locais.get(expressao);
626
- var superClasse = this.ambiente.obterVariavelEm(distancia, 'super');
627
- var objeto = this.ambiente.obterVariavelEm(distancia - 1, 'isto');
601
+ var superClasse = this.pilhaEscoposExecucao.obterVariavelEm(distancia, 'super');
602
+ var objeto = this.pilhaEscoposExecucao.obterVariavelEm(distancia - 1, 'isto');
628
603
  var metodo = superClasse.encontrarMetodo(expressao.metodo.lexema);
629
604
  if (metodo === undefined) {
630
605
  throw new excecoes_1.ErroEmTempoDeExecucao(expressao.metodo, 'Método chamado indefinido.', expressao.linha);
631
606
  }
632
- return metodo.definirEscopo(objeto);
607
+ return metodo.definirInstancia(objeto);
633
608
  };
634
609
  Interpretador.prototype.paraTexto = function (objeto) {
635
610
  if (objeto === null)
@@ -648,6 +623,9 @@ var Interpretador = /** @class */ (function () {
648
623
  return objeto;
649
624
  if (typeof objeto === 'object')
650
625
  return JSON.stringify(objeto);
626
+ if (objeto === undefined) {
627
+ return 'nulo';
628
+ }
651
629
  return objeto.toString();
652
630
  };
653
631
  Interpretador.prototype.executar = function (declaracao, mostrarResultado) {
@@ -659,27 +637,52 @@ var Interpretador = /** @class */ (function () {
659
637
  if (resultado || typeof resultado === 'boolean') {
660
638
  this.resultadoInterpretador.push(this.paraTexto(resultado));
661
639
  }
640
+ return resultado;
662
641
  };
663
- Interpretador.prototype.interpretar = function (objeto) {
642
+ /**
643
+ * Executa o último escopo empilhado no topo na pilha de escopos do interpretador.
644
+ * @param manterAmbiente Se verdadeiro, ambiente do topo da pilha de escopo é copiado para o ambiente imediatamente abaixo.
645
+ * @returns O resultado da execução do escopo, se houver.
646
+ */
647
+ Interpretador.prototype.executarUltimoEscopo = function (manterAmbiente) {
648
+ if (manterAmbiente === void 0) { manterAmbiente = false; }
649
+ var ultimoEscopo = this.pilhaEscoposExecucao.topoDaPilha();
650
+ try {
651
+ var retornoExecucao = void 0;
652
+ for (; !(retornoExecucao instanceof quebras_1.Quebra) && ultimoEscopo.declaracaoAtual < ultimoEscopo.declaracoes.length; ultimoEscopo.declaracaoAtual++) {
653
+ retornoExecucao = this.executar(ultimoEscopo.declaracoes[ultimoEscopo.declaracaoAtual]);
654
+ }
655
+ return retornoExecucao;
656
+ }
657
+ finally {
658
+ this.pilhaEscoposExecucao.removerUltimo();
659
+ if (manterAmbiente) {
660
+ var escopoAnterior = this.pilhaEscoposExecucao.topoDaPilha();
661
+ escopoAnterior.ambiente = Object.assign(escopoAnterior.ambiente, ultimoEscopo.ambiente);
662
+ }
663
+ }
664
+ };
665
+ /**
666
+ * Método que efetivamente inicia o processo de interpretação.
667
+ * @param declaracoes Um vetor de declarações gerado pelo Avaliador Sintático.
668
+ * @param manterAmbiente Se ambiente de execução (variáveis, classes, etc.) deve ser mantido. Normalmente usado
669
+ * pelo modo REPL (LEIA).
670
+ * @returns Um objeto com o resultado da interpretação.
671
+ */
672
+ Interpretador.prototype.interpretar = function (declaracoes, manterAmbiente) {
673
+ if (manterAmbiente === void 0) { manterAmbiente = false; }
664
674
  this.erros = [];
665
- var retornoResolvedor = this.resolvedor.resolver(objeto);
675
+ var retornoResolvedor = this.resolvedor.resolver(declaracoes);
666
676
  this.locais = retornoResolvedor.locais;
677
+ var escopoExecucao = {
678
+ declaracoes: declaracoes,
679
+ declaracaoAtual: 0,
680
+ ambiente: new ambiente_1.Ambiente()
681
+ };
682
+ this.pilhaEscoposExecucao.empilhar(escopoExecucao);
667
683
  var inicioInterpretacao = (0, browser_process_hrtime_1.default)();
668
684
  try {
669
- var declaracoes = objeto.declaracoes || objeto;
670
- if (declaracoes.length === 1) {
671
- var eObjetoExpressao = declaracoes[0].constructor.name === 'Expressao';
672
- if (eObjetoExpressao) {
673
- this.executar(declaracoes[0], true);
674
- return;
675
- }
676
- }
677
- for (var i = 0; i < declaracoes.length; i++) {
678
- this.executar(declaracoes[i]);
679
- }
680
- }
681
- catch (erro) {
682
- this.erros.push(erro);
685
+ this.executarUltimoEscopo(manterAmbiente);
683
686
  }
684
687
  finally {
685
688
  if (this.performance) {
@@ -688,7 +691,7 @@ var Interpretador = /** @class */ (function () {
688
691
  }
689
692
  var retorno = {
690
693
  erros: this.erros,
691
- resultado: this.resultadoInterpretador
694
+ resultado: this.resultadoInterpretador,
692
695
  };
693
696
  this.resultadoInterpretador = [];
694
697
  return retorno;