Skip to content

Commit

Permalink
Erro atribuicao variavel (#34)
Browse files Browse the repository at this point in the history
* refactor: mudando a tipagem no avaliador
* refactor: removendo logs e voltando os testes
* test: melhorando tests
* test: realizado os testes
* refactor: voltando configuração de pacotes
* Atualização de pacotes para passar o build.
* Atualizando workflow do GitHub.

---------

Co-authored-by: Leonel Sanches da Silva <[email protected]>
  • Loading branch information
Aristidescosta and leonelsanchesdasilva authored Oct 19, 2024
1 parent e24f1e7 commit c987b16
Show file tree
Hide file tree
Showing 9 changed files with 406 additions and 103 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/principal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2-beta
- uses: actions/checkout@v3
- uses: actions/setup-node@v4
with:
node-version: '16'
node-version: '20'
# Maneira tradicional de build, sem cobertura.
- name: NPM - Dependências
run: |
Expand Down
35 changes: 22 additions & 13 deletions fontes/analisador-semantico/analisador-semantico-portugol-studio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import {
Variavel,
Vetor,
} from '@designliquido/delegua/construtos';
import { inferirTipoVariavel } from 'fontes/interpretador/inferenciador';
import { inferirTipoVariavel } from '../interpretador/inferenciador';
import tiposDeDados from '../tipos-de-dados';
export class AnalisadorSemanticoPortugolStudio extends AnalisadorSemanticoBase {
pilhaVariaveis: PilhaVariaveis;
variaveis: { [nomeVariavel: string]: VariavelHipoteticaInterface };
Expand Down Expand Up @@ -130,18 +131,26 @@ export class AnalisadorSemanticoPortugolStudio extends AnalisadorSemanticoBase {

if (variavel.tipo) {
if (valor instanceof Literal) {
let valorLiteral = typeof (valor as Literal).valor;
if (valorLiteral === 'string') {
if (!['cadeia', 'caracter'].includes(variavel.tipo.toLowerCase())) {
this.adicionarDiagnostico(simbolo, `Esperado tipo '${variavel.tipo}' na atribuição.`);
return Promise.resolve();
}
}
if (valorLiteral === 'number') {
if (!['inteiro', 'real'].includes(variavel.tipo.replace("[]", "").toLowerCase())) {
this.adicionarDiagnostico(simbolo, `Esperado tipo '${variavel.tipo.replace("[]", "")}' na atribuição.`);
return Promise.resolve();
const tipoInferido = inferirTipoVariavel(valor.valor)
if (tipoInferido !== variavel.tipo) {
switch (variavel.tipo) {
case tiposDeDados.CADEIA:
if (tipoInferido !== tiposDeDados.CARACTER) {
this.adicionarDiagnostico(simbolo, `Não é possível atribuir um valor do tipo '${tipoInferido}' a uma variável do tipo '${variavel.tipo}'.`);
return Promise.resolve();
}
break;
case tiposDeDados.REAL:
if (tipoInferido !== tiposDeDados.INTEIRO) {
this.adicionarDiagnostico(simbolo, `Não é possível atribuir um valor do tipo '${tipoInferido}' a uma variável do tipo '${variavel.tipo}'.`);
return Promise.resolve();
}
break;
default:
this.adicionarDiagnostico(simbolo, `Não é possível atribuir um valor do tipo '${tipoInferido}' a uma variável do tipo '${variavel.tipo}'.`);
return Promise.resolve();
}

}
}
}
Expand Down Expand Up @@ -286,7 +295,7 @@ export class AnalisadorSemanticoPortugolStudio extends AnalisadorSemanticoBase {
this.corpoMetodoPrincipal[this.atual].aceitar(this)
this.atual++;
}

return {
diagnosticos: this.diagnosticos,
} as RetornoAnalisadorSemantico;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
case tiposDeSimbolos.INTEIRO:
const identificador = this.consumir(
tiposDeSimbolos.IDENTIFICADOR,
"Esperado identificador após palavra reservada 'inteiro'."
`Esperado identificador após palavra reservada '${tiposDeDados.INTEIRO}'.`
);
this.consumir(tiposDeSimbolos.IGUAL, 'Esperado símbolo igual para inicialização de variável.');
const literalInicializacao = this.consumir(
Expand Down Expand Up @@ -579,9 +579,9 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
const dimensoes = this.logicaComumDimensoesMatrizes();

if (dimensoes.length > 0) {
inicializacoes.push(this.declaracaoVetorOuMatriz(simboloCadeia, identificador, dimensoes, 'texto'));
inicializacoes.push(this.declaracaoVetorOuMatriz(simboloCadeia, identificador, dimensoes, tiposDeDados.CADEIA));
} else {
inicializacoes.push(this.declaracaoVariavelSemDimensoes(simboloCadeia, identificador, 'texto'));
inicializacoes.push(this.declaracaoVariavelSemDimensoes(simboloCadeia, identificador, tiposDeDados.CADEIA));
}
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));

Expand All @@ -595,17 +595,17 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
do {
const identificador = this.consumir(
tiposDeSimbolos.IDENTIFICADOR,
"Esperado identificador após palavra reservada 'caracter'."
`Esperado identificador após palavra reservada '${tiposDeDados.CARACTER}'.`
);

const dimensoes = this.logicaComumDimensoesMatrizes();

if (dimensoes.length > 0) {
inicializacoes.push(
this.declaracaoVetorOuMatriz(simboloCaracter, identificador, dimensoes, 'caracter')
this.declaracaoVetorOuMatriz(simboloCaracter, identificador, dimensoes, tiposDeDados.CARACTER)
);
} else {
inicializacoes.push(this.declaracaoVariavelSemDimensoes(simboloCaracter, identificador, 'caracter'));
inicializacoes.push(this.declaracaoVariavelSemDimensoes(simboloCaracter, identificador, tiposDeDados.CARACTER));
}
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));

Expand Down Expand Up @@ -878,15 +878,15 @@ export class AvaliadorSintaticoPortugolStudio extends AvaliadorSintaticoBase {
do {
const identificador = this.consumir(
tiposDeSimbolos.IDENTIFICADOR,
"Esperado identificador após palavra reservada 'real'."
`Esperado identificador após palavra reservada '${tiposDeDados.REAL}'.`
);

const dimensoes = this.logicaComumDimensoesMatrizes();

if (dimensoes.length > 0) {
inicializacoes.push(this.declaracaoVetorOuMatriz(simboloReal, identificador, dimensoes, 'real'));
inicializacoes.push(this.declaracaoVetorOuMatriz(simboloReal, identificador, dimensoes, tiposDeDados.REAL));
} else {
inicializacoes.push(this.declaracaoVariavelSemDimensoes(simboloReal, identificador, 'real'));
inicializacoes.push(this.declaracaoVariavelSemDimensoes(simboloReal, identificador, tiposDeDados.REAL));
}
} while (this.verificarSeSimboloAtualEIgualA(tiposDeSimbolos.VIRGULA));

Expand Down
47 changes: 18 additions & 29 deletions fontes/interpretador/inferenciador.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,31 @@
export type TipoInferencia =
| 'texto'
| 'número'
| 'longo'
| 'vetor'
| 'dicionário'
| 'nulo'
| 'cadeia'
| 'caracter'
| 'inteiro'
| 'lógico'
| 'função'
| 'símbolo'
| 'objeto'
| 'módulo';
| 'real'
| 'vazio';

export function inferirTipoVariavel(
variavel: string | number | Array<any> | boolean | null | undefined
): TipoInferencia {
const tipo = typeof variavel;
switch (tipo) {
switch (typeof variavel) {
case 'string':
return 'texto';
if (variavel.length === 1) {
return 'caracter';
}
if (variavel.length === 1) {
console.log("Olha eu a voltar aqui")
}
return 'cadeia';
case 'number':
return 'número';
case 'bigint':
return 'longo';
if (Number.isInteger(variavel))
return 'inteiro';
return 'real';
case 'boolean':
return 'lógico';
case 'undefined':
return 'nulo';
case 'object':
if (Array.isArray(variavel)) return 'vetor';
if (variavel === null) return 'nulo';
if (variavel.constructor.name === 'DeleguaFuncao') return 'função';
if (variavel.constructor.name === 'DeleguaModulo') return 'módulo';
if (variavel.constructor.name === 'Classe') return 'objeto';
return 'dicionário';
case 'function':
return 'função';
case 'symbol':
return 'símbolo';
default:
return 'vazio';
}
}

Expand Down
3 changes: 2 additions & 1 deletion fontes/tipos-de-dados/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ export default {
REAL: 'real',
TEXTO: 'texto',
VETOR: 'vetor',
CADEIA: 'cadeia'
CADEIA: 'cadeia',
CARACTER: 'caracter'
};
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"deixar-codigo-bonito": "prettier --config .prettierrc --write fontes/**/*.ts"
},
"dependencies": {
"@designliquido/delegua": "^0.36.1",
"@designliquido/delegua": "^0.36.2",
"lodash": "^4.17.21",
"node-fetch": "2",
"xml2js": "^0.6.2"
Expand All @@ -39,7 +39,7 @@
"rimraf": "^5.0.5",
"ts-jest": "^29.1.2",
"ts-node": "^10.9.2",
"typedoc": "^0.25.8",
"typedoc": "^0.26.10",
"typescript": "^5.5.4"
}
}
11 changes: 10 additions & 1 deletion testes/analisador-semantico.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,27 @@ describe('Analisador sêmantico', () => {
'real x',
'inteiro y',
'caracter a',
'cadeia b',
'logico l',
'x = "25"',
'y = "6x"',
'l = 24',
'b = 34',
'x = 25',
'y = 25.4',
'}',
'}'
], -1);
const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);
const retornoAnalisadorSemantico = analisadorSemantico.analisar(retornoAvaliadorSintatico.declaracoes);

expect(retornoAnalisadorSemantico).toBeTruthy();
expect(retornoAnalisadorSemantico.diagnosticos).toHaveLength(3);
expect(retornoAnalisadorSemantico.diagnosticos).toHaveLength(5);
expect(retornoAnalisadorSemantico.diagnosticos[0].mensagem).toEqual("Não é possível atribuir um valor do tipo 'cadeia' a uma variável do tipo 'real'.");
expect(retornoAnalisadorSemantico.diagnosticos[1].mensagem).toEqual("Não é possível atribuir um valor do tipo 'cadeia' a uma variável do tipo 'inteiro'.");
expect(retornoAnalisadorSemantico.diagnosticos[2].mensagem).toEqual("Não é possível atribuir um valor do tipo 'inteiro' a uma variável do tipo 'lógico'.");
expect(retornoAnalisadorSemantico.diagnosticos[3].mensagem).toEqual("Não é possível atribuir um valor do tipo 'inteiro' a uma variável do tipo 'cadeia'.");
expect(retornoAnalisadorSemantico.diagnosticos[4].mensagem).toEqual("Não é possível atribuir um valor do tipo 'real' a uma variável do tipo 'inteiro'.");
});

it('Atribuição por indice', () => {
Expand Down
6 changes: 3 additions & 3 deletions testes/avaliador-sintatico.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ describe('Avaliador sintático (Portugol Studio)', () => {
], -1);

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.declaracoes.length).toBe(2);
});
Expand All @@ -411,7 +411,7 @@ describe('Avaliador sintático (Portugol Studio)', () => {
], -1);

const retornoAvaliadorSintatico = avaliadorSintatico.analisar(retornoLexador, -1);

expect(retornoAvaliadorSintatico).toBeTruthy();
expect(retornoAvaliadorSintatico.declaracoes.length).toBe(2);
const declaracaoFuncao = retornoAvaliadorSintatico.declaracoes[0];
Expand Down Expand Up @@ -509,4 +509,4 @@ describe('Avaliador sintático (Portugol Studio)', () => {
});
});
});
});
});
Loading

0 comments on commit c987b16

Please sign in to comment.