@designliquido/delegua 1.22.1 → 1.23.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 (83) hide show
  1. package/analisador-semantico/analisador-semantico.d.ts +2 -2
  2. package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
  3. package/analisador-semantico/analisador-semantico.js +20 -18
  4. package/analisador-semantico/analisador-semantico.js.map +1 -1
  5. package/avaliador-sintatico/avaliador-sintatico.d.ts +0 -1
  6. package/avaliador-sintatico/avaliador-sintatico.d.ts.map +1 -1
  7. package/avaliador-sintatico/avaliador-sintatico.js +1 -7
  8. package/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
  9. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts +0 -1
  10. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
  11. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +22 -26
  12. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
  13. package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.d.ts +0 -1
  14. package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.d.ts.map +1 -1
  15. package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.js +0 -4
  16. package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.js.map +1 -1
  17. package/bibliotecas/testes/modulo-afirmar.d.ts.map +1 -1
  18. package/bibliotecas/testes/modulo-afirmar.js +5 -0
  19. package/bibliotecas/testes/modulo-afirmar.js.map +1 -1
  20. package/bibliotecas/testes/modulo-testes.d.ts.map +1 -1
  21. package/bibliotecas/testes/modulo-testes.js +132 -19
  22. package/bibliotecas/testes/modulo-testes.js.map +1 -1
  23. package/bibliotecas/testes/registro-testes.d.ts +18 -1
  24. package/bibliotecas/testes/registro-testes.d.ts.map +1 -1
  25. package/bibliotecas/testes/registro-testes.js +2 -0
  26. package/bibliotecas/testes/registro-testes.js.map +1 -1
  27. package/bin/package.json +1 -1
  28. package/declaracoes/bloco.d.ts.map +1 -1
  29. package/declaracoes/bloco.js +0 -2
  30. package/declaracoes/bloco.js.map +1 -1
  31. package/declaracoes/const-multiplo.js +2 -2
  32. package/declaracoes/const-multiplo.js.map +1 -1
  33. package/declaracoes/enquanto.d.ts.map +1 -1
  34. package/declaracoes/enquanto.js +1 -2
  35. package/declaracoes/enquanto.js.map +1 -1
  36. package/declaracoes/escolha.d.ts.map +1 -1
  37. package/declaracoes/escolha.js +9 -2
  38. package/declaracoes/escolha.js.map +1 -1
  39. package/declaracoes/fazer.d.ts.map +1 -1
  40. package/declaracoes/fazer.js +1 -2
  41. package/declaracoes/fazer.js.map +1 -1
  42. package/declaracoes/funcao.d.ts.map +1 -1
  43. package/declaracoes/funcao.js +1 -2
  44. package/declaracoes/funcao.js.map +1 -1
  45. package/declaracoes/inicio-algoritmo.d.ts +4 -0
  46. package/declaracoes/inicio-algoritmo.d.ts.map +1 -1
  47. package/declaracoes/inicio-algoritmo.js +4 -2
  48. package/declaracoes/inicio-algoritmo.js.map +1 -1
  49. package/declaracoes/para-cada.d.ts.map +1 -1
  50. package/declaracoes/para-cada.js +1 -2
  51. package/declaracoes/para-cada.js.map +1 -1
  52. package/declaracoes/para.d.ts.map +1 -1
  53. package/declaracoes/para.js +3 -4
  54. package/declaracoes/para.js.map +1 -1
  55. package/declaracoes/se.d.ts.map +1 -1
  56. package/declaracoes/se.js +10 -2
  57. package/declaracoes/se.js.map +1 -1
  58. package/declaracoes/tendo-como.d.ts.map +1 -1
  59. package/declaracoes/tendo-como.js +1 -2
  60. package/declaracoes/tendo-como.js.map +1 -1
  61. package/declaracoes/tente.d.ts.map +1 -1
  62. package/declaracoes/tente.js +7 -2
  63. package/declaracoes/tente.js.map +1 -1
  64. package/declaracoes/var-multiplo.js +2 -2
  65. package/declaracoes/var-multiplo.js.map +1 -1
  66. package/inferenciador.d.ts.map +1 -1
  67. package/inferenciador.js +5 -3
  68. package/inferenciador.js.map +1 -1
  69. package/interfaces/analisador-semantico-interface.d.ts +2 -1
  70. package/interfaces/analisador-semantico-interface.d.ts.map +1 -1
  71. package/interfaces/primitiva-interface.d.ts.map +1 -1
  72. package/interfaces/variavel-interface.d.ts.map +1 -1
  73. package/interpretador/estruturas/delegua-funcao.d.ts.map +1 -1
  74. package/interpretador/estruturas/delegua-funcao.js +0 -2
  75. package/interpretador/estruturas/delegua-funcao.js.map +1 -1
  76. package/interpretador/interpretador-base.d.ts.map +1 -1
  77. package/interpretador/interpretador-base.js +35 -23
  78. package/interpretador/interpretador-base.js.map +1 -1
  79. package/interpretador/pilha-escopos-execucao.d.ts.map +1 -1
  80. package/interpretador/pilha-escopos-execucao.js +20 -10
  81. package/interpretador/pilha-escopos-execucao.js.map +1 -1
  82. package/package.json +1 -1
  83. package/umd/delegua.js +284 -140
package/umd/delegua.js CHANGED
@@ -520,13 +520,15 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
520
520
  this.funcoes = {};
521
521
  this.classesDeclaradas = new Set();
522
522
  this.classesRegistradas = new Map();
523
- this.classesExternasConhecidas = new Set();
523
+ this.classesExternasRegistradas = new Map();
524
524
  this.classeAtualEmAnalise = null;
525
525
  this.atual = 0;
526
526
  this.diagnosticos = [];
527
527
  }
