@designliquido/delegua 1.7.3 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/analisador-semantico/analisador-semantico-base.d.ts +10 -1
  2. package/analisador-semantico/analisador-semantico-base.d.ts.map +1 -1
  3. package/analisador-semantico/analisador-semantico-base.js +89 -0
  4. package/analisador-semantico/analisador-semantico-base.js.map +1 -1
  5. package/analisador-semantico/analisador-semantico.d.ts +3 -9
  6. package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
  7. package/analisador-semantico/analisador-semantico.js +15 -59
  8. package/analisador-semantico/analisador-semantico.js.map +1 -1
  9. package/analisador-semantico/dialetos/analisador-semantico-pitugues.d.ts +5 -6
  10. package/analisador-semantico/dialetos/analisador-semantico-pitugues.d.ts.map +1 -1
  11. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js +33 -43
  12. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js.map +1 -1
  13. package/avaliador-sintatico/avaliador-sintatico-base.d.ts +2 -1
  14. package/avaliador-sintatico/avaliador-sintatico-base.d.ts.map +1 -1
  15. package/avaliador-sintatico/avaliador-sintatico-base.js +4 -0
  16. package/avaliador-sintatico/avaliador-sintatico-base.js.map +1 -1
  17. package/avaliador-sintatico/avaliador-sintatico.d.ts +8 -1
  18. package/avaliador-sintatico/avaliador-sintatico.d.ts.map +1 -1
  19. package/avaliador-sintatico/avaliador-sintatico.js +67 -30
  20. package/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
  21. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
  22. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +3 -5
  23. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
  24. package/avaliador-sintatico/dialetos/avaliador-sintatico-prisma.d.ts.map +1 -1
  25. package/avaliador-sintatico/dialetos/avaliador-sintatico-prisma.js +1 -2
  26. package/avaliador-sintatico/dialetos/avaliador-sintatico-prisma.js.map +1 -1
  27. package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.d.ts.map +1 -1
  28. package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.js +1 -2
  29. package/avaliador-sintatico/dialetos/avaliador-sintatico-tenda.js.map +1 -1
  30. package/avaliador-sintatico/dialetos/micro-avaliador-sintatico-pitugues.d.ts.map +1 -1
  31. package/avaliador-sintatico/dialetos/micro-avaliador-sintatico-pitugues.js +1 -2
  32. package/avaliador-sintatico/dialetos/micro-avaliador-sintatico-pitugues.js.map +1 -1
  33. package/avaliador-sintatico/micro-avaliador-sintatico.d.ts.map +1 -1
  34. package/avaliador-sintatico/micro-avaliador-sintatico.js +10 -17
  35. package/avaliador-sintatico/micro-avaliador-sintatico.js.map +1 -1
  36. package/bibliotecas/biblioteca-global.d.ts.map +1 -1
  37. package/bibliotecas/biblioteca-global.js +8 -42
  38. package/bibliotecas/biblioteca-global.js.map +1 -1
  39. package/bibliotecas/dialetos/pitugues/biblioteca-global.d.ts.map +1 -1
  40. package/bibliotecas/dialetos/pitugues/biblioteca-global.js +4 -40
  41. package/bibliotecas/dialetos/pitugues/biblioteca-global.js.map +1 -1
  42. package/bin/package.json +1 -1
  43. package/construtos/acesso-intervalo-variavel.js +3 -3
  44. package/construtos/acesso-intervalo-variavel.js.map +1 -1
  45. package/construtos/atribuir.d.ts.map +1 -1
  46. package/construtos/atribuir.js +9 -4
  47. package/construtos/atribuir.js.map +1 -1
  48. package/construtos/chamada.d.ts.map +1 -1
  49. package/construtos/chamada.js +5 -2
  50. package/construtos/chamada.js.map +1 -1
  51. package/construtos/decorador.d.ts.map +1 -1
  52. package/construtos/decorador.js +12 -1
  53. package/construtos/decorador.js.map +1 -1
  54. package/construtos/funcao.d.ts.map +1 -1
  55. package/construtos/funcao.js +13 -2
  56. package/construtos/funcao.js.map +1 -1
  57. package/construtos/literal.d.ts +3 -3
  58. package/construtos/literal.d.ts.map +1 -1
  59. package/construtos/literal.js.map +1 -1
  60. package/declaracoes/const-multiplo.d.ts +3 -3
  61. package/declaracoes/const-multiplo.d.ts.map +1 -1
  62. package/declaracoes/const-multiplo.js.map +1 -1
  63. package/declaracoes/se.d.ts +6 -2
  64. package/declaracoes/se.d.ts.map +1 -1
  65. package/declaracoes/se.js.map +1 -1
  66. package/declaracoes/var-multiplo.d.ts +3 -3
  67. package/declaracoes/var-multiplo.d.ts.map +1 -1
  68. package/declaracoes/var-multiplo.js.map +1 -1
  69. package/inferenciador.d.ts +1 -3
  70. package/inferenciador.d.ts.map +1 -1
  71. package/inferenciador.js +0 -8
  72. package/inferenciador.js.map +1 -1
  73. package/interfaces/variavel-hipotetica-interface.d.ts +2 -2
  74. package/interfaces/variavel-hipotetica-interface.d.ts.map +1 -1
  75. package/interpretador/dialetos/egua-classico/interpretador-egua-classico.d.ts.map +1 -1
  76. package/interpretador/dialetos/egua-classico/interpretador-egua-classico.js +2 -10
  77. package/interpretador/dialetos/egua-classico/interpretador-egua-classico.js.map +1 -1
  78. package/interpretador/dialetos/pitugues/interpretador-pitugues.d.ts.map +1 -1
  79. package/interpretador/dialetos/pitugues/interpretador-pitugues.js +16 -0
  80. package/interpretador/dialetos/pitugues/interpretador-pitugues.js.map +1 -1
  81. package/interpretador/interpretador-base.d.ts.map +1 -1
  82. package/interpretador/interpretador-base.js +0 -1
  83. package/interpretador/interpretador-base.js.map +1 -1
  84. package/package.json +1 -1
  85. package/tipos-de-simbolos/comum.d.ts +1 -0
  86. package/tipos-de-simbolos/comum.d.ts.map +1 -1
  87. package/tipos-de-simbolos/comum.js +1 -0
  88. package/tipos-de-simbolos/comum.js.map +1 -1
  89. package/tradutores/tradutor-javascript.d.ts.map +1 -1
  90. package/tradutores/tradutor-javascript.js +57 -23
  91. package/tradutores/tradutor-javascript.js.map +1 -1
  92. package/umd/delegua.js +300 -204
  93. package/tipo-dados-elementar.d.ts +0 -2
  94. package/tipo-dados-elementar.d.ts.map +0 -1
  95. package/tipo-dados-elementar.js +0 -3
  96. package/tipo-dados-elementar.js.map +0 -1
package/umd/delegua.js CHANGED
@@ -56,6 +56,95 @@ class AnalisadorSemanticoBase {
56
56
  correcoes: correcoes,
57
57
  });
58
58
  }
