Skip to content

Commit

Permalink
Merge pull request #558 from DesignLiquido/desestruturacao-leonel
Browse files Browse the repository at this point in the history
Desestruturação de variáveis e constantes
  • Loading branch information
samuelrvg authored Dec 12, 2023
2 parents f6a0550 + 5eec501 commit 99acb73
Show file tree
Hide file tree
Showing 21 changed files with 177 additions and 45 deletions.
75 changes: 72 additions & 3 deletions fontes/avaliador-sintatico/avaliador-sintatico.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import hrtime from 'browser-process-hrtime';

import { AvaliadorSintaticoInterface, ParametroInterface, SimboloInterface } from '../interfaces';
import {
AcessoMetodo as AcessoMetodo,
AcessoMetodoOuPropriedade as AcessoMetodoOuPropriedade,
Agrupamento,
AtribuicaoPorIndice,
Atribuir,
Expand Down Expand Up @@ -329,7 +329,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
expressao = this.finalizarChamada(expressao);
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO)) {
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome do método após '.'.");
expressao = new AcessoMetodo(this.hashArquivo, expressao, nome);
expressao = new AcessoMetodoOuPropriedade(this.hashArquivo, expressao, nome);
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
const indice = this.expressao();
const simboloFechamento = this.consumir(
Expand Down Expand Up @@ -551,7 +551,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
if (expressao instanceof Variavel) {
const simbolo = expressao.simbolo;
return new Atribuir(this.hashArquivo, simbolo, valor);
} else if (expressao instanceof AcessoMetodo) {
} else if (expressao instanceof AcessoMetodoOuPropriedade) {
const get = expressao;
return new DefinirValor(this.hashArquivo, igual.linha, get.objeto, get.simbolo, valor);
} else if (expressao instanceof AcessoIndiceVariavel) {
Expand Down Expand Up @@ -1012,6 +1012,36 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
return this.declaracaoExpressao();
}

protected declaracaoDesestruturacaoVariavel(): Declaracao[] {
const identificadores: SimboloInterface[] = [];

do {
identificadores.push(this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome da variável.'));
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));

this.consumir(tiposDeSimbolos.CHAVE_DIREITA, 'Esperado chave direita para concluir relação de variáveis a serem desestruturadas.');
this.consumir(tiposDeSimbolos.IGUAL, "Esperado igual após relação de propriedades da desestruturação.");

const inicializador = this.expressao();
// TODO: Para cada variável dos identificadores, emitir um `AcessoMetodoOuPropriedade` usando
// como prefixo o nome do inicializador, e o sufixo o nome de cada propriedade.
const retornos = [];
for (let identificador of identificadores) {
retornos.push(
new Var(
identificador,
new AcessoMetodoOuPropriedade(
this.hashArquivo,
inicializador,
identificador
)
)
);
}

return retornos;
}

/**
* Caso símbolo atual seja `var`, devolve uma declaração de variável.
* @returns Um Construto do tipo Var.
Expand All @@ -1021,6 +1051,10 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
let retorno: Declaracao[] = [];
let tipo: any = null;

if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CHAVE_ESQUERDA)) {
return this.declaracaoDesestruturacaoVariavel();
}

do {
identificadores.push(this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome da variável.'));
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
Expand All @@ -1031,6 +1065,7 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
}

if (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.IGUAL)) {
// Inicialização de variáveis sem valor.
for (let [indice, identificador] of identificadores.entries()) {
retorno.push(new Var(identificador, null, tipo));
}
Expand Down Expand Up @@ -1059,6 +1094,36 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
return retorno;
}

protected declaracaoDesestruturacaoConstante(): Declaracao[] {
const identificadores: SimboloInterface[] = [];

do {
identificadores.push(this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome da variável.'));
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));

this.consumir(tiposDeSimbolos.CHAVE_DIREITA, 'Esperado chave direita para concluir relação de variáveis a serem desestruturadas.');
this.consumir(tiposDeSimbolos.IGUAL, "Esperado igual após relação de propriedades da desestruturação.");

const inicializador = this.expressao();
// TODO: Para cada variável dos identificadores, emitir um `AcessoMetodoOuPropriedade` usando
// como prefixo o nome do inicializador, e o sufixo o nome de cada propriedade.
const retornos = [];
for (let identificador of identificadores) {
retornos.push(
new Const(
identificador,
new AcessoMetodoOuPropriedade(
this.hashArquivo,
inicializador,
identificador
)
)
);
}

return retornos;
}

/**
* Caso símbolo atual seja `const, constante ou fixo`, devolve uma declaração de const.
* @returns Um Construto do tipo Const.
Expand All @@ -1067,6 +1132,10 @@ export class AvaliadorSintatico implements AvaliadorSintaticoInterface<SimboloIn
const identificadores: SimboloInterface[] = [];
let tipo: any = null;

if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.CHAVE_ESQUERDA)) {
return this.declaracaoDesestruturacaoConstante();
}

do {
identificadores.push(this.consumir(tiposDeSimbolos.IDENTIFICADOR, 'Esperado nome da constante.'));
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
AcessoIndiceVariavel,
AcessoMetodo,
AcessoMetodoOuPropriedade,
Agrupamento,
AtribuicaoPorIndice,
Atribuir,
Expand Down Expand Up @@ -178,7 +178,7 @@ export class AvaliadorSintaticoBirl extends AvaliadorSintaticoBase {
if (expressao instanceof Variavel) {
const simbolo = expressao.simbolo;
return new Atribuir(this.hashArquivo, simbolo, valor);
} else if (expressao instanceof AcessoMetodo) {
} else if (expressao instanceof AcessoMetodoOuPropriedade) {
const get = expressao;
return new DefinirValor(this.hashArquivo, 0, get.objeto, get.simbolo, valor);
} else if (expressao instanceof AcessoIndiceVariavel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
Dicionario,
DefinirValor,
FuncaoConstruto,
AcessoMetodo,
AcessoMetodoOuPropriedade,
Agrupamento,
Literal,
Logico,
Expand Down Expand Up @@ -247,7 +247,7 @@ export class AvaliadorSintaticoEguaClassico implements AvaliadorSintaticoInterfa
expressao = this.finalizarChamada(expressao);
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO)) {
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome do método após '.'.");
expressao = new AcessoMetodo(this.hashArquivo, expressao, nome);
expressao = new AcessoMetodoOuPropriedade(this.hashArquivo, expressao, nome);
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
const indice = this.expressao();
const simboloFechamento = this.consumir(
Expand Down Expand Up @@ -434,7 +434,7 @@ export class AvaliadorSintaticoEguaClassico implements AvaliadorSintaticoInterfa
if (expressao instanceof Variavel) {
const simbolo = expressao.simbolo;
return new Atribuir(this.hashArquivo, simbolo, valor);
} else if (expressao instanceof AcessoMetodo) {
} else if (expressao instanceof AcessoMetodoOuPropriedade) {
const get = expressao;
return new DefinirValor(this.hashArquivo, 0, get.objeto, get.simbolo, valor);
} else if (expressao instanceof AcessoIndiceVariavel) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
AcessoIndiceVariavel,
AcessoMetodo,
AcessoMetodoOuPropriedade,
AtribuicaoPorIndice,
Atribuir,
Binario,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import hrtime from 'browser-process-hrtime';

import {
AcessoIndiceVariavel,
AcessoMetodo,
AcessoMetodoOuPropriedade,
Agrupamento,
AtribuicaoPorIndice,
Atribuir,
Expand Down Expand Up @@ -305,7 +305,7 @@ export class AvaliadorSintaticoPitugues implements AvaliadorSintaticoInterface<S
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO)) {
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome do método após '.'.");

expressao = new AcessoMetodo(this.hashArquivo, expressao, nome);
expressao = new AcessoMetodoOuPropriedade(this.hashArquivo, expressao, nome);
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
const indice = this.expressao();
const simboloFechamento = this.consumir(
Expand Down Expand Up @@ -497,7 +497,7 @@ export class AvaliadorSintaticoPitugues implements AvaliadorSintaticoInterface<S
if (expressao instanceof Variavel) {
const simbolo = expressao.simbolo;
return new Atribuir(this.hashArquivo, simbolo, valor);
} else if (expressao instanceof AcessoMetodo) {
} else if (expressao instanceof AcessoMetodoOuPropriedade) {
return new DefinirValor(this.hashArquivo, 0, expressao.objeto, expressao.simbolo, valor);
} else if (expressao instanceof AcessoIndiceVariavel) {
return new AtribuicaoPorIndice(this.hashArquivo, 0, expressao.entidadeChamada, expressao.indice, valor);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
AcessoIndiceVariavel,
AcessoMetodo,
AcessoMetodoOuPropriedade,
Agrupamento,
Atribuir,
Binario,
Expand Down Expand Up @@ -420,7 +420,7 @@ export class AvaliadorSintaticoPotigol extends AvaliadorSintaticoBase {
} else {
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome do método após '.'.");
const variavelMetodo = new Variavel(expressao.hashArquivo, (expressao as any).simbolo);
expressao = new AcessoMetodo(this.hashArquivo, variavelMetodo, nome);
expressao = new AcessoMetodoOuPropriedade(this.hashArquivo, variavelMetodo, nome);
}
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
const indice = this.expressao();
Expand Down
4 changes: 2 additions & 2 deletions fontes/avaliador-sintatico/micro-avaliador-sintatico.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
AcessoIndiceVariavel,
AcessoMetodo,
AcessoMetodoOuPropriedade,
Agrupamento,
Binario,
Chamada,
Expand Down Expand Up @@ -186,7 +186,7 @@ export class MicroAvaliadorSintatico extends MicroAvaliadorSintaticoBase {
expressao = this.finalizarChamada(expressao);
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PONTO)) {
const nome = this.consumir(tiposDeSimbolos.IDENTIFICADOR, "Esperado nome do método após '.'.");
expressao = new AcessoMetodo(-1, expressao, nome);
expressao = new AcessoMetodoOuPropriedade(-1, expressao, nome);
} else if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.COLCHETE_ESQUERDO)) {
const indice = this.ou();
const simboloFechamento = this.consumir(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Construto } from './construto';
* Chamado de `Get` em Égua Clássico, é o construto de acesso a métodos ou membros de
* classe.
*/
export class AcessoMetodo implements Construto {
export class AcessoMetodoOuPropriedade implements Construto {
linha: number;
hashArquivo: number;

Expand Down
2 changes: 1 addition & 1 deletion fontes/construtos/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from './acesso-indice-variavel';
export * from './acesso-metodo';
export * from './acesso-metodo-ou-propriedade';
export * from './agrupamento';
export * from './atribuicao-por-indice';
export * from './atribuir';
Expand Down
2 changes: 2 additions & 0 deletions fontes/declaracoes/var.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ export class Var extends Declaracao {
inicializador: Construto;
tipo: TiposDadosInterface;
referencia: boolean;
desestruturacao: boolean;

constructor(simbolo: SimboloInterface, inicializador: Construto, tipo: TiposDadosInterface = undefined) {
super(Number(simbolo.linha), simbolo.hashArquivo);
this.simbolo = simbolo;
this.inicializador = inicializador;
this.tipo = tipo;
this.referencia = false;
this.desestruturacao = false;
}

async aceitar(visitante: VisitanteComumInterface): Promise<any> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AcessoMetodo, Construto, ExpressaoRegular, FimPara, FormatacaoEscrita, QualTipo, Super, TipoDe, Variavel } from '../../../../construtos';
import { AcessoMetodoOuPropriedade, Construto, ExpressaoRegular, FimPara, FormatacaoEscrita, QualTipo, Super, TipoDe, Variavel } from '../../../../construtos';
import {
Bloco,
Const,
Expand Down Expand Up @@ -337,7 +337,7 @@ export class ResolvedorEguaClassico implements ResolvedorInterface, Interpretado
return null;
}

visitarExpressaoAcessoMetodo(expressao: AcessoMetodo): any {
visitarExpressaoAcessoMetodo(expressao: AcessoMetodoOuPropriedade): any {
this.resolver(expressao.objeto);
return null;
}
Expand Down
4 changes: 2 additions & 2 deletions fontes/interpretador/dialetos/potigol/comum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AcessoMetodo } from '../../../construtos';
import { AcessoMetodoOuPropriedade } from '../../../construtos';
import { DeleguaModulo, MetodoPrimitiva, ObjetoDeleguaClasse } from '../../../estruturas';
import { VariavelInterface } from '../../../interfaces';
import { inferirTipoVariavel } from './inferenciador';
Expand All @@ -16,7 +16,7 @@ import { InterpretadorBase } from '../../interpretador-base';
*/
export async function visitarExpressaoAcessoMetodo(
interpretador: InterpretadorBase,
expressao: AcessoMetodo
expressao: AcessoMetodoOuPropriedade
): Promise<any> {
const variavelObjeto: VariavelInterface = await interpretador.avaliar(expressao.objeto);
const objeto = variavelObjeto.hasOwnProperty('valor') ? variavelObjeto.valor : variavelObjeto;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { registrarBibliotecaGlobalPotigol } from '../../../bibliotecas/dialetos/potigol/biblioteca-global';
import { AcessoMetodo } from '../../../construtos';
import { AcessoMetodoOuPropriedade } from '../../../construtos';
import { InterpretadorComDepuracao } from '../../interpretador-com-depuracao';

import * as comum from './comum';
Expand All @@ -21,7 +21,7 @@ export class InterpretadorPotigolComDepuracao extends InterpretadorComDepuracao
return comum.retirarInterpolacao(texto, variaveis);
}

async visitarExpressaoAcessoMetodo(expressao: AcessoMetodo): Promise<any> {
async visitarExpressaoAcessoMetodo(expressao: AcessoMetodoOuPropriedade): Promise<any> {
return comum.visitarExpressaoAcessoMetodo(this, expressao);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { InterpretadorBase } from '../../interpretador-base';

import { registrarBibliotecaGlobalPotigol } from '../../../bibliotecas/dialetos/potigol/biblioteca-global';
import { AcessoMetodo, Binario, ConstanteOuVariavel, Construto, Literal, QualTipo, Unario, Variavel } from '../../../construtos';
import { AcessoMetodoOuPropriedade, Binario, ConstanteOuVariavel, Construto, Literal, QualTipo, Unario, Variavel } from '../../../construtos';

import * as comum from './comum';
import { ObjetoPadrao } from '../../../estruturas';
Expand Down Expand Up @@ -54,7 +54,7 @@ export class InterpretadorPotigol extends InterpretadorBase implements Interpret
return comum.retirarInterpolacao(texto, variaveis);
}

async visitarExpressaoAcessoMetodo(expressao: AcessoMetodo): Promise<any> {
async visitarExpressaoAcessoMetodo(expressao: AcessoMetodoOuPropriedade): Promise<any> {
return comum.visitarExpressaoAcessoMetodo(this, expressao);
}

Expand Down
2 changes: 1 addition & 1 deletion fontes/tradutores/tradutor-assembly-x64.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ _start:`;

dicionarioConstrutos = {
// AcessoIndiceVariavel: this.traduzirAcessoIndiceVariavel.bind(this),
// AcessoMetodo: this.trazudirConstrutoAcessoMetodo.bind(this),
// AcessoMetodoOuPropriedade: this.trazudirConstrutoAcessoMetodo.bind(this),
// Agrupamento: this.traduzirConstrutoAgrupamento.bind(this),
// AtribuicaoPorIndice: this.traduzirConstrutoAtribuicaoPorIndice.bind(this),
// Atribuir: this.traduzirConstrutoAtribuir.bind(this),
Expand Down
6 changes: 3 additions & 3 deletions fontes/tradutores/tradutor-assemblyscript.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
AcessoIndiceVariavel,
AcessoMetodo,
AcessoMetodoOuPropriedade,
Agrupamento,
AtribuicaoPorIndice,
Atribuir,
Expand Down Expand Up @@ -634,7 +634,7 @@ export class TradutorAssemblyScript {
return this.dicionarioConstrutos[agrupamento.constructor.name](agrupamento.expressao || agrupamento);
}

trazudirConstrutoAcessoMetodo(acessoMetodo: AcessoMetodo): string {
trazudirConstrutoAcessoMetodo(acessoMetodo: AcessoMetodoOuPropriedade): string {
if (acessoMetodo.objeto instanceof Variavel) {
let objetoVariavel = acessoMetodo.objeto as Variavel;
return `${objetoVariavel.simbolo.lexema}.${this.traduzirFuncoesNativas(acessoMetodo.simbolo.lexema)}`;
Expand All @@ -657,7 +657,7 @@ export class TradutorAssemblyScript {

dicionarioConstrutos = {
AcessoIndiceVariavel: this.traduzirAcessoIndiceVariavel.bind(this),
AcessoMetodo: this.trazudirConstrutoAcessoMetodo.bind(this),
AcessoMetodoOuPropriedade: this.trazudirConstrutoAcessoMetodo.bind(this),
Agrupamento: this.traduzirConstrutoAgrupamento.bind(this),
AtribuicaoPorIndice: this.traduzirConstrutoAtribuicaoPorIndice.bind(this),
Atribuir: this.traduzirConstrutoAtribuir.bind(this),
Expand Down
Loading

0 comments on commit 99acb73

Please sign in to comment.