@designliquido/delegua 1.24.2 → 1.24.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/umd/delegua.js CHANGED
@@ -3027,10 +3027,11 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3027
3027
  }
3028
3028
  return new construtos_1.TipoDe(this.hashArquivo, simboloAtual, construto);
3029
3029
  }
3030
- // TODO: O correto seria emitir algum aviso aqui que este avaliador sintático não consegue
3031
- // lidar com tópicos de ajuda neste ponto.
3032
3030
  if (this.emAjuda) {
3033
- console.log(this.simbolos[this.atual]);
3031
+ const simboloNaoTratado = this.simbolos[this.atual];
3032
+ this.erros.push(this.erro(simboloNaoTratado, `Avaliador sintático não consegue lidar com o tópico de ajuda '${simboloNaoTratado.lexema}'.`));
3033
+ this.avancarEDevolverAnterior();
3034
+ return new construtos_1.Literal(this.hashArquivo, Number(simboloNaoTratado.linha), null, 'nulo');
3034
3035
  }
3035
3036
  throw this.erro(this.simbolos[this.atual], 'Esperado expressão.');
3036
3037
  }
@@ -3981,16 +3982,16 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3981
3982
  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'.");
3982
3983
  }
3983
3984
  let vetorOuDicionario = await this.expressao();
3984
- if (vetorOuDicionario.constructor === construtos_1.AcessoIndiceVariavel) {
3985
- const construtoAcessoIndiceVariavel = vetorOuDicionario;
3986
- if (construtoAcessoIndiceVariavel.entidadeChamada.tipo === 'dicionário') {
3987
- // A avaliação sintática não deve verificar valores de dicionários.
3988
- // Aqui se supõe que o programador sabe o que está fazendo.
3989
- // TODO: Talvez pensar numa forma melhor de fazer isso.
3990
- vetorOuDicionario.tipo = 'vetor';
3991
- }
3985
+ // Quando o iterável é um acesso a índice de dicionário, o tipo dos elementos
3986
+ // não é determinável estaticamente — assume-se 'qualquer[]' para não bloquear a iteração.
3987
+ let tipoVetor;
3988
+ if (vetorOuDicionario.constructor === construtos_1.AcessoIndiceVariavel &&
3989
+ vetorOuDicionario.entidadeChamada.tipo === 'dicionário') {
3990
+ tipoVetor = 'qualquer[]';
3991
+ }
3992
+ else {
3993
+ tipoVetor = vetorOuDicionario.tipo;
3992
3994
  }
3993
- const tipoVetor = vetorOuDicionario.tipo;
3994
3995
  if (!tipoVetor.endsWith('[]') &&
3995
3996
  !['dicionário', 'qualquer', 'texto', 'vetor'].includes(tipoVetor)) {
3996
3997
  throw this.erro(simboloPara, `Variável ou constante em 'para cada' não é iterável. Tipo resolvido: ${tipoVetor}.`);
@@ -4167,12 +4168,29 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4167
4168
  const entidadeChamadaVariavel = construtoChamada.entidadeChamada;
4168
4169
  tipoInicializacao = entidadeChamadaVariavel.tipo;
4169
4170
  break;
4170
- // TODO: Demais casos
4171
+ case construtos_1.ReferenciaFuncao:
4172
+ const entidadeChamadaReferenciaFuncao = construtoChamada.entidadeChamada;
4173
+ tipoInicializacao = entidadeChamadaReferenciaFuncao.tipo;
4174
+ break;
4175
+ case construtos_1.ArgumentoReferenciaFuncao:
4176
+ tipoInicializacao = 'qualquer';
4177
+ break;
4171
4178
  default:
4172
4179
  break;
4173
4180
  }
4174
4181
  break;
4175
- // TODO: Demais casos
4182
+ case construtos_1.Variavel:
4183
+ tipoInicializacao = expressaoInicializacao.tipo;
4184
+ break;
4185
+ case construtos_1.Literal:
4186
+ tipoInicializacao = expressaoInicializacao.tipo;
4187
+ break;
4188
+ case construtos_1.FuncaoConstruto:
4189
+ tipoInicializacao = `função<${expressaoInicializacao.tipo}>`;
4190
+ break;
4191
+ case construtos_1.AcessoIndiceVariavel:
4192
+ tipoInicializacao = expressaoInicializacao.tipo;
4193
+ break;
4176
4194
  default:
4177
4195
  break;
4178
4196
  }
@@ -4295,13 +4313,23 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4295
4313
  const entidadeChamadaAcessoMetodo = entidadeChamadaChamada;
4296
4314
  const tipoRetornoAcessoMetodoResolvido = entidadeChamadaAcessoMetodo.tipoRetornoMetodo.replace('<T>', entidadeChamadaAcessoMetodo.objeto.tipo);
4297
4315
  return tipoRetornoAcessoMetodoResolvido;
4298
- case construtos_1.AcessoMetodoOuPropriedade:
4299
- return this.logicaComumInferenciaTiposAcessoMetodoOuPropriedade(entidadeChamadaChamada);
4316
+ case construtos_1.AcessoMetodoOuPropriedade: {
4317
+ const tipoMetodo = this.logicaComumInferenciaTiposAcessoMetodoOuPropriedade(entidadeChamadaChamada);
4318
+ // logicaComumInferenciaTiposAcessoMetodoOuPropriedade retorna o tipo da
4319
+ // função ('função<X>') para métodos definidos em código. Em contexto de
4320
+ // Chamada, queremos o tipo de retorno X, não o tipo da função em si.
4321
+ const correspondencia = tipoMetodo.match(/^função<(.+)>$/);
4322
+ return correspondencia ? correspondencia[1] : tipoMetodo;
4323
+ }
4300
4324
  case construtos_1.AcessoPropriedade:
4301
4325
  const entidadeChamadaAcessoPropriedade = entidadeChamadaChamada;
4302
4326
  return entidadeChamadaAcessoPropriedade.tipoRetornoPropriedade;
4303
4327
  case construtos_1.ArgumentoReferenciaFuncao:
4304
- // TODO: Voltar aqui se necessário.
4328
+ const entidadeChamadaArgumentoReferencia = entidadeChamadaChamada;
4329
+ const referenciaFuncaoArgumentada = this.pilhaEscopos.obterReferenciaFuncao(entidadeChamadaArgumentoReferencia.simboloFuncao.lexema);
4330
+ if (referenciaFuncaoArgumentada) {
4331
+ return referenciaFuncaoArgumentada.tipo;
4332
+ }
4305
4333
  return 'qualquer';
4306
4334
  case construtos_1.ReferenciaFuncao:
4307
4335
  const entidadeChamadaReferenciaFuncao = entidadeChamadaChamada;
@@ -4577,10 +4605,11 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4577
4605
  }
4578
4606
  tiposRetornos.delete('qualquer');
4579
4607
  if (tipoRetorno === 'qualquer') {
4580
- if (tiposRetornos.size > 0) {
4581
- // Se o tipo de retorno é 'qualquer', seja implícito ou explícito,
4608
+ if (tiposRetornos.size > 0 && !definicaoExplicitaDeTipo) {
4609
+ // Se o tipo de retorno é 'qualquer' implícito (não anotado),
4582
4610
  // este avaliador sintático pode restringir o tipo baseado nos construtos
4583
4611
  // de retornos encontrados nos blocos internos da função.
4612
+ // Se o tipo foi explicitamente anotado como 'qualquer', respeitamos a anotação.
4584
4613
  const tipoRetornoDeduzido = tiposRetornos.values().next().value;
4585
4614
  tipoRetorno = tipoRetornoDeduzido;
4586
4615
  }
@@ -4739,7 +4768,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4739
4768
  const retornaChamadoExplicitamente = tiposRetornos.size > 0;
4740
4769
  tiposRetornos.delete('qualquer');
4741
4770
  if (tipoRetorno === 'qualquer') {
4742
- if (tiposRetornos.size > 0) {
4771
+ if (tiposRetornos.size > 0 && !definicaoExplicitaDeTipo) {
4743
4772
  tipoRetorno = tiposRetornos.values().next().value;
4744
4773
  }
4745
4774
  else if (!retornaChamadoExplicitamente && !definicaoExplicitaDeTipo) {
@@ -5090,7 +5119,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5090
5119
  const retornaChamadoExplicitamente = tiposRetornos.size > 0;
5091
5120
  tiposRetornos.delete('qualquer');
5092
5121
  if (tipoRetorno === 'qualquer') {
5093
- if (tiposRetornos.size > 0) {
5122
+ if (tiposRetornos.size > 0 && !definicaoExplicitaDeTipo) {
5094
5123
  tipoRetorno = tiposRetornos.values().next().value;
5095
5124
  }
5096
5125
  else if (!retornaChamadoExplicitamente && !definicaoExplicitaDeTipo) {
@@ -5358,6 +5387,10 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5358
5387
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]'),
5359
5388
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('funcaoPesquisa', 'função'),
5360
5389
  ]));
5390
+ this.pilhaEscopos.definirInformacoesVariavel('arredondar', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('arredondar', 'número', true, [
5391
+ new informacao_elemento_sintatico_1.InformacaoElementoSintatico('numero', 'número'),
5392
+ new informacao_elemento_sintatico_1.InformacaoElementoSintatico('casasDecimais', 'número'),
5393
+ ]));
5361
5394
  this.pilhaEscopos.definirInformacoesVariavel('clonar', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('clonar', 'qualquer', true, [
5362
5395
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valor', 'qualquer'),
5363
5396
  ]));
@@ -5458,6 +5491,9 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5458
5491
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('funcaoReducao', 'função'),
5459
5492
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valorInicial', 'qualquer'),
5460
5493
  ]));
5494
+ this.pilhaEscopos.definirInformacoesVariavel('somar', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('somar', 'número', true, [
5495
+ new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]'),
5496
+ ]));
5461
5497
  this.pilhaEscopos.definirInformacoesVariavel('tamanho', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tamanho', 'inteiro', true, [
5462
5498
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('objeto', 'qualquer'),
5463
5499
  ]));