59
+ comparacaoArgumentosContraParametrosFuncao(simboloFuncao, parametros, argumentos) {
60
+ if (parametros.length !== argumentos.length) {
61
+ this.erro(simboloFuncao, `Função '${simboloFuncao.lexema}' espera ${parametros.length} parâmetros. Atual: ${argumentos.length}.`);
62
+ }
63
+ for (let [indice, parametro] of parametros.entries()) {
64
+ const argumento = argumentos[indice];
65
+ if (argumento) {
66
+ // Usando `obterTipoExpressao` para resolver adequadamente o tipo do argumento,
67
+ // independentemente de ser um `Literal` (tipo já resolvido), `Variavel` (tipo inferido do
68
+ // escopo), `Binario`, `Agrupamento`, ou qualquer outro construto (retorna `null` quando
69
+ // o tipo não pode ser determinado em tempo de compilação).
70
+ const tipoArgumento = this.obterTipoExpressao(argumento);
71
+ // Validar apenas quando ambos os lados têm um tipo específico e determinável.
72
+ // Ignorar quando `tipoArgumento` é nulo (por exemplo, resultado de `Chamada`) ou `qualquer`,
73
+ // evitando falsos positivos para expressões cujo tipo é desconhecido em tempo de compilação.
74
+ if (tipoArgumento && tipoArgumento !== 'qualquer' && parametro.tipoDado) {
75
+ if (parametro.tipoDado === 'texto' && tipoArgumento !== 'texto') {
76
+ this.erro(simboloFuncao, `O valor passado para o parâmetro '${parametro.nome.lexema}' (${parametro.tipoDado}) é diferente do esperado pela função (${tipoArgumento}).`);
77
+ }
78
+ else if (['inteiro', 'número', 'real'].includes(parametro.tipoDado)) {
79
+ // Delegua suporta conversões implícitas entre tipos numéricos, mas não
80
+ // entre texto e número.
81
+ if (!['inteiro', 'número', 'real'].includes(tipoArgumento)) {
82
+ this.erro(simboloFuncao, `O valor passado para o parâmetro '${parametro.nome.lexema}' (${parametro.tipoDado}) é diferente do esperado pela função (${tipoArgumento}).`);
83
+ }
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+ /**
90
+ * Obtém o tipo de uma expressão (pode ser Literal, Variavel, Binario, Leia, etc)
91
+ */
92
+ obterTipoExpressao(expressao) {
93
+ if (expressao instanceof construtos_1.Literal) {
94
+ return expressao.tipo;
95
+ }
96
+ if (expressao instanceof construtos_1.Variavel) {
97
+ const variavel = this.gerenciadorEscopos.buscar(expressao.simbolo.lexema);
98
+ return (variavel === null || variavel === void 0 ? void 0 : variavel.tipo) || null;
99
+ }
100
+ if (expressao instanceof construtos_1.Binario) {
101
+ // Para binários, tentamos inferir o tipo baseado nos operandos
102
+ return this.inferirTipoBinario(expressao);
103
+ }
104
+ if (expressao instanceof construtos_1.Logico) {
105
+ // Operadores lógicos sempre retornam tipo lógico
106
+ return 'lógico';
107
+ }
108
+ if (expressao instanceof construtos_1.Agrupamento) {
109
+ return this.obterTipoExpressao(expressao.expressao);
110
+ }
111
+ if (expressao instanceof construtos_1.Leia) {
112
+ // leia() sempre retorna texto
113
+ return 'texto';
114
+ }
115
+ return null;
116
+ }
117
+ /**
118
+ * Infere o tipo de resultado de uma operação binária
119
+ */
120
+ inferirTipoBinario(binario) {
121
+ const operadoresMatematicos = ['ADICAO', 'SUBTRACAO', 'MULTIPLICACAO', 'DIVISAO', 'MODULO'];
122
+ const operadoresComparacao = ['MAIOR', 'MAIOR_IGUAL', 'MENOR', 'MENOR_IGUAL', 'IGUAL', 'DIFERENTE'];
123
+ // Operadores de comparação sempre retornam lógico
124
+ if (operadoresComparacao.includes(binario.operador.tipo)) {
125
+ return 'lógico';
126
+ }
127
+ const tipoEsquerda = this.obterTipoExpressao(binario.esquerda);
128
+ const tipoDireita = this.obterTipoExpressao(binario.direita);
129
+ if (!tipoEsquerda || !tipoDireita) {
130
+ return null;
131
+ }
132
+ if (operadoresMatematicos.includes(binario.operador.tipo)) {
133
+ const tiposNumericos = ['inteiro', 'número', 'real'];
134
+ if (tiposNumericos.includes(tipoEsquerda) && tiposNumericos.includes(tipoDireita)) {
135
+ // Se um dos lados é 'real', o resultado é 'real'
136
+ if (tipoEsquerda === 'real' || tipoDireita === 'real') {
137
+ return 'real';
138
+ }
139
+ return 'número';
140
+ }
141
+ // Concatenação de textos
142
+ if (tipoEsquerda === 'texto' || tipoDireita === 'texto') {
143
+ return 'texto';
144
+ }
145
+ }
146
+ return 'qualquer';
147
+ }
59
148
  /**
60
149
  * Marca as variáveis usadas em uma expressão.
61
150
  */
@@ -375,6 +464,7 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
375
464
  this.pilhaVariaveis = new pilha_variaveis_1.PilhaVariaveis();
376
465
  this.gerenciadorEscopos = new gerenciador_escopos_1.GerenciadorEscopos();
377
466
  this.funcoes = {};
467
+ this.classesDeclararadas = new Set();
378
468
  this.atual = 0;
379
469
  this.diagnosticos = [];
380
470
  }
@@ -879,65 +969,6 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
879
969
  return null;
880
970
  }
881
971
  }
882
- /**
883
- * Obtém o tipo de uma expressão (pode ser Literal, Variavel, Binario, Leia, etc)
884
- */
885
- obterTipoExpressao(expressao) {
886
- if (expressao instanceof construtos_1.Literal) {
887
- return expressao.tipo;
888
- }
889
- if (expressao instanceof construtos_1.Variavel) {
890
- const variavel = this.gerenciadorEscopos.buscar(expressao.simbolo.lexema);
891
- return (variavel === null || variavel === void 0 ? void 0 : variavel.tipo) || null;
892
- }
893
- if (expressao instanceof construtos_1.Binario) {
894
- // Para binários, tentamos inferir o tipo baseado nos operandos
895
- return this.inferirTipoBinario(expressao);
896
- }
897
- if (expressao instanceof construtos_1.Logico) {
898
- // Operadores lógicos sempre retornam tipo lógico
899
- return 'lógico';
900
- }
901
- if (expressao instanceof construtos_1.Agrupamento) {
902
- return this.obterTipoExpressao(expressao.expressao);
903
- }
904
- if (expressao instanceof construtos_1.Leia) {
905
- // leia() sempre retorna texto
906
- return 'texto';
907
- }
908
- return null;
909
- }
910
- /**
911
- * Infere o tipo de resultado de uma operação binária
912
- */
913
- inferirTipoBinario(binario) {
914
- const operadoresMatematicos = ['ADICAO', 'SUBTRACAO', 'MULTIPLICACAO', 'DIVISAO', 'MODULO'];
915
- const operadoresComparacao = ['MAIOR', 'MAIOR_IGUAL', 'MENOR', 'MENOR_IGUAL', 'IGUAL', 'DIFERENTE'];
916
- // Operadores de comparação sempre retornam lógico
917
- if (operadoresComparacao.includes(binario.operador.tipo)) {
918
- return 'lógico';
919
- }
920
- const tipoEsquerda = this.obterTipoExpressao(binario.esquerda);
921
- const tipoDireita = this.obterTipoExpressao(binario.direita);
922
- if (!tipoEsquerda || !tipoDireita) {
923
- return null;
924
- }
925
- if (operadoresMatematicos.includes(binario.operador.tipo)) {
926
- const tiposNumericos = ['inteiro', 'número', 'real'];
927
- if (tiposNumericos.includes(tipoEsquerda) && tiposNumericos.includes(tipoDireita)) {
928
- // Se um dos lados é 'real', o resultado é 'real'
929
- if (tipoEsquerda === 'real' || tipoDireita === 'real') {
930
- return 'real';
931
- }
932
- return 'número';
933
- }
934
- // Concatenação de textos
935
- if (tipoEsquerda === 'texto' || tipoDireita === 'texto') {
936
- return 'texto';
937
- }
938
- }
939
- return 'qualquer';
940
- }
941
972
  verificarExistenciaConstruto(construto) {
942
973
  if (construto instanceof construtos_1.Variavel) {
943
974
  if (!this.gerenciadorEscopos.buscar(construto.simbolo.lexema)) {
@@ -1197,6 +1228,19 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1197
1228
  }
1198
1229
  return Promise.resolve();
1199
1230
  }
1231
+ visitarDeclaracaoClasse(declaracao) {
1232
+ if (declaracao.superClasse) {
1233
+ const nomeSuperclasse = declaracao.superClasse.simbolo.lexema;
1234
+ if (nomeSuperclasse === declaracao.simbolo.lexema) {
1235
+ this.erro(declaracao.superClasse.simbolo, `A classe '${declaracao.simbolo.lexema}' não pode herdar de si mesma.`);
1236
+ }
1237
+ else if (!this.classesDeclararadas.has(nomeSuperclasse)) {
1238
+ this.erro(declaracao.superClasse.simbolo, `Superclasse '${nomeSuperclasse}' não foi declarada.`);
1239
+ }
1240
+ }
1241
+ this.classesDeclararadas.add(declaracao.simbolo.lexema);
1242
+ return Promise.resolve();
1243
+ }
1200
1244
  visitarDeclaracaoDefinicaoFuncao(declaracao) {
1201
1245
  var _a;
1202
1246
  if (declaracao.funcao.tipo === undefined) {
@@ -1271,6 +1315,7 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
1271
1315
  }
1272
1316
  async analisar(declaracoes) {
1273
1317
  this.gerenciadorEscopos = new gerenciador_escopos_1.GerenciadorEscopos();
1318
+ this.classesDeclararadas = new Set();
1274
1319
  this.atual = 0;
1275
1320
  this.diagnosticos = [];
1276
1321
  try {
@@ -1501,6 +1546,10 @@ class AvaliadorSintaticoBase {
1501
1546
  }
1502
1547
  return false;
1503
1548
  }
1549
+ async declaracaoBloco() {
1550
+ const simboloInicioBloco = this.consumir(comum_1.default.CHAVE_ESQUERDA, "Esperado '{' para abertura de bloco.");
1551
+ return new declaracoes_1.Bloco(simboloInicioBloco.hashArquivo, Number(simboloInicioBloco.linha), await this.blocoEscopo());
1552
+ }
1504
1553
  async finalizarChamada(entidadeChamada) {
1505
1554
  const argumentos = [];
1506
1555
  if (!this.verificarTipoSimboloAtual(comum_1.default.PARENTESE_DIREITO)) {
@@ -1931,7 +1980,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
1931
1980
  * @returns {ListaCompreensao} A lista de compreensão resolvida.
1932
1981
  */
1933
1982
  async resolverCompreensaoDeLista(retornoExpressao) {
1934
- this.consumir(delegua_2.default.PARA, "Esperado instrução 'para' após identificado.");
1983
+ this.consumir(delegua_2.default.PARA, "Esperado instrução 'para' após identificador.");
1935
1984
  this.consumir(delegua_2.default.CADA, "Esperado instrução 'cada' após 'para'.");
1936
1985
  const simboloVariavelIteracao = this.consumir(delegua_2.default.IDENTIFICADOR, "Esperado identificador de variável após 'para cada'.");
1937
1986
  if (!this.verificarSeSimboloAtualEIgualA(delegua_2.default.DE, delegua_2.default.EM)) {
@@ -1956,8 +2005,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
1956
2005
  new declaracoes_1.Se(condicao, new declaracoes_1.Bloco(retornoExpressao.hashArquivo, retornoExpressao.linha, [
1957
2006
  new declaracoes_1.Retorna(simboloVariavelIteracao, retornoExpressao),
1958
2007
  ]), [], null),
1959
- ])), 'qualquer[]' // TODO: Talvez um dia inferir o tipo aqui.
1960
- );
2008
+ ])), retornoExpressao.tipo ? `${retornoExpressao.tipo}[]` : 'qualquer[]');
1961
2009
  }
