#include "mytypes.h"
#include "dbug.h"
#include "mymacros.h"

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wswitch"

const char* type_to_str(type_t ty)
{
    DBUG_ENTER("type_to_str");

    switch (ty)
    {
    case TY_bool:
        DBUG_RETURN("bool");
    case TY_int:
        DBUG_RETURN("int");
    case TY_float:
        DBUG_RETURN("float");
    case TY_void:
        DBUG_RETURN("void");
    case TY_bool | TY_arr:
        DBUG_RETURN("bool[]");
    case TY_int | TY_arr:
        DBUG_RETURN("int[]");
    case TY_float | TY_arr:
        DBUG_RETURN("float[]");
     case TY_bool | TY_const:
        DBUG_RETURN("const bool");
    case TY_int | TY_const:
        DBUG_RETURN("const int");
    case TY_float | TY_const:
        DBUG_RETURN("const float");
    default:
        DBUG_ASSERT(0, "Unknown type value!");
    }
}

#pragma GCC diagnostic pop

char type_to_char(type_t ty)
{
    DBUG_ENTER("type_to_char");
    if (ty & TY_arr)
    {
        DBUG_RETURN('a');
    }

    switch (TY_FUNDAMENTAL_TYPE(ty))
    {
    case TY_bool:
        DBUG_RETURN('b');
    case TY_int:
        DBUG_RETURN('i');
    case TY_float:
        DBUG_RETURN('f');
    default:
        DBUG_ASSERT(0, "Unknown type value or void (which is usually a missing type char in instructions)!");
    }
}

const char* binop_to_str(binop bop)
{
    const char* tmp = "";
    switch (bop)
    {
    case BO_add:
        tmp = "+";
        break;
    case BO_sub:
        tmp = "-";
        break;
    case BO_mul:
        tmp = "*";
        break;
    case BO_div:
        tmp = "/";
        break;
    case BO_mod:
        tmp = "%";
        break;
    case BO_lt:
        tmp = "<";
        break;
    case BO_le:
        tmp = "<=";
        break;
    case BO_gt:
        tmp = ">";
        break;
    case BO_ge:
        tmp = ">=";
        break;
    case BO_eq:
        tmp = "==";
        break;
    case BO_ne:
        tmp = "!=";
        break;
    case BO_or:
        tmp = "||";
        break;
    case BO_and:
        tmp = "&&";
        break;
    default:
    case BO_unknown:
        DBUG_ASSERT(0, "unknown binop detected!");
    }
    return tmp;
}

const char* monop_to_str(monop op)
{
    switch (op)
    {
    case MO_not:
        return "!";
    case MO_neg:
        return "-";
    case MO_unknown:
        DBUG_ASSERT(0, "unknown binop detected!");
    }
    return "UNKNOWN MONOP";
}