@designliquido/delegua 1.24.1 → 1.24.3

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 (33) hide show
  1. package/analisador-semantico/analisador-semantico.d.ts.map +1 -1
  2. package/analisador-semantico/analisador-semantico.js +4 -0
  3. package/analisador-semantico/analisador-semantico.js.map +1 -1
  4. package/analisador-semantico/dialetos/analisador-semantico-pitugues.d.ts.map +1 -1
  5. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js +10 -0
  6. package/analisador-semantico/dialetos/analisador-semantico-pitugues.js.map +1 -1
  7. package/avaliador-sintatico/avaliador-sintatico-base.js +1 -1
  8. package/avaliador-sintatico/avaliador-sintatico-base.js.map +1 -1
  9. package/avaliador-sintatico/avaliador-sintatico.d.ts.map +1 -1
  10. package/avaliador-sintatico/avaliador-sintatico.js +55 -17
  11. package/avaliador-sintatico/avaliador-sintatico.js.map +1 -1
  12. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.d.ts.map +1 -1
  13. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js +28 -13
  14. package/avaliador-sintatico/dialetos/avaliador-sintatico-pitugues.js.map +1 -1
  15. package/bin/package.json +1 -1
  16. package/interpretador/depuracao/comum.d.ts.map +1 -1
  17. package/interpretador/depuracao/comum.js +16 -13
  18. package/interpretador/depuracao/comum.js.map +1 -1
  19. package/interpretador/interpretador-base.d.ts.map +1 -1
  20. package/interpretador/interpretador-base.js +55 -30
  21. package/interpretador/interpretador-base.js.map +1 -1
  22. package/interpretador/interpretador.d.ts.map +1 -1
  23. package/interpretador/interpretador.js +32 -5
  24. package/interpretador/interpretador.js.map +1 -1
  25. package/lexador/lexador.d.ts +19 -44
  26. package/lexador/lexador.d.ts.map +1 -1
  27. package/lexador/lexador.js +260 -489
  28. package/lexador/lexador.js.map +1 -1
  29. package/package.json +1 -1
  30. package/tradutores/tradutor-ruby.d.ts.map +1 -1
  31. package/tradutores/tradutor-ruby.js +1 -1
  32. package/tradutores/tradutor-ruby.js.map +1 -1
  33. package/umd/delegua.js +437 -557
package/umd/delegua.js CHANGED
@@ -553,6 +553,10 @@ class AnalisadorSemantico extends analisador_semantico_base_1.AnalisadorSemantic
553
553
  // Chamadas de método/função podem retornar vetores.
554
554
  // A validação detalhada é feita em tempo de execução.
555
555
  }
556
+ else if (declaracao.inicializador instanceof construtos_1.Binario) {
557
+ // Expressões binárias podem produzir vetores em tempo de execução
558
+ // (ex: vetor1 + vetor2 concatena dois vetores), então não geramos erro
559
+ }
556
560
  else {
557
561
  this.erro(declaracao.simbolo, `Atribuição inválida para '${declaracao.simbolo.lexema}': é esperado um vetor de elementos.`);
558
562
  }
@@ -2201,7 +2205,7 @@ class AvaliadorSintaticoBase {
2201
2205
  async unario() {
2202
2206
  if (this.verificarSeSimboloAtualEIgualA(comum_1.default.NEGACAO, comum_1.default.SUBTRACAO)) {
2203
2207
  const operador = this.simbolos[this.atual - 1];
2204
- const direito = await this.unario();
2208
+ const direito = await this.exponenciacao();
2205
2209
  return Promise.resolve(new construtos_1.Unario(this.hashArquivo, operador, direito, 'ANTES'));
2206
2210
  }
2207
2211
  return await this.chamar();
@@ -3023,10 +3027,11 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3023
3027
  }
3024
3028
  return new construtos_1.TipoDe(this.hashArquivo, simboloAtual, construto);
3025
3029
  }
3026
- // TODO: O correto seria emitir algum aviso aqui que este avaliador sintático não consegue
3027
- // lidar com tópicos de ajuda neste ponto.
3028
3030
  if (this.emAjuda) {
3029
- 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');
3030
3035
  }
3031
3036
  throw this.erro(this.simbolos[this.atual], 'Esperado expressão.');
3032
3037
  }
@@ -3374,7 +3379,7 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3374
3379
  }
3375
3380
  if (this.verificarSeSimboloAtualEIgualA(delegua_2.default.NAO, delegua_2.default.NEGACAO, delegua_2.default.ADICAO, delegua_2.default.SUBTRACAO, delegua_2.default.BIT_NOT, delegua_2.default.INCREMENTAR, delegua_2.default.DECREMENTAR)) {
3376
3381
  const operador = this.simbolos[this.atual - 1];
3377
- const direito = await this.unario();
3382
+ const direito = await this.exponenciacao();
3378
3383
  if (operador.tipo === delegua_2.default.NEGACAO ||
3379
3384
  operador.tipo === delegua_2.default.NAO) {
3380
3385
  this.verificarOperandoNegacao(operador, direito);
@@ -3977,16 +3982,16 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
3977
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'.");
3978
3983
  }
3979
3984
  let vetorOuDicionario = await this.expressao();
3980
- if (vetorOuDicionario.constructor === construtos_1.AcessoIndiceVariavel) {
3981
- const construtoAcessoIndiceVariavel = vetorOuDicionario;
3982
- if (construtoAcessoIndiceVariavel.entidadeChamada.tipo === 'dicionário') {
3983
- // A avaliação sintática não deve verificar valores de dicionários.
3984
- // Aqui se supõe que o programador sabe o que está fazendo.
3985
- // TODO: Talvez pensar numa forma melhor de fazer isso.
3986
- vetorOuDicionario.tipo = 'vetor';
3987
- }
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;
3988
3994
  }
3989
- const tipoVetor = vetorOuDicionario.tipo;
3990
3995
  if (!tipoVetor.endsWith('[]') &&
3991
3996
  !['dicionário', 'qualquer', 'texto', 'vetor'].includes(tipoVetor)) {
3992
3997
  throw this.erro(simboloPara, `Variável ou constante em 'para cada' não é iterável. Tipo resolvido: ${tipoVetor}.`);
@@ -4163,12 +4168,29 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4163
4168
  const entidadeChamadaVariavel = construtoChamada.entidadeChamada;
4164
4169
  tipoInicializacao = entidadeChamadaVariavel.tipo;
4165
4170
  break;
4166
- // 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;
4167
4178
  default:
4168
4179
  break;
4169
4180
  }
4170
4181
  break;
4171
- // 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;
4172
4194
  default:
4173
4195
  break;
4174
4196
  }
@@ -4297,7 +4319,11 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4297
4319
  const entidadeChamadaAcessoPropriedade = entidadeChamadaChamada;
4298
4320
  return entidadeChamadaAcessoPropriedade.tipoRetornoPropriedade;
4299
4321
  case construtos_1.ArgumentoReferenciaFuncao:
4300
- // TODO: Voltar aqui se necessário.
4322
+ const entidadeChamadaArgumentoReferencia = entidadeChamadaChamada;
4323
+ const referenciaFuncaoArgumentada = this.pilhaEscopos.obterReferenciaFuncao(entidadeChamadaArgumentoReferencia.simboloFuncao.lexema);
4324
+ if (referenciaFuncaoArgumentada) {
4325
+ return referenciaFuncaoArgumentada.tipo;
4326
+ }
4301
4327
  return 'qualquer';
4302
4328
  case construtos_1.ReferenciaFuncao:
4303
4329
  const entidadeChamadaReferenciaFuncao = entidadeChamadaChamada;
@@ -5354,6 +5380,10 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5354
5380
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]'),
5355
5381
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('funcaoPesquisa', 'função'),
5356
5382
  ]));
5383
+ this.pilhaEscopos.definirInformacoesVariavel('arredondar', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('arredondar', 'número', true, [
5384
+ new informacao_elemento_sintatico_1.InformacaoElementoSintatico('numero', 'número'),
5385
+ new informacao_elemento_sintatico_1.InformacaoElementoSintatico('casasDecimais', 'número'),
5386
+ ]));
5357
5387
  this.pilhaEscopos.definirInformacoesVariavel('clonar', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('clonar', 'qualquer', true, [
5358
5388
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valor', 'qualquer'),
5359
5389
  ]));
@@ -5454,6 +5484,9 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5454
5484
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('funcaoReducao', 'função'),
5455
5485
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valorInicial', 'qualquer'),
5456
5486
  ]));
5487
+ this.pilhaEscopos.definirInformacoesVariavel('somar', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('somar', 'número', true, [
5488
+ new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]'),
5489
+ ]));
5457
5490
  this.pilhaEscopos.definirInformacoesVariavel('tamanho', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tamanho', 'inteiro', true, [
5458
5491
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('objeto', 'qualquer'),
5459
5492
  ]));
@@ -5474,11 +5507,20 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5474
5507
  this.pilhaEscopos.definirInformacoesVariavel('tupla', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tupla', 'tupla', true, [
5475
5508
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]'),
5476
5509
  ]));
5510
+ this.pilhaEscopos.definirInformacoesVariavel('vetor', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]', true, [
5511
+ new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tupla', 'qualquer'),
5512
+ ]));
5477
5513
  // Classe base global `Objeto`, registrada pelo interpretador em tempo de execução.
5478
5514
  this.pilhaEscopos.definirInformacoesVariavel('Objeto', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('Objeto', 'qualquer'));
