@designliquido/delegua 1.24.2 → 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.
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
  }
@@ -4301,7 +4319,11 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
4301
4319
  const entidadeChamadaAcessoPropriedade = entidadeChamadaChamada;
4302
4320
  return entidadeChamadaAcessoPropriedade.tipoRetornoPropriedade;
4303
4321
  case construtos_1.ArgumentoReferenciaFuncao:
4304
- // 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
+ }
4305
4327
  return 'qualquer';
4306
4328
  case construtos_1.ReferenciaFuncao:
4307
4329
  const entidadeChamadaReferenciaFuncao = entidadeChamadaChamada;
@@ -5358,6 +5380,10 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5358
5380
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]'),
5359
5381
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('funcaoPesquisa', 'função'),
5360
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
+ ]));
5361
5387
  this.pilhaEscopos.definirInformacoesVariavel('clonar', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('clonar', 'qualquer', true, [
5362
5388
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valor', 'qualquer'),
5363
5389
  ]));
@@ -5458,6 +5484,9 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5458
5484
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('funcaoReducao', 'função'),
5459
5485
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('valorInicial', 'qualquer'),
5460
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
+ ]));
5461
5490
  this.pilhaEscopos.definirInformacoesVariavel('tamanho', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tamanho', 'inteiro', true, [
5462
5491
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('objeto', 'qualquer'),
5463
5492
  ]));
@@ -5478,11 +5507,20 @@ class AvaliadorSintatico extends avaliador_sintatico_base_1.AvaliadorSintaticoBa
5478
5507
  this.pilhaEscopos.definirInformacoesVariavel('tupla', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('tupla', 'tupla', true, [
5479
5508
  new informacao_elemento_sintatico_1.InformacaoElementoSintatico('vetor', 'qualquer[]'),
5480
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
+ ]));
5481
5513
  // Classe base global `Objeto`, registrada pelo interpretador em tempo de execução.
5482
5514
  this.pilhaEscopos.definirInformacoesVariavel('Objeto', new informacao_elemento_sintatico_1.InformacaoElementoSintatico('Objeto', 'qualquer'));
5483
- // TODO: Escrever algum tipo de validação aqui.
5484
5515
  for (const tipos of Object.values(this.tiposDeFerramentasExternas)) {
5485
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
+ }
5486
5524
  this.pilhaEscopos.definirInformacoesVariavel(nomeTipo, new informacao_elemento_sintatico_1.InformacaoElementoSintatico(nomeTipo, tipo));
5487
5525
  }
5488
5526
  }
