"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TipoNativoSimbolo = void 0;
exports.inferirTipoVariavel = inferirTipoVariavel;
exports.tipoInferenciaParaTipoDadosElementar = tipoInferenciaParaTipoDadosElementar;
const primitivos_1 = __importDefault(require("./tipos-de-dados/primitivos"));
const delegua_1 = __importDefault(require("./tipos-de-dados/delegua"));
const delegua_2 = __importDefault(require("./tipos-de-simbolos/delegua"));
var TipoNativoSimbolo;
(function (TipoNativoSimbolo) {
    TipoNativoSimbolo["ESCREVA"] = "<palavra reservada escreva ajuda=\"palavra reservada usada para apresentar informa\u00E7\u00F5es\">";
    TipoNativoSimbolo["LEIA"] = "<palavra reservada leia ajuda=\"palavra reservada usada para entrada de dados\">";
    TipoNativoSimbolo["FUNCAO"] = "<palavra reservada funcao ajuda=\"palavra reservada usada para criar fun\u00E7\u00F5es\">";
    TipoNativoSimbolo["SE"] = "<palavra reservada se ajuda=\"palavra reservada usada para estruturas condicionais\">";
    TipoNativoSimbolo["ENQUANTO"] = "<palavra reservada enquanto ajuda=\"palavra reservada usada para loops enquanto\">";
    TipoNativoSimbolo["PARA"] = "<palavra reservada para ajuda=\"palavra reservada usada para loops para\">";
    TipoNativoSimbolo["RETORNA"] = "<palavra reservada retornar ajuda=\"palavra reservada usada para retornar valores em fun\u00E7\u00F5es\">";
    TipoNativoSimbolo["INTEIRO"] = "<palavra reservada inteiro ajuda=\"palavra reservada usada para definir vari\u00E1veis do tipo inteiro\">";
    TipoNativoSimbolo["TEXTO"] = "<palavra reservada texto ajuda=\"palavra reservada usada para definir vari\u00E1veis do tipo texto\">";
    TipoNativoSimbolo["BOOLEANO"] = "<palavra reservada booleano ajuda=\"palavra reservada usada para definir vari\u00E1veis do tipo booleano\">";
    TipoNativoSimbolo["VAZIO"] = "<palavra reservada vazio ajuda=\"palavra reservada usada para definir fun\u00E7\u00F5es que n\u00E3o retornam valores\">";
})(TipoNativoSimbolo || (exports.TipoNativoSimbolo = TipoNativoSimbolo = {}));
function inferirVetor(vetor) {
    const tiposEmVetor = new Set(vetor.map((elemento) => elemento.constructor.name));
    if (tiposEmVetor.size > 1) {
        return 'vetor';
    }
    const tipoVetor = tiposEmVetor.values().next().value;
    switch (tipoVetor) {
        case 'bigint':
            return 'longo[]';
        case 'boolean':
            return 'lógico[]';
        case 'number':
            return 'número[]';
        case 'string':
            return 'texto[]';
        case 'object':
            const tiposObjetosEmVetor = new Set(vetor.map((elemento) => elemento.tipo));
            if (tiposObjetosEmVetor.size > 1) {
                return 'vetor';
            }
            return `${tiposObjetosEmVetor.values().next().value}[]`;
        case 'Literal':
            // TODO: Não sei se é seguro inferir pelo primeiro valor do vetor.
            return `${vetor[0].tipo}[]`;
        default:
            return 'vetor';
    }
}
function inferirTipoVariavel(variavel) {
    if (variavel === null) {
        return 'nulo';
    }
    const tipo = variavel && variavel.constructor ? variavel.constructor.name : typeof variavel;
    switch (tipo) {
        case 'String':
        case 'string':
            return 'texto';
        case 'Number':
        case 'number':
            return 'número';
        case 'bigint':
            return 'longo';
        case 'Boolean':
        case 'boolean':
            return 'lógico';
        case 'undefined':
            return 'nulo';
        case 'Object':
        case 'object':
            if (variavel === null)
                return 'nulo';
            return 'dicionário';
        case 'Array':
        case 'Vetor':
            return inferirVetor(variavel);
        case 'DeleguaFuncao':
            return 'função';
        case 'DeleguaModulo':
            return 'módulo';
        case 'Classe':
        case 'DescritorTipoClasse':
        case 'ObjetoDeleguaClasse':
            return 'objeto';
        case 'Simbolo': // TODO: Repensar.
            const simbolo = variavel;
            switch (simbolo.tipo) {
                case primitivos_1.default.BOOLEANO:
                    return TipoNativoSimbolo.BOOLEANO;
                case delegua_2.default.ENQUANTO:
                    return TipoNativoSimbolo.ENQUANTO;
                case delegua_2.default.ESCREVA:
                    return TipoNativoSimbolo.ESCREVA;
                case delegua_2.default.FUNCAO:
                case delegua_2.default.FUNÇÃO:
                    return TipoNativoSimbolo.FUNCAO;
                case delegua_2.default.LEIA:
                    return TipoNativoSimbolo.LEIA;
                case delegua_2.default.PARA:
                    return TipoNativoSimbolo.PARA;
                case delegua_2.default.RETORNA:
                    return TipoNativoSimbolo.RETORNA;
                case delegua_2.default.SE:
                    return TipoNativoSimbolo.SE;
                case primitivos_1.default.TEXTO:
                    return TipoNativoSimbolo.TEXTO;
                case delegua_1.default.VAZIO:
                    return TipoNativoSimbolo.VAZIO;
            }
        case 'function':
        case 'FuncaoPadrao':
            return 'função';
        case 'symbol':
            return 'símbolo';
    }
}
function tipoInferenciaParaTipoDadosElementar(tipoInferencia) {
    switch (tipoInferencia) {
        // TODO: Colocar exceções aqui.
        default:
            return tipoInferencia;
    }
}
//# sourceMappingURL=inferenciador.js.map