1962
2010
  async primario() {
1963
2011
  const simboloAtual = this.simbolos[this.atual];
@@ -2098,8 +2146,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2098
2146
  case delegua_2.default.TEXTO:
2099
2147
  const simboloNumeroTexto = this.avancarEDevolverAnterior();
2100
2148
  const tipoInferido = (0, inferenciador_1.inferirTipoVariavel)(simboloNumeroTexto.literal);
2101
- const tipoDadosElementar = (0, inferenciador_1.tipoInferenciaParaTipoDadosElementar)(tipoInferido);
2102
- return new construtos_1.Literal(this.hashArquivo, Number(simboloNumeroTexto.linha), simboloNumeroTexto.literal, tipoDadosElementar);
2149
+ return new construtos_1.Literal(this.hashArquivo, Number(simboloNumeroTexto.linha), simboloNumeroTexto.literal, tipoInferido);
2103
2150
  case delegua_2.default.PARA:
2104
2151
  const simboloPara = this.avancarEDevolverAnterior();
2105
2152
  return await this.paraComoConstruto(simboloPara);
@@ -2227,6 +2274,50 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2227
2274
  }
2228
2275
  return tipoAcesso;
2229
2276
  }
2277
+ /**
2278
+ * Resolve um construto do tipo `Variavel`, `AcessoMetodoOuPropriedade` ou `AcessoIndiceVariavel`
2279
+ * para um `ElementoMontaoTipos` correspondente, caso exista.
2280
+ * @param construto O construto.
2281
+ * @returns O `ElementoMontaoTipos` correspondente ou `null` se não existir.
2282
+ */
2283
+ resolverElementoMontao(construto) {
2284
+ switch (construto.constructor) {
2285
+ case construtos_1.Variavel:
2286
+ try {
2287
+ const nomeVariavel = construto.simbolo.lexema;
2288
+ const elementoMontao = this.pilhaEscopos.obterElementoMontaoTipos(nomeVariavel);
2289
+ if (elementoMontao.endereco) {
2290
+ const referenciaMontaoTipos = this.montaoTipos.obterReferencia(construto.hashArquivo, construto.linha, elementoMontao.endereco);
2291
+ if (referenciaMontaoTipos instanceof elemento_montao_tipos_1.ElementoMontaoTipos) {
2292
+ return referenciaMontaoTipos;
2293
+ }
2294
+ return null;
2295
+ }
2296
+ return elementoMontao;
2297
+ }
2298
+ catch (_a) {
2299
+ return null;
2300
+ }
2301
+ case construtos_1.AcessoMetodoOuPropriedade: {
2302
+ const acesso = construto;
2303
+ const elementoObjeto = this.resolverElementoMontao(acesso.objeto);
2304
+ if (!elementoObjeto) {
2305
+ return null;
2306
+ }
2307
+ return elementoObjeto.subElementos[acesso.simbolo.lexema] || null;
2308
+ }
2309
+ case construtos_1.AcessoIndiceVariavel: {
2310
+ const acessoIndice = construto;
2311
+ const elementoObjeto = this.resolverElementoMontao(acessoIndice.entidadeChamada);
2312
+ if (!elementoObjeto || !(acessoIndice.indice instanceof construtos_1.Literal)) {
2313
+ return null;
2314
+ }
2315
+ return elementoObjeto.subElementos[String(acessoIndice.indice.valor)] || null;
2316
+ }
2317
+ default:
2318
+ return null;
2319
+ }
2320
+ }
2230
2321
  async resolverCadeiaChamadas(expressaoAnterior, tipoAnterior = 'qualquer') {
2231
2322
  if (!this.simbolos[this.atual]) {
2232
2323
  return expressaoAnterior;
@@ -2244,12 +2335,10 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2244
2335
  // Se não for um dicionário anônimo (ou seja, ser variável ou constante com nome)
2245
2336
  if (expressaoAnterior.tipo === 'dicionário' &&
2246
2337
  expressaoAnterior.constructor !== construtos_1.Dicionario) {
2247
- // TODO: Achar algum caso em que aqui não seja variável.
2248
- const nomeDicionario = expressaoAnterior.simbolo.lexema;
2249
- const elementoDicionarioPilha = this.pilhaEscopos.obterElementoMontaoTipos(nomeDicionario);
2250
- const referenciaMontaoTipos = this.montaoTipos.obterReferencia(expressaoAnterior.hashArquivo, expressaoAnterior.linha, elementoDicionarioPilha.endereco);
2251
- if (nome.lexema in referenciaMontaoTipos.subElementos) {
2252
- tipoInferido = referenciaMontaoTipos.subElementos[nome.lexema].tipo;
2338
+ const elementoMontaoTipos = this.resolverElementoMontao(expressaoAnterior);
2339
+ if (elementoMontaoTipos &&
2340
+ nome.lexema in elementoMontaoTipos.subElementos) {
2341
+ tipoInferido = elementoMontaoTipos.subElementos[nome.lexema].tipo;
2253
2342
  }
2254
2343
  }
2255
2344
  const acesso = new construtos_1.AcessoMetodoOuPropriedade(this.hashArquivo, expressaoAnterior, nome, tipoInferido);
@@ -2714,7 +2803,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2714
2803
  if (Array.isArray(retornoDeclaracao)) {
2715
2804
  declaracoes = declaracoes.concat(retornoDeclaracao);
2716
2805
  }
2717
- else {
2806
+ else if (retornoDeclaracao !== null) {
2718
2807
  declaracoes.push(retornoDeclaracao);
2719
2808
  }
2720
2809
  }
@@ -2746,8 +2835,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2746
2835
  }
2747
2836
  async logicaComumEnquanto() {
2748
2837
  const condicao = await this.expressao();
2749
- // TODO: Talvez não seja uma ideia melhor chamar o método de `Bloco` aqui?
2750
- const corpo = await this.resolverDeclaracao();
2838
+ const corpo = await this.declaracaoBloco();
2751
2839
  return {
2752
2840
  condicao,
2753
2841
  corpo,
@@ -2851,7 +2939,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2851
2939
  return new declaracoes_1.Falhar(simboloFalha, expressaoFalha);
2852
2940
  }
2853
2941
  async logicaComumFazer() {
2854
- const caminhoFazer = await this.resolverDeclaracao();
2942
+ const caminhoFazer = await this.declaracaoBloco();
2855
2943
  this.consumir(delegua_2.default.ENQUANTO, "Esperado declaração do 'enquanto' após o escopo do 'fazer'.");
2856
2944
  const condicaoEnquanto = await this.expressao();
2857
2945
  return {
@@ -2863,8 +2951,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2863
2951
  try {
2864
2952
  this.blocos += 1;
2865
2953
  const { caminhoFazer, condicaoEnquanto } = await this.logicaComumFazer();
2866
- return new declaracoes_1.Fazer(simboloFazer.hashArquivo, Number(simboloFazer.linha), caminhoFazer, // TODO: Aqui pode ser um `Bloco`?
2867
- condicaoEnquanto);
2954
+ return new declaracoes_1.Fazer(simboloFazer.hashArquivo, Number(simboloFazer.linha), caminhoFazer, condicaoEnquanto);
2868
2955
  }
2869
2956
  finally {
2870
2957
  this.blocos -= 1;
@@ -2948,8 +3035,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2948
3035
  }
2949
3036
  this.pilhaEscopos.definirInformacoesVariavel(nomeVariavelChave.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(nomeVariavelChave.lexema, 'qualquer'));
2950
3037
  this.pilhaEscopos.definirInformacoesVariavel(nomeVariavelValor.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(nomeVariavelValor.lexema, 'qualquer'));
2951
- // TODO: Talvez não seja uma ideia melhor chamar o método de `Bloco` aqui?
2952
- const corpo = await this.resolverDeclaracao();
3038
+ const corpo = await this.declaracaoBloco();
2953
3039
  return {
2954
3040
  nomeVariavelChave,
2955
3041
  nomeVariavelValor,
@@ -2987,8 +3073,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
2987
3073
  tipoVariavelIteracao = tipoVetor.slice(0, -2);
2988
3074
  }
2989
3075
  this.pilhaEscopos.definirInformacoesVariavel(nomeVariavelIteracao.lexema, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(nomeVariavelIteracao.lexema, tipoVariavelIteracao));
2990
- // TODO: Talvez não seja uma ideia melhor chamar o método de `Bloco` aqui?
2991
- const corpo = await this.resolverDeclaracao();
3076
+ const corpo = await this.declaracaoBloco();
2992
3077
  return {
2993
3078
  variavelIteracao,
2994
3079
  vetor: vetorOuDicionario,
@@ -3037,8 +3122,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3037
3122
  if (comParenteses) {
3038
3123
  this.consumir(delegua_2.default.PARENTESE_DIREITO, "Esperado ')' após cláusulas de inicialização, condição e incremento.");
3039
3124
  }
3040
- // TODO: Talvez não seja uma ideia melhor chamar o método de `Bloco` aqui?
3041
- const corpo = await this.resolverDeclaracao();
3125
+ const corpo = await this.declaracaoBloco();
3042
3126
  return {
3043
3127
  inicializador,
3044
3128
  condicao,
@@ -3569,9 +3653,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3569
3653
  let superClasse = null;
3570
3654
  if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.HERDA)) {
3571
3655
  const simboloSuperclasse = this.consumir(delegua_2.default.IDENTIFICADOR, 'Esperado nome da Superclasse.');
3572
- // TODO: Validar classes existentes?
3573
3656
  this.superclasseAtual = simboloSuperclasse.lexema;
3574
- // TODO: Colocar tipo aqui?
3575
3657
  superClasse = new construtos_1.Variavel(this.hashArquivo, this.simbolos[this.atual - 1], simboloSuperclasse.lexema);
3576
3658
  }
3577
3659
  this.consumir(delegua_2.default.CHAVE_ESQUERDA, "Esperado '{' antes do escopo da classe.");
@@ -3651,10 +3733,15 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3651
3733
  * @returns Sempre retorna `void`.
3652
3734
  */
3653
3735
  sincronizar() {
3654
- this.avancarEDevolverAnterior();
3736
+ this.avancarEDevolverAnterior(); // avança além do token com erro
3655
3737
  while (!this.estaNoFinal()) {
3656
- const tipoSimboloAtual = this.simbolos[this.atual - 1].tipo;
3657
- switch (tipoSimboloAtual) {
3738
+ // Um ponto-e-vírgula consumido indica fronteira limpa entre declarações.
3739
+ if (this.simbolos[this.atual - 1].tipo === delegua_2.default.PONTO_E_VIRGULA)
3740
+ return;
3741
+ // Uma palavra-chave de início de declaração ou fecha-chave à frente:
3742
+ // retorna SEM consumir o token, para que o chamador o analise normalmente.
3743
+ switch (this.simbolos[this.atual].tipo) {
3744
+ case delegua_2.default.CHAVE_DIREITA:
3658
3745
  case delegua_2.default.CLASSE:
3659
3746
  case delegua_2.default.FUNCAO:
3660
3747
  case delegua_2.default.FUNÇÃO:
@@ -3682,8 +3769,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3682
3769
  case delegua_2.default.AJUDA:
3683
3770
  return await this.declaracaoAjuda();
3684
3771
  case delegua_2.default.CHAVE_ESQUERDA:
3685
- const simboloInicioBloco = this.avancarEDevolverAnterior();
3686
- return new declaracoes_1.Bloco(simboloInicioBloco.hashArquivo, Number(simboloInicioBloco.linha), await this.blocoEscopo());
3772
+ return await this.declaracaoBloco();
3687
3773
  case delegua_2.default.COMENTARIO:
3688
3774
  return this.declaracaoComentarioUmaLinha();
3689
3775
  case delegua_2.default.CONSTANTE:
@@ -5157,8 +5243,7 @@ class AvaliadorSintaticoPitugues {
5157
5243
  case pitugues_2.default.TEXTO:
5158
5244
  const simboloLiteral = this.avancarEDevolverAnterior();
5159
5245
  const tipoInferido = (0, inferenciador_1.inferirTipoVariavel)(simboloLiteral.literal);
5160
- const tipoDadosElementar = (0, inferenciador_1.tipoInferenciaParaTipoDadosElementar)(tipoInferido);
5161
- return new construtos_1.Literal(this.hashArquivo, Number(simboloLiteral.linha), simboloLiteral.literal, tipoDadosElementar);
5246
+ return new construtos_1.Literal(this.hashArquivo, Number(simboloLiteral.linha), simboloLiteral.literal, tipoInferido);
5162
5247
  case pitugues_2.default.TIPO:
5163
5248
  const simboloTipo = this.avancarEDevolverAnterior();
5164
5249
  this.consumir(pitugues_2.default.PARENTESE_ESQUERDO, "Esperado '(' após 'tipo'.");
@@ -5840,7 +5925,7 @@ class AvaliadorSintaticoPitugues {
5840
5925
  * @returns {ListaCompreensao} A lista de compreensão resolvida.
5841
5926
  */
5842
5927
  async resolverCompreensaoDeLista(retornoExpressao) {
5843
- this.consumir(pitugues_2.default.PARA, "Esperado instrução 'para' após identificado.");
5928
+ this.consumir(pitugues_2.default.PARA, "Esperado instrução 'para' após identificador.");
5844
5929
  this.consumir(pitugues_2.default.CADA, "Esperado instrução 'cada' após 'para'.");
5845
5930
  const simboloVariavelIteracao = this.consumir(pitugues_2.default.IDENTIFICADOR, "Esperado identificador de variável após 'para cada'.");
5846
5931
  // TODO: Manter essa validação aqui? Se sim, como resolver a expressão?
@@ -5868,8 +5953,7 @@ class AvaliadorSintaticoPitugues {
5868
5953
  new declaracoes_1.Se(condicao, new declaracoes_1.Bloco(retornoExpressao.hashArquivo, retornoExpressao.linha, [
5869
5954
  new declaracoes_1.Retorna(simboloVariavelIteracao, retornoExpressao),
5870
5955
  ]), [], null),
5871
- ])), 'qualquer[]' // TODO: Talvez um dia inferir o tipo aqui.
5872
- );
5956
+ ])), retornoExpressao.tipo ? `${retornoExpressao.tipo}[]` : 'qualquer[]');
5873
5957
  }
5874
5958
  verificarDefinicaoTipoAtual() {
5875
5959
  const tipos = [...Object.values(pitugues_1.default)];
@@ -6588,8 +6672,7 @@ class AvaliadorSintaticoPrisma extends avaliador_sintatico_base_1.AvaliadorSinta
6588
6672
  case prisma_1.default.TEXTO:
6589
6673
  const simboloLiteral = this.avancarEDevolverAnterior();
6590
6674
  const tipoInferido = (0, inferenciador_1.inferirTipoVariavel)(simboloLiteral.literal);
6591
- const tipoDadosElementar = (0, inferenciador_1.tipoInferenciaParaTipoDadosElementar)(tipoInferido);
6592
- return new construtos_1.Literal(this.hashArquivo, Number(simboloLiteral.linha), simboloLiteral.literal, tipoDadosElementar);
6675
+ return new construtos_1.Literal(this.hashArquivo, Number(simboloLiteral.linha), simboloLiteral.literal, tipoInferido);
6593
6676
  case prisma_1.default.IDENTIFICADOR:
6594
6677
  const simboloIdentificador = this.avancarEDevolverAnterior();
6595
6678
  let tipoOperando;
@@ -7414,8 +7497,7 @@ class AvaliadorSintaticoTenda extends avaliador_sintatico_base_1.AvaliadorSintat
7414
7497
  case tenda_1.default.TEXTO:
7415
7498
  const simboloNumeroTexto = this.avancarEDevolverAnterior();
7416
7499
  const tipoInferido = (0, inferenciador_1.inferirTipoVariavel)(simboloNumeroTexto.literal);
7417
- const tipoDadosElementar = (0, inferenciador_1.tipoInferenciaParaTipoDadosElementar)(tipoInferido);
7418
- return new construtos_1.Literal(this.hashArquivo, Number(simboloNumeroTexto.linha), simboloNumeroTexto.literal, tipoDadosElementar);
7500
+ return new construtos_1.Literal(this.hashArquivo, Number(simboloNumeroTexto.linha), simboloNumeroTexto.literal, tipoInferido);
7419
7501
  case tenda_1.default.PARENTESE_ESQUERDO:
7420
7502
  this.avancarEDevolverAnterior();
7421
7503
  const expressao = await this.expressao();
@@ -8261,8 +8343,7 @@ class MicroAvaliadorSintaticoPitugues extends micro_avaliador_sintatico_base_1.M
8261
8343
  case pitugues_1.default.TEXTO:
8262
8344
  const simboloNumeroTexto = this.avancarEDevolverAnterior();
8263
8345
  const tipoInferido = (0, inferenciador_1.inferirTipoVariavel)(simboloNumeroTexto.literal);
8264
- const tiposDadosElementar = (0, inferenciador_1.tipoInferenciaParaTipoDadosElementar)(tipoInferido);
8265
- return new construtos_1.Literal(-1, Number(this.linha), simboloNumeroTexto.literal, tiposDadosElementar);
8346
+ return new construtos_1.Literal(-1, Number(this.linha), simboloNumeroTexto.literal, tipoInferido);
8266
8347
  case pitugues_1.default.IDENTIFICADOR:
8267
8348
  const simboloIdentificador = this.avancarEDevolverAnterior();
8268
8349
  return new construtos_1.Variavel(-1, simboloIdentificador);
@@ -8633,31 +8714,24 @@ class MicroAvaliadorSintatico extends micro_avaliador_sintatico_base_1.MicroAval
8633
8714
  const simboloAtual = this.simbolos[this.atual];
8634
8715
  let valores = [];
8635
8716
  switch (simboloAtual.tipo) {
8636
- // TODO: Verificar se vamos usar isso.
8637
- /* case tiposDeSimbolos.CHAVE_ESQUERDA:
8717
+ case delegua_1.default.CHAVE_ESQUERDA:
8638
8718
  this.avancarEDevolverAnterior();
8639
8719
  const chaves = [];
8640
8720
  valores = [];
8641
-
8642
- if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CHAVE_DIREITA)) {
8643
- return new Dicionario(-1, Number(this.linha), [], []);
8721
+ if (this.verificarSeSimboloAtualEIgualA(delegua_1.default.CHAVE_DIREITA)) {
8722
+ return new construtos_1.Dicionario(-1, Number(this.linha), [], []);
8644
8723
  }
8645
-
8646
- while (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CHAVE_DIREITA)) {
8647
- const chave = this.atribuir();
8648
- this.consumir(tiposDeSimbolos.DOIS_PONTOS, "Esperado ':' entre chave e valor.");
8649
- const valor = this.atribuir();
8650
-
8724
+ while (!this.verificarSeSimboloAtualEIgualA(delegua_1.default.CHAVE_DIREITA)) {
8725
+ const chave = this.declaracao();
8726
+ this.consumir(delegua_1.default.DOIS_PONTOS, "Esperado ':' entre chave e valor.");
8727
+ const valor = this.declaracao();
8651
8728
  chaves.push(chave);
8652
8729
  valores.push(valor);
8653
-
8654
- if (this.simbolos[this.atual].tipo !== tiposDeSimbolos.CHAVE_DIREITA) {
8655
- this.consumir(tiposDeSimbolos.VIRGULA, 'Esperado vírgula antes da próxima expressão.');
8730
+ if (this.simbolos[this.atual].tipo !== delegua_1.default.CHAVE_DIREITA) {
8731
+ this.consumir(delegua_1.default.VIRGULA, 'Esperado vírgula antes da próxima expressão.');
8656
8732
  }
8657
8733
  }
8658
-
8659
- return new Dicionario(-1, Number(this.linha), chaves, valores); */
8660
- // TODO: Verificar se vamos usar isso.
8734
+ return new construtos_1.Dicionario(-1, Number(this.linha), chaves, valores);
8661
8735
  case delegua_1.default.COLCHETE_ESQUERDO:
8662
8736
  this.avancarEDevolverAnterior();
8663
8737
  valores = [];
@@ -9610,20 +9684,6 @@ async function mapear(interpretador, vetor, funcaoMapeamento) {
9610
9684
  }, 'Parâmetro inválido. O primeiro parâmetro da função mapear() não pode ser nulo.'));
9611
9685
  const valorVetor = interpretador.resolverValor(vetor);
9612
9686
  const valorFuncaoMapeamento = interpretador.resolverValor(funcaoMapeamento);
9613
- // TODO: As lógicas de validação abaixo deixam de fazer sentido com a validação de argumentos feita
9614
- // na avaliação sintática. Estudar remoção.
9615
- if (!Array.isArray(valorVetor)) {
9616
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
9617
- hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
9618
- linha: interpretador.linhaDeclaracaoAtual,
9619
- }, 'Parâmetro inválido. O primeiro parâmetro da função mapear() deve ser um vetor.'));
9620
- }
9621
- if (valorFuncaoMapeamento.constructor !== estruturas_1.DeleguaFuncao) {
9622
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
9623
- hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
9624
- linha: interpretador.linhaDeclaracaoAtual,
9625
- }, 'Parâmetro inválido. O segundo parâmetro da função mapear() deve ser uma função.'));
9626
- }
9627
9687
  const resultados = [];