@@ -5478,11 +5514,20 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5478
5514
  this.pilhaEscopos.definirInformacoesVariavel('tupla', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tupla', 'tupla', true, [
5479
5515
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]'),
5480
5516
  ]));
5517
+ this.pilhaEscopos.definirInformacoesVariavel('vetor', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]', true, [
5518
+ new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tupla', 'qualquer'),
5519
+ ]));
5481
5520
  // Classe base global `Objeto`, registrada pelo interpretador em tempo de execução.
5482
5521
  this.pilhaEscopos.definirInformacoesVariavel('Objeto', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('Objeto', 'qualquer'));
5483
- // TODO: Escrever algum tipo de validação aqui.
5484
5522
  for (const tipos of Object.values(this.tiposDeFerramentasExternas)) {
5485
5523
  for (const [nomeTipo, tipo] of Object.entries(tipos)) {
5524
+ if (!nomeTipo || !tipo) {
5525
+ continue;
5526
+ }
5527
+ if (nomeTipo in this.tiposDefinidosEmCodigo) {
5528
+ this.erros.push(new erro_avaliador_sintatico_1.ErroAvaliadorSintatico(new simbolo_1.Simbolo(delegua_2.default.IDENTIFICADOR, nomeTipo, nomeTipo, 0, 0), `Tipo '${nomeTipo}' de ferramenta externa conflita com tipo já definido em código.`));
5529
+ continue;
5530
+ }
5486
5531
  this.pilhaEscopos.definirInformacoesVariavel(nomeTipo, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(nomeTipo, tipo));
5487
5532
  }
5488
5533
  }
@@ -7039,7 +7084,7 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7039
7084
  this.erro(operador, "O símbolo '?' não é um operador válido em Pituguês.");
7040
7085
  return direito;
7041
7086
  }