5479
- // TODO: Escrever algum tipo de validação aqui.
5480
5515
  for (const tipos of Object.values(this.tiposDeFerramentasExternas)) {
5481
5516
  for (const [nomeTipo, tipo] of Object.entries(tipos)) {
5517
+ if (!nomeTipo || !tipo) {
5518
+ continue;
5519
+ }
5520
+ if (nomeTipo in this.tiposDefinidosEmCodigo) {
5521
+ 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.`));
5522
+ continue;
5523
+ }
5482
5524
  this.pilhaEscopos.definirInformacoesVariavel(nomeTipo, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(nomeTipo, tipo));
5483
5525
  }
5484
5526
  }
@@ -7037,7 +7079,7 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7037
7079
  }
7038
7080
  if (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.NEGACAO, pitugues_2.default.SUBTRACAO, pitugues_2.default.BIT_NOT)) {
7039
7081
  const operador = this.simboloAnterior();
7040
- const direito = await this.unario();
7082
+ const direito = await this.exponenciacao();
7041
7083
  return new construtos_1.Unario(this.hashArquivo, operador, direito);
7042
7084
  }
7043
7085
  return await this.chamar();
@@ -7262,7 +7304,7 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7262
7304
  const simboloOperador = new lexador_1.Simbolo(tipoOperadorMatematico, operadorAtribuicao.lexema.charAt(0), null, operadorAtribuicao.linha, operadorAtribuicao.hashArquivo);
7263
7305
  const operacaoBinaria = new construtos_1.Binario(this.hashArquivo, expressao, simboloOperador, valor);
7264
7306
  if (expressao instanceof construtos_1.Variavel) {
7265
- return new construtos_1.Atribuir(this.hashArquivo, expressao, operacaoBinaria);
7307
+ return new construtos_1.Atribuir(this.hashArquivo, expressao, operacaoBinaria, undefined, operadorAtribuicao);
7266
7308
  }
7267
7309
  if (expressao instanceof construtos_1.AcessoMetodoOuPropriedade) {
7268
7310
  return new construtos_1.DefinirValor(this.hashArquivo, 0, expressao.objeto, expressao.simbolo, operacaoBinaria);
@@ -7495,11 +7537,10 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7495
7537
  async resolverDecoradores() {
7496
7538
  while (this.verificarTipoSimboloAtual(pitugues_2.default.ARROBA)) {
7497
7539
  this.avancarEDevolverAnterior();
7498
- let nomeDecorador = '@';
7499
- let linha;
7500
- let parametros = [];
7501
7540
  const atributos = {};
7502
7541
  const primeiraParteNomeDecorador = this.consumir(pitugues_2.default.IDENTIFICADOR, 'Esperado nome de decorador após "@".');
7542
+ let linha;
7543
+ let nomeDecorador = '@';
7503
7544
  linha = Number(primeiraParteNomeDecorador.linha);
7504
7545
  nomeDecorador += primeiraParteNomeDecorador.lexema;
7505
7546
  while (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.PONTO)) {
@@ -7507,16 +7548,17 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7507
7548
  nomeDecorador += '.' + parteNomeDecorador.lexema;
7508
7549
  }
7509
7550
  if (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.PARENTESE_ESQUERDO)) {
7510
- if (!this.verificarTipoSimboloAtual(pitugues_2.default.PARENTESE_DIREITO)) {
7511
- parametros = await this.logicaComumParametros();
7512
- }
7513
- for (const parametro of parametros) {
7514
- if (parametro.nome.lexema in atributos) {
7515
- throw this.erro(parametro.nome, `Atributo de decorador declarado duas ou mais vezes: ${parametro.nome.lexema}`);
7551
+ const entidadeChamada = new construtos_1.Variavel(this.hashArquivo, primeiraParteNomeDecorador);
7552
+ const chamada = await this.finalizarChamada(entidadeChamada);
7553
+ if (chamada && 'argumentos' in chamada) {
7554
+ const argumentos = chamada.argumentos;
7555
+ for (let i = 0; i < argumentos.length; i++) {
7556
+ atributos[i] = argumentos[i];
7516
7557
  }
7517
- atributos[parametro.nome.lexema] = parametro.valorPadrao;
7518
7558
  }
7519
- this.consumir(pitugues_2.default.PARENTESE_DIREITO, 'Esperado ")" após argumentos do decorador.');
7559
+ else {
7560
+ throw this.erro(primeiraParteNomeDecorador, `Esperado formato de chamada de função para os parâmetros do decorador '@${nomeDecorador}'.`);
7561
+ }
7520
7562
  }
7521
7563
  this.pilhaDecoradores.push(new construtos_1.Decorador(this.hashArquivo, linha, nomeDecorador, atributos));
7522
7564
  }
@@ -7816,6 +7858,21 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7816
7858
  async resolverMetodoOuConstrutor(simboloAnterior, metodos) {
7817
7859
  const ehConstrutor = simboloAnterior.tipo === pitugues_2.default.CONSTRUTOR;
7818
7860
  const metodoResolvido = await this.funcao('método', ehConstrutor);
7861
+ if (metodoResolvido.decoradores &&
7862
+ metodoResolvido.decoradores.length > 0) {
7863
+ for (const decorador of metodoResolvido.decoradores) {
7864
+ if (decorador.nome === '@propriedade') {
7865
+ metodoResolvido.eObtenedor = true;
7866
+ }
7867
+ else if (typeof decorador.nome === 'string' &&
7868
+ decorador.nome.endsWith('.definidor')) {
7869
+ metodoResolvido.eDefinidor = true;
7870
+ }
7871
+ else if (decorador.nome === '@metodo_estatico') {
7872
+ metodoResolvido.estatico = true;
7873
+ }
7874
+ }
7875
+ }
7819
7876
  metodos.push(metodoResolvido);
7820
7877
  }
7821
7878
  async resolverMembroDeClasse(metodos, propriedadesDeClasse) {
@@ -21958,7 +22015,7 @@ class InterpretadorBase {
21958
22015
  */
21959
22016
  resolverNomeObjectoAcessado(objetoAcessado) {
21960
22017
  switch (objetoAcessado.constructor) {
21961
- // TODO: Não habilitar isso até que vetores sejam repassados para o montão.
22018
+ // Habilitado somente quando vetores forem repassados para o montão.
21962
22019
  /* case AcessoMetodoOuPropriedade:
21963
22020
  return (objetoAcessado as AcessoMetodoOuPropriedade).simbolo.lexema;
21964
22021
  case AcessoIndiceVariavel:
@@ -21976,6 +22033,7 @@ class InterpretadorBase {
21976
22033
  case construtos_1.Dicionario:
21977
22034
  case construtos_1.Leia:
21978
22035
  case construtos_1.Literal:
22036
+ case construtos_1.Unario:
21979
22037
  case construtos_1.Vetor:
21980
22038
  return '';
21981
22039
  case construtos_1.Isto:
@@ -22299,6 +22357,7 @@ class InterpretadorBase {
22299
22357
  this.verificarOperandoNumero(expressao.operador, valor);
22300
22358
  return -valor;
22301
22359
  case delegua_1.default.NEGACAO:
22360
+ case delegua_1.default.NAO:
22302
22361
  return !this.eVerdadeiro(valor);
22303
22362
  case delegua_1.default.BIT_NOT:
22304
22363
  if (typeof valor === 'bigint') {
@@ -22311,6 +22370,9 @@ class InterpretadorBase {
22311
22370
  // Se veio antes e o operando é uma variável, precisamos incrementar/decrementar,
22312
22371
  // armazenar o valor da variável pra só então devolver o valor.
22313
22372
  case delegua_1.default.INCREMENTAR:
22373
+ if (typeof valor === 'string') {
22374
+ throw new excecoes_1.ErroEmTempoDeExecucao(expressao.operador, `Operador '${expressao.operador.lexema}' não pode ser aplicado a um texto.`, expressao.linha);
22375
+ }
22314
22376
  if (expressao.incidenciaOperador === 'ANTES') {
22315
22377
  valor++;
22316
22378
  if (expressao.operando instanceof construtos_1.Variavel) {
@@ -22324,6 +22386,9 @@ class InterpretadorBase {
22324
22386
  }
22325
22387
  return valorAnteriorIncremento;
22326
22388
  case delegua_1.default.DECREMENTAR:
22389
+ if (typeof valor === 'string') {
22390
+ throw new excecoes_1.ErroEmTempoDeExecucao(expressao.operador, `Operador '${expressao.operador.lexema}' não pode ser aplicado a um texto.`, expressao.linha);
22391
+ }
22327
22392
  if (expressao.incidenciaOperador === 'ANTES') {
22328
22393
  valor--;
22329
22394
  if (expressao.operando instanceof construtos_1.Variavel) {
@@ -22538,8 +22603,8 @@ class InterpretadorBase {
22538
22603
  if (valorEsquerdo === null || valorDireito === null) {
22539
22604
  return this.paraTexto(valorEsquerdo) + this.paraTexto(valorDireito);
22540
22605
  }
22541
- // TODO: Se tipo for 'qualquer', seria uma boa confiar nos operadores
22542
- // tradicionais do JavaScript?
22606
+ // Para tipos 'qualquer', delegamos ao operador nativo do JavaScript,
22607
+ // que resolve concatenação ou soma dependendo dos valores em tempo de execução.
22543
22608
  if (tipoEsquerdo === 'qualquer' || tipoDireito === 'qualquer') {
22544
22609
  return valorEsquerdo + valorDireito;
22545
22610
  }
@@ -22772,8 +22837,12 @@ class InterpretadorBase {
22772
22837
  }
22773
22838
  if (entidadeChamada instanceof estruturas_1.FuncaoPadrao) {
22774
22839
  try {
22775
- return await entidadeChamada.chamar(this, argumentos.map((a) => a && this.resolverValor(a.valor)), expressao.entidadeChamada.simbolo // TODO: O que exatamente pode ser aqui?
22776
- );
22840
+ // entidadeChamada pode ser Variavel, AcessoMetodo, ReferenciaFuncao, etc.
22841
+ // Todos os construtos concretos que chegam aqui têm `simbolo: SimboloInterface`.
22842
+ const simboloChamada = 'simbolo' in expressao.entidadeChamada
22843
+ ? expressao.entidadeChamada.simbolo
22844
+ : null;
22845
+ return await entidadeChamada.chamar(this, argumentos.map((a) => a && this.resolverValor(a.valor)), simboloChamada);
22777
22846
  }
22778
22847
  catch (erro) {
22779
22848
  if (this.emDeclaracaoTente) {
@@ -22810,7 +22879,6 @@ class InterpretadorBase {
22810
22879
  if (typeof entidadeChamada === primitivos_1.default.FUNCAO) {
22811
22880
  let objeto = null;
22812
22881
  if (expressao.entidadeChamada.objeto) {
22813
- // TODO: Qual o tipo certo aqui?
22814
22882
  objeto = await this.avaliar(expressao.entidadeChamada.objeto);
22815
22883
  }
22816
22884
  return entidadeChamada.apply(this.resolverValor(objeto), argumentos);
@@ -22863,6 +22931,31 @@ class InterpretadorBase {
22863
22931
  break;
22864
22932
  case construtos_1.Variavel:
22865
22933
  const alvoVariavel = expressao.alvo;
22934
+ if (expressao.simboloOperador) {
22935
+ let valorAtual;
22936
+ valorAtual = this.resolverValor(this.pilhaEscoposExecucao.obterValorVariavel(alvoVariavel.simbolo));
22937
+ if (typeof valorAtual === 'string') {
22938
+ let valorDireito;
22939
+ if (expressao.valor instanceof construtos_1.Binario) {
22940
+ valorDireito = this.resolverValor(await this.avaliar(expressao.valor.direita));
22941
+ }
22942
+ else {
22943
+ valorDireito = valorResolvido;
22944
+ }
22945
+ if (expressao.simboloOperador.tipo === delegua_1.default.MAIS_IGUAL) {
22946
+ if (typeof valorDireito !== 'string') {
22947
+ throw new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloOperador, `Operador '+=' não pode concatenar texto com ${typeof valorDireito}. Use conversão explícita.`, expressao.linha);
22948
+ }
22949
+ }
22950
+ else if ([delegua_1.default.MENOS_IGUAL,
22951
+ delegua_1.default.MULTIPLICACAO_IGUAL,
22952
+ delegua_1.default.DIVISAO_IGUAL,
22953
+ delegua_1.default.MODULO_IGUAL]
22954
+ .includes(expressao.simboloOperador.tipo)) {
22955
+ throw new excecoes_1.ErroEmTempoDeExecucao(expressao.simboloOperador, `Operador '${expressao.simboloOperador.lexema}' não pode ser aplicado a um texto.`, expressao.linha);
22956
+ }
22957
+ }
22958
+ }
22866
22959
  this.atribuirVariavel(alvoVariavel, valorResolvido, indice);
22867
22960
  break;
22868
22961
  default:
@@ -23006,10 +23099,9 @@ class InterpretadorBase {
23006
23099
  const vetorResolvido = await this.avaliar(declaracao.vetorOuDicionario);
23007
23100
  let valorVetorResolvido = this.resolverValor(vetorResolvido);
23008
23101
  // Se até aqui vetor resolvido é um dicionário, converte dicionário
23009
- // para vetor de duplas.
23010
- // TODO: Converter elementos para `Construto` se necessário.
23102
+ // para vetor de duplas com elementos envoltos em Literal, preservando tipo.
23011
23103
  if (declaracao.vetorOuDicionario.tipo === 'dicionário') {
23012
- valorVetorResolvido = Object.entries(valorVetorResolvido).map((v) => new construtos_1.Dupla(v[0], v[1]));
23104
+ 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]))));
23013
23105
  }
23014
23106
  if (!Array.isArray(valorVetorResolvido)) {
23015
23107
  return Promise.reject("Variável ou literal provida em instrução 'para cada' não é um vetor.");
@@ -23025,13 +23117,11 @@ class InterpretadorBase {
23025
23117
  }
23026
23118
  if (declaracao.variavelIteracao instanceof construtos_1.Dupla) {
23027
23119
  const valorComoDupla = valorVetorResolvido[declaracao.posicaoAtual];
23028
- const promises = await Promise.all([
23029
- this.avaliar(declaracao.variavelIteracao.primeiro),
23030
- this.avaliar(declaracao.variavelIteracao.segundo),
23031
- ]);
23032
- // TODO: O que fazer quando não forem literais?
23033
- this.pilhaEscoposExecucao.definirVariavel(String(promises[0].valor), valorComoDupla.primeiro);
23034
- this.pilhaEscoposExecucao.definirVariavel(String(promises[1].valor), valorComoDupla.segundo);
23120
+ // Os nomes das variáveis vêm diretamente dos Literais do AST (não precisam ser avaliados).
23121
+ const nomePrimeiro = declaracao.variavelIteracao.primeiro.valor?.toString() ?? '';
23122
+ const nomeSegundo = declaracao.variavelIteracao.segundo.valor?.toString() ?? '';
23123
+ this.pilhaEscoposExecucao.definirVariavel(nomePrimeiro, this.resolverValor(valorComoDupla.primeiro));
23124
+ this.pilhaEscoposExecucao.definirVariavel(nomeSegundo, this.resolverValor(valorComoDupla.segundo));
23035
23125
  }
23036
23126
  retornoExecucao = await this.executar(declaracao.corpo);
23037
23127
  if (retornoExecucao && retornoExecucao.valorRetornado instanceof quebras_1.SustarQuebra) {
@@ -23519,14 +23609,14 @@ class InterpretadorBase {
23519
23609
  }
23520
23610
  mesclaResolvidas.push(misturável);
23521
23611
  }
23522
- // TODO: Precisamos disso?
23612
+ // Necessário para que a declaração da classe seja acessível durante a resolução
23613
+ // dos seus próprios métodos (ex.: construtores que instanciam a própria classe).
23523
23614
  this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, declaracao);
23524
23615
  if (superClassesResolvidas.length > 0) {
23525
23616
  this.pilhaEscoposExecucao.definirVariavel('super', superClassesResolvidas[0]);
23526
23617
  }
23527
23618
  const descritorTipoClasse = this.resolverMetodoDeClasse(declaracao, superClassesResolvidas, mesclaResolvidas);
23528
- // TODO: Até então, a única exceção a isso é Égua Clássico.
23529
- // Por enquanto, tudo bem deixar isso aqui.
23619
+ // A única exceção a isso até então é Égua Clássico, que requer declaração de propriedades.
23530
23620
  descritorTipoClasse.dialetoRequerDeclaracaoPropriedades = this.requerDeclaracaoPropriedades;
23531
23621
  this.pilhaEscoposExecucao.atribuirVariavel(declaracao.simbolo, descritorTipoClasse);
23532
23622
  return descritorTipoClasse;
@@ -23682,11 +23772,9 @@ class InterpretadorBase {
23682
23772
  if (Array.isArray(objeto)) {
23683
23773
  if (expressao.simbolo.lexema in primitivas_vetor_1.default) {
23684
23774
  const metodoDePrimitivaVetor = primitivas_vetor_1.default[expressao.simbolo.lexema].implementacao;
23685
- // TODO: Um problema a ser resolvido na questão de vetores é quando eles pertencem a outro objeto.
23686
- // Por exemplo, um dicionário.
23687
- // Existe uma lógica nas bibliotecas padrão que, quando a primitiva tem um nome, ela deve ser definida na
23688
- // pilha de escopos, para registrar a mutação do vetor corretamente.
23689
- // Não é uma boa solução. Algo melhor precisa ser feito.
23775
+ // Limitação conhecida: quando o vetor pertence a um objeto pai (ex.: um dicionário),
23776
+ // as bibliotecas padrão registram a mutação pelo nome do vetor na pilha de escopos,
23777
+ // o que não funciona corretamente nesse caso. Requer refatoração futura.
23690
23778
  return new metodo_primitiva_1.MetodoPrimitiva(nomeObjeto, objeto, metodoDePrimitivaVetor, expressao.simbolo.lexema, tipoObjeto);
23691
23779
  }
23692
23780
  }
@@ -23759,12 +23847,6 @@ class InterpretadorBase {
23759
23847
  tipoResolvido = (0, inferenciador_1.inferirTipoVariavel)(valorFinal);
23760
23848
  }
23761
23849
  this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, valorFinal, tipoResolvido, declaracao.tipoExplicito && declaracao.tipoOriginal !== 'qualquer');
23762
- // TODO: É relevante registrar uma declaração de variável no
23763
- // resultado do interpretador?
23764
- /* return {
23765
- tipo: declaracao.tipo,
23766
- tipoExplicito: declaracao.tipoExplicito
23767
- }; */
23768
23850
  return null;
23769
23851
  }
23770
23852
  /**
@@ -24407,9 +24489,28 @@ class Interpretador extends interpretador_base_1.InterpretadorBase {
24407
24489
  const nomeDecorador = decorador.nome.slice(1);
24408
24490
  const variavelDecoradora = this.pilhaEscoposExecucao.obterVariavelPorNome(nomeDecorador);
24409
24491
  const funcaoDecoradora = variavelDecoradora.valor;
24410
- const resultado = await funcaoDecoradora.chamar(this, [
24411
- { nome: '', valor: funcao },
24412
- ]);
24492
+ const argumentosDecorador = [
24493
+ { nome: '', valor: funcao }
24494
+ ];
24495
+ if (decorador.atributos) {
24496
+ const chaves = Object.keys(decorador.atributos)
24497
+ .map(Number)
24498
+ .sort((a, b) => a - b);
24499
+ for (const chave of chaves) {
24500
+ let valorArg = decorador.atributos[chave];
24501
+ if (typeof valorArg?.aceitar === 'function') {
24502
+ valorArg = await this.avaliar(valorArg);
24503
+ }
24504
+ else if (valorArg?.hasOwnProperty('valor')) {
24505
+ valorArg = this.resolverValor(valorArg);
24506
+ }
24507
+ else {
24508
+ 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.`));
24509
+ }
24510
+ argumentosDecorador.push({ nome: '', valor: valorArg });
24511
+ }
24512
+ }
24513
+ const resultado = await funcaoDecoradora.chamar(this, argumentosDecorador);
24413
24514
  funcao = this.resolverValorRecursivo(resultado);
