@designliquido/delegua
Version:
Linguagem de programação simples e moderna usando português estruturado.
145 lines • 6.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AvaliadorExpressaoDepuracao = void 0;
const construtos_1 = require("../../construtos");
const inferenciador_1 = require("../../inferenciador");
/**
* Verifica se uma expressão tem efeitos colaterais que não devem ser executados
* durante a avaliação de expressões no painel de depuração.
* @param expressao A expressão a ser verificada.
* @returns `true` se a expressão tem efeitos colaterais, `false` caso contrário.
*/
function temEfeitosColaterais(expressao) {
// Atribuições modificam o estado
if (expressao instanceof construtos_1.Atribuir ||
expressao instanceof construtos_1.AtribuicaoPorIndice ||
expressao instanceof construtos_1.AtribuicaoPorIndicesMatriz) {
return true;
}
// Leia requer entrada do usuário
if (expressao instanceof construtos_1.Leia) {
return true;
}
// Chamadas de função podem ter efeitos colaterais
// Por enquanto, permitimos chamadas (comentar esta linha se quiser bloquear)
// if (expressao instanceof Chamada) {
// return true;
// }
return false;
}
/**
* Avaliador de expressões para depuração.
*
* Este avaliador é usado para avaliar expressões no painel de depuração do VSCode
* (watch panel) de forma segura, sem modificar o estado da execução do programa.
*
* Utiliza a infraestrutura existente do interpretador (MicroLexador, MicroAvaliadorSintatico)
* e delega a avaliação para o InterpretadorComDepuracao, garantindo que expressões com
* efeitos colaterais sejam bloqueadas.
*
* Exemplo de uso:
* ```typescript
* const avaliador = new AvaliadorExpressaoDepuracao(interpretador);
* const resultado = await avaliador.avaliarExpressao('variavel + 10');
* if (resultado.sucesso) {
* console.log(`Valor: ${resultado.valor}, Tipo: ${resultado.tipo}`);
* } else {
* console.error(`Erro: ${resultado.erro}`);
* }
* ```
*/
class AvaliadorExpressaoDepuracao {
constructor(interpretador) {
this.interpretador = interpretador;
}
/**
* Avalia uma expressão em formato de texto e retorna seu resultado.
*
* Este método:
* 1. Usa o MicroLexador para tokenizar a expressão
* 2. Usa o MicroAvaliadorSintatico para gerar a AST
* 3. Valida se a expressão não tem efeitos colaterais
* 4. Delega a avaliação para o interpretador
* 5. Resolve e formata o valor resultante
*
* @param expressaoTexto A expressão em formato de texto (ex: "variavel + 10")
* @param permitirEfeitosColaterais Se `true`, permite expressões com efeitos colaterais.
* Padrão: `false` (somente leitura).
* @returns Uma Promise que resolve para um ResultadoAvaliacao com o resultado ou erro.
*/
async avaliarExpressao(expressaoTexto, permitirEfeitosColaterais = false) {
try {
const retornoLexador = this.interpretador.microLexador.mapear(expressaoTexto);
if (retornoLexador.simbolos.length === 0) {
return {
sucesso: false,
erro: 'Expressão vazia ou inválida',
};
}
const retornoAvaliadorSintatico = this.interpretador.microAvaliadorSintatico.analisar(retornoLexador, -1);
if (retornoAvaliadorSintatico.declaracoes.length === 0) {
return {
sucesso: false,
erro: 'Não foi possível analisar a expressão',
};
}
if (retornoAvaliadorSintatico.declaracoes.length > 1) {
return {
sucesso: false,
erro: 'Múltiplas expressões não são permitidas',
};
}
const expressao = retornoAvaliadorSintatico.declaracoes[0];
// Validar se não tem efeitos colaterais (opcional)
if (!permitirEfeitosColaterais && temEfeitosColaterais(expressao)) {
return {
sucesso: false,
erro: 'Expressões com efeitos colaterais não são permitidas no painel de depuração',
};
}
const resultadoBruto = await this.interpretador.avaliar(expressao);
const valorResolvido = this.interpretador.resolverValor(resultadoBruto);
const tipo = (0, inferenciador_1.inferirTipoVariavel)(valorResolvido);
return {
sucesso: true,
valor: valorResolvido,
tipo: tipo,
};
}
catch (erro) {
return {
sucesso: false,
erro: erro.message || String(erro),
};
}
}
/**
* Formata o valor de uma expressão para exibição no painel de depuração.
* Converte o valor para uma representação textual legível.
*
* @param valor O valor a ser formatado.
* @returns Uma string representando o valor.
*/
formatarValorParaExibicao(valor) {
return this.interpretador.paraTexto(valor);
}
/**
* Avalia uma expressão e retorna diretamente seu valor formatado para exibição.
* Atalho para `avaliarExpressao()` seguido de `formatarValorParaExibicao()`.
*
* @param expressaoTexto A expressão em formato de texto.
* @param permitirEfeitosColaterais Se `true`, permite expressões com efeitos colaterais.
* @returns Uma Promise que resolve para uma string com o valor formatado ou mensagem de erro.
*/
async avaliarEFormatar(expressaoTexto, permitirEfeitosColaterais = false) {
const resultado = await this.avaliarExpressao(expressaoTexto, permitirEfeitosColaterais);
if (resultado.sucesso) {
return this.formatarValorParaExibicao(resultado.valor);
}
else {
return `Erro: ${resultado.erro}`;
}
}
}
exports.AvaliadorExpressaoDepuracao = AvaliadorExpressaoDepuracao;
//# sourceMappingURL=avaliador-expressao-depuracao.js.map