528
- definirClassesExternasConhecidas(classesExternasConhecidas) {
529
- this.classesExternasConhecidas = new Set(classesExternasConhecidas);
528
+ registrarClassesExternas(classes) {
529
+ for (const classe of classes) {
530
+ this.classesExternasRegistradas.set(classe.simbolo.lexema, classe);
531
+ }
530
532
  }
531
533
  verificarTipoAtribuido(declaracao) {
532
534
  if (declaracao.tipo) {
@@ -626,19 +628,19 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
626
628
  this.erro(simboloFuncao, `Função '${simboloFuncao.lexema}' espera ${parametros.length} parâmetros. Atual: ${argumentos.length}.`);
627
629
  }
628
630
  for (let [indice, parametro] of parametros.entries()) {
629
- // TODO: `argumento` pode ser Literal (tipo já resolvido) ou variável (tipo inferido em outra etapa).
630
631
  const argumento = argumentos[indice];
631
- if (argumento) {
632
- if (parametro.tipoDado === 'texto' && argumento.tipo !== 'texto') {
633
- this.erro(simboloFuncao, `O valor passado para o parâmetro '${parametro.nome.lexema}' (${parametro.tipoDado}) é diferente do esperado pela função (${argumento.tipo}).`);
634
- }
635
- else if (['inteiro', 'número', 'real'].includes(parametro.tipoDado)) {
636
- // Aqui, se houver diferença entre os tipos do parâmetro e do argumento, não há erro,
637
- // porque Delégua pode trabalhar com conversões implícitas.
638
- // Isso pode ou não mudar no futuro.
639
- if (!['inteiro', 'número', 'real'].includes(argumento.tipo)) {
640
- this.erro(simboloFuncao, `O valor passado para o parâmetro '${parametro.nome.lexema}' (${parametro.tipoDado}) é diferente do esperado pela função (${argumento.tipo}).`);
641
- }
632
+ if (!argumento)
633
+ continue;
634
+ const tipoArgumento = argumento.tipo ?? 'qualquer';
635
+ if (tipoArgumento === 'qualquer')
636
+ continue;
637
+ if (parametro.tipoDado === 'texto' && tipoArgumento !== 'texto') {
638
+ this.erro(simboloFuncao, `O valor passado para o parâmetro '${parametro.nome.lexema}' (${parametro.tipoDado}) é diferente do esperado pela função (${tipoArgumento}).`);
639
+ }
640
+ else if (['inteiro', 'número', 'real'].includes(parametro.tipoDado)) {
641
+ // Delégua pode trabalhar com conversões implícitas entre tipos numéricos.
642
+ if (!['inteiro', 'número', 'real'].includes(tipoArgumento)) {
643
+ this.erro(simboloFuncao, `O valor passado para o parâmetro '${parametro.nome.lexema}' (${parametro.tipoDado}) é diferente do esperado pela função (${tipoArgumento}).`);
642
644
  }
643
645
  }
644
646
  }
@@ -1692,7 +1694,7 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1692
1694
  this.erro(superClasseVariavel.simbolo, `A classe '${declaracao.simbolo.lexema}' não pode herdar de si mesma.`);
1693
1695
  }
1694
1696
  else if (!this.classesDeclaradas.has(nomeSuperclasse) &&
1695
- !this.classesExternasConhecidas.has(nomeSuperclasse)) {
1697
+ !this.classesRegistradas.has(nomeSuperclasse)) {
1696
1698
  this.erro(superClasseVariavel.simbolo, `Superclasse '${nomeSuperclasse}' não foi declarada.`);
1697
1699
  }
1698
1700
  }
@@ -1861,8 +1863,8 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1861
1863
  }
1862
1864
  async analisar(declaracoes) {
1863
1865
  this.gerenciadorEscopos = new gerenciador_escopos_1.GerenciadorEscopos();
1864
- this.classesDeclaradas = new Set();
1865
- this.classesRegistradas = new Map();
1866
+ this.classesDeclaradas = new Set(this.classesExternasRegistradas.keys());
1867
+ this.classesRegistradas = new Map(this.classesExternasRegistradas);
1866
1868
  this.classeAtualEmAnalise = null;
1867
1869
  this.atual = 0;
1868
1870
  this.diagnosticos = [];
@@ -2836,8 +2838,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2836
2838
  // Esta indicação é utilizada para compreensões de lista, onde o
2837
2839
  // tipo do identificador de iteração é 'qualquer' por definição.
2838
2840
  tipoOperando = 'qualquer';
2839
- this.pilhaEscopos.definirInformacoesVariavel(simboloIdentificador.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(simboloIdentificador.lexema, 'qualquer') // TODO: Talvez um dia inferir o tipo aqui.
2840
- );
2841
+ this.pilhaEscopos.definirInformacoesVariavel(simboloIdentificador.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(simboloIdentificador.lexema, 'qualquer'));
2841
2842
  }
2842
2843
  else if (simboloIdentificador.lexema in this.tiposDefinidosEmCodigo) {
2843
2844
  tipoOperando = simboloIdentificador.lexema;
@@ -3626,10 +3627,6 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3626
3627
  this.consumir(delegua_2.default.PARENTESE_DIREITO, "Esperado ')' após os argumentos em instrução `leia`.");
3627
3628
  return new construtos_1.Leia(simboloLeia, argumentos);
3628
3629
  }
3629
- // TODO: Depreciar.
3630
- async expressao() {
3631
- return await this.atribuir();
3632
- }
3633
3630
  async blocoEscopo() {
3634
3631
  this.pilhaEscopos.empilhar(new informacao_escopo_1.InformacaoEscopo());
3635
3632
  let declaracoes = [];
@@ -4384,7 +4381,6 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4384
4381
  const inicializador = await this.expressao();
4385
4382
  const retornos = [];
4386
4383
  for (let identificador of identificadores) {
4387
- // TODO: Melhorar dicionário para intuir o tipo de cada propriedade.
4388
4384
  this.pilhaEscopos.definirInformacoesVariavel(identificador.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(identificador.lexema, 'qualquer'));
4389
4385
  const declaracaoConst = new declaracoes_1.Const(identificador, new construtos_1.AcessoMetodoOuPropriedade(this.hashArquivo, inicializador, identificador));
4390
4386
  declaracaoConst.decoradores = Array.from(this.pilhaDecoradores);
@@ -6432,7 +6428,7 @@ class AvaliadorSintaticoPitugues {
6432
6428
  this.consumir(pitugues_2.default.PARENTESE_ESQUERDO, "Esperado '(' antes dos valores em leia.");
6433
6429
  const argumentos = [];
6434
6430
  do {
6435
- argumentos.push(await this.expressao());
6431
+ argumentos.push(await this.atribuir());
6436
6432
  } while (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.VIRGULA));
6437
6433
  this.consumir(pitugues_2.default.PARENTESE_DIREITO, "Esperado ')' após os valores em leia.");
6438
6434
  return new construtos_1.Leia(simboloLeia, argumentos);
@@ -6462,7 +6458,7 @@ class AvaliadorSintaticoPitugues {
6462
6458
  if (this.estaNoFinal()) {
6463
6459
  throw this.erro(this.simboloAnterior(), 'Esperado valor após o símbolo de igual.');
6464
6460
  }
6465
- const valor = await this.expressao();
6461
+ const valor = await this.atribuir();
6466
6462
  if (!tipoExplicito) {
6467
6463
  tipo = this.logicaComumInferenciaTiposVariaveisEConstantes(valor, 'qualquer');
6468
6464
  }
@@ -6561,7 +6557,7 @@ class AvaliadorSintaticoPitugues {
6561
6557
  if (this.estaNoFinal()) {
6562
6558
  throw this.erro(this.simboloAtual(), 'Esperado inicializador após vírgula.');
6563
6559
  }
6564
- inicializadores.push(await this.expressao());
6560
+ inicializadores.push(await this.atribuir());
6565
6561
  } while (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.VIRGULA));
6566
6562
  return inicializadores;
6567
6563
  }
@@ -6834,7 +6830,7 @@ class AvaliadorSintaticoPitugues {
6834
6830
  case pitugues_2.default.TIPO:
6835
6831
  const simboloTipo = this.avancarEDevolverAnterior();
6836
6832
  this.consumir(pitugues_2.default.PARENTESE_ESQUERDO, "Esperado '(' após 'tipo'.");
6837
- const expressaoAvaliar = await this.expressao();
6833
+ const expressaoAvaliar = await this.atribuir();
6838
6834
  this.consumir(pitugues_2.default.PARENTESE_DIREITO, "Esperado ')' após expressão em 'tipo'.");
6839
6835
  return new construtos_1.TipoDe(simboloTipo.hashArquivo, simboloTipo, expressaoAvaliar);
6840
6836
  case pitugues_2.default.IDENTIFICADOR:
@@ -6910,7 +6906,7 @@ class AvaliadorSintaticoPitugues {
6910
6906
  if (argumentos.length >= 255) {
6911
6907
  throw this.erro(this.simboloAtual(), 'Não pode haver mais de 255 argumentos.');
6912
6908
  }
6913
- argumentos.push(await this.expressao());
6909
+ argumentos.push(await this.atribuir());
6914
6910
  } while (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.VIRGULA));
6915
6911
  }
6916
6912
  this.consumir(pitugues_2.default.PARENTESE_DIREITO, "Esperado ')' após os argumentos.");
@@ -6930,7 +6926,7 @@ class AvaliadorSintaticoPitugues {
6930
6926
  }
6931
6927
  else if (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.COLCHETE_ESQUERDO)) {
6932
6928
  const inicio = !this.verificarTipoSimboloAtual(pitugues_2.default.DOIS_PONTOS)
6933
- ? await this.expressao()
6929
+ ? await this.atribuir()
6934
6930
  : null;
6935
6931
  let ehFatiamento = false;
6936
6932
  let fim = null;
@@ -6939,10 +6935,10 @@ class AvaliadorSintaticoPitugues {
6939
6935
  ehFatiamento = true;
6940
6936
  if (!this.verificarTipoSimboloAtual(pitugues_2.default.DOIS_PONTOS) &&
6941
6937
  !this.verificarTipoSimboloAtual(pitugues_2.default.COLCHETE_DIREITO))
6942
- fim = await this.expressao();
6938
+ fim = await this.atribuir();
6943
6939
  if (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.DOIS_PONTOS) &&
6944
6940
  !this.verificarTipoSimboloAtual(pitugues_2.default.COLCHETE_DIREITO))
6945
- passo = await this.expressao();
6941
+ passo = await this.atribuir();
6946
6942
  }