24414
24515
  }
24415
24516
  }
@@ -24664,7 +24765,7 @@ class Interpretador extends interpretador_base_1.InterpretadorBase {
24664
24765
  const metodoFinalizar = retornoInicializacaoResolvido.classe.encontrarMetodo('finalizar');
24665
24766
  if (metodoFinalizar) {
24666
24767
  const chamavel = metodoFinalizar.funcaoPorMetodoDeClasse(retornoInicializacaoResolvido);
24667
- chamavel.chamar(this, []);
24768
+ await chamavel.chamar(this, []);
24668
24769
  }
24669
24770
  }
24670
24771
  return null;
@@ -25540,7 +25641,15 @@ class Interpretador extends interpretador_base_1.InterpretadorBase {
25540
25641
  const alvoTipoDe = await this.avaliar(valorTipoDe);
25541
25642
  return `tipo de<${alvoTipoDe}>`;
25542
25643
  case construtos_1.Variavel:
25543
- return valorTipoDe.tipo || (0, inferenciador_1.inferirTipoVariavel)(await this.avaliar(valorTipoDe));
25644
+ const tipoEstatico = valorTipoDe.tipo;
25645
+ if (tipoEstatico !== 'qualquer')
25646
+ return tipoEstatico;
25647
+ const valorAvaliado = await this.avaliar(valorTipoDe);
25648
+ const valorResolvido = this.resolverValor(valorAvaliado);
25649
+ if (valorResolvido === undefined || valorResolvido === null) {
25650
+ return 'qualquer';
25651
+ }
25652
+ return (0, inferenciador_1.inferirTipoVariavel)(valorResolvido);
25544
25653
  case construtos_1.Vetor:
25545
25654
  const vetor = valorTipoDe;
25546
25655
  const apenasValores = vetor.valores.filter((v) => !['ComentarioComoConstruto', 'Separador'].includes(v.constructor.name));
@@ -29061,366 +29170,117 @@ Object.defineProperty(exports, "__esModule", { value: true });
29061
29170
  exports.Lexador = void 0;
29062
29171
  const browser_process_hrtime_1 = __importDefault(require("browser-process-hrtime"));
29063
29172
  const simbolo_1 = require("./simbolo");
29173
+ const lexador_base_1 = require("./lexador-base");
29064
29174
  const palavras_reservadas_1 = require("./palavras-reservadas");
29065
29175
  const delegua_1 = __importDefault(require("../tipos-de-simbolos/delegua"));
29066
- /**
29067
- * O Lexador é responsável por transformar o código em uma coleção de tokens de linguagem.
29068
- * Cada token de linguagem é representado por um tipo, um lexema e informações da linha de código em que foi expresso.
29069
- * Também é responsável por mapear as palavras reservadas da linguagem, que não podem ser usadas por outras
29070
- * estruturas, tais como nomes de variáveis, funções, literais, classes e assim por diante.
29071
- */
29072
- class Lexador {
29176
+ const tokensSimples = {
29177
+ '@': delegua_1.default.ARROBA,
29178
+ '[': delegua_1.default.COLCHETE_ESQUERDO,
29179
+ ']': delegua_1.default.COLCHETE_DIREITO,
29180
+ '(': delegua_1.default.PARENTESE_ESQUERDO,
29181
+ ')': delegua_1.default.PARENTESE_DIREITO,
29182
+ '{': delegua_1.default.CHAVE_ESQUERDA,
29183
+ '}': delegua_1.default.CHAVE_DIREITA,
29184
+ ',': delegua_1.default.VIRGULA,
29185
+ ':': delegua_1.default.DOIS_PONTOS,
29186
+ // Ponto-e-vírgula é opcional em Delégua, mas em alguns casos pode ser
29187
+ // necessário. Por exemplo, declaração de `para` sem inicializador.
29188
+ ';': delegua_1.default.PONTO_E_VIRGULA,
29189
+ '^': delegua_1.default.CIRCUMFLEXO,
29190
+ '~': delegua_1.default.BIT_NOT,
29191
+ '&': delegua_1.default.BIT_AND
29192
+ };
29193
+ /*
29194
+ * O Lexador é responsável por transformar o código em uma coleção de tokens de linguagem.
29195
+ * Cada token de linguagem é representado por um tipo, um lexema e informações da linha de código em que foi expresso.
29196
+ * Também é responsável por mapear as palavras reservadas da linguagem, que não podem ser usadas por outras
29197
+ * estruturas, tais como nomes de variáveis, funções, literais, classes e assim por diante.
29198
+ */
29199
+ class Lexador extends lexador_base_1.LexadorBase {
29073
29200
  constructor(performance = false) {
29074
- this.codigo = [];
29201
+ super();
29202
+ this.regexAlfabeto = /[a-zA-Z_áàâãéèêíïóôõöúçñÁÀÂÃÉÈÊÍÏÓÔÕÖÚÇÑ]/;
29203
+ this.regexEmoji = /\p{Extended_Pictographic}(?:\uFE0F|\u200D\p{Extended_Pictographic})*/u;
29075
29204
  this.performance = performance;
29076
- this.simbolos = [];
29077
- this.erros = [];
29078
- this.hashArquivo = -1;
29079
- this.inicioSimbolo = 0;
29080
- this.atual = 0;
29081
- this.linha = 0;
29082
- }
29083
- eDigito(caractere) {
29084
- return caractere >= '0' && caractere <= '9';
29085
- }
29086
- eAlfabeto(caractere) {
29087
- const acentuacoes = [
29088
- 'á',
29089
- 'Á',
29090
- 'ã',
29091
- 'Ã',
29092
- 'â',
29093
- 'Â',
29094
- 'à',
29095
- 'À',
29096
- 'é',
29097
- 'É',
29098
- 'ê',
29099
- 'Ê',
29100
- 'í',
29101
- 'Í',
29102
- 'ó',
29103
- 'Ó',
29104
- 'õ',
29105
- 'Õ',
29106
- 'ô',
29107
- 'Ô',
29108
- 'ú',
29109
- 'Ú',
29110
- 'ç',
29111
- 'Ç',
29112
- '_',
29113
- ];
29114
- return ((caractere >= 'a' && caractere <= 'z') ||
29115
- (caractere >= 'A' && caractere <= 'Z') ||
29116
- acentuacoes.includes(caractere));
29117
- }
29118
- eAlfabetoOuDigito(caractere) {
29119
- return this.eDigito(caractere) || this.eAlfabeto(caractere);
29120
- }
29121
- eHexDigito(caractere) {
29122
- return ((caractere >= '0' && caractere <= '9') ||
29123
- (caractere >= 'a' && caractere <= 'f') ||
29124
- (caractere >= 'A' && caractere <= 'F'));
29125
29205
  }
29126
- eBinarioDigito(caractere) {
29127
- return caractere === '0' || caractere === '1';
29128
- }
29129
- eOctalDigito(caractere) {
29130
- return caractere >= '0' && caractere <= '7';
29206
+ eAlfabeto(c) {
29207
+ return this.regexAlfabeto.test(c);
29131
29208
  }
29132
- eFinalDaLinha() {
29133
- if (this.codigo.length === this.linha) {
29134
- return true;
29135
- }
29136
- return this.atual >= this.codigo[this.linha].length;
29137
- }
29138
- /**
29139
- * Indica se o código está na última linha.
29140
- * @returns Verdadeiro se contador de linhas está na última linha.
29141
- * Falso caso contrário.
29142
- */
29143
- eUltimaLinha() {
29144
- return this.linha >= this.codigo.length - 1;
29145
- }
29146
- eFinalDoCodigo() {
29147
- return this.eUltimaLinha() && this.codigo[this.codigo.length - 1].length <= this.atual;
29209
+ eEmoji(c) {
29210
+ return this.regexEmoji.test(c);
29148
29211
  }
29149
29212
  avancar() {
29150
- const linha = this.codigo[this.linha];
29151
- const codePoint = linha.codePointAt(this.atual);
29213
+ const codePoint = this.codigo[this.linha].codePointAt(this.atual);
29152
29214
  this.atual += codePoint && codePoint > 0xffff ? 2 : 1;
29153
29215
  if (this.eFinalDaLinha() && !this.eUltimaLinha()) {
29154
29216
  this.linha++;
29155
29217
  this.atual = 0;
29156
29218
  }
29157
29219
  }
29158
- adicionarSimbolo(tipo, literal = null) {
29159
- const texto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29160
- const lexema = literal || texto;
29161
- const comprimentoLexema = typeof lexema === 'string' ? lexema.length : 0;
29162
- const comprimento = Math.max(comprimentoLexema, texto.length) || 1;
29163
- const colunaInicio = this.inicioSimbolo + 1;
29164
- const colunaFim = this.inicioSimbolo + comprimento;
29165
- this.simbolos.push(new simbolo_1.Simbolo(tipo, lexema, literal, this.linha + 1, this.hashArquivo, colunaInicio, colunaFim));
29166
- }
29167
29220
  simboloAtual() {
29168
29221
  if (this.eFinalDaLinha())
29169
29222
  return '\0';
29170
- const linha = this.codigo[this.linha];
29171
- const codePoint = linha.codePointAt(this.atual);
29172
- if (codePoint === undefined) {
29173
- return '\0';
29174
- }
29175
- return String.fromCodePoint(codePoint);
29176
- }
29177
- comentarioMultilinha() {
29178
- let conteudo = '';
29179
- while (!this.eFinalDoCodigo()) {
29180
- this.avancar();
29181
- conteudo += this.codigo[this.linha].charAt(this.atual);
29182
- if (this.simboloAtual() === '*' && this.proximoSimbolo() === '/') {
29183
- const linhas = conteudo.split('\0');
29184
- for (let linha of linhas) {
29185
- this.adicionarSimbolo(delegua_1.default.LINHA_COMENTARIO, linha.trim());
29186
- }
29187
- // Remove o asterisco da última linha
29188
- let lexemaUltimaLinha = this.simbolos[this.simbolos.length - 1].lexema;
29189
- lexemaUltimaLinha = lexemaUltimaLinha.substring(0, lexemaUltimaLinha.length - 1);
29190
- this.simbolos[this.simbolos.length - 1].lexema = lexemaUltimaLinha;
29191
- this.simbolos[this.simbolos.length - 1].literal = lexemaUltimaLinha;
29192
- this.avancar();
29193
- this.avancar();
29194
- break;
29195
- }
29196
- }
29197
- }
29198
- /**
29199
- * Lê um comentário documentário (iniciado com `/**`), agregando o conteúdo
29200
- * em um único token DOCUMENTARIO. Linhas com `*` inicial (convenção JSDoc)
29201
- * têm o asterisco removido.
29202
- */
29203
- comentarioDocumentario() {
29204
- // Cursor está no primeiro '*' de '/**'. Avança para pular o segundo '*'.
29205
- this.avancar();
29206
- let conteudo = '';
29207
- while (!this.eFinalDoCodigo()) {
29208
- this.avancar();
29209
- if (this.simboloAtual() === '*' && this.proximoSimbolo() === '/') {
29210
- // Fecha o documentário sem adicionar o '*' ao conteúdo.
29211
- this.avancar(); // pula '*'
29212
- this.avancar(); // pula '/'
29213
- break;
29214
- }
29215
- conteudo += this.codigo[this.linha].charAt(this.atual);
29216
- }
29217
- // Divide por '\0' (separador de linha), remove asteriscos iniciais e filtra vazios.
29218
- const conteudoLimpo = conteudo
29219
- .split('\0')
29220
- .map((l) => {
29221
- const trimmed = l.trim();
29222
- return trimmed.startsWith('*') ? trimmed.substring(1).trim() : trimmed;
29223
- })
29224
- .filter((l) => l.length > 0)
29225
- .join('\n');
29226
- this.adicionarSimbolo(delegua_1.default.DOCUMENTARIO, conteudoLimpo || '');
29227
- }
29228
- comentarioUmaLinha() {
29229
- this.avancar();
29230
- const linhaAtual = this.linha;
29231
- let ultimoAtual = this.atual;
29232
- while (linhaAtual === this.linha && !this.eFinalDoCodigo()) {
29233
- ultimoAtual = this.atual;
29234
- this.avancar();
29235
- }
29236
- const conteudo = this.codigo[linhaAtual].substring(this.inicioSimbolo + 2, ultimoAtual);
29237
- this.adicionarSimbolo(delegua_1.default.COMENTARIO, conteudo.trim());
29223
+ const codePoint = this.codigo[this.linha].codePointAt(this.atual);
29224
+ return codePoint === undefined ? '\0' : String.fromCodePoint(codePoint);
29238
29225
  }
29239
29226
  proximoSimbolo() {
29240
- const linha = this.codigo[this.linha];
29241
- const atual = this.simboloAtual();
29242
- const incremento = atual.length;
29243
- const codePoint = linha.codePointAt(this.atual + incremento);
29244
- if (codePoint === undefined) {
29245
- return '\0';
29246
- }
29247
- return String.fromCodePoint(codePoint);
29227
+ const atualStr = this.simboloAtual();
29228
+ const codePoint = this.codigo[this.linha].codePointAt(this.atual + atualStr.length);
29229
+ return codePoint === undefined ? '\0' : String.fromCodePoint(codePoint);
29248
29230
  }
29249
29231
  simboloAnterior() {
29250
29232
  const linha = this.codigo[this.linha];
29251
- const indiceAnterior = this.atual -
29252
- (linha.codePointAt(this.atual - 2) > 0xffff ? 2 : 1);
29233
+ const indiceAnterior = this.atual - (linha.codePointAt(this.atual - 2) > 0xffff ? 2 : 1);
29253
29234
  const codePoint = linha.codePointAt(indiceAnterior);
29254
- if (codePoint === undefined) {
29255
- return '\0';
29256
- }
29257
- }
29258
- analisarTexto(delimitador = '"') {
29259
- let valor = '';
29260
- this.avancar();
29261
- while (!this.eFinalDoCodigo()) {
29262
- const caractere = this.simboloAtual();
29263
- if (caractere === delimitador) {
29264
- this.avancar();
29265
- this.adicionarSimbolo(delegua_1.default.TEXTO, valor);
29266
- const ultimoSimbolo = this.simbolos[this.simbolos.length - 1];
29267
- ultimoSimbolo.delimitadorTexto = delimitador;
29268
- return;
29269
- }
29270
- if (caractere === '\0' && this.eUltimaLinha()) {
29271
- this.erros.push({
29272
- linha: this.linha + 1,
29273
- caractere: this.simboloAnterior(),
29274
- mensagem: 'Texto não finalizado.',
29275
- });
29276
- return;
29277
- }
29278
- if (caractere === '\0') {
29279
- valor += '\n';
29280
- this.avancar();
29281
- continue;
29282
- }
29283
- if (caractere === '\\') {
29284
- this.avancar();
29285
- const proximoCaractere = this.simboloAtual();
29286
- switch (proximoCaractere) {
29287
- case 'n':
29288
- valor += '\n';
29289
- break;
29290
- case 't':
29291
- valor += '\t';
29292
- break;
29293
- case 'r':
29294
- valor += '\r';
29295
- break;
29296
- case 'b':
29297
- valor += '\b';
29298
- break;
29299
- case "'":
29300
- valor += "'";
29301
- break;
29302
- case '"':
29303
- valor += '"';
29304
- break;
29305
- case '\\':
29306
- valor += '\\';
29307
- break;
29308
- case 'e':
29309
- valor += '\x1B';
29310
- break;
29311
- case 'x': {
29312
- let hex = '';
29313
- for (let i = 0; i < 2; i++) {
29314
- const c = this.proximoSimbolo();
29315
- if (/[0-9a-fA-F]/.test(c)) {
29316
- this.avancar();
29317
- hex += c;
29318
- }
29319
- else {
29320
- break;
29321
- }
29322
- }
29323
- valor +=
29324
- hex.length === 2 ? String.fromCharCode(parseInt(hex, 16)) : '\\x' + hex;
29325
- break;
29326
- }
29327
- case '\0':
29328
- break; // barra invertida no fim de linha: ignora e continua na próxima linha
29329
- default:
29330
- valor += '\\' + proximoCaractere;
29331
- break;
29332
- }
29333
- }
29334
- else {
29335
- valor += caractere;
29336
- }
29337
- this.avancar();
29338
- }
29339
- this.erros.push({
29340
- linha: this.linha + 1,
29341
- caractere: this.simboloAnterior(),
29342
- mensagem: 'Texto não finalizado.',
29343
- });
29235
+ return codePoint === undefined ? '\0' : String.fromCodePoint(codePoint);
29344
29236
  }
29345
- analisarHexadecimal() {
29346
- this.avancar(); // Pula '0'
29347
- this.avancar(); // Pula 'x' ou 'X'
29348
- while (this.eHexDigito(this.simboloAtual())) {
29349
- this.avancar();
29350
- }
29351
- const hexString = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29352
- try {
29353
- const bigintValue = BigInt(hexString);
29354
- this.adicionarSimbolo(delegua_1.default.NUMERO, bigintValue);
29355
- }
29356
- catch (e) {
29357
- this.erros.push({
29358
- linha: this.linha + 1,
29359
- caractere: this.simboloAnterior(),
29360
- mensagem: `Literal hexadecimal inválido: ${hexString}`,
29361
- });
29362
- }
29237
+ adicionarSimbolo(tipo, literal = null) {
29238
+ const texto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29239
+ const lexema = literal !== null ? literal : texto;
29240
+ const comprimento = Math.max(typeof lexema === 'string' ? lexema.length : 0, texto.length) || 1;
29241
+ this.simbolos.push(new simbolo_1.Simbolo(tipo, lexema, literal, this.linha + 1, this.hashArquivo, this.inicioSimbolo + 1, this.inicioSimbolo + comprimento));
29363
29242
  }
29364
- analisarBinario() {
29365
- this.avancar(); // Pula '0'
29366
- this.avancar(); // Pula 'b' ou 'B'
29367
- while (this.eBinarioDigito(this.simboloAtual())) {
29368
- this.avancar();
29369
- }
29370
- const binaryString = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29371
- try {
29372
- const bigintValue = BigInt(binaryString);
29373
- this.adicionarSimbolo(delegua_1.default.NUMERO, bigintValue);
29374
- }
29375
- catch (e) {
29376
- this.erros.push({
29377
- linha: this.linha + 1,
29378
- caractere: this.simboloAnterior(),
29379
- mensagem: `Literal binário inválido: ${binaryString}`,
29380
- });
29381
- }
29243
+ verificarEAvancar(esperado) {
29244
+ if (this.eFinalDaLinha() || this.simboloAtual() !== esperado)
29245
+ return false;
29246
+ this.avancar();
29247
+ return true;
29382
29248
  }
29383
- analisarOctal() {
29249
+ analisarBaseNumerica(validadorDigito, tipoErro) {
29384
29250
  this.avancar(); // Pula '0'
29385
- this.avancar(); // Pula 'o' ou 'O'
29386
- while (this.eOctalDigito(this.simboloAtual())) {
29251
+ this.avancar(); // Pula 'x', 'b' ou 'o'
29252
+ while (validadorDigito.call(this, this.simboloAtual())) {
29387
29253
  this.avancar();
29388
29254
  }
29389
- const octalString = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29255
+ const texto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29390
29256
  try {
29391
- const bigintValue = BigInt(octalString);
29392
- this.adicionarSimbolo(delegua_1.default.NUMERO, bigintValue);
29257
+ this.adicionarSimbolo(delegua_1.default.NUMERO, BigInt(texto));
29393
29258
  }
29394
29259
  catch (e) {
29395
29260
  this.erros.push({
29396
29261
  linha: this.linha + 1,
29397
29262
  caractere: this.simboloAnterior(),
29398
- mensagem: `Literal octal inválido: ${octalString}`,
29263
+ mensagem: `Literal ${tipoErro} inválido: ${texto}`
29399
29264
  });
29400
29265
  }
29401
29266
  }
29402
29267
  analisarNumero() {
29403
- // Verifica se é um literal especial (hexadecimal, binário ou octal)
29404
29268
  if (this.simboloAtual() === '0') {
29405
- const proximoChar = this.proximoSimbolo();
29406
- if (proximoChar === 'x' || proximoChar === 'X') {
29407
- this.analisarHexadecimal();
29408
- return;
29269
+ const prox = this.proximoSimbolo().toLowerCase();
29270
+ if (prox === 'x') {
29271
+ return this.analisarBaseNumerica(this.eHexDigito, 'hexadecimal');
29409
29272
  }
29410
- else if (proximoChar === 'b' || proximoChar === 'B') {
29411
- this.analisarBinario();
29412
- return;
29273
+ if (prox === 'b') {
29274
+ return this.analisarBaseNumerica(this.eBinarioDigito, 'binário');
29413
29275
  }
29414
- else if (proximoChar === 'o' || proximoChar === 'O') {
29415
- this.analisarOctal();
29416
- return;
29276
+ if (prox === 'o') {
29277
+ return this.analisarBaseNumerica(this.eOctalDigito, 'octal');
29417
29278
  }
29418
29279
  }
29419
- // Análise de número decimal normal
29420
29280
  while (this.eDigito(this.simboloAtual())) {
29421
29281
  this.avancar();
29422
29282
  }
29423
- if (this.simboloAtual() == '.' && this.eDigito(this.proximoSimbolo())) {
29283
+ if (this.simboloAtual() === '.' && this.eDigito(this.proximoSimbolo())) {
29424
29284
  this.avancar();
29425
29285
  while (this.eDigito(this.simboloAtual())) {
29426
29286
  this.avancar();
@@ -29429,155 +29289,222 @@ class Lexador {
29429
29289
  const numeroCompleto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29430
29290
  this.adicionarSimbolo(delegua_1.default.NUMERO, parseFloat(numeroCompleto));
29431
29291
  }
29292
+ analisarTexto(delimitador = '"') {
29293
+ let valor = '';
29294
+ this.avancar();
29295
+ while (!this.eFinalDoCodigo()) {
29296
+ const c = this.simboloAtual();
29297
+ if (c === delimitador) {
29298
+ this.avancar();
29299
+ this.adicionarSimbolo(delegua_1.default.TEXTO, valor);
29300
+ this.simbolos[this.simbolos.length - 1].delimitadorTexto = delimitador;
29301
+ return;
29302
+ }
29303
+ if (c === '\0' && this.eUltimaLinha())
29304
+ break;
29305
+ if (c === '\0') {
29306
+ valor += '\n';
29307
+ this.avancar();
29308
+ continue;
29309
+ }
29310
+ if (c === '\\') {
29311
+ this.avancar();
29312
+ const prox = this.simboloAtual();
29313
+ const escapes = {
29314
+ 'n': '\n',
29315
+ 't': '\t',
29316
+ 'r': '\r',
29317
+ 'b': '\b',
29318
+ "'": "'",
29319
+ '"': '"',
29320
+ '\\': '\\',
29321
+ 'e': '\x1B'
29322
+ };
29323
+ if (escapes[prox]) {
29324
+ valor += escapes[prox];
29325
+ }
29326
+ else if (prox === 'x') {
29327
+ let hex = '';
29328
+ for (let i = 0; i < 2; i++) {
29329
+ const h = this.proximoSimbolo();
29330
+ if (/[0-9a-fA-F]/.test(h)) {
29331
+ this.avancar();
29332
+ hex += h;
29333
+ }
29334
+ else
29335
+ break;
29336
+ }
29337
+ valor += hex.length === 2
29338
+ ? String.fromCharCode(parseInt(hex, 16))
29339
+ : '\\x' + hex;
29340
+ }
29341
+ else if (prox !== '\0') {
29342
+ valor += '\\' + prox;
29343
+ }
29344
+ }
29345
+ else {
29346
+ valor += c;
29347
+ }
29348
+ this.avancar();
29349
+ }
29350
+ this.erros.push({
29351
+ linha: this.linha + 1,
29352
+ caractere: this.simboloAnterior(),
29353
+ mensagem: 'Texto não finalizado.'
29354
+ });
29355
+ }
29432
29356
  identificarPalavraChave() {
29433
29357
  while (this.eAlfabetoOuDigito(this.simboloAtual())) {
29434
29358
  this.avancar();
29435
29359
  }
29436
29360
  const codigo = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29437
- const tipo = codigo in palavras_reservadas_1.palavrasReservadasDelegua
29361
+ this.adicionarSimbolo(codigo in palavras_reservadas_1.palavrasReservadasDelegua
29438
29362
  ? palavras_reservadas_1.palavrasReservadasDelegua[codigo]
29439
- : delegua_1.default.IDENTIFICADOR;
29440
- this.adicionarSimbolo(tipo);
29441
- }
29442
- eEmoji(caractere) {
29443
- const emojiRegex = /\p{Extended_Pictographic}(?:\uFE0F|\u200D\p{Extended_Pictographic})*/u;
29444
- return emojiRegex.test(caractere);
29363
+ : delegua_1.default.IDENTIFICADOR);
29445
29364
  }
29446
29365
  analisarEmoji() {
29447
- const simboloAtual = this.simboloAtual();
29448
29366
  this.erros.push({
29449
29367
  linha: this.linha + 1,
29450
- caractere: simboloAtual,
29451
- mensagem: 'Emojis devem estar envoltos por aspas.',
29368
+ caractere: this.simboloAtual(),
29369
+ mensagem: 'Emojis devem estar envoltos por aspas.'
29452
29370
  });
29453
29371
  this.avancar();
29454
29372
  }
29455
- analisarToken() {
29456
- const caractere = this.simboloAtual();
29457
- switch (caractere) {
29458
- case '@':
29459
- this.adicionarSimbolo(delegua_1.default.ARROBA, '@');
29460
- this.avancar();
29461
- break;
29462
- case '[':
29463
- this.adicionarSimbolo(delegua_1.default.COLCHETE_ESQUERDO, '[');
29464
- this.avancar();
29465
- break;
29466
- case ']':
29467
- this.adicionarSimbolo(delegua_1.default.COLCHETE_DIREITO, ']');
29468
- this.avancar();
29469
- break;
29470
- case '(':
29471
- this.adicionarSimbolo(delegua_1.default.PARENTESE_ESQUERDO, '(');
29472
- this.avancar();
29473
- break;
29474
- case ')':
29475
- this.adicionarSimbolo(delegua_1.default.PARENTESE_DIREITO, ')');
29476
- this.avancar();
29477
- break;
29478
- case '{':
29479
- this.adicionarSimbolo(delegua_1.default.CHAVE_ESQUERDA, '{');
29480
- this.avancar();
29481
- break;
29482
- case '}':
29483
- this.adicionarSimbolo(delegua_1.default.CHAVE_DIREITA, '}');
29484
- this.avancar();
29373
+ comentarioUmaLinha() {
29374
+ const linhaAtual = this.linha;
29375
+ let ultimoAtual = this.atual;
29376
+ while (linhaAtual === this.linha && !this.eFinalDoCodigo()) {
29377
+ ultimoAtual = this.atual;
29378
+ this.avancar();
29379
+ }
29380
+ const conteudo = this.codigo[linhaAtual].substring(this.inicioSimbolo + 2, ultimoAtual);
29381
+ this.adicionarSimbolo(delegua_1.default.COMENTARIO, conteudo.trim());
29382
+ }
29383
+ comentarioMultilinha() {
29384
+ let conteudo = '';
29385
+ while (!this.eFinalDoCodigo()) {
29386
+ if (this.simboloAtual() === '*' && this.proximoSimbolo() === '/') {
29387
+ this.avancar(); // pula o '*'
29388
+ this.avancar(); // pula o '/'
29389
+ conteudo
29390
+ .split('\0')
29391
+ .forEach(l => this.adicionarSimbolo(delegua_1.default.LINHA_COMENTARIO, l.trim()));
29485
29392
  break;
29486
- case ',':
29487
- this.adicionarSimbolo(delegua_1.default.VIRGULA, ',');
29488
- this.avancar();
29393
+ }
29394
+ conteudo += this.simboloAtual();
29395
+ this.avancar();
29396
+ }
29397
+ }
29398
+ /**
29399
+ * Lê um comentário documentário (iniciado com `/**`), agregando o conteúdo
29400
+ * em um único token DOCUMENTARIO. Linhas com `*` inicial (convenção JSDoc)
29401
+ * têm o asterisco removido.
29402
+ */
29403
+ comentarioDocumentario() {
29404
+ let conteudo = '';
29405
+ while (!this.eFinalDoCodigo()) {
29406
+ if (this.simboloAtual() === '*' && this.proximoSimbolo() === '/') {
29407
+ this.avancar(); // pula '*'
29408
+ this.avancar(); // pula '/'
29489
29409
  break;
29410
+ }
29411
+ conteudo += this.simboloAtual();
29412
+ this.avancar();
29413
+ }
29414
+ const conteudoLimpo = conteudo
29415
+ .split('\0')
29416
+ .map(l => l.trim().startsWith('*')
29417
+ ? l.trim().substring(1).trim()
29418
+ : l.trim())
29419
+ .filter(l => l.length > 0)
29420
+ .join('\n');
29421
+ this.adicionarSimbolo(delegua_1.default.DOCUMENTARIO, conteudoLimpo || '');
29422
+ }
29423
+ analisarToken() {
29424
+ const c = this.simboloAtual();
29425
+ if (tokensSimples[c]) {
29426
+ this.adicionarSimbolo(tokensSimples[c], c);
29427
+ this.avancar();
29428
+ return;
29429
+ }
29430
+ if (c === ' ' || c === '\0' || c === '\r' || c === '\t') {
29431
+ this.avancar();
29432
+ return;
29433
+ }
29434
+ this.inicioSimbolo = this.atual;
29435
+ if (c === '"' || c === "'") {
29436
+ this.analisarTexto(c);
29437
+ return;
29438
+ }
29439
+ switch (c) {
29490
29440
  case '.':
29491
- this.inicioSimbolo = this.atual;
29492
29441
  this.avancar();
29493
- if (this.simboloAtual() === '.') {
29494
- this.avancar();
29495
- if (this.simboloAtual() !== '.') {
29442
+ if (this.verificarEAvancar('.')) {
29443
+ if (this.verificarEAvancar('.')) {
29444
+ this.adicionarSimbolo(delegua_1.default.RETICENCIAS, '...');
29445
+ }
29446
+ else {
29496
29447
  this.erros.push({
29497
29448
  linha: this.linha + 1,
29498
29449
  caractere: this.simboloAtual(),
29499
- mensagem: 'Esperado ou apenas um ponto, ou três pontos em sequência.',
29450
+ mensagem: 'Esperado ou apenas um ponto, ou três pontos em sequência.'
29500
29451
  });
29501
29452
  this.adicionarSimbolo(delegua_1.default.PONTO, '.');
29502
29453
  }
29503
- else {
29504
- this.avancar();
29505
- this.adicionarSimbolo(delegua_1.default.RETICENCIAS, '...');
29506
- }
29507
29454
  }
29508
29455
  else {
29509
29456
  this.adicionarSimbolo(delegua_1.default.PONTO, '.');
29510
29457
  }
29511
29458
  break;
29512
29459
  case '-':
29513
- this.inicioSimbolo = this.atual;
29514
29460
  this.avancar();
29515
- if (this.simboloAtual() === '=') {
29461
+ if (this.verificarEAvancar('=')) {
29516
29462
  this.adicionarSimbolo(delegua_1.default.MENOS_IGUAL, '-=');
29517
- this.avancar();
29518
29463
  }
29519
- else if (this.simboloAtual() === '-') {
29464
+ else if (this.verificarEAvancar('-')) {
29520
29465
  this.adicionarSimbolo(delegua_1.default.DECREMENTAR, '--');
29521
- this.avancar();
29522
29466
  }
29523
29467
  else {
29524
29468
  this.adicionarSimbolo(delegua_1.default.SUBTRACAO);
29525
29469
  }
29526
29470
  break;
29527
29471
  case '+':
29528
- this.inicioSimbolo = this.atual;
29529
29472
  this.avancar();
29530
- if (this.simboloAtual() === '=') {
29473
+ if (this.verificarEAvancar('=')) {
29531
29474
  this.adicionarSimbolo(delegua_1.default.MAIS_IGUAL, '+=');
29532
- this.avancar();
29533
29475
  }
29534
- else if (this.simboloAtual() === '+') {
29476
+ else if (this.verificarEAvancar('+')) {
29535
29477
  this.adicionarSimbolo(delegua_1.default.INCREMENTAR, '++');
29536
- this.avancar();
29537
29478
  }
29538
29479
  else {
29539
29480
  this.adicionarSimbolo(delegua_1.default.ADICAO);
29540
29481
  }
29541
29482
  break;
29542
- case ':':
29543
- this.adicionarSimbolo(delegua_1.default.DOIS_PONTOS);
29544
- this.avancar();
29545
- break;
29546
29483
  case '%':
29547
- this.inicioSimbolo = this.atual;
29548
29484
  this.avancar();
29549
- switch (this.simboloAtual()) {
29550
- case '=':
29551
- this.avancar();
29552
- this.adicionarSimbolo(delegua_1.default.MODULO_IGUAL, '%=');
29553
- break;
29554
- default:
29555
- this.adicionarSimbolo(delegua_1.default.MODULO);
29556
- break;
29485
+ if (this.verificarEAvancar('=')) {
29486
+ this.adicionarSimbolo(delegua_1.default.MODULO_IGUAL, '%=');
29487
+ }
29488
+ else {
29489
+ this.adicionarSimbolo(delegua_1.default.MODULO);
29557
29490
  }
29558
29491
  break;
29559
29492
  case '*':
29560
- this.inicioSimbolo = this.atual;
29561
29493
  this.avancar();
29562
- switch (this.simboloAtual()) {
29563
- case '*':
29564
- this.avancar();
29565
- this.adicionarSimbolo(delegua_1.default.EXPONENCIACAO, '**');
29566
- break;
29567
- case '=':
29568
- this.avancar();
29569
- this.adicionarSimbolo(delegua_1.default.MULTIPLICACAO_IGUAL, '*=');
29570
- break;
29571
- default:
29572
- this.adicionarSimbolo(delegua_1.default.MULTIPLICACAO);
29573
- break;
29494
+ if (this.verificarEAvancar('*')) {
29495
+ this.adicionarSimbolo(delegua_1.default.EXPONENCIACAO, '**');
29496
+ }
29497
+ else if (this.verificarEAvancar('=')) {
29498
+ this.adicionarSimbolo(delegua_1.default.MULTIPLICACAO_IGUAL, '*=');
29499
+ }
29500
+ else {
29501
+ this.adicionarSimbolo(delegua_1.default.MULTIPLICACAO);
29574
29502
  }
29575
29503
  break;
29576
29504
  case '!':
29577
29505
  this.avancar();
29578
- if (this.simboloAtual() === '=') {
29506
+ if (this.verificarEAvancar('=')) {
29579
29507
  this.adicionarSimbolo(delegua_1.default.DIFERENTE, '!=');
29580
- this.avancar();
29581
29508
  }
29582
29509
  else {
29583
29510
  this.adicionarSimbolo(delegua_1.default.NEGACAO);
@@ -29585,49 +29512,32 @@ class Lexador {
29585
29512
  break;
29586
29513
  case '=':
29587
29514
  this.avancar();
29588
- if (this.simboloAtual() === '=') {
29515
+ if (this.verificarEAvancar('=')) {
29589
29516
  this.adicionarSimbolo(delegua_1.default.IGUAL_IGUAL, '==');
29590
- this.avancar();
29591
29517
  }
29592
29518
  else {
29593
29519
  this.adicionarSimbolo(delegua_1.default.IGUAL);
29594
29520
  }
29595
29521
  break;
29596
- case '&':
29597
- this.adicionarSimbolo(delegua_1.default.BIT_AND);
29598
- this.avancar();
29599
- break;
29600
- case '~':
29601
- this.adicionarSimbolo(delegua_1.default.BIT_NOT);
29602
- this.avancar();
29603
- break;
29604
29522
  case '|':
29605
29523
  this.avancar();
29606
- if (this.simboloAtual() === '|') {
29524
+ if (this.verificarEAvancar('|')) {
29607
29525
  this.adicionarSimbolo(delegua_1.default.EXPRESSAO_REGULAR, '||');
29608
- this.avancar();
29609
29526
  }
29610
29527
  else {
29611
29528
  this.adicionarSimbolo(delegua_1.default.BIT_OR);
29612
29529
  }
29613
29530
  break;
29614
- case '^':
29615
- this.adicionarSimbolo(delegua_1.default.CIRCUMFLEXO);
29616
- this.avancar();
29617
- break;
29618
29531
  case '<':
29619
29532
  this.avancar();
29620
- if (this.simboloAtual() === '=') {
29533
+ if (this.verificarEAvancar('=')) {
29621
29534
  this.adicionarSimbolo(delegua_1.default.MENOR_IGUAL, '<=');
29622
- this.avancar();
29623
29535
  }
29624
- else if (this.simboloAtual() === '<') {
29536
+ else if (this.verificarEAvancar('<')) {
29625
29537
  this.adicionarSimbolo(delegua_1.default.MENOR_MENOR, '<<');
29626
- this.avancar();
29627
29538
  }
29628
- else if (this.simboloAtual() === '-') {
29539
+ else if (this.verificarEAvancar('-')) {
29629
29540
  this.adicionarSimbolo(delegua_1.default.SETA_ESQUERDA, '<-');
29630
- this.avancar();
29631
29541
  }
29632
29542
  else {
29633
29543
  this.adicionarSimbolo(delegua_1.default.MENOR);
@@ -29635,13 +29545,11 @@ class Lexador {
29635
29545
  break;
29636
29546
  case '>':
29637
29547
  this.avancar();
29638
- if (this.simboloAtual() === '=') {
29548
+ if (this.verificarEAvancar('=')) {
29639
29549
  this.adicionarSimbolo(delegua_1.default.MAIOR_IGUAL, '>=');
29640
- this.avancar();
29641
29550
  }
29642
- else if (this.simboloAtual() === '>') {
29551
+ else if (this.verificarEAvancar('>')) {
29643
29552
  this.adicionarSimbolo(delegua_1.default.MAIOR_MAIOR, '>>');
29644
- this.avancar();
29645
29553
  }
29646
29554
  else {
29647
29555
  this.adicionarSimbolo(delegua_1.default.MAIOR);
@@ -29649,81 +29557,57 @@ class Lexador {
29649
29557
  break;
29650
29558
  case '/':
29651
29559
  this.avancar();
29652
- switch (this.simboloAtual()) {
29653
- case '/':
29654
- this.comentarioUmaLinha();
29655
- break;
29656
- case '*':
29657
- if (this.proximoSimbolo() === '*') {
29658
- this.comentarioDocumentario();
29659
- }
29660
- else {
29661
- this.comentarioMultilinha();
29662
- }
29663
- break;
29664
- case '=':
29665
- this.adicionarSimbolo(delegua_1.default.DIVISAO_IGUAL, '/=');
29666
- this.avancar();
29667
- break;
29668
- default:
29669
- this.adicionarSimbolo(delegua_1.default.DIVISAO);
29670
- break;
29560
+ if (this.verificarEAvancar('/')) {
29561
+ this.comentarioUmaLinha();
29562
+ }
29563
+ else if (this.verificarEAvancar('*')) {
29564
+ if (this.verificarEAvancar('*')) {
29565
+ this.comentarioDocumentario();
29566
+ }
29567
+ else {
29568
+ this.comentarioMultilinha();
29569
+ }
29570
+ }
29571
+ else if (this.verificarEAvancar('=')) {
29572
+ this.adicionarSimbolo(delegua_1.default.DIVISAO_IGUAL, '/=');
29573
+ }
29574
+ else {
29575
+ this.adicionarSimbolo(delegua_1.default.DIVISAO);
29671
29576
  }
29672
29577
  break;
29673
29578
  case '\\':
29674
- this.inicioSimbolo = this.atual;
29675
29579
  this.avancar();
29676
- switch (this.simboloAtual()) {
29677
- case '=':
29678
- this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA_IGUAL, '\\=');
29679
- this.avancar();
29680
- break;
29681
- default:
29682
- this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA);
29683
- break;
29580
+ if (this.verificarEAvancar('=')) {
29581
+ this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA_IGUAL, '\\=');
29582
+ }
29583
+ else {
29584
+ this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA);
29684
29585
  }
29685
29586
  break;
29686
29587
  case '?':
29687
29588
  this.avancar();
29688
- if (this.simboloAtual() === ':') {
29589
+ if (this.verificarEAvancar(':')) {
29689
29590
  this.adicionarSimbolo(delegua_1.default.ELVIS, '?:');
29690
- this.avancar();
29691
29591
  }
29692
29592
  else {
29693
29593
  this.adicionarSimbolo(delegua_1.default.INTERROGACAO);
29694
29594
  }
29695
29595
  break;
29696
- // Esta sessão ignora espaços em branco (ou similares) na tokenização.
29697
- case ' ':
29698
- case '\0':
29699
- case '\r':
29700
- case '\t':
29701
- this.avancar();
29702
- break;
29703
- // Ponto-e-vírgula é opcional em Delégua, mas em alguns casos pode ser
29704
- // necessário. Por exemplo, declaração de `para` sem inicializador.
29705
- case ';':
29706
- this.adicionarSimbolo(delegua_1.default.PONTO_E_VIRGULA);
29707
- this.avancar();
29708
- break;
29709
- case '"':
29710
- this.analisarTexto('"');
29711
- break;
29712
- case "'":
29713
- this.analisarTexto("'");
29714
- break;
29715
29596
  default:
29716
- if (this.eDigito(caractere))
29597
+ if (this.eDigito(c)) {
29717
29598
  this.analisarNumero();
29718
- else if (this.eEmoji(caractere))
29599
+ }
29600
+ else if (this.eEmoji(c)) {
29719
29601
  this.analisarEmoji();
29720
- else if (this.eAlfabeto(caractere))
29602
+ }
29603
+ else if (this.eAlfabeto(c)) {
29721
29604
  this.identificarPalavraChave();
29605
+ }
29722
29606
  else {
29723
29607
  this.erros.push({
29724
29608
  linha: this.linha + 1,
29725
- caractere: caractere,
29726
- mensagem: 'Caractere inesperado.',
29609
+ caractere: c,
29610
+ mensagem: 'Caractere inesperado.'
29727
29611
  });
29728
29612
  this.avancar();
29729
29613
  }
@@ -29736,16 +29620,12 @@ class Lexador {
29736
29620
  this.inicioSimbolo = 0;
29737
29621
  this.atual = 0;
29738
29622
  this.linha = 0;
29739
- this.codigo = codigo || [''];
29740
- if (codigo.length === 0) {
29741
- this.codigo = [''];
29742
- }
29623
+ this.codigo = codigo && codigo.length > 0 ? codigo : [''];
29743
29624
  this.hashArquivo = hashArquivo;
29744
29625
  for (let iterador = 0; iterador < this.codigo.length; iterador++) {
29745
29626
  this.codigo[iterador] += '\0';
29746
29627
  }
29747
29628
  while (!this.eFinalDoCodigo()) {
29748
- this.inicioSimbolo = this.atual;
29749
29629
  this.analisarToken();
29750
29630
  }
29751
29631
  if (this.performance) {
@@ -29755,13 +29635,13 @@ class Lexador {
29755
29635
  }
29756
29636
  return {
29757
29637
  simbolos: this.simbolos,
29758
- erros: this.erros,
29638
+ erros: this.erros
29759
29639
  };
29760
29640
  }
29761
29641
  }
29762
29642
  exports.Lexador = Lexador;
29763
29643
 
29764
- },{"../tipos-de-simbolos/delegua":256,"./palavras-reservadas":248,"./simbolo":249,"browser-process-hrtime":449}],245:[function(require,module,exports){
29644
+ },{"../tipos-de-simbolos/delegua":256,"./lexador-base":243,"./palavras-reservadas":248,"./simbolo":249,"browser-process-hrtime":449}],245:[function(require,module,exports){
29765
29645
  "use strict";
29766
29646
  var __importDefault = (this && this.__importDefault) || function (mod) {
29767
29647
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -53365,7 +53245,7 @@ class TradutorRuby {
53365
53245
  if (definirValor.objeto instanceof construtos_1.Isto) {
53366
53246
  resultado = '@' + definirValor.nome.lexema + ' = ';
53367
53247
  }
53368
- resultado += definirValor.valor.simbolo.lexema;
53248
+ resultado += this.dicionarioConstrutos[definirValor.valor.constructor.name](definirValor.valor);
53369
53249
  return resultado;
53370
53250
  }
53371
53251
  traduzirConstrutoDicionario(dicionario) {