9628
9688
  for (let indice = 0; indice < valorVetor.length; ++indice) {
9629
9689
  const informacoesRetorno = await valorFuncaoMapeamento.chamar(interpretador, [
@@ -9790,20 +9850,6 @@ async function paraCada(interpretador, vetor, funcaoFiltragem) {
9790
9850
  const valorFuncaoFiltragem = funcaoFiltragem.hasOwnProperty('valor')
9791
9851
  ? funcaoFiltragem.valor
9792
9852
  : funcaoFiltragem;
9793
- // TODO: As lógicas de validação abaixo deixam de fazer sentido com a validação de argumentos feita
9794
- // na avaliação sintática. Estudar remoção.
9795
- if (!Array.isArray(valorVetor)) {
9796
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
9797
- hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
9798
- linha: interpretador.linhaDeclaracaoAtual,
9799
- }, 'Parâmetro inválido. O primeiro parâmetro da função paraCada() deve ser um vetor.'));
9800
- }
9801
- if (valorFuncaoFiltragem.constructor !== estruturas_1.DeleguaFuncao) {
9802
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
9803
- hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
9804
- linha: interpretador.linhaDeclaracaoAtual,
9805
- }, 'Parâmetro inválido. O segundo parâmetro da função paraCada() deve ser uma função.'));
9806
- }
9807
9853
  for (let indice = 0; indice < valorVetor.length; ++indice) {
9808
9854
  await valorFuncaoFiltragem.chamar(interpretador, [valorVetor[indice]]);
9809
9855
  }