6947
6943
  const simboloFechamento = this.consumir(pitugues_2.default.COLCHETE_DIREITO, "Esperado ']' após escrita do indice.");
6948
6944
  if (ehFatiamento) {
@@ -7176,15 +7172,11 @@ class AvaliadorSintaticoPitugues {
7176
7172
  }
7177
7173
  return expressao;
7178
7174
  }
7179
- // TODO: Depreciar.
7180
- async expressao() {
7181
- return await this.atribuir();
7182
- }
7183
7175
  async declaracaoEscreva(simboloEscreva) {
7184
7176
  this.consumir(pitugues_2.default.PARENTESE_ESQUERDO, "Esperado '(' antes dos valores em escreva.");
7185
7177
  const argumentos = [];
7186
7178
  do {
7187
- argumentos.push(await this.expressao());
7179
+ argumentos.push(await this.atribuir());
7188
7180
  } while (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.VIRGULA));
7189
7181
  this.consumir(pitugues_2.default.PARENTESE_DIREITO, "Esperado ')' após os valores em escreva.");
7190
7182
  const declaracaoEscreva = new declaracoes_1.Escreva(Number(simboloEscreva.linha), simboloEscreva.hashArquivo, argumentos);
@@ -7192,7 +7184,7 @@ class AvaliadorSintaticoPitugues {
7192
7184
  return declaracaoEscreva;
7193
7185
  }
7194
7186
  async declaracaoExpressao() {
7195
- const expressao = await this.expressao();
7187
+ const expressao = await this.atribuir();
7196
7188
  return new declaracoes_1.Expressao(expressao);
7197
7189
  }
