"use strict";
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