@@ -7499,11 +7537,10 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7499
7537
  async resolverDecoradores() {
7500
7538
  while (this.verificarTipoSimboloAtual(pitugues_2.default.ARROBA)) {
7501
7539
  this.avancarEDevolverAnterior();
7502
- let nomeDecorador = '@';
7503
- let linha;
7504
- let parametros = [];
7505
7540
  const atributos = {};
7506
7541
  const primeiraParteNomeDecorador = this.consumir(pitugues_2.default.IDENTIFICADOR, 'Esperado nome de decorador após "@".');
7542
+ let linha;
7543
+ let nomeDecorador = '@';
7507
7544
  linha = Number(primeiraParteNomeDecorador.linha);
7508
7545
  nomeDecorador += primeiraParteNomeDecorador.lexema;
7509
7546
  while (this.verificarSeSimboloAtualEIgualA(pitugues_2.default.PONTO)) {
@@ -7511,16 +7548,17 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7511
7548
  nomeDecorador += '.' + parteNomeDecorador.lexema;
7512
7549
  }
7513
7550
  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}`);
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];
7520
7557
  }
7521
- atributos[parametro.nome.lexema] = parametro.valorPadrao;
7522
7558
  }
7523
- 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
+ }
7524
7562
  }
7525
7563
  this.pilhaDecoradores.push(new construtos_1.Decorador(this.hashArquivo, linha, nomeDecorador, atributos));
7526
7564
  }
@@ -7820,6 +7858,21 @@ class AvaliadorSintaticoPitugues extends avaliador_sintatico_base_1.AvaliadorSin
7820
7858
  async resolverMetodoOuConstrutor(simboloAnterior, metodos) {
7821
7859
  const ehConstrutor = simboloAnterior.tipo === pitugues_2.default.CONSTRUTOR;
7822
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
+ }
7823
7876
  metodos.push(metodoResolvido);
7824
7877
  }
7825
7878
  async resolverMembroDeClasse(metodos, propriedadesDeClasse) {
@@ -21962,7 +22015,7 @@ class InterpretadorBase {
21962
22015
  */
21963
22016
  resolverNomeObjectoAcessado(objetoAcessado) {
21964
22017
  switch (objetoAcessado.constructor) {
21965
- // 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.
21966
22019
  /* case AcessoMetodoOuPropriedade:
21967
22020
  return (objetoAcessado as AcessoMetodoOuPropriedade).simbolo.lexema;
21968
22021
  case AcessoIndiceVariavel:
@@ -21980,6 +22033,7 @@ class InterpretadorBase {
21980
22033
  case construtos_1.Dicionario:
21981
22034
  case construtos_1.Leia:
21982
22035
  case construtos_1.Literal:
22036
+ case construtos_1.Unario:
21983
22037
  case construtos_1.Vetor:
21984
22038
  return '';
21985
22039
  case construtos_1.Isto:
@@ -22303,6 +22357,7 @@ class InterpretadorBase {
22303
22357
  this.verificarOperandoNumero(expressao.operador, valor);
22304
22358
  return -valor;
22305
22359
  case delegua_1.default.NEGACAO:
22360
+ case delegua_1.default.NAO:
22306
22361
  return !this.eVerdadeiro(valor);
22307
22362
  case delegua_1.default.BIT_NOT:
22308
22363
  if (typeof valor === 'bigint') {
@@ -22548,8 +22603,8 @@ class InterpretadorBase {
22548
22603
  if (valorEsquerdo === null || valorDireito === null) {
22549
22604
  return this.paraTexto(valorEsquerdo) + this.paraTexto(valorDireito);
22550
22605
  }
22551
- // TODO: Se tipo for 'qualquer', seria uma boa confiar nos operadores
22552
- // 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.
22553
22608
  if (tipoEsquerdo === 'qualquer' || tipoDireito === 'qualquer') {
22554
22609
  return valorEsquerdo + valorDireito;
22555
22610
  }
@@ -22782,8 +22837,12 @@ class InterpretadorBase {
22782
22837
  }
22783
22838
  if (entidadeChamada instanceof estruturas_1.FuncaoPadrao) {
22784
22839
  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
- );
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);
22787
22846
  }
22788
22847
  catch (erro) {
22789
22848
  if (this.emDeclaracaoTente) {
@@ -22820,7 +22879,6 @@ class InterpretadorBase {
22820
22879
  if (typeof entidadeChamada === primitivos_1.default.FUNCAO) {
22821
22880
  let objeto = null;
22822
22881
  if (expressao.entidadeChamada.objeto) {
22823
- // TODO: Qual o tipo certo aqui?
22824
22882
  objeto = await this.avaliar(expressao.entidadeChamada.objeto);
22825
22883
  }
22826
22884
  return entidadeChamada.apply(this.resolverValor(objeto), argumentos);
@@ -23041,10 +23099,9 @@ class InterpretadorBase {
23041
23099
  const vetorResolvido = await this.avaliar(declaracao.vetorOuDicionario);
23042
23100
  let valorVetorResolvido = this.resolverValor(vetorResolvido);
23043
23101
  // 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.
23102
+ // para vetor de duplas com elementos envoltos em Literal, preservando tipo.
23046
23103
  if (declaracao.vetorOuDicionario.tipo === 'dicionário') {
23047
- 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]))));
23048
23105
  }
23049
23106
  if (!Array.isArray(valorVetorResolvido)) {
23050
23107
  return Promise.reject("Variável ou literal provida em instrução 'para cada' não é um vetor.");
@@ -23060,13 +23117,11 @@ class InterpretadorBase {
23060
23117
  }
23061
23118
  if (declaracao.variavelIteracao instanceof construtos_1.Dupla) {
23062
23119
  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);
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));
23070
23125
  }
23071
23126
  retornoExecucao = await this.executar(declaracao.corpo);
23072
23127
  if (retornoExecucao && retornoExecucao.valorRetornado instanceof quebras_1.SustarQuebra) {
@@ -23554,14 +23609,14 @@ class InterpretadorBase {
23554
23609
  }
23555
23610
  mesclaResolvidas.push(misturável);
23556
23611
  }
23557
- // 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).
23558
23614
  this.pilhaEscoposExecucao.definirVariavel(declaracao.simbolo.lexema, declaracao);
23559
23615
  if (superClassesResolvidas.length > 0) {
23560
23616
  this.pilhaEscoposExecucao.definirVariavel('super', superClassesResolvidas[0]);
23561
23617
  }
23562
23618
  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.
23619
+ // A única exceção a isso até então é Égua Clássico, que requer declaração de propriedades.
23565
23620
  descritorTipoClasse.dialetoRequerDeclaracaoPropriedades = this.requerDeclaracaoPropriedades;
23566
23621
  this.pilhaEscoposExecucao.atribuirVariavel(declaracao.simbolo, descritorTipoClasse);
23567
23622
  return descritorTipoClasse;
@@ -23717,11 +23772,9 @@ class InterpretadorBase {
23717
23772
  if (Array.isArray(objeto)) {
23718
23773
  if (expressao.simbolo.lexema in primitivas_vetor_1.default) {
23719
23774
  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.
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.
23725
23778
  return new metodo_primitiva_1.MetodoPrimitiva(nomeObjeto, objeto, metodoDePrimitivaVetor, expressao.simbolo.lexema, tipoObjeto);
23726
23779
  }
23727
23780
  }
@@ -23794,12 +23847,6 @@ class InterpretadorBase {
23794
23847
  tipoResolvido = (0, inferenciador_1.inferirTipoVariavel)(valorFinal);
23795
23848
  }
23796
23849
  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
23850
  return null;
23804
23851
  }
23805
23852
  /**
@@ -24442,9 +24489,28 @@ class Interpretador extends interpretador_base_1.InterpretadorBase {
24442
24489
  const nomeDecorador = decorador.nome.slice(1);
24443
24490
  const variavelDecoradora = this.pilhaEscoposExecucao.obterVariavelPorNome(nomeDecorador);
24444
24491
  const funcaoDecoradora = variavelDecoradora.valor;
24445
- const resultado = await funcaoDecoradora.chamar(this, [
24446
- { nome: '', valor: funcao },
24447
- ]);
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);
24448
24514
  funcao = this.resolverValorRecursivo(resultado);
24449
24515
  }
24450
24516
  }
@@ -24699,7 +24765,7 @@ class Interpretador extends interpretador_base_1.InterpretadorBase {
24699
24765
  const metodoFinalizar = retornoInicializacaoResolvido.classe.encontrarMetodo('finalizar');
24700
24766
  if (metodoFinalizar) {
24701
24767
  const chamavel = metodoFinalizar.funcaoPorMetodoDeClasse(retornoInicializacaoResolvido);
24702
- chamavel.chamar(this, []);
24768
+ await chamavel.chamar(this, []);
24703
24769
  }
24704
24770
  }
24705
24771
  return null;
@@ -29104,366 +29170,117 @@ Object.defineProperty(exports, "__esModule", { value: true });
29104
29170
  exports.Lexador = void 0;
29105
29171
  const browser_process_hrtime_1 = __importDefault(require("browser-process-hrtime"));
29106
29172
  const simbolo_1 = require("./simbolo");
29173
+ const lexador_base_1 = require("./lexador-base");
29107
29174
  const palavras_reservadas_1 = require("./palavras-reservadas");
29108
29175
  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 {
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 {
29116
29200
  constructor(performance = false) {
29117
- this.codigo = [];
29201
+ super();
29202
+ this.regexAlfabeto = /[a-zA-Z_áàâãéèêíïóôõöúçñÁÀÂÃÉÈÊÍÏÓÔÕÖÚÇÑ]/;
29203
+ this.regexEmoji = /\p{Extended_Pictographic}(?:\uFE0F|\u200D\p{Extended_Pictographic})*/u;
29118
29204
  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
29205
  }
29126
- eDigito(caractere) {
29127
- return caractere >= '0' && caractere <= '9';
29206
+ eAlfabeto(c) {
29207
+ return this.regexAlfabeto.test(c);
29128
29208
  }
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
- }
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;
29188
- }
29189
- eFinalDoCodigo() {
29190
- return this.eUltimaLinha() && this.codigo[this.codigo.length - 1].length <= this.atual;
29209
+ eEmoji(c) {
29210
+ return this.regexEmoji.test(c);
29191
29211
  }
29192
29212
  avancar() {
29193
- const linha = this.codigo[this.linha];
29194
- const codePoint = linha.codePointAt(this.atual);
29213
+ const codePoint = this.codigo[this.linha].codePointAt(this.atual);
29195
29214
  this.atual += codePoint && codePoint > 0xffff ? 2 : 1;
29196
29215
  if (this.eFinalDaLinha() && !this.eUltimaLinha()) {
29197
29216
  this.linha++;
29198
29217
  this.atual = 0;
29199
29218
  }
29200
29219
  }
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
29220
  simboloAtual() {
29211
29221
  if (this.eFinalDaLinha())
29212
29222
  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());
29223
+ const codePoint = this.codigo[this.linha].codePointAt(this.atual);
29224
+ return codePoint === undefined ? '\0' : String.fromCodePoint(codePoint);
29281
29225
  }
29282
29226
  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);
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);
29291
29230
  }
29292
29231
  simboloAnterior() {
29293
29232
  const linha = this.codigo[this.linha];
29294
- const indiceAnterior = this.atual -
29295
- (linha.codePointAt(this.atual - 2) > 0xffff ? 2 : 1);
29233
+ const indiceAnterior = this.atual - (linha.codePointAt(this.atual - 2) > 0xffff ? 2 : 1);
29296
29234
  const codePoint = linha.codePointAt(indiceAnterior);
29297
- if (codePoint === undefined) {
29298
- return '\0';
29299
- }
29235
+ return codePoint === undefined ? '\0' : String.fromCodePoint(codePoint);
29300
29236
  }
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
- });
29387
- }
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
- }
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));
29406
29242
  }
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
- }
29243
+ verificarEAvancar(esperado) {
29244
+ if (this.eFinalDaLinha() || this.simboloAtual() !== esperado)
29245
+ return false;
29246
+ this.avancar();
29247
+ return true;
29425
29248
  }
29426
- analisarOctal() {
29249
+ analisarBaseNumerica(validadorDigito, tipoErro) {
29427
29250
  this.avancar(); // Pula '0'
29428
- this.avancar(); // Pula 'o' ou 'O'
29429
- while (this.eOctalDigito(this.simboloAtual())) {
29251
+ this.avancar(); // Pula 'x', 'b' ou 'o'
29252
+ while (validadorDigito.call(this, this.simboloAtual())) {
29430
29253
  this.avancar();
29431
29254
  }
29432
- const octalString = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29255
+ const texto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29433
29256
  try {
29434
- const bigintValue = BigInt(octalString);
29435
- this.adicionarSimbolo(delegua_1.default.NUMERO, bigintValue);
29257
+ this.adicionarSimbolo(delegua_1.default.NUMERO, BigInt(texto));
29436
29258
  }
29437
29259
  catch (e) {
29438
29260
  this.erros.push({
29439
29261
  linha: this.linha + 1,
29440
29262
  caractere: this.simboloAnterior(),
29441
- mensagem: `Literal octal inválido: ${octalString}`,
29263
+ mensagem: `Literal ${tipoErro} inválido: ${texto}`
29442
29264
  });
29443
29265
  }
29444
29266
  }
29445
29267
  analisarNumero() {
29446
- // Verifica se é um literal especial (hexadecimal, binário ou octal)
29447
29268
  if (this.simboloAtual() === '0') {
29448
- const proximoChar = this.proximoSimbolo();
29449
- if (proximoChar === 'x' || proximoChar === 'X') {
29450
- this.analisarHexadecimal();
29451
- return;
29269
+ const prox = this.proximoSimbolo().toLowerCase();
29270
+ if (prox === 'x') {
29271
+ return this.analisarBaseNumerica(this.eHexDigito, 'hexadecimal');
29452
29272
  }
29453
- else if (proximoChar === 'b' || proximoChar === 'B') {
29454
- this.analisarBinario();
29455
- return;
29273
+ if (prox === 'b') {
29274
+ return this.analisarBaseNumerica(this.eBinarioDigito, 'binário');
29456
29275
  }
29457
- else if (proximoChar === 'o' || proximoChar === 'O') {
29458
- this.analisarOctal();
29459
- return;
29276
+ if (prox === 'o') {
29277
+ return this.analisarBaseNumerica(this.eOctalDigito, 'octal');
29460
29278
  }
29461
29279
  }
29462
- // Análise de número decimal normal
29463
29280
  while (this.eDigito(this.simboloAtual())) {
29464
29281
  this.avancar();
29465
29282
  }
29466
- if (this.simboloAtual() == '.' && this.eDigito(this.proximoSimbolo())) {
29283
+ if (this.simboloAtual() === '.' && this.eDigito(this.proximoSimbolo())) {
29467
29284
  this.avancar();
29468
29285
  while (this.eDigito(this.simboloAtual())) {
29469
29286
  this.avancar();
@@ -29472,155 +29289,222 @@ class Lexador {
29472
29289
  const numeroCompleto = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29473
29290
  this.adicionarSimbolo(delegua_1.default.NUMERO, parseFloat(numeroCompleto));
29474
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
+ }
29475
29356
  identificarPalavraChave() {
29476
29357
  while (this.eAlfabetoOuDigito(this.simboloAtual())) {
29477
29358
  this.avancar();
29478
29359
  }
29479
29360
  const codigo = this.codigo[this.linha].substring(this.inicioSimbolo, this.atual);
29480
- const tipo = codigo in palavras_reservadas_1.palavrasReservadasDelegua
29361
+ this.adicionarSimbolo(codigo in palavras_reservadas_1.palavrasReservadasDelegua
29481
29362
  ? 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);
29363
+ : delegua_1.default.IDENTIFICADOR);
29488
29364
  }
29489
29365
  analisarEmoji() {
29490
- const simboloAtual = this.simboloAtual();
29491
29366
  this.erros.push({
29492
29367
  linha: this.linha + 1,
29493
- caractere: simboloAtual,
29494
- mensagem: 'Emojis devem estar envoltos por aspas.',
29368
+ caractere: this.simboloAtual(),
29369
+ mensagem: 'Emojis devem estar envoltos por aspas.'
29495
29370
  });
29496
29371
  this.avancar();
29497
29372
  }
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();
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()));
29528
29392
  break;
29529
- case ',':
29530
- this.adicionarSimbolo(delegua_1.default.VIRGULA, ',');
29531
- 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 '/'
29532
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) {
29533
29440
  case '.':
29534
- this.inicioSimbolo = this.atual;
29535
29441
  this.avancar();
29536
- if (this.simboloAtual() === '.') {
29537
- this.avancar();
29538
- if (this.simboloAtual() !== '.') {
29442
+ if (this.verificarEAvancar('.')) {
29443
+ if (this.verificarEAvancar('.')) {
29444
+ this.adicionarSimbolo(delegua_1.default.RETICENCIAS, '...');
29445
+ }
29446
+ else {
29539
29447
  this.erros.push({
29540
29448
  linha: this.linha + 1,
29541
29449
  caractere: this.simboloAtual(),
29542
- 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.'
29543
29451
  });
29544
29452
  this.adicionarSimbolo(delegua_1.default.PONTO, '.');
29545
29453
  }
29546
- else {
29547
- this.avancar();
29548
- this.adicionarSimbolo(delegua_1.default.RETICENCIAS, '...');
29549
- }
29550
29454
  }
29551
29455
  else {
29552
29456
  this.adicionarSimbolo(delegua_1.default.PONTO, '.');
29553
29457
  }
29554
29458
  break;
29555
29459
  case '-':
29556
- this.inicioSimbolo = this.atual;
29557
29460
  this.avancar();
29558
- if (this.simboloAtual() === '=') {
29461
+ if (this.verificarEAvancar('=')) {
29559
29462
  this.adicionarSimbolo(delegua_1.default.MENOS_IGUAL, '-=');
29560
- this.avancar();
29561
29463
  }
29562
- else if (this.simboloAtual() === '-') {
29464
+ else if (this.verificarEAvancar('-')) {
29563
29465
  this.adicionarSimbolo(delegua_1.default.DECREMENTAR, '--');
29564
- this.avancar();
29565
29466
  }
29566
29467
  else {
29567
29468
  this.adicionarSimbolo(delegua_1.default.SUBTRACAO);
29568
29469
  }
29569
29470
  break;
29570
29471
  case '+':
29571
- this.inicioSimbolo = this.atual;
29572
29472
  this.avancar();
29573
- if (this.simboloAtual() === '=') {
29473
+ if (this.verificarEAvancar('=')) {
29574
29474
  this.adicionarSimbolo(delegua_1.default.MAIS_IGUAL, '+=');
29575
- this.avancar();
29576
29475
  }
29577
- else if (this.simboloAtual() === '+') {
29476
+ else if (this.verificarEAvancar('+')) {
29578
29477
  this.adicionarSimbolo(delegua_1.default.INCREMENTAR, '++');
29579
- this.avancar();
29580
29478
  }
29581
29479
  else {
29582
29480
  this.adicionarSimbolo(delegua_1.default.ADICAO);
29583
29481
  }
29584
29482
  break;
29585
- case ':':
29586
- this.adicionarSimbolo(delegua_1.default.DOIS_PONTOS);
29587
- this.avancar();
29588
- break;
29589
29483
  case '%':
29590
- this.inicioSimbolo = this.atual;
29591
29484
  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;
29485
+ if (this.verificarEAvancar('=')) {
29486
+ this.adicionarSimbolo(delegua_1.default.MODULO_IGUAL, '%=');
29487
+ }
29488
+ else {
29489
+ this.adicionarSimbolo(delegua_1.default.MODULO);
29600
29490
  }
29601
29491
  break;
29602
29492
  case '*':
29603
- this.inicioSimbolo = this.atual;
29604
29493
  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;
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);
29617
29502
  }
29618
29503
  break;
29619
29504
  case '!':
29620
29505
  this.avancar();
29621
- if (this.simboloAtual() === '=') {
29506
+ if (this.verificarEAvancar('=')) {
29622
29507
  this.adicionarSimbolo(delegua_1.default.DIFERENTE, '!=');
29623
- this.avancar();
29624
29508
  }
29625
29509
  else {
29626
29510
  this.adicionarSimbolo(delegua_1.default.NEGACAO);
@@ -29628,49 +29512,32 @@ class Lexador {
29628
29512
  break;
29629
29513
  case '=':
29630
29514
  this.avancar();
29631
- if (this.simboloAtual() === '=') {
29515
+ if (this.verificarEAvancar('=')) {
29632
29516
  this.adicionarSimbolo(delegua_1.default.IGUAL_IGUAL, '==');
29633
- this.avancar();
29634
29517
  }
29635
29518
  else {
29636
29519
  this.adicionarSimbolo(delegua_1.default.IGUAL);
29637
29520
  }
29638
29521
  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
29522
  case '|':
29648
29523
  this.avancar();
29649
- if (this.simboloAtual() === '|') {
29524
+ if (this.verificarEAvancar('|')) {
29650
29525
  this.adicionarSimbolo(delegua_1.default.EXPRESSAO_REGULAR, '||');
29651
- this.avancar();
29652
29526
  }
29653
29527
  else {
29654
29528
  this.adicionarSimbolo(delegua_1.default.BIT_OR);
29655
29529
  }
29656
29530
  break;
29657
- case '^':
29658
- this.adicionarSimbolo(delegua_1.default.CIRCUMFLEXO);
29659
- this.avancar();
29660
- break;
29661
29531
  case '<':
29662
29532
  this.avancar();
29663
- if (this.simboloAtual() === '=') {
29533
+ if (this.verificarEAvancar('=')) {
29664
29534
  this.adicionarSimbolo(delegua_1.default.MENOR_IGUAL, '<=');
29665
- this.avancar();
29666
29535
  }
29667
- else if (this.simboloAtual() === '<') {
29536
+ else if (this.verificarEAvancar('<')) {
29668
29537
  this.adicionarSimbolo(delegua_1.default.MENOR_MENOR, '<<');
29669
- this.avancar();
29670
29538
  }
29671
- else if (this.simboloAtual() === '-') {
29539
+ else if (this.verificarEAvancar('-')) {
29672
29540
  this.adicionarSimbolo(delegua_1.default.SETA_ESQUERDA, '<-');
29673
- this.avancar();
29674
29541
  }
29675
29542
  else {
29676
29543
  this.adicionarSimbolo(delegua_1.default.MENOR);
@@ -29678,13 +29545,11 @@ class Lexador {
29678
29545
  break;
29679
29546
  case '>':
29680
29547
  this.avancar();
29681
- if (this.simboloAtual() === '=') {
29548
+ if (this.verificarEAvancar('=')) {
29682
29549
  this.adicionarSimbolo(delegua_1.default.MAIOR_IGUAL, '>=');
29683
- this.avancar();
29684
29550
  }
29685
- else if (this.simboloAtual() === '>') {
29551
+ else if (this.verificarEAvancar('>')) {
29686
29552
  this.adicionarSimbolo(delegua_1.default.MAIOR_MAIOR, '>>');
29687
- this.avancar();
29688
29553
  }
29689
29554
  else {
29690
29555
  this.adicionarSimbolo(delegua_1.default.MAIOR);
@@ -29692,81 +29557,57 @@ class Lexador {
29692
29557
  break;
29693
29558
  case '/':
29694
29559
  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;
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);
29714
29576
  }
29715
29577
  break;
29716
29578
  case '\\':
29717
- this.inicioSimbolo = this.atual;
29718
29579
  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;
29580
+ if (this.verificarEAvancar('=')) {
29581
+ this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA_IGUAL, '\\=');
29582
+ }
29583
+ else {
29584
+ this.adicionarSimbolo(delegua_1.default.DIVISAO_INTEIRA);
29727
29585
  }
29728
29586
  break;
29729
29587
  case '?':
29730
29588
  this.avancar();
29731
- if (this.simboloAtual() === ':') {
29589
+ if (this.verificarEAvancar(':')) {
29732
29590
  this.adicionarSimbolo(delegua_1.default.ELVIS, '?:');
29733
- this.avancar();
29734
29591
  }
29735
29592
  else {
29736
29593
  this.adicionarSimbolo(delegua_1.default.INTERROGACAO);
29737
29594
  }
29738
29595
  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
29596
  default:
29759
- if (this.eDigito(caractere))
29597
+ if (this.eDigito(c)) {
29760
29598
  this.analisarNumero();
29761
- else if (this.eEmoji(caractere))
29599
+ }
29600
+ else if (this.eEmoji(c)) {
29762
29601
  this.analisarEmoji();
29763
- else if (this.eAlfabeto(caractere))
29602
+ }
29603
+ else if (this.eAlfabeto(c)) {
29764
29604
  this.identificarPalavraChave();
29605
+ }
29765
29606
  else {
29766
29607
  this.erros.push({
29767
29608
  linha: this.linha + 1,
29768
- caractere: caractere,
29769
- mensagem: 'Caractere inesperado.',
29609
+ caractere: c,
29610
+ mensagem: 'Caractere inesperado.'
29770
29611
  });
29771
29612
  this.avancar();
29772
29613
  }
@@ -29779,16 +29620,12 @@ class Lexador {
29779
29620
  this.inicioSimbolo = 0;
29780
29621
  this.atual = 0;
29781
29622
  this.linha = 0;
29782
- this.codigo = codigo || [''];
29783
- if (codigo.length === 0) {
29784
- this.codigo = [''];
29785
- }
29623
+ this.codigo = codigo && codigo.length > 0 ? codigo : [''];
29786
29624
  this.hashArquivo = hashArquivo;
29787
29625
  for (let iterador = 0; iterador < this.codigo.length; iterador++) {
29788
29626
  this.codigo[iterador] += '\0';
29789
29627
  }
29790
29628
  while (!this.eFinalDoCodigo()) {
29791
- this.inicioSimbolo = this.atual;
29792
29629
  this.analisarToken();
29793
29630
  }
29794
29631
  if (this.performance) {
@@ -29798,13 +29635,13 @@ class Lexador {
29798
29635
  }
29799
29636
  return {
29800
29637
  simbolos: this.simbolos,
29801
- erros: this.erros,
29638
+ erros: this.erros
29802
29639
  };
29803
29640
  }
29804
29641
  }
29805
29642
  exports.Lexador = Lexador;
29806
29643
 
29807
- },{"../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){
29808
29645
  "use strict";
29809
29646
  var __importDefault = (this && this.__importDefault) || function (mod) {
29810
29647
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -53408,7 +53245,7 @@ class TradutorRuby {
53408
53245
  if (definirValor.objeto instanceof construtos_1.Isto) {
53409
53246
  resultado = '@' + definirValor.nome.lexema + ' = ';
53410
53247
  }
53411
- resultado += definirValor.valor.simbolo.lexema;
53248
+ resultado += this.dicionarioConstrutos[definirValor.valor.constructor.name](definirValor.valor);
53412
53249
  return resultado;
53413
53250
  }
53414
53251
  traduzirConstrutoDicionario(dicionario) {