7042
- if (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.NEGACAO, pitugues_2.default.SUBTRACAO, pitugues_2.default.BIT_NOT)) {
7087
+ if (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.NAO, pitugues_2.default.NEGACAO, pitugues_2.default.SUBTRACAO, pitugues_2.default.BIT_NOT)) {
7043
7088
  const operador = this.simboloAnterior();
7044
7089
  const direito = await this.exponenciacao();
7045
7090
  return new construtos_1.Unario(this.hashArquivo, operador, direito);
@@ -7499,11 +7544,10 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7499
7544
  async resolverDecoradores() {
7500
7545
  while (this.verificarTipoSimboloAtual(pitugues_2.default.ARROBA)) {
7501
7546
  this.avancarEDevolverAnterior();
7502
- let nomeDecorador = '@';
7503
- let linha;
7504
- let parametros = [];
7505
7547
  const atributos = {};
7506
7548
  const primeiraParteNomeDecorador = this.consumir(pitugues_2.default.IDENTIFICADOR, 'Esperado nome de decorador após "@".');
7549
+ let linha;
7550
+ let nomeDecorador = '@';
7507
7551
  linha = Number(primeiraParteNomeDecorador.linha);
7508
7552
  nomeDecorador += primeiraParteNomeDecorador.lexema;
7509
7553
  while (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.PONTO)) {
@@ -7511,16 +7555,17 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7511
7555
  nomeDecorador += '.' + parteNomeDecorador.lexema;
7512
7556
  }
7513
7557
  if (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.PARENTESE_ESQUERDO)) {
7514
- if (!this.verificarTipoSimboloAtual(pitugues_2.default.PARENTESE_DIREITO)) {
7515
- parametros = await this.logicaComumParametros();
7516
- }
7517
- for (const parametro of parametros) {
7518
- if (parametro.nome.lexema in atributos) {
7519
- throw this.erro(parametro.nome, `Atributo de decorador declarado duas ou mais vezes: ${parametro.nome.lexema}`);
7558
+ const entidadeChamada = new construtos_1.Variavel(this.hashArquivo, primeiraParteNomeDecorador);
7559
+ const chamada = await this.finalizarChamada(entidadeChamada);
7560
+ if (chamada && 'argumentos' in chamada) {
7561
+ const argumentos = chamada.argumentos;
7562
+ for (let i = 0; i < argumentos.length; i++) {
7563
+ atributos[i] = argumentos[i];
7520
7564
  }
7521
- atributos[parametro.nome.lexema] = parametro.valorPadrao;
7522
7565
  }
7523
- this.consumir(pitugues_2.default.PARENTESE_DIREITO, 'Esperado ")" após argumentos do decorador.');
7566
+ else {
7567
+ throw this.erro(primeiraParteNomeDecorador, `Esperado formato de chamada de função para os parâmetros do decorador '@${nomeDecorador}'.`);
7568
+ }
7524
7569
  }
7525
7570
  this.pilhaDecoradores.push(new construtos_1.Decorador(this.hashArquivo, linha, nomeDecorador, atributos));
7526
7571
  }
@@ -7820,6 +7865,21 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7820
7865
  async resolverMetodoOuConstrutor(simboloAnterior, metodos) {
7821
7866
  const ehConstrutor = simboloAnterior.tipo === pitugues_2.default.CONSTRUTOR;
7822
7867
  const metodoResolvido = await this.funcao('método', ehConstrutor);
7868
+ if (metodoResolvido.decoradores &&
7869
+ metodoResolvido.decoradores.length > 0) {
7870
+ for (const decorador of metodoResolvido.decoradores) {
7871
+ if (decorador.nome === '@propriedade') {
7872
+ metodoResolvido.eObtenedor = true;
7873
+ }
7874
+ else if (typeof decorador.nome === 'string' &&
7875
+ decorador.nome.endsWith('.definidor')) {
7876
+ metodoResolvido.eDefinidor = true;
7877
+ }
7878
+ else if (decorador.nome === '@metodo_estatico') {
7879
+ metodoResolvido.estatico = true;
7880
+ }
7881
+ }
7882
+ }
7823
7883
  metodos.push(metodoResolvido);
7824
7884
  }
7825
7885
  async resolverMembroDeClasse(metodos, propriedadesDeClasse) {
@@ -21962,7 +22022,7 @@ class InterpretadorBase {
21962
22022
  */
21963
22023
  resolverNomeObjectoAcessado(objetoAcessado) {
21964
22024
  switch (objetoAcessado.constructor) {
21965
- // TODO: Não habilitar isso até que vetores sejam repassados para o montão.
22025
+ // Habilitado somente quando vetores forem repassados para o montão.
21966
22026
  /* case AcessoMetodoOuPropriedade:
21967
22027
  return (objetoAcessado as AcessoMetodoOuPropriedade).simbolo.lexema;
21968
22028
  case AcessoIndiceVariavel:
@@ -21980,6 +22040,7 @@ class InterpretadorBase {
21980
22040
  case construtos_1.Dicionario:
21981
22041
  case construtos_1.Leia:
21982
22042
  case construtos_1.Literal:
22043
+ case construtos_1.Unario:
21983
22044
  case construtos_1.Vetor:
21984
22045
  return '';
21985
22046
  case construtos_1.Isto:
@@ -22303,6 +22364,7 @@ class InterpretadorBase {
22303
22364
  this.verificarOperandoNumero(expressao.operador, valor);
22304
22365
  return -valor;
22305
22366
  case delegua_1.default.NEGACAO:
22367
+ case delegua_1.default.NAO:
22306
22368
  return !this.eVerdadeiro(valor);
22307
22369
  case delegua_1.default.BIT_NOT:
22308
22370
  if (typeof valor === 'bigint') {
@@ -22548,8 +22610,8 @@ class InterpretadorBase {
22548
22610
  if (valorEsquerdo === null || valorDireito === null) {
22549
22611
  return this.paraTexto(valorEsquerdo) + this.paraTexto(valorDireito);
22550
22612
  }
22551
- // TODO: Se tipo for 'qualquer', seria uma boa confiar nos operadores
22552
- // tradicionais do JavaScript?
22613
+ // Para tipos 'qualquer', delegamos ao operador nativo do JavaScript,
22614
+ // que resolve concatenação ou soma dependendo dos valores em tempo de execução.
22553
22615
  if (tipoEsquerdo === 'qualquer' || tipoDireito === 'qualquer') {
22554
22616
  return valorEsquerdo + valorDireito;
22555
22617
  }
@@ -22782,8 +22844,12 @@ class InterpretadorBase {
22782
22844
  }
22783
22845
  if (entidadeChamada instanceof estruturas_1.FuncaoPadrao) {
22784
22846
  try {
22785
- return await entidadeChamada.chamar(this, argumentos.map((a) => a && this.resolverValor(a.valor)), expressao.entidadeChamada.simbolo // TODO: O que exatamente pode ser aqui?
22786
- );
22847
+ // entidadeChamada pode ser Variavel, AcessoMetodo, ReferenciaFuncao, etc.
22848
+ // Todos os construtos concretos que chegam aqui têm `simbolo: SimboloInterface`.
22849
+ const simboloChamada = 'simbolo' in expressao.entidadeChamada
22850
+ ? expressao.entidadeChamada.simbolo
22851
+ : null;
22852
+ return await entidadeChamada.chamar(this, argumentos.map((a) => a && this.resolverValor(a.valor)), simboloChamada);
22787
22853
  }
22788
22854
  catch (erro) {
22789
22855
  if (this.emDeclaracaoTente) {
@@ -22820,7 +22886,6 @@ class InterpretadorBase {
22820
22886
  if (typeof entidadeChamada === primitivos_1.default.FUNCAO) {
22821
22887
  let objeto = null;
22822
22888
  if (expressao.entidadeChamada.objeto) {
22823
- // TODO: Qual o tipo certo aqui?
22824
22889
  objeto = await this.avaliar(expressao.entidadeChamada.objeto);
22825
22890
  }
22826
22891
  return entidadeChamada.apply(this.resolverValor(objeto), argumentos);
@@ -23041,10 +23106,9 @@ class InterpretadorBase {
23041
23106
  const vetorResolvido = await this.avaliar(declaracao.vetorOuDicionario);
23042
23107
  let valorVetorResolvido = this.resolverValor(vetorResolvido);
23043
23108
  // Se até aqui vetor resolvido é um dicionário, converte dicionário
23044
- // para vetor de duplas.
23045
- // TODO: Converter elementos para `Construto` se necessário.
23109
+ // para vetor de duplas com elementos envoltos em Literal, preservando tipo.
23046
23110
  if (declaracao.vetorOuDicionario.tipo === 'dicionário') {
23047
- valorVetorResolvido = Object.entries(valorVetorResolvido).map((v) => new construtos_1.Dupla(v[0], v[1]));
23111
+ valorVetorResolvido = Object.entries(valorVetorResolvido).map((v) => new construtos_1.Dupla(new construtos_1.Literal(declaracao.hashArquivo, declaracao.linha, v[0], 'texto'), new construtos_1.Literal(declaracao.hashArquivo, declaracao.linha, v[1], (0, inferenciador_1.inferirTipoVariavel)(v[1]))));
23048
23112
  }
23049
23113
  if (!Array.isArray(valorVetorResolvido)) {
23050
23114
  return Promise.reject("Variável ou literal provida em instrução 'para cada' não é um vetor.");
@@ -23060,13 +23124,11 @@ class InterpretadorBase {
23060
23124
  }
23061
23125
  if (declaracao.variavelIteracao instanceof construtos_1.Dupla) {
23062
23126
  const valorComoDupla = valorVetorResolvido[declaracao.posicaoAtual];
23063
- const promises = await Promise.all([
23064
- this.avaliar(declaracao.variavelIteracao.primeiro),
23065
- this.avaliar(declaracao.variavelIteracao.segundo),
23066
- ]);
23067
- // TODO: O que fazer quando não forem literais?
23068
- this.pilhaEscoposExecucao.definirVariavel(String(promises[0].valor), valorComoDupla.primeiro);
23069
- this.pilhaEscoposExecucao.definirVariavel(String(promises[1].valor), valorComoDupla.segundo);
23127
+ // Os nomes das variáveis vêm diretamente dos Literais do AST (não precisam ser avaliados).
23128
+ const nomePrimeiro = declaracao.variavelIteracao.primeiro.valor?.toString() ?? '';
23129
+ const nomeSegundo = declaracao.variavelIteracao.segundo.valor?.toString() ?? '';
23130
+ this.pilhaEscoposExecucao.definirVariavel(nomePrimeiro, this.resolverValor(valorComoDupla.primeiro));
23131
+ this.pilhaEscoposExecucao.definirVariavel(nomeSegundo, this.resolverValor(valorComoDupla.segundo));
23070
23132
  }
23071
23133
  retornoExecucao = await this.executar(declaracao.corpo);
23072
23134
  if (retornoExecucao && retornoExecucao.valorRetornado instanceof quebras_1.SustarQuebra) {
@@ -23554,14 +23616,14 @@ class InterpretadorBase {
23554
23616
  }
23555
23617
  mesclaResolvidas.push(misturável);
23556
23618
  }
23557
- // TODO: Precisamos disso?
23619
+ // Necessário para que a declaração da classe seja acessível durante a resolução
23620
+ // dos seus próprios métodos (ex.: construtores que instanciam a própria classe).
23558
23621
  this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, declaracao);
23559
23622
  if (superClassesResolvidas.length > 0) {
23560
23623
  this.pilhaEscoposExecucao.definirVariavel('super', superClassesResolvidas[0]);
23561
23624
  }
23562
23625
  const descritorTipoClasse = this.resolverMetodoDeClasse(declaracao, superClassesResolvidas, mesclaResolvidas);
23563
- // TODO: Até então, a única exceção a isso é Égua Clássico.
23564
- // Por enquanto, tudo bem deixar isso aqui.
23626
+ // A única exceção a isso até então é Égua Clássico, que requer declaração de propriedades.
23565
23627
  descritorTipoClasse.dialetoRequerDeclaracaoPropriedades = this.requerDeclaracaoPropriedades;
23566
23628
  this.pilhaEscoposExecucao.atribuirVariavel(declaracao.simbolo, descritorTipoClasse);
23567
23629
  return descritorTipoClasse;
@@ -23717,11 +23779,9 @@ class InterpretadorBase {
23717
23779
  if (Array.isArray(objeto)) {
23718
23780
  if (expressao.simbolo.lexema in primitivas_vetor_1.default) {
23719
23781
  const metodoDePrimitivaVetor = primitivas_vetor_1.default[expressao.simbolo.lexema].implementacao;
23720
- // TODO: Um problema a ser resolvido na questão de vetores é quando eles pertencem a outro objeto.
23721
- // Por exemplo, um dicionário.
23722
- // Existe uma lógica nas bibliotecas padrão que, quando a primitiva tem um nome, ela deve ser definida na
23723
- // pilha de escopos, para registrar a mutação do vetor corretamente.
23724
- // Não é uma boa solução. Algo melhor precisa ser feito.
23782
+ // Limitação conhecida: quando o vetor pertence a um objeto pai (ex.: um dicionário),
23783
+ // as bibliotecas padrão registram a mutação pelo nome do vetor na pilha de escopos,
23784
+ // o que não funciona corretamente nesse caso. Requer refatoração futura.
23725
23785
  return new metodo_primitiva_1.MetodoPrimitiva(nomeObjeto, objeto, metodoDePrimitivaVetor, expressao.simbolo.lexema, tipoObjeto);
23726
23786
  }
23727
23787
  }
@@ -23794,12 +23854,6 @@ class InterpretadorBase {
23794
23854
  tipoResolvido = (0, inferenciador_1.inferirTipoVariavel)(valorFinal);
23795
23855
  }
23796
23856
  this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, valorFinal, tipoResolvido, declaracao.tipoExplicito && declaracao.tipoOriginal !== 'qualquer');
23797
- // TODO: É relevante registrar uma declaração de variável no
23798
- // resultado do interpretador?
23799
- /* return {
23800
- tipo: declaracao.tipo,
23801
- tipoExplicito: declaracao.tipoExplicito
23802
- }; */
23803
23857
  return null;
23804
23858
  }
23805
23859
  /**
@@ -24434,17 +24488,56 @@ class Interpretador extends interpretador_base_1.InterpretadorBase {
24434
24488
  }
24435
24489
  return Promise.resolve((0, comum_1.pontoEntradaAjuda)(declaracao.funcao, declaracao.elemento));
24436
24490
  }
24491
+ criarSimboloDecorador(lexema, linha, hashArquivo) {
24492
+ return {
24493
+ lexema,
24494
+ tipo: 'IDENTIFICADOR',
24495
+ literal: null,
24496
+ linha,
24497
+ hashArquivo,
24498
+ };
24499
+ }
24500
+ async resolverFuncaoDecoradora(nomeDecorador, linha, hashArquivo) {
24501
+ const partesNome = nomeDecorador.split('.');
24502
+ if (partesNome.length === 1) {
24503
+ const variavelDecoradora = this.pilhaEscoposExecucao.obterVariavelPorNome(nomeDecorador);
24504
+ return variavelDecoradora.valor;
24505
+ }
24506
+ let expressaoDecoradora = new construtos_1.Variavel(hashArquivo, this.criarSimboloDecorador(partesNome[0], linha, hashArquivo));
24507
+ for (const parteNome of partesNome.slice(1)) {
24508
+ expressaoDecoradora = new construtos_1.AcessoMetodoOuPropriedade(hashArquivo, expressaoDecoradora, this.criarSimboloDecorador(parteNome, linha, hashArquivo));
24509
+ }
24510
+ return this.resolverValor(await this.avaliar(expressaoDecoradora), true);
24511
+ }
24437
24512
  async visitarDeclaracaoDefinicaoFuncao(declaracao) {
24438
24513
  let funcao = new estruturas_1.DeleguaFuncao(declaracao.simbolo.lexema, declaracao.funcao);
24439
24514
  funcao.documentacao = declaracao.documentacao;
24440
24515
  if (declaracao.decoradores && declaracao.decoradores.length > 0) {
24441
24516
  for (const decorador of [...declaracao.decoradores].reverse()) {
24442
24517
  const nomeDecorador = decorador.nome.slice(1);
24443
- const variavelDecoradora = this.pilhaEscoposExecucao.obterVariavelPorNome(nomeDecorador);
24444
- const funcaoDecoradora = variavelDecoradora.valor;
24445
- const resultado = await funcaoDecoradora.chamar(this, [
24446
- { nome: '', valor: funcao },
24447
- ]);
24518
+ const funcaoDecoradora = await this.resolverFuncaoDecoradora(nomeDecorador, decorador.linha, decorador.hashArquivo);
24519
+ const argumentosDecorador = [
24520
+ { nome: '', valor: funcao }
24521
+ ];
24522
+ if (decorador.atributos) {
24523
+ const chaves = Object.keys(decorador.atributos)
24524
+ .map(Number)
24525
+ .sort((a, b) => a - b);
24526
+ for (const chave of chaves) {
24527
+ let valorArg = decorador.atributos[chave];
24528
+ if (typeof valorArg?.aceitar === 'function') {
24529
+ valorArg = await this.avaliar(valorArg);
24530
+ }
24531
+ else if (valorArg?.hasOwnProperty('valor')) {
24532
+ valorArg = this.resolverValor(valorArg);
24533
+ }
24534
+ else {
24535
+ return Promise.reject(new excecoes_1.ErroEmTempoDeExecucao(declaracao.simbolo, `Não foi possível resolver o argumento do decorador '@${nomeDecorador}'. O tipo de dado ou expressão não é suportado.`));
24536
+ }
24537
+ argumentosDecorador.push({ nome: '', valor: valorArg });
24538
+ }
24539
+ }
24540
+ const resultado = await funcaoDecoradora.chamar(this, argumentosDecorador);
24448
24541
  funcao = this.resolverValorRecursivo(resultado);
24449
24542
  }
24450
24543
  }
@@ -24699,7 +24792,7 @@ class Interpretador extends interpretador_base_1.InterpretadorBase {
24699
24792
  const metodoFinalizar = retornoInicializacaoResolvido.classe.encontrarMetodo('finalizar');
24700
24793
  if (metodoFinalizar) {
24701
24794
  const chamavel = metodoFinalizar.funcaoPorMetodoDeClasse(retornoInicializacaoResolvido);
24702
- chamavel.chamar(this, []);
24795
+ await chamavel.chamar(this, []);
24703
24796
  }
24704
24797
  }
24705
24798
  return null;
@@ -29104,366 +29197,117 @@ Object.defineProperty(exports, "__esModule", { value: true });
29104
29197
  exports.Lexador = void 0;
29105
29198
  const browser_process_hrtime_1 = __importDefault(require("browser-process-hrtime"));
29106
29199
  const simbolo_1 = require("./simbolo");
29200
+ const lexador_base_1 = require("./lexador-base");
29107
29201
  const palavras_reservadas_1 = require("./palavras-reservadas");
29108
29202
  const delegua_1 = __importDefault(require("../tipos-de-simbolos/delegua"));
29109
- /**
29110
- * O Lexador é responsável por transformar o código em uma coleção de tokens de linguagem.
29111
- * Cada token de linguagem é representado por um tipo, um lexema e informações da linha de código em que foi expresso.
29112
- * Também é responsável por mapear as palavras reservadas da linguagem, que não podem ser usadas por outras
29113
- * estruturas, tais como nomes de variáveis, funções, literais, classes e assim por diante.
29114
- */
29115
- class Lexador {
29203
+ const tokensSimples = {
29204
+ '@': delegua_1.default.ARROBA,
29205
+ '[': delegua_1.default.COLCHETE_ESQUERDO,
29206
+ ']': delegua_1.default.COLCHETE_DIREITO,
29207
+ '(': delegua_1.default.PARENTESE_ESQUERDO,
29208
+ ')': delegua_1.default.PARENTESE_DIREITO,
29209
+ '{': delegua_1.default.CHAVE_ESQUERDA,
29210
+ '}': delegua_1.default.CHAVE_DIREITA,
29211
+ ',': delegua_1.default.VIRGULA,
29212
+ ':': delegua_1.default.DOIS_PONTOS,
29213
+ // Ponto-e-vírgula é opcional em Delégua, mas em alguns casos pode ser
29214
+ // necessário. Por exemplo, declaração de `para` sem inicializador.
29215
+ ';': delegua_1.default.PONTO_E_VIRGULA,
29216
+ '^': delegua_1.default.CIRCUMFLEXO,
29217
+ '~': delegua_1.default.BIT_NOT,
29218
+ '&': delegua_1.default.BIT_AND
29219
+ };
29220
+ /*
29221
+ * O Lexador é responsável por transformar o código em uma coleção de tokens de linguagem.
29222
+ * Cada token de linguagem é representado por um tipo, um lexema e informações da linha de código em que foi expresso.
29223
+ * Também é responsável por mapear as palavras reservadas da linguagem, que não podem ser usadas por outras
29224
+ * estruturas, tais como nomes de variáveis, funções, literais, classes e assim por diante.
29225
+ */
29226
+ class Lexador extends lexador_base_1.LexadorBase {
29116
29227
  constructor(performance = false) {
29117
- this.codigo = [];
29228
+ super();
29229
+ this.regexAlfabeto = /[a-zA-Z_áàâãéèêíïóôõöúçñÁÀÂÃÉÈÊÍÏÓÔÕÖÚÇÑ]/;
29230
+ this.regexEmoji = /\p{Extended_Pictographic}(?:\uFE0F|\u200D\p{Extended_Pictographic})*/u;
29118
29231
  this.performance = performance;
29119
- this.simbolos = [];
29120
- this.erros = [];
29121
- this.hashArquivo = -1;
29122
- this.inicioSimbolo = 0;
29123
- this.atual = 0;
29124
- this.linha = 0;
29125
- }
29126
- eDigito(caractere) {
29127
- return caractere >= '0' && caractere <= '9';
29128
- }
29129
- eAlfabeto(caractere) {
29130
- const acentuacoes = [
29131
- 'á',
29132
- 'Á',
29133
- 'ã',
29134
- 'Ã',
29135
- 'â',
29136
- 'Â',
29137
- 'à',
29138
- 'À',
29139
- 'é',
29140
- 'É',
29141
- 'ê',
29142
- 'Ê',
29143
- 'í',
29144
- 'Í',
29145
- 'ó',
29146
- 'Ó',
29147
- 'õ',
29148
- 'Õ',
29149
- 'ô',
29150
- 'Ô',
29151
- 'ú',
29152
- 'Ú',
29153
- 'ç',
29154
- 'Ç',
29155
- '_',
29156
- ];
29157
- return ((caractere >= 'a' && caractere <= 'z') ||
29158
- (caractere >= 'A' && caractere <= 'Z') ||
29159
- acentuacoes.includes(caractere));
29160
- }
29161
- eAlfabetoOuDigito(caractere) {
29162
- return this.eDigito(caractere) || this.eAlfabeto(caractere);
29163
- }
29164
- eHexDigito(caractere) {
29165
- return ((caractere >= '0' && caractere <= '9') ||
29166
- (caractere >= 'a' && caractere <= 'f') ||
29167
- (caractere >= 'A' && caractere <= 'F'));
29168
- }
29169
- eBinarioDigito(caractere) {
29170
- return caractere === '0' || caractere === '1';
29171
- }
29172
- eOctalDigito(caractere) {
29173
- return caractere >= '0' && caractere <= '7';
29174
- }
29175
- eFinalDaLinha() {
29176
- if (this.codigo.length === this.linha) {
29177
- return true;
29178
- }
29179
- return this.atual >= this.codigo[this.linha].length;
29180
29232
  }
29181
- /**
29182
- * Indica se o código está na última linha.
29183
- * @returns Verdadeiro se contador de linhas está na última linha.
29184
- * Falso caso contrário.
29185
- */
29186
- eUltimaLinha() {
29187
- return this.linha >= this.codigo.length - 1;
29233
+ eAlfabeto(c) {
29234
+ return this.regexAlfabeto.test(c);
29188
29235
  }
29189
- eFinalDoCodigo() {
29190
- return this.eUltimaLinha() && this.codigo[this.codigo.length - 1].length <= this.atual;
29236
+ eEmoji(c) {
29237
+ return this.regexEmoji.test(c);
29191
29238
  }
29192
29239
  avancar() {
29193
- const linha = this.codigo[this.linha];
29194
- const codePoint = linha.codePointAt(this.atual);
29240
+ const codePoint = this.codigo[this.linha].codePointAt(this.atual);
29195
29241
  this.atual += codePoint && codePoint > 0xffff ? 2 : 1;
29196
29242
  if (this.eFinalDaLinha() && !this.eUltimaLinha()) {
29197
29243
  this.linha++;
29198
29244
  this.atual = 0;
29199
29245
  }
29200
29246
  }
29201
- adicionarSimbolo(tipo, literal = null) {
29202
- const texto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29203
- const lexema = literal || texto;
29204
- const comprimentoLexema = typeof lexema === 'string' ? lexema.length : 0;
29205
- const comprimento = Math.max(comprimentoLexema, texto.length) || 1;
29206
- const colunaInicio = this.inicioSimbolo + 1;
29207
- const colunaFim = this.inicioSimbolo + comprimento;
29208
- this.simbolos.push(new simbolo_1.Simbolo(tipo, lexema, literal, this.linha + 1, this.hashArquivo, colunaInicio, colunaFim));
29209
- }
29210
29247
  simboloAtual() {
29211
29248
  if (this.eFinalDaLinha())
29212
29249
  return '\0';
29213
- const linha = this.codigo[this.linha];
29214
- const codePoint = linha.codePointAt(this.atual);
29215
- if (codePoint === undefined) {
29216
- return '\0';
29217
- }
29218
- return String.fromCodePoint(codePoint);
29219
- }
29220
- comentarioMultilinha() {
29221
- let conteudo = '';
29222
- while (!this.eFinalDoCodigo()) {
29223
- this.avancar();
29224
- conteudo += this.codigo[this.linha].charAt(this.atual);
29225
- if (this.simboloAtual() === '*' && this.proximoSimbolo() === '/') {
29226
- const linhas = conteudo.split('\0');
29227
- for (let linha of linhas) {
29228
- this.adicionarSimbolo(delegua_1.default.LINHA_COMENTARIO, linha.trim());
29229
- }
29230
- // Remove o asterisco da última linha
29231
- let lexemaUltimaLinha = this.simbolos[this.simbolos.length - 1].lexema;
29232
- lexemaUltimaLinha = lexemaUltimaLinha.substring(0, lexemaUltimaLinha.length - 1);
29233
- this.simbolos[this.simbolos.length - 1].lexema = lexemaUltimaLinha;
29234
- this.simbolos[this.simbolos.length - 1].literal = lexemaUltimaLinha;
29235
- this.avancar();
29236
- this.avancar();
29237
- break;
29238
- }
29239
- }
29240
- }
29241
- /**
29242
- * Lê um comentário documentário (iniciado com `/**`), agregando o conteúdo
29243
- * em um único token DOCUMENTARIO. Linhas com `*` inicial (convenção JSDoc)
29244
- * têm o asterisco removido.
29245
- */
29246
- comentarioDocumentario() {
29247
- // Cursor está no primeiro '*' de '/**'. Avança para pular o segundo '*'.
29248
- this.avancar();
29249
- let conteudo = '';
29250
- while (!this.eFinalDoCodigo()) {
29251
- this.avancar();
29252
- if (this.simboloAtual() === '*' && this.proximoSimbolo() === '/') {
29253
- // Fecha o documentário sem adicionar o '*' ao conteúdo.
29254
- this.avancar(); // pula '*'
29255
- this.avancar(); // pula '/'
29256
- break;
29257
- }
29258
- conteudo += this.codigo[this.linha].charAt(this.atual);
29259
- }
29260
- // Divide por '\0' (separador de linha), remove asteriscos iniciais e filtra vazios.
29261
- const conteudoLimpo = conteudo
29262
- .split('\0')
29263
- .map((l) => {
29264
- const trimmed = l.trim();
29265
- return trimmed.startsWith('*') ? trimmed.substring(1).trim() : trimmed;
29266
- })
29267
- .filter((l) => l.length > 0)
29268
- .join('\n');
29269
- this.adicionarSimbolo(delegua_1.default.DOCUMENTARIO, conteudoLimpo || '');
29270
- }
29271
- comentarioUmaLinha() {
29272
- this.avancar();
29273
- const linhaAtual = this.linha;
29274
- let ultimoAtual = this.atual;
29275
- while (linhaAtual === this.linha && !this.eFinalDoCodigo()) {
29276
- ultimoAtual = this.atual;
29277
- this.avancar();
29278
- }
29279
- const conteudo = this.codigo[linhaAtual].substring(this.inicioSimbolo + 2, ultimoAtual);
29280
- this.adicionarSimbolo(delegua_1.default.COMENTARIO, conteudo.trim());
29250
+ const codePoint = this.codigo[this.linha].codePointAt(this.atual);
29251
+ return codePoint === undefined ? '\0' : String.fromCodePoint(codePoint);
29281
29252
  }
29282
29253
  proximoSimbolo() {
29283
- const linha = this.codigo[this.linha];
29284
- const atual = this.simboloAtual();
29285
- const incremento = atual.length;
29286
- const codePoint = linha.codePointAt(this.atual + incremento);
29287
- if (codePoint === undefined) {
29288
- return '\0';
29289
- }
29290
- return String.fromCodePoint(codePoint);
29254
+ const atualStr = this.simboloAtual();
29255
+ const codePoint = this.codigo[this.linha].codePointAt(this.atual + atualStr.length);
29256
+ return codePoint === undefined ? '\0' : String.fromCodePoint(codePoint);
29291
29257
  }
29292
29258
  simboloAnterior() {
29293
29259
  const linha = this.codigo[this.linha];
29294
- const indiceAnterior = this.atual -
29295
- (linha.codePointAt(this.atual - 2) > 0xffff ? 2 : 1);
29260
+ const indiceAnterior = this.atual - (linha.codePointAt(this.atual - 2) > 0xffff ? 2 : 1);
29296
29261
  const codePoint = linha.codePointAt(indiceAnterior);
29297
- if (codePoint === undefined) {
29298
- return '\0';
29299
- }
29300
- }
29301
- analisarTexto(delimitador = '"') {
29302
- let valor = '';
29303
- this.avancar();
29304
- while (!this.eFinalDoCodigo()) {
29305
- const caractere = this.simboloAtual();
29306
- if (caractere === delimitador) {
29307
- this.avancar();
29308
- this.adicionarSimbolo(delegua_1.default.TEXTO, valor);
29309
- const ultimoSimbolo = this.simbolos[this.simbolos.length - 1];
29310
- ultimoSimbolo.delimitadorTexto = delimitador;
29311
- return;
29312
- }
29313
- if (caractere === '\0' && this.eUltimaLinha()) {
29314
- this.erros.push({
29315
- linha: this.linha + 1,
29316
- caractere: this.simboloAnterior(),
29317
- mensagem: 'Texto não finalizado.',
29318
- });
29319
- return;
29320
- }
29321
- if (caractere === '\0') {
29322
- valor += '\n';
29323
- this.avancar();
29324
- continue;
29325
- }
29326
- if (caractere === '\\') {
29327
- this.avancar();
29328
- const proximoCaractere = this.simboloAtual();
29329
- switch (proximoCaractere) {
29330
- case 'n':
29331
- valor += '\n';
29332
- break;
29333
- case 't':
29334
- valor += '\t';
29335
- break;
29336
- case 'r':
29337
- valor += '\r';
29338
- break;
29339
- case 'b':
29340
- valor += '\b';
29341
- break;
29342
- case "'":
29343
- valor += "'";
29344
- break;
29345
- case '"':
29346
- valor += '"';
29347
- break;
29348
- case '\\':
29349
- valor += '\\';
29350
- break;
29351
- case 'e':
29352
- valor += '\x1B';
29353
- break;
29354
- case 'x': {
29355
- let hex = '';
29356
- for (let i = 0; i < 2; i++) {
29357
- const c = this.proximoSimbolo();
29358
- if (/[0-9a-fA-F]/.test(c)) {
29359
- this.avancar();
29360
- hex += c;
29361
- }
29362
- else {
29363
- break;
29364
- }
29365
- }
29366
- valor +=
29367
- hex.length === 2 ? String.fromCharCode(parseInt(hex, 16)) : '\\x' + hex;
29368
- break;
29369
- }
29370
- case '\0':
29371
- break; // barra invertida no fim de linha: ignora e continua na próxima linha
29372
- default:
29373
- valor += '\\' + proximoCaractere;
29374
- break;
29375
- }
29376
- }
29377
- else {
29378
- valor += caractere;
29379
- }
29380
- this.avancar();
29381
- }
29382
- this.erros.push({
29383
- linha: this.linha + 1,
29384
- caractere: this.simboloAnterior(),
29385
- mensagem: 'Texto não finalizado.',
29386
- });
29262
+ return codePoint === undefined ? '\0' : String.fromCodePoint(codePoint);
29387
29263
  }
29388
- analisarHexadecimal() {
29389
- this.avancar(); // Pula '0'
29390
- this.avancar(); // Pula 'x' ou 'X'
29391
- while (this.eHexDigito(this.simboloAtual())) {
29392
- this.avancar();
29393
- }
29394
- const hexString = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29395
- try {
29396
- const bigintValue = BigInt(hexString);
29397
- this.adicionarSimbolo(delegua_1.default.NUMERO, bigintValue);
29398
- }
29399
- catch (e) {
29400
- this.erros.push({
29401
- linha: this.linha + 1,
29402
- caractere: this.simboloAnterior(),
29403
- mensagem: `Literal hexadecimal inválido: ${hexString}`,
29404
- });
29405
- }
29264
+ adicionarSimbolo(tipo, literal = null) {
29265
+ const texto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29266
+ const lexema = literal !== null ? literal : texto;
29267
+ const comprimento = Math.max(typeof lexema === 'string' ? lexema.length : 0, texto.length) || 1;
29268
+ this.simbolos.push(new simbolo_1.Simbolo(tipo, lexema, literal, this.linha + 1, this.hashArquivo, this.inicioSimbolo + 1, this.inicioSimbolo + comprimento));
29406
29269
  }
29407
- analisarBinario() {
29408
- this.avancar(); // Pula '0'
29409
- this.avancar(); // Pula 'b' ou 'B'
29410
- while (this.eBinarioDigito(this.simboloAtual())) {
29411
- this.avancar();
29412
- }
29413
- const binaryString = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29414
- try {
29415
- const bigintValue = BigInt(binaryString);
29416
- this.adicionarSimbolo(delegua_1.default.NUMERO, bigintValue);
29417
- }
29418
- catch (e) {
29419
- this.erros.push({
29420
- linha: this.linha + 1,
29421
- caractere: this.simboloAnterior(),
29422
- mensagem: `Literal binário inválido: ${binaryString}`,
29423
- });
29424
- }
29270
+ verificarEAvancar(esperado) {
29271
+ if (this.eFinalDaLinha() || this.simboloAtual() !== esperado)
29272
+ return false;
29273
+ this.avancar();
29274
+ return true;
29425
29275
  }
29426
- analisarOctal() {
29276
+ analisarBaseNumerica(validadorDigito, tipoErro) {
29427
29277
  this.avancar(); // Pula '0'
29428
- this.avancar(); // Pula 'o' ou 'O'
29429
- while (this.eOctalDigito(this.simboloAtual())) {
29278
+ this.avancar(); // Pula 'x', 'b' ou 'o'
29279
+ while (validadorDigito.call(this, this.simboloAtual())) {
29430
29280
  this.avancar();
29431
29281
  }
29432
- const octalString = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29282
+ const texto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29433
29283
  try {
29434
- const bigintValue = BigInt(octalString);
29435
- this.adicionarSimbolo(delegua_1.default.NUMERO, bigintValue);
29284
+ this.adicionarSimbolo(delegua_1.default.NUMERO, BigInt(texto));
29436
29285
  }
29437
29286
  catch (e) {
29438
29287
  this.erros.push({
29439
29288
  linha: this.linha + 1,
29440
29289
  caractere: this.simboloAnterior(),
29441
- mensagem: `Literal octal inválido: ${octalString}`,
29290
+ mensagem: `Literal ${tipoErro} inválido: ${texto}`
29442
29291
  });
29443
29292
  }
29444
29293
  }
29445
29294
  analisarNumero() {
29446
- // Verifica se é um literal especial (hexadecimal, binário ou octal)
29447
29295
  if (this.simboloAtual() === '0') {
29448
- const proximoChar = this.proximoSimbolo();
29449
- if (proximoChar === 'x' || proximoChar === 'X') {
29450
- this.analisarHexadecimal();
29451
- return;
29296
+ const prox = this.proximoSimbolo().toLowerCase();
29297
+ if (prox === 'x') {
29298
+ return this.analisarBaseNumerica(this.eHexDigito, 'hexadecimal');
29452
29299
  }
29453
- else if (proximoChar === 'b' || proximoChar === 'B') {
29454
- this.analisarBinario();
29455
- return;
29300
+ if (prox === 'b') {
29301
+ return this.analisarBaseNumerica(this.eBinarioDigito, 'binário');
29456
29302
  }
29457
- else if (proximoChar === 'o' || proximoChar === 'O') {
29458
- this.analisarOctal();
29459
- return;
29303
+ if (prox === 'o') {
29304
+ return this.analisarBaseNumerica(this.eOctalDigito, 'octal');
29460
29305
  }
29461
29306
  }
29462
- // Análise de número decimal normal
29463
29307
  while (this.eDigito(this.simboloAtual())) {
29464
29308
  this.avancar();
29465
29309
  }
29466
- if (this.simboloAtual() == '.' && this.eDigito(this.proximoSimbolo())) {
29310
+ if (this.simboloAtual() === '.' && this.eDigito(this.proximoSimbolo())) {
29467
29311
  this.avancar();
29468
29312
  while (this.eDigito(this.simboloAtual())) {
29469
29313
  this.avancar();
@@ -29472,155 +29316,222 @@ class Lexador {
29472
29316
  const numeroCompleto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29473
29317
  this.adicionarSimbolo(delegua_1.default.NUMERO, parseFloat(numeroCompleto));
29474
29318
  }
29319
+ analisarTexto(delimitador = '"') {
29320
+ let valor = '';
29321
+ this.avancar();
29322
+ while (!this.eFinalDoCodigo()) {
29323
+ const c = this.simboloAtual();
29324
+ if (c === delimitador) {
29325
+ this.avancar();
29326
+ this.adicionarSimbolo(delegua_1.default.TEXTO, valor);
29327
+ this.simbolos[this.simbolos.length - 1].delimitadorTexto = delimitador;
29328
+ return;
29329
+ }
29330
+ if (c === '\0' && this.eUltimaLinha())
29331
+ break;
29332
+ if (c === '\0') {
29333
+ valor += '\n';
29334
+ this.avancar();
29335
+ continue;
29336
+ }
29337
+ if (c === '\\') {
29338
+ this.avancar();
29339
+ const prox = this.simboloAtual();
29340
+ const escapes = {
29341
+ 'n': '\n',
29342
+ 't': '\t',
29343
+ 'r': '\r',
29344
+ 'b': '\b',
29345
+ "'": "'",
29346
+ '"': '"',
29347
+ '\\': '\\',
29348
+ 'e': '\x1B'
29349
+ };
29350
+ if (escapes[prox]) {
29351
+ valor += escapes[prox];
29352
+ }
29353
+ else if (prox === 'x') {
29354
+ let hex = '';
29355
+ for (let i = 0; i < 2; i++) {
29356
+ const h = this.proximoSimbolo();
29357
+ if (/[0-9a-fA-F]/.test(h)) {
29358
+ this.avancar();
29359
+ hex += h;
29360
+ }
29361
+ else
29362
+ break;
29363
+ }
29364
+ valor += hex.length === 2
29365
+ ? String.fromCharCode(parseInt(hex, 16))
29366
+ : '\\x' + hex;
29367
+ }
29368
+ else if (prox !== '\0') {
29369
+ valor += '\\' + prox;
29370
+ }
29371
+ }
29372
+ else {
29373
+ valor += c;
29374
+ }
29375
+ this.avancar();
29376
+ }
29377
+ this.erros.push({
29378
+ linha: this.linha + 1,
29379
+ caractere: this.simboloAnterior(),
29380
+ mensagem: 'Texto não finalizado.'
29381
+ });
29382
+ }
29475
29383
  identificarPalavraChave() {
29476
29384
  while (this.eAlfabetoOuDigito(this.simboloAtual())) {
29477
29385
  this.avancar();
29478
29386
  }
29479
29387
  const codigo = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29480
- const tipo = codigo in palavras_reservadas_1.palavrasReservadasDelegua
29388
+ this.adicionarSimbolo(codigo in palavras_reservadas_1.palavrasReservadasDelegua
29481
29389
  ? palavras_reservadas_1.palavrasReservadasDelegua[codigo]
29482
- : delegua_1.default.IDENTIFICADOR;
29483
- this.adicionarSimbolo(tipo);
29484
- }
29485
- eEmoji(caractere) {
29486
- const emojiRegex = /\p{Extended_Pictographic}(?:\uFE0F|\u200D\p{Extended_Pictographic})*/u;
29487
- return emojiRegex.test(caractere);
29390
+ : delegua_1.default.IDENTIFICADOR);
29488
29391
  }
29489
29392
  analisarEmoji() {
29490
- const simboloAtual = this.simboloAtual();
29491
29393
  this.erros.push({
29492
29394
  linha: this.linha + 1,
29493
- caractere: simboloAtual,
29494
- mensagem: 'Emojis devem estar envoltos por aspas.',
29395
+ caractere: this.simboloAtual(),
29396
+ mensagem: 'Emojis devem estar envoltos por aspas.'
29495
29397
  });
29496
29398
  this.avancar();
29497
29399
  }
29498
- analisarToken() {
29499
- const caractere = this.simboloAtual();
29500
- switch (caractere) {
29501
- case '@':
29502
- this.adicionarSimbolo(delegua_1.default.ARROBA, '@');
29503
- this.avancar();
29504
- break;
29505
- case '[':
29506
- this.adicionarSimbolo(delegua_1.default.COLCHETE_ESQUERDO, '[');
29507
- this.avancar();
29508
- break;
29509
- case ']':
29510
- this.adicionarSimbolo(delegua_1.default.COLCHETE_DIREITO, ']');
29511
- this.avancar();
29512
- break;
29513
- case '(':
29514
- this.adicionarSimbolo(delegua_1.default.PARENTESE_ESQUERDO, '(');
29515
- this.avancar();
29516
- break;
29517
- case ')':
29518
- this.adicionarSimbolo(delegua_1.default.PARENTESE_DIREITO, ')');
29519
- this.avancar();
29520
- break;
29521
- case '{':
29522
- this.adicionarSimbolo(delegua_1.default.CHAVE_ESQUERDA, '{');
29523
- this.avancar();
29524
- break;
29525
- case '}':
29526
- this.adicionarSimbolo(delegua_1.default.CHAVE_DIREITA, '}');
29527
- this.avancar();
29400
+ comentarioUmaLinha() {
29401
+ const linhaAtual = this.linha;
29402
+ let ultimoAtual = this.atual;
29403
+ while (linhaAtual === this.linha && !this.eFinalDoCodigo()) {
29404
+ ultimoAtual = this.atual;
29405
+ this.avancar();
29406
+ }
29407
+ const conteudo = this.codigo[linhaAtual].substring(this.inicioSimbolo + 2, ultimoAtual);
29408
+ this.adicionarSimbolo(delegua_1.default.COMENTARIO, conteudo.trim());
29409
+ }
29410
+ comentarioMultilinha() {
29411
+ let conteudo = '';
29412
+ while (!this.eFinalDoCodigo()) {
29413
+ if (this.simboloAtual() === '*' && this.proximoSimbolo() === '/') {
29414
+ this.avancar(); // pula o '*'
29415
+ this.avancar(); // pula o '/'
29416
+ conteudo
29417
+ .split('\0')
29418
+ .forEach(l => this.adicionarSimbolo(delegua_1.default.LINHA_COMENTARIO, l.trim()));
29528
29419
  break;
29529
- case ',':
29530
- this.adicionarSimbolo(delegua_1.default.VIRGULA, ',');
29531
- this.avancar();
29420
+ }
29421
+ conteudo += this.simboloAtual();
29422
+ this.avancar();
29423
+ }
29424
+ }
29425
+ /**
29426
+ * Lê um comentário documentário (iniciado com `/**`), agregando o conteúdo
29427
+ * em um único token DOCUMENTARIO. Linhas com `*` inicial (convenção JSDoc)
29428
+ * têm o asterisco removido.
29429
+ */
29430
+ comentarioDocumentario() {
29431
+ let conteudo = '';
29432
+ while (!this.eFinalDoCodigo()) {
29433
+ if (this.simboloAtual() === '*' && this.proximoSimbolo() === '/') {
29434
+ this.avancar(); // pula '*'
29435
+ this.avancar(); // pula '/'
29532
29436
  break;
29437
+ }
29438
+ conteudo += this.simboloAtual();
29439
+ this.avancar();
29440
+ }
29441
+ const conteudoLimpo = conteudo
29442
+ .split('\0')
29443
+ .map(l => l.trim().startsWith('*')
29444
+ ? l.trim().substring(1).trim()
29445
+ : l.trim())
29446
+ .filter(l => l.length > 0)
29447
+ .join('\n');
29448
+ this.adicionarSimbolo(delegua_1.default.DOCUMENTARIO, conteudoLimpo || '');
29449
+ }
29450
+ analisarToken() {
29451
+ const c = this.simboloAtual();
29452
+ if (tokensSimples[c]) {
29453
+ this.adicionarSimbolo(tokensSimples[c], c);
29454
+ this.avancar();
29455
+ return;
29456
+ }
29457
+ if (c === ' ' || c === '\0' || c === '\r' || c === '\t') {
29458
+ this.avancar();
29459
+ return;
29460
+ }
29461
+ this.inicioSimbolo = this.atual;
29462
+ if (c === '"' || c === "'") {
29463
+ this.analisarTexto(c);
29464
+ return;
29465
+ }
29466
+ switch (c) {
29533
29467
  case '.':
29534
- this.inicioSimbolo = this.atual;
29535
29468
  this.avancar();
29536
- if (this.simboloAtual() === '.') {
29537
- this.avancar();
29538
- if (this.simboloAtual() !== '.') {
29469
+ if (this.verificarEAvancar('.')) {
29470
+ if (this.verificarEAvancar('.')) {
29471
+ this.adicionarSimbolo(delegua_1.default.RETICENCIAS, '...');
29472
+ }
29473
+ else {
29539
29474
  this.erros.push({
29540
29475
  linha: this.linha + 1,
29541
29476
  caractere: this.simboloAtual(),
29542
- mensagem: 'Esperado ou apenas um ponto, ou três pontos em sequência.',
29477
+ mensagem: 'Esperado ou apenas um ponto, ou três pontos em sequência.'
29543
29478
  });
29544
29479
  this.adicionarSimbolo(delegua_1.default.PONTO, '.');
29545
29480
  }
29546
- else {
29547
- this.avancar();
29548
- this.adicionarSimbolo(delegua_1.default.RETICENCIAS, '...');
29549
- }
29550
29481
  }
29551
29482
  else {
29552
29483
  this.adicionarSimbolo(delegua_1.default.PONTO, '.');
29553
29484
  }
29554
29485
  break;
29555
29486
  case '-':
29556
- this.inicioSimbolo = this.atual;
29557
29487
  this.avancar();
29558
- if (this.simboloAtual() === '=') {
29488
+ if (this.verificarEAvancar('=')) {
29559
29489
  this.adicionarSimbolo(delegua_1.default.MENOS_IGUAL, '-=');
29560
- this.avancar();
29561
29490
  }
29562
- else if (this.simboloAtual() === '-') {
29491
+ else if (this.verificarEAvancar('-')) {
29563
29492
  this.adicionarSimbolo(delegua_1.default.DECREMENTAR, '--');
29564
- this.avancar();
29565
29493
  }
29566
29494
  else {
29567
29495
  this.adicionarSimbolo(delegua_1.default.SUBTRACAO);
29568
29496
  }
29569
29497
  break;
29570
29498
  case '+':
29571
- this.inicioSimbolo = this.atual;
29572
29499
  this.avancar();
29573
- if (this.simboloAtual() === '=') {
29500
+ if (this.verificarEAvancar('=')) {
29574
29501
  this.adicionarSimbolo(delegua_1.default.MAIS_IGUAL, '+=');
29575
- this.avancar();
29576
29502
  }
29577
- else if (this.simboloAtual() === '+') {
29503
+ else if (this.verificarEAvancar('+')) {
29578
29504
  this.adicionarSimbolo(delegua_1.default.INCREMENTAR, '++');
29579
- this.avancar();
29580
29505
  }
29581
29506
  else {
29582
29507
  this.adicionarSimbolo(delegua_1.default.ADICAO);
29583
29508
  }
29584
29509
  break;
29585
- case ':':
29586
- this.adicionarSimbolo(delegua_1.default.DOIS_PONTOS);
29587
- this.avancar();
29588
- break;
29589
29510
  case '%':
29590
- this.inicioSimbolo = this.atual;
29591
29511
  this.avancar();
29592
- switch (this.simboloAtual()) {
29593
- case '=':
29594
- this.avancar();
29595
- this.adicionarSimbolo(delegua_1.default.MODULO_IGUAL, '%=');
29596
- break;
29597
- default:
29598
- this.adicionarSimbolo(delegua_1.default.MODULO);
29599
- break;
29512
+ if (this.verificarEAvancar('=')) {
29513
+ this.adicionarSimbolo(delegua_1.default.MODULO_IGUAL, '%=');
29514
+ }
29515
+ else {
29516
+ this.adicionarSimbolo(delegua_1.default.MODULO);
29600
29517
  }
29601
29518
  break;
29602
29519
  case '*':
29603
- this.inicioSimbolo = this.atual;
29604
29520
  this.avancar();
29605
- switch (this.simboloAtual()) {
29606
- case '*':
29607
- this.avancar();
29608
- this.adicionarSimbolo(delegua_1.default.EXPONENCIACAO, '**');
29609
- break;
29610
- case '=':
29611
- this.avancar();
29612
- this.adicionarSimbolo(delegua_1.default.MULTIPLICACAO_IGUAL, '*=');
29613
- break;
29614
- default:
29615
- this.adicionarSimbolo(delegua_1.default.MULTIPLICACAO);
29616
- break;
29521
+ if (this.verificarEAvancar('*')) {
29522
+ this.adicionarSimbolo(delegua_1.default.EXPONENCIACAO, '**');
29523
+ }
29524
+ else if (this.verificarEAvancar('=')) {
29525
+ this.adicionarSimbolo(delegua_1.default.MULTIPLICACAO_IGUAL, '*=');
29526
+ }
29527
+ else {
29528
+ this.adicionarSimbolo(delegua_1.default.MULTIPLICACAO);
29617
29529
  }
29618
29530
  break;
29619
29531
  case '!':
29620
29532
  this.avancar();
29621
- if (this.simboloAtual() === '=') {
29533
+ if (this.verificarEAvancar('=')) {
29622
29534
  this.adicionarSimbolo(delegua_1.default.DIFERENTE, '!=');
29623
- this.avancar();
29624
29535
  }
29625
29536
  else {
29626
29537
  this.adicionarSimbolo(delegua_1.default.NEGACAO);
@@ -29628,49 +29539,32 @@ class Lexador {
29628
29539
  break;
29629
29540
  case '=':
29630
29541
  this.avancar();
29631
- if (this.simboloAtual() === '=') {
29542
+ if (this.verificarEAvancar('=')) {
29632
29543
  this.adicionarSimbolo(delegua_1.default.IGUAL_IGUAL, '==');
29633
- this.avancar();
29634
29544
  }
29635
29545
  else {
29636
29546
  this.adicionarSimbolo(delegua_1.default.IGUAL);
29637
29547
  }
29638
29548
  break;
29639
- case '&':
29640
- this.adicionarSimbolo(delegua_1.default.BIT_AND);
29641
- this.avancar();
29642
- break;
29643
- case '~':
29644
- this.adicionarSimbolo(delegua_1.default.BIT_NOT);
29645
- this.avancar();
29646
- break;
29647
29549
  case '|':
29648
29550
  this.avancar();
29649
- if (this.simboloAtual() === '|') {
29551
+ if (this.verificarEAvancar('|')) {
29650
29552
  this.adicionarSimbolo(delegua_1.default.EXPRESSAO_REGULAR, '||');
29651
- this.avancar();
29652
29553
  }
29653
29554
  else {
29654
29555
  this.adicionarSimbolo(delegua_1.default.BIT_OR);
29655
29556
  }
29656
29557
  break;
29657
- case '^':
29658
- this.adicionarSimbolo(delegua_1.default.CIRCUMFLEXO);
29659
- this.avancar();
29660
- break;
29661
29558
  case '<':
29662
29559
  this.avancar();
29663
- if (this.simboloAtual() === '=') {
29560
+ if (this.verificarEAvancar('=')) {
29664
29561
  this.adicionarSimbolo(delegua_1.default.MENOR_IGUAL, '<=');
29665
- this.avancar();
29666
29562
  }
29667
- else if (this.simboloAtual() === '<') {
29563
+ else if (this.verificarEAvancar('<')) {
29668
29564
  this.adicionarSimbolo(delegua_1.default.MENOR_MENOR, '<<');
29669
- this.avancar();
29670
29565
  }
29671
- else if (this.simboloAtual() === '-') {
29566
+ else if (this.verificarEAvancar('-')) {
29672
29567
  this.adicionarSimbolo(delegua_1.default.SETA_ESQUERDA, '<-');
29673
- this.avancar();
29674
29568
  }
29675
29569
  else {
29676
29570
  this.adicionarSimbolo(delegua_1.default.MENOR);
@@ -29678,13 +29572,11 @@ class Lexador {
29678
29572
  break;
29679
29573
  case '>':
29680
29574
  this.avancar();
29681
- if (this.simboloAtual() === '=') {
29575
+ if (this.verificarEAvancar('=')) {
29682
29576
  this.adicionarSimbolo(delegua_1.default.MAIOR_IGUAL, '>=');
29683
- this.avancar();
29684
29577
  }
29685
- else if (this.simboloAtual() === '>') {
29578
+ else if (this.verificarEAvancar('>')) {
29686
29579
  this.adicionarSimbolo(delegua_1.default.MAIOR_MAIOR, '>>');
29687
- this.avancar();
29688
29580
  }
29689
29581
  else {
29690
29582
  this.adicionarSimbolo(delegua_1.default.MAIOR);
@@ -29692,81 +29584,57 @@ class Lexador {
29692
29584
  break;
29693
29585
  case '/':
29694
29586
  this.avancar();
29695
- switch (this.simboloAtual()) {
29696
- case '/':
29697
- this.comentarioUmaLinha();
29698
- break;
29699
- case '*':
29700
- if (this.proximoSimbolo() === '*') {
29701
- this.comentarioDocumentario();
29702
- }
29703
- else {
29704
- this.comentarioMultilinha();
29705
- }
29706
- break;
29707
- case '=':
29708
- this.adicionarSimbolo(delegua_1.default.DIVISAO_IGUAL, '/=');
29709
- this.avancar();
29710
- break;
29711
- default:
29712
- this.adicionarSimbolo(delegua_1.default.DIVISAO);
29713
- break;
29587
+ if (this.verificarEAvancar('/')) {
29588
+ this.comentarioUmaLinha();
29589
+ }
29590
+ else if (this.verificarEAvancar('*')) {
29591
+ if (this.verificarEAvancar('*')) {
29592
+ this.comentarioDocumentario();
29593
+ }
29594
+ else {
29595
+ this.comentarioMultilinha();
29596
+ }
29597
+ }
29598
+ else if (this.verificarEAvancar('=')) {
29599
+ this.adicionarSimbolo(delegua_1.default.DIVISAO_IGUAL, '/=');
29600
+ }
29601
+ else {
29602
+ this.adicionarSimbolo(delegua_1.default.DIVISAO);
29714
29603
  }
29715
29604
  break;
29716
29605
  case '\\':
29717
- this.inicioSimbolo = this.atual;
29718
29606
  this.avancar();
29719
- switch (this.simboloAtual()) {
29720
- case '=':
29721
- this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA_IGUAL, '\\=');
29722
- this.avancar();
29723
- break;
29724
- default:
29725
- this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA);
29726
- break;
29607
+ if (this.verificarEAvancar('=')) {
29608
+ this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA_IGUAL, '\\=');
29609
+ }
29610
+ else {
29611
+ this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA);
29727
29612
  }
29728
29613
  break;
29729
29614
  case '?':
29730
29615
  this.avancar();
29731
- if (this.simboloAtual() === ':') {
29616
+ if (this.verificarEAvancar(':')) {
29732
29617
  this.adicionarSimbolo(delegua_1.default.ELVIS, '?:');
29733
- this.avancar();
29734
29618
  }
29735
29619
  else {
29736
29620
  this.adicionarSimbolo(delegua_1.default.INTERROGACAO);
29737
29621
  }
29738
29622
  break;
29739
- // Esta sessão ignora espaços em branco (ou similares) na tokenização.
29740
- case ' ':
29741
- case '\0':
29742
- case '\r':
29743
- case '\t':
29744
- this.avancar();
29745
- break;
29746
- // Ponto-e-vírgula é opcional em Delégua, mas em alguns casos pode ser
29747
- // necessário. Por exemplo, declaração de `para` sem inicializador.
29748
- case ';':
29749
- this.adicionarSimbolo(delegua_1.default.PONTO_E_VIRGULA);
29750
- this.avancar();
29751
- break;
29752
- case '"':
29753
- this.analisarTexto('"');
29754
- break;
29755
- case "'":
29756
- this.analisarTexto("'");
29757
- break;
29758
29623
  default:
29759
- if (this.eDigito(caractere))
29624
+ if (this.eDigito(c)) {
29760
29625
  this.analisarNumero();
29761
- else if (this.eEmoji(caractere))
29626
+ }
29627
+ else if (this.eEmoji(c)) {
29762
29628
  this.analisarEmoji();
29763
- else if (this.eAlfabeto(caractere))
29629
+ }
29630
+ else if (this.eAlfabeto(c)) {
29764
29631
  this.identificarPalavraChave();
29632
+ }
29765
29633
  else {
29766
29634
  this.erros.push({
29767
29635
  linha: this.linha + 1,
29768
- caractere: caractere,
29769
- mensagem: 'Caractere inesperado.',
29636
+ caractere: c,
29637
+ mensagem: 'Caractere inesperado.'
29770
29638
  });
29771
29639
  this.avancar();
29772
29640
  }
@@ -29779,16 +29647,12 @@ class Lexador {
29779
29647
  this.inicioSimbolo = 0;
29780
29648
  this.atual = 0;
29781
29649
  this.linha = 0;
29782
- this.codigo = codigo || [''];
29783
- if (codigo.length === 0) {
29784
- this.codigo = [''];
29785
- }
29650
+ this.codigo = codigo && codigo.length > 0 ? codigo : [''];
29786
29651
  this.hashArquivo = hashArquivo;
29787
29652
  for (let iterador = 0; iterador < this.codigo.length; iterador++) {
29788
29653
  this.codigo[iterador] += '\0';
29789
29654
  }
29790
29655
  while (!this.eFinalDoCodigo()) {
29791
- this.inicioSimbolo = this.atual;
29792
29656
  this.analisarToken();
29793
29657
  }
29794
29658
  if (this.performance) {
@@ -29798,13 +29662,13 @@ class Lexador {
29798
29662
  }
29799
29663
  return {
29800
29664
  simbolos: this.simbolos,
29801
- erros: this.erros,
29665
+ erros: this.erros
29802
29666
  };
29803
29667
  }
29804
29668
  }
29805
29669
  exports.Lexador = Lexador;
29806
29670
 
29807
- },{"../tipos-de-simbolos/delegua":256,"./palavras-reservadas":248,"./simbolo":249,"browser-process-hrtime":449}],245:[function(require,module,exports){
29671
+ },{"../tipos-de-simbolos/delegua":256,"./lexador-base":243,"./palavras-reservadas":248,"./simbolo":249,"browser-process-hrtime":449}],245:[function(require,module,exports){
29808
29672
  "use strict";
29809
29673
  var __importDefault = (this && this.__importDefault) || function (mod) {
29810
29674
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -53408,7 +53272,7 @@ class TradutorRuby {
53408
53272
  if (definirValor.objeto instanceof construtos_1.Isto) {
53409
53273
  resultado = '@' + definirValor.nome.lexema + ' = ';
53410
53274
  }
53411
- resultado += definirValor.valor.simbolo.lexema;
53275
+ resultado += this.dicionarioConstrutos[definirValor.valor.constructor.name](definirValor.valor);
53412
53276
  return resultado;
53413
53277
  }
53414
53278
  traduzirConstrutoDicionario(dicionario) {