7198
7190
  async blocoEscopo() {
@@ -7236,7 +7228,7 @@ class AvaliadorSintaticoPitugues {
7236
7228
  async declaracaoEnquanto() {
7237
7229
  try {
7238
7230
  this.blocos += 1;
7239
- const condicao = await this.expressao();
7231
+ const condicao = await this.atribuir();
7240
7232
  const bloco = (await this.resolverDeclaracao());
7241
7233
  return new declaracoes_1.Enquanto(condicao, bloco);
7242
7234
  }
@@ -7247,18 +7239,18 @@ class AvaliadorSintaticoPitugues {
7247
7239
  async declaracaoEscolha() {
7248
7240
  try {
7249
7241
  this.blocos += 1;
7250
- const condicao = await this.expressao();
7242
+ const condicao = await this.atribuir();
7251
7243
  this.consumir(pitugues_2.default.DOIS_PONTOS, "Esperado ':' após 'escolha'.");
7252
7244
  const caminhos = [];
7253
7245
  let caminhoPadrao = null;
7254
7246
  while (!this.estaNoFinal() &&
7255
7247
  [pitugues_2.default.CASO, pitugues_2.default.PADRAO].includes(this.simbolos[this.atual].tipo)) {
7256
7248
  if (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.CASO)) {
7257
- const caminhoCondicoes = [await this.expressao()];
7249
+ const caminhoCondicoes = [await this.atribuir()];
7258
7250
  this.consumir(pitugues_2.default.DOIS_PONTOS, "Esperado ':' após o 'caso'.");
7259
7251
  while (this.verificarTipoSimboloAtual(pitugues_2.default.CASO)) {
7260
7252
  this.consumir(pitugues_2.default.CASO, null);
7261
- caminhoCondicoes.push(await this.expressao());
7253
+ caminhoCondicoes.push(await this.atribuir());
7262
7254
  this.consumir(pitugues_2.default.DOIS_PONTOS, "Esperado ':' após declaração do 'caso'.");
7263
7255
  }
7264
7256
  // Como dois-pontos é um símbolo usado para conferir se há um início de bloco,
@@ -7301,7 +7293,7 @@ class AvaliadorSintaticoPitugues {
7301
7293
  if (!this.verificarSeSimboloAtualEIgualA(pitugues_2.default.DE, pitugues_2.default.EM)) {
7302
7294
  throw this.erro(this.simbolos[this.atual], "Esperado palavras reservadas 'em' ou 'de' após variável de iteração em instrução 'para cada'.");
7303
7295
  }
7304
- const vetor = await this.expressao();
7296
+ const vetor = await this.atribuir();
7305
7297
  if (!vetor.hasOwnProperty('tipo')) {
7306
7298
  throw this.erro(simboloPara, `Variável ou constante em 'para cada' não parece possuir um tipo iterável.`);
7307
7299
  }
@@ -7336,7 +7328,7 @@ class AvaliadorSintaticoPitugues {
7336
7328
  if (!this.verificarSeSimboloAtualEIgualA(pitugues_2.default.DE, pitugues_2.default.EM)) {
7337
7329
  throw this.erro(this.simbolos[this.atual], "Esperado palavras reservadas 'em' ou 'de' após variável de iteração em instrução 'para cada'.");
7338
7330
  }
7339
- const alvoIteracao = await this.expressao();
7331
+ const alvoIteracao = await this.atribuir();
7340
7332
  this.validarSeAlvoEIteravel(simboloPara, alvoIteracao, !!simboloSegundaVariavel);
7341
7333
  this.pilhaEscopos.definirInformacoesVariavel(primeiraVariavel.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(primeiraVariavel.lexema, 'qualquer'));
7342
7334
  if (simboloSegundaVariavel) {
@@ -7371,7 +7363,7 @@ class AvaliadorSintaticoPitugues {
7371
7363
  }
7372
7364
  }
7373
7365
  async declaracaoSe() {
7374
- const condicao = await this.expressao();
7366
+ const condicao = await this.atribuir();
7375
7367
  this.consumir(pitugues_2.default.DOIS_PONTOS, "Esperado ':' após condição do 'se'.");
7376
7368
  const simboloColonEntao = this.simboloAnterior();
7377
7369
  const caminhoEntao = new declaracoes_1.Bloco(simboloColonEntao.hashArquivo, Number(simboloColonEntao.linha), await this.blocoEscopo());
@@ -7438,14 +7430,14 @@ class AvaliadorSintaticoPitugues {
7438
7430
  const palavraChave = this.simboloAnterior();
7439
7431
  let valor = null;
7440
7432
  if (!this.verificarTipoSimboloAtual(pitugues_2.default.PONTO_E_VIRGULA)) {
7441
- valor = await this.expressao();
7433
+ valor = await this.atribuir();
7442
7434
  }
7443
7435
  return new declaracoes_1.Retorna(palavraChave, valor);
7444
7436
  }
7445
7437
  async construtoImportar() {
7446
7438
  this.avancarEDevolverAnterior();
7447
7439
  this.consumir(pitugues_2.default.PARENTESE_ESQUERDO, "Esperado '(' após declaração.");
7448
- const caminho = await this.expressao();
7440
+ const caminho = await this.atribuir();
7449
7441
  this.consumir(pitugues_2.default.PARENTESE_DIREITO, "Esperado ')' após declaração.");
7450
7442
  return new construtos_1.ImportarComoConstruto(caminho);
7451
7443
  }
@@ -7522,7 +7514,7 @@ class AvaliadorSintaticoPitugues {
7522
7514
  this.blocos += 1;
7523
7515
  const declaracaoOuBlocoFazer = (await this.resolverDeclaracao());
7524
7516
  this.consumir(pitugues_2.default.ENQUANTO, "Esperado declaração do 'enquanto' após o escopo da declaração 'fazer'.");
7525
- const condicaoEnquanto = await this.expressao();
7517
+ const condicaoEnquanto = await this.atribuir();
7526
7518
  return new declaracoes_1.Fazer(simboloFazer.hashArquivo, Number(simboloFazer.linha), declaracaoOuBlocoFazer, condicaoEnquanto);
7527
7519
  }
7528
7520
  finally {
@@ -7598,7 +7590,7 @@ class AvaliadorSintaticoPitugues {
7598
7590
  // TODO: Reavaliar a precedência do se ternário.
7599
7591
  const vetor = await this.ou();
7600
7592
  this.consumir(pitugues_2.default.SE, "Esperado condição 'se' após vetor.");
7601
- const condicao = await this.expressao();
7593
+ const condicao = await this.atribuir();
7602
7594
  this.consumir(pitugues_2.default.COLCHETE_DIREITO, 'Espero fechamento de colchetes após condição.');
7603
7595
  const tipoVetor = vetor.tipo;
7604
7596
  if (!tipoVetor.endsWith('[]') && !['qualquer', 'vetor'].includes(tipoVetor)) {
@@ -7708,7 +7700,7 @@ class AvaliadorSintaticoPitugues {
7708
7700
  tipoLexema = simboloTipo.lexema;
7709
7701
  }
7710
7702
  else if (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.IGUAL)) {
7711
- valorPropriedade = await this.expressao();
7703
+ valorPropriedade = await this.atribuir();
7712
7704
  possuiValorInicial = true;
7713
7705
  }
7714
7706
  else {
@@ -10186,10 +10178,6 @@ class AvaliadorSintaticoTenda extends avaliador_sintatico_base_1.AvaliadorSintat
10186
10178
  this.consumir(tenda_1.default.PARENTESE_DIREITO, "Esperado ')' após os argumentos em instrução `leia`.");
10187
10179
  return new construtos_1.Leia(simboloLeia, argumentos);
10188
10180
  }
10189
- // TODO: Depreciar.
10190
- async expressao() {
10191
- return await this.atribuir();
10192
- }
10193
10181
  async blocoEscopo(tipo) {
10194
10182
  this.pilhaEscopos.empilhar(new informacao_escopo_1.InformacaoEscopo());
10195
10183
  let declaracoes = [];
@@ -13742,12 +13730,17 @@ function construirModuloAfirmar() {
13742
13730
  modulo.componentes['erro'] = new funcao_padrao_1.FuncaoPadrao(1, async function (interpretador, funcaoTestada) {
13743
13731
  const funcao = interpretador.resolverValor(funcaoTestada);
13744
13732
  let erroLancado = false;
13733
+ const errosAntes = interpretador.erros.length;
13745
13734
  try {
13746
13735
  await funcao.chamar(interpretador, [], null);
13747
13736
  }
13748
13737
  catch (_) {
13749
13738
  erroLancado = true;
13750
13739
  }
13740
+ if (!erroLancado && interpretador.erros.length > errosAntes) {
13741
+ erroLancado = true;
13742
+ interpretador.erros.splice(errosAntes);
13743
+ }
13751
13744
  if (!erroLancado) {
13752
13745
  return Promise.reject(new erro_de_assertiva_1.ErroDeAssertiva(simboloAtual(interpretador), 'Esperava que a função lançasse um erro, mas ela completou sem erros.'));
13753
13746
  }
@@ -13772,29 +13765,17 @@ function simboloAtual(interpretador) {
13772
13765
  function construirModuloDeTestes(interpretador, registro) {
13773
13766
  const modulo = new modulo_1.DeleguaModulo('testes');
13774
13767
  modulo.componentes['afirmar'] = (0, modulo_afirmar_1.construirModuloAfirmar)();
13775
- modulo.componentes['grupo'] = new funcao_padrao_1.FuncaoPadrao(2, async function (_visitante, nomeRaw, funcaoRaw) {
13776
- const nome = interpretador.resolverValor(nomeRaw);
13777
- const funcao = interpretador.resolverValor(funcaoRaw);
13778
- const suiteAnterior = registro.suiteAtual;
13779
- registro.suiteAtual = suiteAnterior ? `${suiteAnterior} > ${nome}` : nome;
13780
- const emDeclaracaoTenteAnterior = interpretador.emDeclaracaoTente;
13781
- interpretador.emDeclaracaoTente = true;
13782
- try {
13783
- await funcao.chamar(interpretador, [], null);
13784
- }
13785
- finally {
13786
- registro.suiteAtual = suiteAnterior;
13787
- interpretador.emDeclaracaoTente = emDeclaracaoTenteAnterior;
13788
- }
13789
- });
13790
- modulo.componentes['teste'] = new funcao_padrao_1.FuncaoPadrao(2, async function (_visitante, nomeRaw, funcaoRaw) {
13791
- const nome = interpretador.resolverValor(nomeRaw);
13792
- const funcao = interpretador.resolverValor(funcaoRaw);
13768
+ async function executarTeste(nome, fn) {
13793
13769
  const inicio = Date.now();
13794
13770
  const emDeclaracaoTenteAnterior = interpretador.emDeclaracaoTente;
13795
13771
  interpretador.emDeclaracaoTente = true;
13772
+ for (const escopo of registro.pilhaEscopos) {
13773
+ for (const h of escopo.antesDeCada) {
13774
+ await h.chamar(interpretador, [], null);
13775
+ }
13776
+ }
13796
13777
  try {
13797
- await funcao.chamar(interpretador, [], null);
13778
+ await fn.chamar(interpretador, [], null);
13798
13779
  registro.resultados.push({
13799
13780
  nomeSuite: registro.suiteAtual,
13800
13781
  nomeTeste: nome,
@@ -13812,9 +13793,134 @@ function construirModuloDeTestes(interpretador, registro) {
13812
13793
  });
13813
13794
  }
13814
13795
  finally {
13796
+ for (const escopo of [...registro.pilhaEscopos].reverse()) {
13797
+ for (const h of escopo.depoisDeCada) {
13798
+ await h.chamar(interpretador, [], null);
13799
+ }
13800
+ }
13815
13801
  interpretador.emDeclaracaoTente = emDeclaracaoTenteAnterior;
13816
13802
  }
13803
+ }
13804
+ async function executarGrupo(nome, fn) {
13805
+ const suiteAnterior = registro.suiteAtual;
13806
+ registro.suiteAtual = suiteAnterior ? `${suiteAnterior} > ${nome}` : nome;
13807
+ const escopo = {
13808
+ antesDeCada: [],
13809
+ antesDeTodos: [],
13810
+ depoisDeCada: [],
13811
+ depoisDeTodos: [],
13812
+ itensColetados: [],
13813
+ temApenas: false,
13814
+ };
13815
+ registro.pilhaEscopos.push(escopo);
13816
+ const modoColetarAnterior = registro.modoColeta;
13817
+ registro.modoColeta = true;
13818
+ const emDeclaracaoTenteAnterior = interpretador.emDeclaracaoTente;
13819
+ interpretador.emDeclaracaoTente = true;
13820
+ try {
13821
+ await fn.chamar(interpretador, [], null);
13822
+ registro.modoColeta = modoColetarAnterior;
13823
+ for (const h of escopo.antesDeTodos) {
13824
+ await h.chamar(interpretador, [], null);
13825
+ }
13826
+ for (const item of escopo.itensColetados) {
13827
+ if (escopo.temApenas && !item.apenas)
13828
+ continue;
13829
+ if (item.pular) {
13830
+ if (item.tipo === 'teste') {
13831
+ registro.resultados.push({
13832
+ nomeSuite: registro.suiteAtual,
13833
+ nomeTeste: item.nome,
13834
+ status: 'pulado',
13835
+ tempoMs: 0,
13836
+ });
13837
+ }
13838
+ continue;
13839
+ }
13840
+ if (item.tipo === 'teste') {
13841
+ await executarTeste(item.nome, item.fn);
13842
+ }
13843
+ else {
13844
+ await executarGrupo(item.nome, item.fn);
13845
+ }
13846
+ }
13847
+ for (const h of escopo.depoisDeTodos) {
13848
+ await h.chamar(interpretador, [], null);
13849
+ }
13850
+ }
13851
+ finally {
13852
+ registro.pilhaEscopos.pop();
13853
+ registro.modoColeta = modoColetarAnterior;
13854
+ registro.suiteAtual = suiteAnterior;
13855
+ interpretador.emDeclaracaoTente = emDeclaracaoTenteAnterior;
13856
+ }
13857
+ }
13858
+ function coletarOuExecutar(tipo, nome, fn, pular, apenas) {
13859
+ if (registro.modoColeta && registro.pilhaEscopos.length > 0) {
13860
+ const escopoAtual = registro.pilhaEscopos[registro.pilhaEscopos.length - 1];
13861
+ if (apenas)
13862
+ escopoAtual.temApenas = true;
13863
+ escopoAtual.itensColetados.push({ tipo, nome, fn, pular, apenas });
13864
+ return Promise.resolve();
13865
+ }
13866
+ if (pular) {
13867
+ if (tipo === 'teste') {
13868
+ registro.resultados.push({
13869
+ nomeSuite: registro.suiteAtual,
13870
+ nomeTeste: nome,
13871
+ status: 'pulado',
13872
+ tempoMs: 0,
13873
+ });
13874
+ }
13875
+ return Promise.resolve();
13876
+ }
13877
+ return tipo === 'teste' ? executarTeste(nome, fn) : executarGrupo(nome, fn);
13878
+ }
13879
+ const grupoFn = new funcao_padrao_1.FuncaoPadrao(2, async function (_visitante, nomeRaw, funcaoRaw) {
13880
+ const nome = interpretador.resolverValor(nomeRaw);
13881
+ const fn = interpretador.resolverValor(funcaoRaw);
13882
+ return coletarOuExecutar('grupo', nome, fn, false, false);
13883
+ });
13884
+ grupoFn['pular'] = new funcao_padrao_1.FuncaoPadrao(2, async function (_visitante, nomeRaw, funcaoRaw) {
13885
+ const nome = interpretador.resolverValor(nomeRaw);
13886
+ const fn = interpretador.resolverValor(funcaoRaw);
13887
+ return coletarOuExecutar('grupo', nome, fn, true, false);
13888
+ });
13889
+ grupoFn['apenas'] = new funcao_padrao_1.FuncaoPadrao(2, async function (_visitante, nomeRaw, funcaoRaw) {
13890
+ const nome = interpretador.resolverValor(nomeRaw);
13891
+ const fn = interpretador.resolverValor(funcaoRaw);
13892
+ return coletarOuExecutar('grupo', nome, fn, false, true);
13893
+ });
13894
+ modulo.componentes['grupo'] = grupoFn;
13895
+ const testeFn = new funcao_padrao_1.FuncaoPadrao(2, async function (_visitante, nomeRaw, funcaoRaw) {
13896
+ const nome = interpretador.resolverValor(nomeRaw);
13897
+ const fn = interpretador.resolverValor(funcaoRaw);
13898
+ return coletarOuExecutar('teste', nome, fn, false, false);
13899
+ });
13900
+ testeFn['pular'] = new funcao_padrao_1.FuncaoPadrao(2, async function (_visitante, nomeRaw, funcaoRaw) {
13901
+ const nome = interpretador.resolverValor(nomeRaw);
13902
+ const fn = interpretador.resolverValor(funcaoRaw);
13903
+ return coletarOuExecutar('teste', nome, fn, true, false);
13817
13904
  });
13905
+ testeFn['apenas'] = new funcao_padrao_1.FuncaoPadrao(2, async function (_visitante, nomeRaw, funcaoRaw) {
13906
+ const nome = interpretador.resolverValor(nomeRaw);
13907
+ const fn = interpretador.resolverValor(funcaoRaw);
13908
+ return coletarOuExecutar('teste', nome, fn, false, true);
13909
+ });
13910
+ modulo.componentes['teste'] = testeFn;
13911
+ function registrarHook(campo) {
13912
+ return new funcao_padrao_1.FuncaoPadrao(1, function (_visitante, funcaoRaw) {
13913
+ const fn = interpretador.resolverValor(funcaoRaw);
13914
+ if (registro.pilhaEscopos.length > 0) {
13915
+ registro.pilhaEscopos[registro.pilhaEscopos.length - 1][campo].push(fn);
13916
+ }
13917
+ return Promise.resolve(null);
13918
+ });
13919
+ }
13920
+ modulo.componentes['antesDeCada'] = registrarHook('antesDeCada');
13921
+ modulo.componentes['antesDeTodos'] = registrarHook('antesDeTodos');
13922
+ modulo.componentes['depoisDeCada'] = registrarHook('depoisDeCada');
13923
+ modulo.componentes['depoisDeTodos'] = registrarHook('depoisDeTodos');
13818
13924
  modulo.componentes['lancarErro'] = new funcao_padrao_1.FuncaoPadrao(1, function (_visitante, mensagemRaw) {
13819
13925
  const mensagem = interpretador.resolverValor(mensagemRaw);
13820
13926
  return Promise.reject(new erro_de_assertiva_1.ErroDeAssertiva(simboloAtual(interpretador), String(mensagem)));
@@ -13830,6 +13936,8 @@ class RegistroTestes {
13830
13936
  constructor() {
13831
13937
  this.resultados = [];
13832
13938
  this.suiteAtual = '';
13939
+ this.pilhaEscopos = [];
13940
+ this.modoColeta = false;
13833
13941
  }
13834
13942
  }
13835
13943
  exports.RegistroTestes = RegistroTestes;
@@ -15673,8 +15781,6 @@ exports.Ajuda = Ajuda;
15673
15781
  Object.defineProperty(exports, "__esModule", { value: true });
15674
15782
  exports.Bloco = void 0;
15675
15783
  const declaracao_1 = require("./declaracao");
15676
- // TODO: `Bloco` só deveria ser declaração quando representa um escopo órfão.
15677
- // Estudar transformar em construto e suas implicações.
15678
15784
  class Bloco extends declaracao_1.Declaracao {
15679
15785
  constructor(hashArquivo, linha, declaracoes) {
15680
15786
  super(linha, hashArquivo);
@@ -15807,8 +15913,8 @@ class ConstMultiplo extends declaracao_1.Declaracao {
15807
15913
  return await visitante.visitarDeclaracaoConstMultiplo(this);
15808
15914
  }
15809
15915
  paraTexto() {
15810
- // TODO: Terminar
15811
- return `<const-múltiplo />`;
15916
+ const nomes = this.simbolos.map((s) => s.lexema).join(',');
15917
+ return `<const-múltiplo nomes=[${nomes}] inicializador=${this.inicializador.paraTexto()} tipo=${this.tipo ?? 'qualquer'} />`;
15812
15918
  }
15813
15919
  }
15814
15920
  exports.ConstMultiplo = ConstMultiplo;
@@ -15899,8 +16005,7 @@ class Enquanto extends declaracao_1.Declaracao {
15899
16005
  return await visitante.visitarDeclaracaoEnquanto(this);
15900
16006
  }
15901
16007
  paraTexto() {
15902
- // TODO: Bloco.
15903
- return `<enquanto condição=${this.condicao.paraTexto()} />`;
16008
+ return `<enquanto condição=${this.condicao.paraTexto()}>${this.corpo.paraTexto()}</enquanto>`;
15904
16009
  }
15905
16010
  }
15906
16011
  exports.Enquanto = Enquanto;
@@ -15924,8 +16029,15 @@ class Escolha extends declaracao_1.Declaracao {
15924
16029
  return await visitante.visitarDeclaracaoEscolha(this);
15925
16030
  }
15926
16031
  paraTexto() {
15927
- // TODO: Caminhos
15928
- return `<escolha identificadorOuLiteral=${this.identificadorOuLiteral} />`;
16032
+ const caminhos = this.caminhos
16033
+ .map((c) => {
16034
+ const condicoes = c.condicoes.map((cond) => cond.paraTexto()).join(',');
16035
+ const declaracoes = c.declaracoes.map((d) => d.paraTexto()).join('');
16036
+ return `<caminho condicoes=[${condicoes}]>${declaracoes}</caminho>`;
16037
+ })
16038
+ .join('');
16039
+ const padrao = this.caminhoPadrao?.declaracoes.map((d) => d.paraTexto()).join('') ?? '';
16040
+ return `<escolha identificadorOuLiteral=${this.identificadorOuLiteral.paraTexto()}>${caminhos}<padrão>${padrao}</padrão></escolha>`;
15929
16041
  }
15930
16042
  }
15931
16043
  exports.Escolha = Escolha;
@@ -16052,8 +16164,7 @@ class Fazer extends declaracao_1.Declaracao {
16052
16164
  return await visitante.visitarDeclaracaoFazer(this);
16053
16165
  }
16054
16166
  paraTexto() {
16055
- // TODO: Bloco.
16056
- return `<fazer condição=${this.condicaoEnquanto.paraTexto()} />`;
16167
+ return `<fazer>${this.caminhoFazer.paraTexto()}<condição>${this.condicaoEnquanto.paraTexto()}</condição></fazer>`;
16057
16168
  }
16058
16169
  }
16059
16170
  exports.Fazer = Fazer;
@@ -16086,8 +16197,7 @@ class FuncaoDeclaracao extends declaracao_1.Declaracao {
16086
16197
  return await visitante.visitarDeclaracaoDefinicaoFuncao(this);
16087
16198
  }
16088
16199
  paraTexto() {
16089
- // TODO: Corpo.
16090
- return `<declaração-função nome=${this.simbolo.lexema} tipo=${this.tipo} />`;
16200
+ return `<declaração-função nome=${this.simbolo.lexema} tipo=${this.tipo}>${this.funcao.paraTexto()}</declaração-função>`;
16091
16201
  }
16092
16202
  }
16093
16203
  exports.FuncaoDeclaracao = FuncaoDeclaracao;
@@ -16174,8 +16284,10 @@ __exportStar(require("./var-multiplo"), exports);
16174
16284
  Object.defineProperty(exports, "__esModule", { value: true });
16175
16285
  exports.InicioAlgoritmo = void 0;
16176
16286
  const declaracao_1 = require("./declaracao");
16177
- // TODO: Localizar dialeto que usa este construto e mover
16178
- // esta classe para ele.
16287
+ /**
16288
+ * Representa a declaração de início do algoritmo, que é o ponto de entrada do programa.
16289
+ * Usado por dialetos como Portugol Studio, Portugol IPT e VisusAlg.
16290
+ */
16179
16291
  class InicioAlgoritmo extends declaracao_1.Declaracao {
16180
16292
  constructor(linha, hashArquivo) {
16181
16293
  super(linha, hashArquivo);
@@ -16252,8 +16364,7 @@ class ParaCada extends declaracao_1.Declaracao {
16252
16364
  return await visitante.visitarDeclaracaoParaCada(this);
16253
16365
  }
16254
16366
  paraTexto() {
16255
- // TODO: Corpo.
16256
- return `<para-cada variávelIteração=${this.variavelIteracao.paraTexto()} />`;
16367
+ return `<para-cada variávelIteração=${this.variavelIteracao.paraTexto()} vetor=${this.vetorOuDicionario.paraTexto()}>${this.corpo.paraTexto()}</para-cada>`;
16257
16368
  }
16258
16369
  }
16259
16370
  exports.ParaCada = ParaCada;
@@ -16284,13 +16395,12 @@ class Para extends declaracao_1.Declaracao {
16284
16395
  paraTexto() {
16285
16396
  let inicializador = '';
16286
16397
  if (Array.isArray(this.inicializador)) {
16287
- inicializador = this.inicializador.reduce((anterior, atual) => (anterior += atual.paraTexto() + ` `), 'inicialização=');
16398
+ inicializador = this.inicializador.map((d) => d.paraTexto()).join(' ');
16288
16399
  }
16289
16400
  else if (this.inicializador) {
16290
- inicializador = `inicialização=${this.inicializador.paraTexto()} `;
16401
+ inicializador = this.inicializador.paraTexto();
16291
16402
  }
16292
- // TODO: Bloco.
16293
- return `<para ${this.inicializador} condição=${this.condicao.paraTexto()} />`;
16403
+ return `<para inicializador=[${inicializador}] condição=${this.condicao.paraTexto()} incremento=${this.incrementar.paraTexto()}>${this.corpo.paraTexto()}</para>`;
16294
16404
  }
16295
16405
  }
16296
16406
  exports.Para = Para;
@@ -16364,8 +16474,16 @@ class Se extends declaracao_1.Declaracao {
16364
16474
  return await visitante.visitarDeclaracaoSe(this);
16365
16475
  }
16366
16476
  paraTexto() {
16367
- // TODO: Bloco então, bloco senão, outros.
16368
- return `<se condiçao=${this.condicao.paraTexto()} />`;
16477
+ let resultado = `<se condicao=${this.condicao.paraTexto()}><então>${this.caminhoEntao.paraTexto()}</então>`;
16478
+ if (this.caminhosSeSenao) {
16479
+ for (const seSenao of this.caminhosSeSenao) {
16480
+ resultado += `<senão-se condicao=${seSenao.condicao.paraTexto()}>${seSenao.caminho.paraTexto()}</senão-se>`;
16481
+ }
16482
+ }
16483
+ if (this.caminhoSenao) {
16484
+ resultado += `<senão>${this.caminhoSenao.paraTexto()}</senão>`;
16485
+ }
16486
+ return resultado + '</se>';
16369
16487
  }
16370
16488
  }
16371
16489
  exports.Se = Se;
@@ -16409,8 +16527,7 @@ class TendoComo extends declaracao_1.Declaracao {
16409
16527
  return await visitante.visitarDeclaracaoTendoComo(this);
16410
16528
  }
16411
16529
  paraTexto() {
16412
- // TODO: Bloco.
16413
- return `<tendo variável=${this.simboloVariavel.lexema} como=${this.inicializacaoVariavel.paraTexto()} />`;
16530
+ return `<tendo variável=${this.simboloVariavel.lexema} como=${this.inicializacaoVariavel.paraTexto()}>${this.corpo.paraTexto()}</tendo>`;
16414
16531
  }
16415
16532
  }
16416
16533
  exports.TendoComo = TendoComo;
@@ -16435,8 +16552,13 @@ class Tente extends declaracao_1.Declaracao {
16435
16552
  return await visitante.visitarDeclaracaoTente(this);
16436
16553
  }
16437
16554
  paraTexto() {
16438
- // TODO: Terminar.
16439
- return `<tente />`;
16555
+ const tente = this.caminhoTente.map((d) => d.paraTexto()).join('');
16556
+ const pegue = Array.isArray(this.caminhoPegue)
16557
+ ? this.caminhoPegue.map((d) => d.paraTexto()).join('')
16558
+ : this.caminhoPegue.paraTexto();
16559
+ const senao = this.caminhoSenao.map((d) => d.paraTexto()).join('');
16560
+ const finalmente = this.caminhoFinalmente.map((d) => d.paraTexto()).join('');
16561
+ return `<tente><tente-corpo>${tente}</tente-corpo><pegue>${pegue}</pegue><senão>${senao}</senão><finalmente>${finalmente}</finalmente></tente>`;
16440
16562
  }
16441
16563
  }
16442
16564
  exports.Tente = Tente;
@@ -16483,8 +16605,8 @@ class VarMultiplo extends declaracao_1.Declaracao {
16483
16605
  return await visitante.visitarDeclaracaoVarMultiplo(this);
16484
16606
  }
16485
16607
  paraTexto() {
16486
- // TODO: Terminar.
16487
- return `<var-múltiplo />`;
16608
+ const nomes = this.simbolos.map((s) => s.lexema).join(',');
16609
+ return `<var-múltiplo nomes=[${nomes}] inicializador=${this.inicializador.paraTexto()} tipo=${this.tipo ?? 'qualquer'} />`;
16488
16610
  }
16489
16611
  }
16490
16612
  exports.VarMultiplo = VarMultiplo;
@@ -19036,8 +19158,10 @@ function inferirVetor(vetor) {
19036
19158
  }
19037
19159
  return `${tiposObjetosEmVetor.values().next().value}[]`;
19038
19160
  case 'Literal':
19039
- // TODO: Não sei se é seguro inferir pelo primeiro valor do vetor.
19040
- return `${vetor[0].tipo}[]`;
19161
+ const tiposLiterais = new Set(vetor.map((e) => e.tipo));
19162
+ if (tiposLiterais.size > 1)
19163
+ return 'vetor';
19164
+ return `${tiposLiterais.values().next().value}[]`;
19041
19165
  default:
19042
19166
  return 'vetor';
19043
19167
  }
@@ -19078,7 +19202,7 @@ function inferirTipoVariavel(variavel) {
19078
19202
  case 'DescritorTipoClasse':
19079
19203
  case 'ObjetoDeleguaClasse':
19080
19204
  return 'objeto';
19081
- case 'Simbolo': // TODO: Repensar.
19205
+ case 'Simbolo':
19082
19206
  const simbolo = variavel;
19083
19207
  switch (simbolo.tipo) {
19084
19208
  case primitivos_1.default.BOOLEANO:
@@ -20408,8 +20532,6 @@ class DeleguaFuncao extends chamavel_1.Chamavel {
20408
20532
  };
20409
20533
  }
20410
20534
  }
20411
- // TODO: Repensar essa dinâmica para análise semântica (levar toda a lógica abaixo para
20412
- // o interpretador).
20413
20535
  const interpretador = visitante;
20414
20536
  interpretador.proximoEscopo = 'funcao';
20415
20537
  // Rastrear a classe atual em execução para verificação de acesso.
@@ -21828,12 +21950,11 @@ class InterpretadorBase {
21828
21950
  retirarInterpolacao(texto, interpolacoes) {
21829
21951
  let textoFinal = texto;
21830
21952
  for (const elemento of interpolacoes) {
21831
- // TODO: alguma chance de `elemento` ser `undefined` aqui?
21832
- let valor = elemento?.valor;
21833
- if (valor.hasOwnProperty && valor.hasOwnProperty('valorRetornado')) {
21953
+ let valor = elemento.valor;
21954
+ if (valor?.hasOwnProperty && valor.hasOwnProperty('valorRetornado')) {
21834
21955
  valor = valor.valorRetornado;
21835
21956
  }
21836
- if (valor.tipo === delegua_2.default.LOGICO) {
21957
+ if (valor?.tipo === delegua_2.default.LOGICO) {
21837
21958
  textoFinal = textoFinal.replace('${' + elemento.expressaoInterpolacao + '}', this.paraTexto(valor));
21838
21959
  }
21839
21960
  else {
@@ -21910,7 +22031,7 @@ class InterpretadorBase {
21910
22031
  */
21911
22032
  async visitarExpressaoAgrupamento(expressao) {
21912
22033
  const avaliacaoAgrupamento = await this.avaliar(expressao.expressao);
21913
- if (avaliacaoAgrupamento.declaracao !== undefined) {
22034
+ if (avaliacaoAgrupamento !== null && avaliacaoAgrupamento.declaracao) {
21914
22035
  return avaliacaoAgrupamento.declaracao;
21915
22036
  }
21916
22037
  return avaliacaoAgrupamento;
@@ -21962,9 +22083,9 @@ class InterpretadorBase {
21962
22083
  return valor;
21963
22084
  }
21964
22085
  const valorAnteriorIncremento = valor;
21965
- // TODO: Provavelmente isso está incorreto. Descobrir se operando resolve para
21966
- // `Construto` ou para `Simbolo`.
21967
- this.pilhaEscoposExecucao.atribuirVariavel(expressao.operando.simbolo, ++valor);
22086
+ if (expressao.operando instanceof construtos_1.Variavel) {
22087
+ this.pilhaEscoposExecucao.atribuirVariavel(expressao.operando.simbolo, ++valor);
22088
+ }
21968
22089
  return valorAnteriorIncremento;
21969
22090
  case delegua_1.default.DECREMENTAR:
21970
22091
  if (expressao.incidenciaOperador === 'ANTES') {
@@ -21975,9 +22096,9 @@ class InterpretadorBase {
21975
22096
  return valor;
21976
22097
  }
21977
22098
  const valorAnteriorDecremento = valor;
21978
- // TODO: Provavelmente isso está incorreto. Descobrir se operando resolve para
21979
- // `Construto` ou para `Simbolo`.
21980
- this.pilhaEscoposExecucao.atribuirVariavel(expressao.operando.simbolo, --valor);
22099
+ if (expressao.operando instanceof construtos_1.Variavel) {
22100
+ this.pilhaEscoposExecucao.atribuirVariavel(expressao.operando.simbolo, --valor);
22101
+ }
21981
22102
  return valorAnteriorDecremento;
21982
22103
  }
21983
22104
  return null;
@@ -22351,8 +22472,10 @@ class InterpretadorBase {
22351
22472
  */
22352
22473
  async visitarExpressaoDeChamada(expressao) {
22353
22474
  try {
22354
- let variavelEntidadeChamada = await this.avaliar(expressao.entidadeChamada);
22355
- if (variavelEntidadeChamada === null || variavelEntidadeChamada === undefined) {
22475
+ let variavelEntidadeChamada = await this
22476
+ .avaliar(expressao.entidadeChamada);
22477
+ if (variavelEntidadeChamada === null ||
22478
+ variavelEntidadeChamada === undefined) {
22356
22479
  return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.parentese, 'Chamada de função ou método inexistente: ' +
22357
22480
  String(expressao.entidadeChamada), expressao.linha));
22358
22481
  }
@@ -22370,7 +22493,8 @@ class InterpretadorBase {
22370
22493
  if (entidadeChamada instanceof metodo_primitiva_1.MetodoPrimitiva) {
22371
22494
  return await this.chamarMetodoPrimitiva(expressao, entidadeChamada);
22372
22495
  }
22373
- const argumentos = await this.resolverArgumentosChamada(expressao);
22496
+ const argumentos = await this
22497
+ .resolverArgumentosChamada(expressao);
22374
22498
  const aridade = entidadeChamada.aridade
22375
22499
  ? entidadeChamada.aridade()
22376
22500
  : entidadeChamada.length;
@@ -22381,6 +22505,16 @@ class InterpretadorBase {
22381
22505
  const ehPolimorfico = entidadeChamada instanceof estruturas_1.MetodoPolimorfico ||
22382
22506
  (entidadeChamada instanceof estruturas_1.DescritorTipoClasse &&
22383
22507
  entidadeChamada.encontrarMetodo('construtor') instanceof estruturas_1.MetodoPolimorfico);
22508
+ if (entidadeChamada instanceof estruturas_1.DeleguaFuncao && entidadeChamada.declaracao) {
22509
+ // Pega os parâmetros da declaração e filtra apenas os obrigatórios
22510
+ // (ignora os que têm valor padrão ou são rest parameters)
22511
+ const parametros = entidadeChamada.declaracao.parametros || [];
22512
+ const parametrosObrigatorios = parametros.filter((p) => !p.valorPadrao && p.abrangencia !== 'multiplo').length;
22513
+ if (argumentos.length < parametrosObrigatorios) {
22514
+ const nomeFuncao = entidadeChamada.nome || 'anônima';
22515
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.parentese, `A função '${nomeFuncao}' esperava no mínimo ${parametrosObrigatorios} argumento(s), mas recebeu ${argumentos.length}.`, expressao.linha));
22516
+ }
22517
+ }
22384
22518
  if (!ehPolimorfico && argumentos.length < aridade) {
22385
22519
  const diferenca = aridade - argumentos.length;
22386
22520
  for (let i = 0; i < diferenca; i++) {
@@ -23037,8 +23171,15 @@ class InterpretadorBase {
23037
23171
  if (objeto instanceof construtos_1.Vetor) {
23038
23172
  return objeto.valores[valorIndice];
23039
23173
  }
23040
- if (objeto.constructor === Object ||
23041
- objeto instanceof estruturas_1.ObjetoDeleguaClasse ||
23174
+ if (objeto.constructor === Object) {
23175
+ if (!Object.prototype.hasOwnProperty.call(objeto, valorIndice)) {
23176
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloFechamento, `Chave '${valorIndice}' não encontrada no dicionário.`, expressao.linha));
23177
+ }
23178
+ if (objeto[valorIndice] === 0)
23179
+ return 0;
23180
+ return objeto[valorIndice];
23181
+ }
23182
+ if (objeto instanceof estruturas_1.ObjetoDeleguaClasse ||
23042
23183
  objeto instanceof estruturas_1.DeleguaFuncao ||
23043
23184
  objeto instanceof estruturas_1.DescritorTipoClasse ||
23044
23185
  objeto instanceof estruturas_1.DeleguaModulo) {
@@ -23264,7 +23405,6 @@ class InterpretadorBase {
23264
23405
  tipoObjeto = (0, inferenciador_1.inferirTipoVariavel)(variavelObjeto);
23265
23406
  }
23266
23407
  // Caso 3: Vetor simples do JavaScript.
23267
- // TODO: Em teoria, isso deve estar no interpretador de Delégua, não aqui.
23268
23408
  if (Array.isArray(objeto)) {
23269
23409
  if (expressao.simbolo.lexema in primitivas_vetor_1.default) {
23270
23410
  const metodoDePrimitivaVetor = primitivas_vetor_1.default[expressao.simbolo.lexema].implementacao;
@@ -23689,17 +23829,11 @@ class InterpretadorBase {
23689
23829
  const inicioInterpretacao = (0, browser_process_hrtime_1.default)();
23690
23830
  try {
23691
23831
  const retornoOuErro = await this.executarUltimoEscopo(manterAmbiente);
23692
- // TODO: Esta lógica já ocorre em `executarUltimoEscopo`.
23693
- // Estudar remoção.
23694
- if (retornoOuErro instanceof excecoes_1.ErroEmTempoDeExecucao) {
23695
- this.erros.push(retornoOuErro);
23696
- }
23697
23832
  if (retornoOuErro !== undefined) {
23698
23833
  this.resultadoInterpretador.push(retornoOuErro);
23699
23834
  }
23700
23835
  }
23701
23836
  catch (erro) {
23702
- // TODO: Estudar remoção do `catch`.
23703
23837
  throw new Error(`Não deveria estar caindo aqui. Há erros no interpretador que não estão tratados corretamente. Erro atual: ${JSON.stringify(erro)}.`);
23704
23838
  }
23705
23839
  finally {
@@ -25398,15 +25532,20 @@ class PilhaEscoposExecucao {
25398
25532
  if ([delegua_1.default.VETOR, delegua_1.default.TUPLA].includes(tipoConstante)) {
25399
25533
  let subtipo = '';
25400
25534
  if (valor instanceof Array) {
25401
- // TODO: verificar tipo lógico e outros possíveis subtipos
25402
- let numeros = valor.some((v) => typeof v === 'number');
25403
- let textos = valor.some((v) => typeof v === 'string');
25404
- if (numeros && textos)
25535
+ const numeros = valor.some((v) => typeof v === 'number');
25536
+ const textos = valor.some((v) => typeof v === 'string');
25537
+ const logicos = valor.some((v) => typeof v === 'boolean');
25538
+ const tiposDistintos = [numeros, textos, logicos].filter(Boolean).length;
25539
+ if (tiposDistintos > 1)
25405
25540
  subtipo = delegua_1.default.QUALQUER;
25406
25541
  else if (numeros)
25407
25542
  subtipo = delegua_1.default.NUMERO;
25408
- else
25543
+ else if (logicos)
25544
+ subtipo = delegua_1.default.LOGICO;
25545
+ else if (textos)
25409
25546
  subtipo = delegua_1.default.TEXTO;
25547
+ else
25548
+ subtipo = delegua_1.default.QUALQUER;
25410
25549
  }
25411
25550
  elementoAlvo.subtipo = subtipo;
25412
25551
  }
@@ -25442,15 +25581,20 @@ class PilhaEscoposExecucao {
25442
25581
  if ([delegua_1.default.VETOR, delegua_1.default.TUPLA].includes(tipoVariavel)) {
25443
25582
  let subtipo = '';
25444
25583
  if (valor instanceof Array) {
25445
- // TODO: verificar tipo lógico e outros possíveis subtipos
25446
- let numeros = valor.some((v) => typeof v === 'number');
25447
- let textos = valor.some((v) => typeof v === 'string');
25448
- if (numeros && textos)
25584
+ const numeros = valor.some((v) => typeof v === 'number');
25585
+ const textos = valor.some((v) => typeof v === 'string');
25586
+ const logicos = valor.some((v) => typeof v === 'boolean');
25587
+ const tiposDistintos = [numeros, textos, logicos].filter(Boolean).length;
25588
+ if (tiposDistintos > 1)
25449
25589
  subtipo = delegua_1.default.QUALQUER;
25450
25590
  else if (numeros)
25451
25591
  subtipo = delegua_1.default.NUMERO;
25452
- else
25592
+ else if (logicos)
25593
+ subtipo = delegua_1.default.LOGICO;
25594
+ else if (textos)
25453
25595
  subtipo = delegua_1.default.TEXTO;
25596
+ else
25597
+ subtipo = delegua_1.default.QUALQUER;
25454
25598
  }
25455
25599
  elementoAlvo.subtipo = subtipo;
25456
25600
  }