A long time ago I wanted to get the type term() in Erlang, and I wrote the following code
dataType(Data) when is_list(Data) -> list;
dataType(Data) when is_integer(Data) -> integer;
dataType(Data) when is_binary(Data) -> binary;
dataType(Data) when is_function(Data) -> function;
dataType(Data) when is_tuple(Data) -> tuple;
dataType(Data) when is_map(Data) -> map;
dataType(Data) when is_atom(Data) -> atom;
%%dataType(Data) when is_boolean(Data) -> boolean;
dataType(Data) when is_bitstring(Data) -> bitstring;
dataType(Data) when is_float(Data) -> float;
dataType(Data) when is_number(Data) -> number;
dataType(Data) when is_reference(Data) -> reference;
dataType(Data) when is_pid(Data) -> pid;
dataType(Data) when is_port(Data) -> port;
dataType(_Data) -> not_know.
But today I found a new function erts_internal:term_type/1
But I saw it come true
BIF_RETTYPE erts_internal_term_type_1(BIF_ALIST_1) {
Eterm obj = BIF_ARG_1;
switch (primary_tag(obj)) {
case TAG_PRIMARY_LIST:
BIF_RET(ERTS_MAKE_AM("list"));
case TAG_PRIMARY_BOXED: {
Eterm hdr = *boxed_val(obj);
ASSERT(is_header(hdr));
switch (hdr & _TAG_HEADER_MASK) {
case ARITYVAL_SUBTAG:
BIF_RET(ERTS_MAKE_AM("tuple"));
case FUN_SUBTAG:
{
ErlFunThing *funp = (ErlFunThing *)fun_val(obj);
if (is_local_fun(funp)) {
BIF_RET(ERTS_MAKE_AM("fun"));
} else {
ASSERT(is_external_fun(funp) && funp->next == NULL);
BIF_RET(ERTS_MAKE_AM("export"));
}
}
case MAP_SUBTAG:
switch (MAP_HEADER_TYPE(hdr)) {
case MAP_HEADER_TAG_FLATMAP_HEAD :
BIF_RET(ERTS_MAKE_AM("flatmap"));
case MAP_HEADER_TAG_HAMT_HEAD_BITMAP :
case MAP_HEADER_TAG_HAMT_HEAD_ARRAY :
BIF_RET(ERTS_MAKE_AM("hashmap"));
case MAP_HEADER_TAG_HAMT_NODE_BITMAP :
BIF_RET(ERTS_MAKE_AM("hashmap_node"));
default:
erts_exit(ERTS_ABORT_EXIT, "term_type: bad map header type %d\n", MAP_HEADER_TYPE(hdr));
}
case REFC_BINARY_SUBTAG:
BIF_RET(ERTS_MAKE_AM("refc_binary"));
case HEAP_BINARY_SUBTAG:
BIF_RET(ERTS_MAKE_AM("heap_binary"));
case SUB_BINARY_SUBTAG:
BIF_RET(ERTS_MAKE_AM("sub_binary"));
case BIN_MATCHSTATE_SUBTAG:
BIF_RET(ERTS_MAKE_AM("matchstate"));
case POS_BIG_SUBTAG:
case NEG_BIG_SUBTAG:
BIF_RET(ERTS_MAKE_AM("bignum"));
case REF_SUBTAG:
BIF_RET(ERTS_MAKE_AM("reference"));
case EXTERNAL_REF_SUBTAG:
BIF_RET(ERTS_MAKE_AM("external_reference"));
case EXTERNAL_PID_SUBTAG:
BIF_RET(ERTS_MAKE_AM("external_pid"));
case EXTERNAL_PORT_SUBTAG:
BIF_RET(ERTS_MAKE_AM("external_port"));
case FLOAT_SUBTAG:
BIF_RET(ERTS_MAKE_AM("hfloat"));
default:
erts_exit(ERTS_ABORT_EXIT, "term_type: Invalid tag (0x%X)\n", hdr);
}
}
case TAG_PRIMARY_IMMED1:
switch (obj & _TAG_IMMED1_MASK) {
case _TAG_IMMED1_SMALL:
BIF_RET(ERTS_MAKE_AM("fixnum"));
case _TAG_IMMED1_PID:
BIF_RET(ERTS_MAKE_AM("pid"));
case _TAG_IMMED1_PORT:
BIF_RET(ERTS_MAKE_AM("port"));
case _TAG_IMMED1_IMMED2:
switch (obj & _TAG_IMMED2_MASK) {
case _TAG_IMMED2_ATOM:
BIF_RET(ERTS_MAKE_AM("atom"));
case _TAG_IMMED2_CATCH:
BIF_RET(ERTS_MAKE_AM("catch"));
case _TAG_IMMED2_NIL:
BIF_RET(ERTS_MAKE_AM("nil"));
default:
erts_exit(ERTS_ABORT_EXIT, "term_type: Invalid tag (0x%X)\n", obj);
}
default:
erts_exit(ERTS_ABORT_EXIT, "term_type: Invalid tag (0x%X)\n", obj);
}
default:
erts_exit(ERTS_ABORT_EXIT, "term_type: Invalid tag (0x%X)\n", obj);
}
}
if the return result BIF_RET(ERTS_MAKE_AM(βXXXβ)) write to as BIF_RET(am_xxx) is more better