@@ -10069,21 +10115,11 @@ async function todosEmCondicao(interpretador, iteravel, funcaoCondicional) {
10069
10115
  */
10070
10116
  async function tupla(interpretador, vetor) {
10071
10117
  const valorVetor = interpretador.resolverValor(vetor);
10072
- // TODO: As lógicas de validação abaixo deixam de fazer sentido com a validação de argumentos feita
10073
- // na avaliação sintática. Estudar remoção.
10074
- if (!Array.isArray(valorVetor)) {
10075
- return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
10076
- hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
10077
- linha: interpretador.linhaDeclaracaoAtual,
10078
- }, 'Argumento de função nativa `tupla` não parece ser um vetor.'));
10079
- }
10080
10118
  const elementos = valorVetor.map(item => new construtos_1.Literal(interpretador.hashArquivoDeclaracaoAtual, interpretador.linhaDeclaracaoAtual, interpretador.resolverValor(item)));
10081
10119
  return new construtos_1.TuplaN(interpretador.hashArquivoDeclaracaoAtual, interpretador.linhaDeclaracaoAtual, elementos);
10082
10120
  }
10083
10121
  async function vetor(interpretador, tupla) {
10084
10122
  const objetoTupla = interpretador.resolverValor(tupla);
10085
- // TODO: As lógicas de validação abaixo deixam de fazer sentido com a validação de argumentos feita
10086
- // na avaliação sintática. Estudar remoção.
10087
10123
  if (!(objetoTupla instanceof construtos_1.Tupla || objetoTupla instanceof construtos_1.TuplaN)) {
10088
10124
  return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao({
10089
10125
  hashArquivo: interpretador.hashArquivoDeclaracaoAtual,
@@ -10096,16 +10132,20 @@ async function vetor(interpretador, tupla) {
10096
10132
  }
10097
10133
  else {
10098
10134
  const nomeClasse = objetoTupla.constructor.name;
10099
- if (mapaPropriedadesTuplas.hasOwnProperty(nomeClasse)) {
10100
- const props = mapaPropriedadesTuplas[nomeClasse];
10135
+ const props = mapaPropriedadesTuplas[nomeClasse];
10136
+ if (props) {
10101
10137
  resultado = props.map(prop => objetoTupla[prop]);
10102
10138
  }
10103
10139
  else if (objetoTupla.elementos && Array.isArray(objetoTupla.elementos)) {
10104
10140
  resultado = objetoTupla.elementos;
10105
10141
  }
10106
10142
  }
10107
- const resultadoFinal = resultado.map(item => (item && item.hasOwnProperty('valor')) ? item.valor : item);
10108
- return Promise.resolve(resultadoFinal);
10143
+ const resultadoFinal = new Array(resultado.length);
10144
+ for (let i = 0; i < resultado.length; i++) {
10145
+ const item = resultado[i];
10146
+ resultadoFinal[i] = item && typeof item === 'object' && 'valor' in item ? item.valor : item;
10147
+ }
10148
+ return resultadoFinal;
10109
10149
  }
10110
10150
 
10111
10151
  },{"../construtos":62,"../excecoes":129,"../interpretador/estruturas":176,"../interpretador/estruturas/descritor-tipo-classe":174,"../interpretador/estruturas/funcao-padrao":175,"../interpretador/estruturas/objeto-delegua-classe":180,"../quebras":212}],28:[function(require,module,exports){
@@ -11106,9 +11146,9 @@ class AcessoIntervaloVariavel {
11106
11146
  return await visitante.visitarExpressaoAcessoIntervaloVariavel(this);
11107
11147
  }
11108
11148
  paraTexto() {
11109
- const inicio = this.indiceInicio ? this.indiceInicio.paraTexto() : 'sem-início';
11110
- const fim = this.indiceFim ? this.indiceFim.paraTexto() : 'sem-fim';
11111
- const passo = this.indicePasso ? this.indicePasso.paraTexto() : 'sem-passo';
11149
+ const inicio = this.indiceInicio ? this.indiceInicio.paraTexto() : '(sem início)';
11150
+ const fim = this.indiceFim ? this.indiceFim.paraTexto() : '(sem fim)';
11151
+ const passo = this.indicePasso ? this.indicePasso.paraTexto() : '(sem passo)';
11112
11152
  return (`<acesso-índice-variável entidadeChamada=${this.entidadeChamada.paraTexto()} ` +
11113
11153
  `inicio=${inicio} ` +
11114
11154
  `fim=${fim}` +
@@ -11350,19 +11390,24 @@ exports.AtribuicaoPorIndicesMatriz = AtribuicaoPorIndicesMatriz;
11350
11390
  "use strict";
11351
11391
  Object.defineProperty(exports, "__esModule", { value: true });
11352
11392
  exports.Atribuir = void 0;
11393
+ const variavel_1 = require("./variavel");
11353
11394
  /**
11354
11395
  * Construto de atribuição de um valor a um símbolo.
11355
11396
  */
11356
11397
  class Atribuir {
11357
- constructor(hashArquivo, alvo, valor,
11358
- // indice so é usado para variaveis de vetores
11359
- // TODO: criar alguma validaçao para garantir que `indice` só seja passado para variáveis de vetores
11360
- indice, simboloOperador) {
11398
+ constructor(hashArquivo, alvo, valor, indice, simboloOperador) {
11361
11399
  this.linha = Number(alvo.linha);
11362
11400
  this.hashArquivo = hashArquivo;
11363
11401
  this.alvo = alvo;
11364
11402
  this.valor = valor;
11365
11403
  if (indice !== undefined) {
11404
+ const alvoComoVariavel = alvo;
11405
+ const tipoAlvo = alvoComoVariavel === null || alvoComoVariavel === void 0 ? void 0 : alvoComoVariavel.tipo;
11406
+ const alvoSuportaIndice = alvo instanceof variavel_1.Variavel &&
11407
+ (tipoAlvo === 'vetor' || tipoAlvo === 'dicionário' || tipoAlvo === 'qualquer' || (tipoAlvo === null || tipoAlvo === void 0 ? void 0 : tipoAlvo.endsWith('[]')));
11408
+ if (!alvoSuportaIndice) {
11409
+ throw new Error("`indice` só pode ser informado quando o alvo for uma variável de vetor ou dicionário.");
11410
+ }
11366
11411
  this.indice = indice;
11367
11412
  }
11368
11413
  if (simboloOperador !== undefined) {
@@ -11385,7 +11430,7 @@ class Atribuir {
11385
11430
  }
11386
11431
  exports.Atribuir = Atribuir;
11387
11432
 
11388
- },{}],45:[function(require,module,exports){
11433
+ },{"./variavel":89}],45:[function(require,module,exports){
11389
11434
  "use strict";
11390
11435
  Object.defineProperty(exports, "__esModule", { value: true });
11391
11436
  exports.Binario = void 0;
@@ -11478,8 +11523,11 @@ class Chamada {
11478
11523
  return await visitante.visitarExpressaoDeChamada(this);
11479
11524
  }
11480
11525
  paraTexto() {
11481
- // TODO: Argumentos
11482
- return `<chamada entidadeChamada=${this.entidadeChamada.paraTexto()} />`;
11526
+ let argumentos = '';
11527
+ for (let indice = 0; indice < this.argumentos.length; indice++) {
11528
+ argumentos += this.argumentos[indice].paraTexto();
11529
+ }
11530
+ return `<chamada entidadeChamada=${this.entidadeChamada.paraTexto()} argumentos=[${argumentos}] />`;
11483
11531
  }
11484
11532
  paraTextoSaida() {
11485
11533
  throw new Error('Método não implementado.');
@@ -11588,7 +11636,18 @@ class Decorador {
11588
11636
  return Promise.reject(new Error('Este método não deveria ser chamado.'));
11589
11637
  }
11590
11638
  paraTexto() {
11591
- // TODO: Atributos
11639
+ let atributos = '';
11640
+ for (const chave in this.atributos) {
11641
+ if (!Object.prototype.hasOwnProperty.call(this.atributos, chave)) {
11642
+ continue;
11643
+ }
11644
+ const valor = this.atributos[chave];
11645
+ const valorTexto = valor && typeof valor === 'object' && typeof valor.paraTexto === 'function' ? valor.paraTexto() : valor;
11646
+ atributos += `${chave}=${valorTexto} `;
11647
+ }
11648
+ if (atributos.length > 0) {
11649
+ return `<decorador nome=${this.nome} ${atributos.slice(0, -1)} />`;
11650
+ }
11592
11651
  return `<decorador nome=${this.nome} />`;
11593
11652
  }
11594
11653
  paraTextoSaida() {
@@ -11820,8 +11879,19 @@ class FuncaoConstruto {
11820
11879
  return Promise.resolve(visitante.visitarExpressaoFuncaoConstruto(this));
11821
11880
  }
11822
11881
  paraTexto() {
11823
- // TODO: Corpo.
11824
- return `<construto-função parâmetros=${this.parametros} tipoRetorno=${this.tipo} tipoExplícito=${this.tipoExplicito ? 'Sim' : 'Não'} />`;
11882
+ let parametros = '';
11883
+ for (let indice = 0; indice < this.parametros.length; indice++) {
11884
+ const parametro = this.parametros[indice];
11885
+ parametros += `${parametro.nome.lexema}:${parametro.tipoDado}`;
11886
+ if (indice < this.parametros.length - 1) {
11887
+ parametros += ',';
11888
+ }
11889
+ }
11890
+ let corpo = '';
11891
+ for (let indice = 0; indice < this.corpo.length; indice++) {
11892
+ corpo += this.corpo[indice].paraTexto();
11893
+ }
11894
+ return `<construto-função parâmetros=[${parametros}] corpo=[${corpo}] tipoRetorno=${this.tipo} tipoExplícito=${this.tipoExplicito ? 'Sim' : 'Não'} />`;
11825
11895
  }
11826
11896
  paraTextoSaida() {
11827
11897
  throw new Error('Método não implementado.');
@@ -15435,7 +15505,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
15435
15505
  Object.defineProperty(exports, "__esModule", { value: true });
15436
15506
  exports.TipoNativoSimbolo = void 0;
15437
15507
  exports.inferirTipoVariavel = inferirTipoVariavel;
15438
- exports.tipoInferenciaParaTipoDadosElementar = tipoInferenciaParaTipoDadosElementar;
15439
15508
  const primitivos_1 = __importDefault(require("./tipos-de-dados/primitivos"));
15440
15509
  const delegua_1 = __importDefault(require("./tipos-de-dados/delegua"));
15441
15510
  const delegua_2 = __importDefault(require("./tipos-de-simbolos/delegua"));
@@ -15549,13 +15618,6 @@ function inferirTipoVariavel(variavel) {
15549
15618
  return 'símbolo';
15550
15619
  }
15551
15620
  }
15552
- function tipoInferenciaParaTipoDadosElementar(tipoInferencia) {
15553
- switch (tipoInferencia) {
15554
- // TODO: Colocar exceções aqui.
15555
- default:
15556
- return tipoInferencia;
15557
- }
15558
- }
15559
15621
 
15560
15622
  },{"./tipos-de-dados/delegua":213,"./tipos-de-dados/primitivos":215,"./tipos-de-simbolos/delegua":218}],136:[function(require,module,exports){
15561
15623
  "use strict";
@@ -18124,7 +18186,6 @@ class InterpretadorBase {
18124
18186
  return await this.executar(declaracao.caminhoEntao);
18125
18187
  }
18126
18188
  for (let i = 0; i < declaracao.caminhosSeSenao.length; i++) {
18127
- // TODO: Qual o tipo de `atual`?
18128
18189
  const atual = declaracao.caminhosSeSenao[i];
18129
18190
  if (this.eVerdadeiro(await this.avaliar(atual.condicao))) {
18130
18191
  return await this.executar(atual.caminho);
@@ -24742,6 +24803,7 @@ exports.default = {
24742
24803
  Object.defineProperty(exports, "__esModule", { value: true });
24743
24804
  exports.default = {
24744
24805
  ADICAO: 'ADICAO',
24806
+ CHAVE_ESQUERDA: 'CHAVE_ESQUERDA',
24745
24807
  DIFERENTE: 'DIFERENTE',
24746
24808
  DIVISAO: 'DIVISAO',
24747
24809
  DIVISAO_INTEIRA: 'DIVISAO_INTEIRA',
@@ -41595,14 +41657,22 @@ class TradutorJavaScript {
41595
41657
  case 'adicionar':
41596
41658
  case 'empilhar':
41597
41659
  return `${objetoResolvido}.push(${textoArgumentos})`;
41660
+ case 'concatenar':
41661
+ return `${objetoResolvido}.concat(${argumentosResolvidos[0]})`;
41662
+ case 'encaixar':
41663
+ return `${objetoResolvido}.splice(${textoArgumentos})`;
41598
41664
  case 'fatiar':
41599
- return `${objetoResolvido}.slice(${argumentos[0]}, ${argumentos[1]})`;
41665
+ return `${objetoResolvido}.slice(${textoArgumentos})`;
41666
+ case 'filtrarPor':
41667
+ return `${objetoResolvido}.filter(${this.traduzirFuncaoAnonimaParaLambda(argumentos[0])})`;
41600
41668
  case 'inclui':
41601
41669
  return `${objetoResolvido}.includes(${argumentosResolvidos[0]})`;
41602
41670
  case 'inverter':
41603
41671
  return `${objetoResolvido}.toReversed()`;
41604
41672
  case 'juntar':
41605
- return `${argumentosResolvidos[0]}.join(${objetoResolvido})`;
41673
+ return argumentosResolvidos.length > 0
41674
+ ? `${objetoResolvido}.join(${argumentosResolvidos[0]})`
41675
+ : `${objetoResolvido}.join()`;
41606
41676
  case 'maiusculo':
41607
41677
  return `${objetoResolvido}.toUpperCase()`;
41608
41678
  case 'mapear':
@@ -41610,9 +41680,11 @@ class TradutorJavaScript {
41610
41680
  case 'minusculo':
41611
41681
  return `${objetoResolvido}.toLowerCase()`;
41612
41682
  case 'ordenar':
41613
- return `${objetoResolvido}.sort()`;
41683
+ return argumentosResolvidos.length > 0
41684
+ ? `${objetoResolvido}.sort(${argumentosResolvidos[0]})`
41685
+ : `${objetoResolvido}.sort()`;
41614
41686
  case 'remover':
41615
- return `delete ${objetoResolvido}[${argumentosResolvidos[0]}]`;
41687
+ return `${objetoResolvido}.splice(${objetoResolvido}.indexOf(${argumentosResolvidos[0]}), 1)`;
41616
41688
  case 'removerPrimeiro':
41617
41689
  return `${objetoResolvido}.shift()`;
41618
41690
  case 'removerUltimo':
@@ -42030,9 +42102,26 @@ class TradutorJavaScript {
42030
42102
  }
42031
42103
  return resultado;
42032
42104
  }
42033
- // TODO: Talvez terminar (ou remover, sei lá).
42034
42105
  traduzirFuncaoAnonimaParaLambda(argumento) {
42035
- return '';
42106
+ var _a, _b, _c;
42107
+ if (argumento instanceof construtos_1.FuncaoConstruto) {
42108
+ const params = argumento.parametros.map((p) => p.nome.lexema).join(', ');
42109
+ // Retorno de um valor → retorno conciso
42110
+ if (argumento.corpo.length === 1 && argumento.corpo[0] instanceof declaracoes_1.Retorna) {
42111
+ const retorna = argumento.corpo[0];
42112
+ const expr = this.dicionarioConstrutos[retorna.valor.constructor.name](retorna.valor);
42113
+ return `(${params}) => ${expr}`;
42114
+ }
42115
+ // O JavaScript não tem suporte nativo para blocos de função anônimos, então usamos uma função de seta com corpo de bloco.
42116
+ return `(${params}) => ${this.logicaComumBlocoEscopo(argumento.corpo)}`;
42117
+ }
42118
+ if (argumento instanceof construtos_1.Variavel) {
42119
+ return argumento.simbolo.lexema;
42120
+ }
42121
+ if (argumento instanceof construtos_1.ReferenciaFuncao || argumento instanceof construtos_1.ArgumentoReferenciaFuncao) {
42122
+ return argumento.simboloFuncao.lexema;
42123
+ }
42124
+ return (_c = (_b = (_a = this.dicionarioConstrutos)[argumento.constructor.name]) === null || _b === void 0 ? void 0 : _b.call(_a, argumento)) !== null && _c !== void 0 ? _c : '';
42036
42125
  }
42037
42126
  traduzirExpressaoAcessoMetodoVetor(objeto, nomeMetodo, argumentos) {
42038
42127
  const objetoResolvido = this.dicionarioConstrutos[objeto.constructor.name](objeto);
@@ -42041,34 +42130,43 @@ class TradutorJavaScript {
42041
42130
  const argumentoResolvido = this.dicionarioConstrutos[argumento.constructor.name](argumento);
42042
42131
  argumentosResolvidos.push(argumentoResolvido);
42043
42132
  }
42133
+ const textoArgumentos = argumentosResolvidos.join(', ');
42044
42134
  switch (nomeMetodo) {
42045
42135
  case 'adicionar':
42046
42136
  case 'empilhar':
42047
- let textoArgumentos = argumentosResolvidos.reduce((atual, proximo) => (atual += proximo + ', '), '');
42048
- textoArgumentos = textoArgumentos.slice(0, -2);
42049
42137
  return `${objetoResolvido}.push(${textoArgumentos})`;
42138
+ case 'concatenar':
42139
+ return `${objetoResolvido}.concat(${argumentosResolvidos[0]})`;
42140
+ case 'encaixar':
42141
+ return `${objetoResolvido}.splice(${textoArgumentos})`;
42050
42142
  case 'fatiar':
42051
- return `${objetoResolvido}[${argumentos[0]}:${argumentos[1]}]`;
42143
+ return `${objetoResolvido}.slice(${textoArgumentos})`;
42144
+ case 'filtrarPor':
42145
+ return `${objetoResolvido}.filter(${this.traduzirFuncaoAnonimaParaLambda(argumentos[0])})`;
42052
42146
  case 'inclui':
42053
- return `${argumentos[0]} in ${objetoResolvido}`;
42147
+ return `${objetoResolvido}.includes(${argumentosResolvidos[0]})`;
42054
42148
  case 'inverter':
42055
- return `reversed(${objetoResolvido})`;
42149
+ return `${objetoResolvido}.toReversed()`;
42056
42150
  case 'juntar':
42057
- return `${argumentos[0]}.join(${objetoResolvido})`;
42151
+ return argumentosResolvidos.length > 0
42152
+ ? `${objetoResolvido}.join(${argumentosResolvidos[0]})`
42153
+ : `${objetoResolvido}.join()`;
42058
42154
  case 'mapear':
42059
- return `list(map(${this.traduzirFuncaoAnonimaParaLambda(argumentos[0])}), ${objetoResolvido})`;
42155
+ return `${objetoResolvido}.map(${this.traduzirFuncaoAnonimaParaLambda(argumentos[0])})`;
42060
42156
  case 'ordenar':
42061
- return `${objetoResolvido}.sort()`;
42157
+ return argumentosResolvidos.length > 0
42158
+ ? `${objetoResolvido}.sort(${argumentosResolvidos[0]})`
42159
+ : `${objetoResolvido}.sort()`;
42062
42160
  case 'remover':
42063
- return `del ${objetoResolvido}[${argumentos[0]}]`;
42161
+ return `${objetoResolvido}.splice(${objetoResolvido}.indexOf(${argumentosResolvidos[0]}), 1)`;
42064
42162
  case 'removerPrimeiro':
42065
- return `del ${objetoResolvido}[0]`;
42163
+ return `${objetoResolvido}.shift()`;
42066
42164
  case 'removerUltimo':
42067
- return `del ${objetoResolvido}[-1]`;
42165
+ return `${objetoResolvido}.pop()`;
42068
42166
  case 'somar':
42069
- return `sum(${objetoResolvido})`;
42167
+ return `${objetoResolvido}.reduce((acumulador, valorAtual) => acumulador + valorAtual, 0)`;
42070
42168
  case 'tamanho':
42071
- return `len(${objetoResolvido})`;
42169
+ return `${objetoResolvido}.length`;
42072
42170
  }
42073
42171
  }
42074
42172
  traduzirExpressaoAcessoMetodo(acessoMetodo, argumentos) {
@@ -42117,16 +42215,14 @@ class TradutorJavaScript {
42117
42215
  let esquerda = this.dicionarioConstrutos[logico.esquerda.constructor.name](logico.esquerda);
42118
42216
  return `${direita} ${operador} ${esquerda}`;
42119
42217
  }
42120
- // TODO: Eliminar o soft cast para `any`.
42121
42218
  traduzirExpressaoAtribuicaoPorIndice(AtribuicaoPorIndice) {
42122
- var _a, _b;
42123
42219
  let resultado = '';
42124
42220
  resultado += AtribuicaoPorIndice.objeto.simbolo.lexema + '[';
42125
42221
  resultado +=
42126
42222
  this.dicionarioConstrutos[AtribuicaoPorIndice.indice.constructor.name](AtribuicaoPorIndice.indice) + ']';
42127
42223
  resultado += ' = ';
42128
- if ((_b = (_a = AtribuicaoPorIndice === null || AtribuicaoPorIndice === void 0 ? void 0 : AtribuicaoPorIndice.valor) === null || _a === void 0 ? void 0 : _a.simbolo) === null || _b === void 0 ? void 0 : _b.lexema) {
42129
- resultado += `${AtribuicaoPorIndice.valor.simbolo.lexema}`;
42224
+ if (AtribuicaoPorIndice.valor instanceof construtos_1.Variavel) {
42225
+ resultado += AtribuicaoPorIndice.valor.simbolo.lexema;
42130
42226
  }
42131
42227
  else {
42132
42228
  resultado += this.dicionarioConstrutos[AtribuicaoPorIndice.valor.constructor.name](AtribuicaoPorIndice.valor);