Skip to content

Atualização de Delégua para a versão 0.39.3. #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions fontes/analisador-semantico/analisador-semantico-visualg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { VariavelHipoteticaInterface } from '@designliquido/delegua/interfaces/v
import { RetornoQuebra } from '@designliquido/delegua/quebras';

import { PilhaVariaveis } from './pilha-variaveis';
import { TipoDadosElementar } from '@designliquido/delegua/tipo-dados-elementar';

export class AnalisadorSemanticoVisuAlg extends AnalisadorSemanticoBase {
pilhaVariaveis: PilhaVariaveis;
Expand Down Expand Up @@ -59,24 +60,27 @@ export class AnalisadorSemanticoVisuAlg extends AnalisadorSemanticoBase {
}

visitarExpressaoDeAtribuicao(expressao: Atribuir) {
const { simbolo, valor } = expressao;
let variavel = this.variaveis[simbolo.lexema];
const { alvo, valor } = expressao;
// Provavelmente o alvo é sempre `Variavel`
const alvoVariavel: Variavel = alvo as Variavel;

let variavel = this.variaveis[alvoVariavel.simbolo.lexema];
if (!variavel) {
this.adicionarDiagnostico(simbolo, `Variável ${simbolo.lexema} ainda não foi declarada.`);
this.adicionarDiagnostico(alvoVariavel.simbolo, `Variável ${alvoVariavel.simbolo.lexema} ainda não foi declarada.`);
return Promise.resolve();
}

if (variavel.tipo) {
if (valor instanceof Literal && variavel.tipo.includes('[]')) {
this.adicionarDiagnostico(
simbolo,
alvoVariavel.simbolo,
`Atribuição inválida, esperado tipo '${variavel.tipo}' na atribuição.`
);
return Promise.resolve();
}
if (valor instanceof Vetor && !variavel.tipo.includes('[]')) {
this.adicionarDiagnostico(
simbolo,
alvoVariavel.simbolo,
`Atribuição inválida, esperado tipo '${variavel.tipo}' na atribuição.`
);
return Promise.resolve();
Expand All @@ -87,13 +91,13 @@ export class AnalisadorSemanticoVisuAlg extends AnalisadorSemanticoBase {
if (!['qualquer'].includes(variavel.tipo)) {
if (valorLiteral === 'string') {
if (variavel.tipo.toLowerCase() != 'caractere') {
this.adicionarDiagnostico(simbolo, `Esperado tipo '${variavel.tipo}' na atribuição.`);
this.adicionarDiagnostico(alvoVariavel.simbolo, `Esperado tipo '${variavel.tipo}' na atribuição.`);
return Promise.resolve();
}
}
if (valorLiteral === 'number') {
if (!['inteiro', 'real'].includes(variavel.tipo.toLowerCase())) {
this.adicionarDiagnostico(simbolo, `Esperado tipo '${variavel.tipo}' na atribuição.`);
this.adicionarDiagnostico(alvoVariavel.simbolo, `Esperado tipo '${variavel.tipo}' na atribuição.`);
return Promise.resolve();
}
}
Expand All @@ -102,7 +106,7 @@ export class AnalisadorSemanticoVisuAlg extends AnalisadorSemanticoBase {
}

if (variavel) {
this.variaveis[simbolo.lexema].valor = valor;
this.variaveis[alvoVariavel.simbolo.lexema].valor = valor;
}
}

Expand Down Expand Up @@ -171,7 +175,7 @@ export class AnalisadorSemanticoVisuAlg extends AnalisadorSemanticoBase {
visitarDeclaracaoVar(declaracao: Var): Promise<any> {
this.variaveis[declaracao.simbolo.lexema] = {
imutavel: false,
tipo: declaracao.tipo,
tipo: declaracao.tipo as TipoDadosElementar,
valor:
declaracao.inicializador !== null
? declaracao.inicializador.valor !== undefined
Expand Down Expand Up @@ -201,10 +205,10 @@ export class AnalisadorSemanticoVisuAlg extends AnalisadorSemanticoBase {

visitarDeclaracaoDefinicaoFuncao(declaracao: FuncaoDeclaracao) {
for (let parametro of declaracao.funcao.parametros) {
if (parametro.hasOwnProperty('tipoDado') && !parametro.tipoDado.tipo) {
if (parametro.hasOwnProperty('tipoDado') && !parametro.tipoDado) {
this.adicionarDiagnostico(
declaracao.simbolo,
`O tipo '${parametro.tipoDado.tipoInvalido}' não é valido`
`O tipo '${parametro.tipoDado}' não é valido`
);
}
}
Expand Down Expand Up @@ -269,7 +273,7 @@ export class AnalisadorSemanticoVisuAlg extends AnalisadorSemanticoBase {

for (let [indice, argumento] of expressao.argumentos.entries()) {
const parametroCorrespondente = funcao.parametros[indice];
const tipoDadoParametro = parametroCorrespondente.tipoDado.tipo.toLowerCase();
const tipoDadoParametro = parametroCorrespondente.tipoDado.toLowerCase();

if (argumento instanceof Variavel) {
const lexemaVariavelCorrespondente = (argumento as Variavel).simbolo.lexema;
Expand Down
112 changes: 57 additions & 55 deletions fontes/avaliador-sintatico/avaliador-sintatico-visualg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,6 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
this.hashArquivo
)
),
undefined,
[]
)
),
Expand Down Expand Up @@ -349,7 +348,6 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
this.hashArquivo
)
),
undefined,
[]
),
dadosVariaveis.tipo as any
Expand Down Expand Up @@ -394,7 +392,7 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
const variavel = new Variavel(this.hashArquivo, simboloIdentificadorOuMetodo);
// Chamada de função ou procedimento sem parâmetros.
if (this.funcoesProcedimentosConhecidos.includes(simboloIdentificadorOuMetodo.lexema)) {
return new Chamada(this.hashArquivo, variavel, undefined, []);
return new Chamada(this.hashArquivo, variavel, []);
}

return variavel;
Expand Down Expand Up @@ -456,29 +454,40 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
const setaAtribuicao = this.simbolos[this.atual - 1];
const valor = this.atribuir();

if (expressao instanceof Variavel) {
const simbolo = expressao.simbolo;
return new Atribuir(this.hashArquivo, simbolo, valor);
} else if (expressao instanceof AcessoIndiceVariavel) {
return new AtribuicaoPorIndice(
this.hashArquivo,
expressao.linha,
expressao.entidadeChamada,
expressao.indice,
valor
);
} else if (expressao instanceof AcessoElementoMatriz) {
return new AtribuicaoPorIndicesMatriz(
this.hashArquivo,
expressao.linha,
expressao.entidadeChamada,
expressao.indicePrimario,
expressao.indiceSecundario,
valor
);
switch (expressao.constructor.name) {
case 'Variavel':
return new Atribuir(this.hashArquivo, expressao, valor);
case 'AcessoIndiceVariavel':
const expressaoAcessoIndiceVariavel = expressao as AcessoIndiceVariavel;
return new AtribuicaoPorIndice(
this.hashArquivo,
expressaoAcessoIndiceVariavel.linha,
expressaoAcessoIndiceVariavel.entidadeChamada,
expressaoAcessoIndiceVariavel.indice,
valor
);
case 'AcessoElementoMatriz':
const expressaoAcessoElementoMatriz = expressao as AcessoElementoMatriz;
return new AtribuicaoPorIndicesMatriz(
this.hashArquivo,
expressaoAcessoElementoMatriz.linha,
expressaoAcessoElementoMatriz.entidadeChamada,
expressaoAcessoElementoMatriz.indicePrimario,
expressaoAcessoElementoMatriz.indiceSecundario,
valor
);
case 'AcessoMetodoOuPropriedade':
const expressaAcessoMetodoOuPropriedade = expressao as AcessoMetodoOuPropriedade;
return new DefinirValor(
expressaAcessoMetodoOuPropriedade.hashArquivo,
expressaAcessoMetodoOuPropriedade.linha,
expressaAcessoMetodoOuPropriedade.objeto,
expressaAcessoMetodoOuPropriedade.simbolo,
valor
);
default:
throw this.erro(setaAtribuicao, 'Tarefa de atribuição inválida');
}

throw this.erro(setaAtribuicao, 'Tarefa de atribuição inválida');
}

return expressao;
Expand Down Expand Up @@ -517,24 +526,21 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
override finalizarChamada(entidadeChamada: Construto): Chamada {
const argumentos: Array<Construto> = [];

let parenteseDireito: SimboloInterface<string>;
if (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PARENTESE_DIREITO)) {
do {
if (argumentos.length >= 255) {
throw this.erro(this.simbolos[this.atual], 'Não pode haver mais de 255 argumentos.');
}
argumentos.push(this.expressao());
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));
while (!this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARENTESE_DIREITO)) {
if (argumentos.length >= 255) {
throw this.erro(this.simbolos[this.atual], 'Não pode haver mais de 255 argumentos.');
}

parenteseDireito = this.consumir(tiposDeSimbolos.PARENTESE_DIREITO, "Esperado ')' após os argumentos.");
argumentos.push(this.expressao());
this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA);
}

if (entidadeChamada instanceof Chamada) {
entidadeChamada.argumentos = argumentos;
return entidadeChamada;
}

return new Chamada(this.hashArquivo, entidadeChamada, parenteseDireito, argumentos);
return new Chamada(this.hashArquivo, entidadeChamada, argumentos);
}

chamar(): Construto {
Expand Down Expand Up @@ -951,15 +957,15 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {

let operadorCondicao = new Simbolo(
tiposDeSimbolos.MENOR_IGUAL,
'',
'',
'<=',
null,
Number(simboloPara.linha),
this.hashArquivo
);
let operadorCondicaoIncremento = new Simbolo(
tiposDeSimbolos.MENOR,
'',
'',
'<',
null,
Number(simboloPara.linha),
this.hashArquivo
);
Expand Down Expand Up @@ -1023,7 +1029,7 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
}
} else {
// Passo e operador de condição precisam ser resolvidos em tempo de execução.
passo = undefined;
passo = new Literal(this.hashArquivo, Number(simboloPara.linha), 1);
operadorCondicao = undefined;
operadorCondicaoIncremento = undefined;
resolverIncrementoEmExecucao = true;
Expand Down Expand Up @@ -1062,11 +1068,15 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
this.hashArquivo,
Number(simboloPara.linha),
// Inicialização.
new Atribuir(this.hashArquivo, variavelIteracao, literalOuVariavelInicio),
new Atribuir(
this.hashArquivo,
new Variavel(this.hashArquivo, variavelIteracao, 'inteiro'),
literalOuVariavelInicio
),
// Condição.
new Binario(
this.hashArquivo,
new Variavel(this.hashArquivo, variavelIteracao),
new Variavel(this.hashArquivo, variavelIteracao, 'inteiro'),
operadorCondicao,
literalOuVariavelFim
),
Expand All @@ -1076,18 +1086,18 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
Number(simboloPara.linha),
new Binario(
this.hashArquivo,
new Variavel(this.hashArquivo, variavelIteracao),
new Variavel(this.hashArquivo, variavelIteracao, 'inteiro'),
operadorCondicaoIncremento,
literalOuVariavelFim
),
new Expressao(
new Atribuir(
this.hashArquivo,
variavelIteracao,
new Variavel(this.hashArquivo, variavelIteracao, 'inteiro'),
new Binario(
this.hashArquivo,
new Variavel(this.hashArquivo, variavelIteracao),
new Simbolo(tiposDeSimbolos.ADICAO, '', null, Number(simboloPara.linha), this.hashArquivo),
new Variavel(this.hashArquivo, variavelIteracao, 'inteiro'),
new Simbolo(tiposDeSimbolos.ADICAO, '+', null, Number(simboloPara.linha), this.hashArquivo),
passo
)
)
Expand All @@ -1105,21 +1115,13 @@ export class AvaliadorSintaticoVisuAlg extends AvaliadorSintaticoBase {
if (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.PARENTESE_ESQUERDO)) {
while (!this.verificarTipoSimboloAtual(tiposDeSimbolos.PARENTESE_DIREITO)) {
const dadosParametros = this.logicaComumParametroVisuAlg();
const tipoDadoParametro = {
nome: dadosParametros.simbolo.lexema,
tipo: dadosParametros.tipo as TipoDadosElementar,
// TODO: Remover isso. O máximo que o avaliador sintático
// deveria olhar é o símbolo anterior, não dois
// símbolos para trás.
tipoInvalido: !dadosParametros.tipo ? this.simbolos[this.atual - 2].lexema : null,
};

for (let parametro of dadosParametros.identificadores) {
parametros.push({
abrangencia: 'padrao',
nome: parametro,
referencia: dadosParametros.referencia,
tipoDado: tipoDadoParametro,
tipoDado: dadosParametros.tipo as TipoDadosElementar,
});
}
}
Expand Down
17 changes: 12 additions & 5 deletions fontes/formatador/formatador.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
AcessoIndiceVariavel,
AcessoMetodoOuPropriedade,
AcessoPropriedade,
Agrupamento,
AtribuicaoPorIndice,
Atribuir,
Expand Down Expand Up @@ -73,7 +74,7 @@ export class FormatadorVisuAlg implements VisitanteVisuAlgInterface {
devePularLinha: boolean;
deveIndentar: boolean;
contadorDeclaracaoVar: number;
retornoFuncaoAtual: SimboloInterface;
retornoFuncaoAtual: string;

constructor(quebraLinha: string, tamanhoIndentacao: number = 4) {
this.quebraLinha = quebraLinha;
Expand All @@ -88,6 +89,14 @@ export class FormatadorVisuAlg implements VisitanteVisuAlgInterface {
this.retornoFuncaoAtual = undefined;
}

visitarExpressaoAcessoMetodoOuPropriedade(expressao: AcessoMetodoOuPropriedade): Promise<any> | void {
throw new Error('Método não implementado.');
}

visitarExpressaoAcessoPropriedade(expressao: AcessoPropriedade): Promise<any> | void {
throw new Error('Método não implementado.');
}

visitarExpressaoLimpaTela(expressao: LimpaTela): void | Promise<any> {
this.codigoFormatado += ' '.repeat(this.indentacaoAtual);
this.codigoFormatado += 'limpatela';
Expand Down Expand Up @@ -161,7 +170,7 @@ export class FormatadorVisuAlg implements VisitanteVisuAlgInterface {
}

visitarExpressaoDeAtribuicao(expressao: Atribuir) {
this.codigoFormatado += `${expressao.simbolo.lexema} <- `;
this.codigoFormatado += `${this.formatarDeclaracaoOuConstruto(expressao.alvo)} <- `;
this.formatarDeclaracaoOuConstruto(expressao.valor);

if (this.devePularLinha) {
Expand Down Expand Up @@ -654,9 +663,7 @@ export class FormatadorVisuAlg implements VisitanteVisuAlgInterface {
if (expressao.parametros.length > 0) {
this.codigoFormatado += `(`;
for (let argumento of expressao.parametros) {
this.codigoFormatado += `${argumento.nome.lexema}${
argumento.tipoDado && argumento.tipoDado.tipo ? `: ${argumento.tipoDado.tipo}, ` : ', '
}`;
this.codigoFormatado += `${argumento.nome.lexema}${argumento.tipoDado || ''}, `;
}
this.codigoFormatado = this.codigoFormatado.slice(0, -2);
this.codigoFormatado += `) `;
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,21 @@
"deixar-codigo-bonito": "yarn prettier --config .prettierrc --write fontes/**/*.ts"
},
"dependencies": {
"@designliquido/delegua": "^0.37.2",
"@designliquido/delegua": "^0.39.3",
"lodash": "^4.17.21"
},
"devDependencies": {
"@types/estree": "^1.0.6",
"@types/jest": "^29.5.14",
"@types/lodash": "^4.17.13",
"@types/node": "^22.10.1",
"@types/lodash": "^4.17.16",
"@types/node": "^22.13.10",
"copyfiles": "^2.4.1",
"jest": "^29.7.0",
"prettier": "^3.4.1",
"prettier": "^3.5.3",
"rimraf": "^6.0.1",
"ts-jest": "^29.2.5",
"ts-jest": "^29.2.6",
"ts-node": "^10.9.2",
"typedoc": "^0.27.1",
"typescript": "^5.7.2"
"typedoc": "^0.27.9",
"typescript": "^5.8.2"
}
}
1 change: 1 addition & 0 deletions testes/avaliador-sintatico.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ describe('Avaliador sintático', () => {

expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.declaracoes).toHaveLength(32);
expect(retornoAvaliadorSintatico.erros).toHaveLength(0);
});

it('Repita', () => {
Expand Down
Loading