#include "vm.hpp"
#include "json.hpp"

using namespace sliger;

auto sliger::maybe_op_to_string(uint32_t value) -> std::string
{
    switch (static_cast<Op>(value)) {
            /* clang-format off */
        case Op::Nop: return "Nop";
        case Op::PushNull: return "PushNull";
        case Op::PushInt: return "PushInt";
        case Op::PushBool: return "PushBool";
        case Op::PushString: return "PushString";
        case Op::PushPtr: return "PushPtr";
        case Op::Pop: return "Pop";
        case Op::ReserveStatic: return "ReserveStatic";
        case Op::LoadStatic: return "LoadStatic";
        case Op::StoreStatic: return "StoreStatic";
        case Op::LoadLocal: return "LoadLocal";
        case Op::StoreLocal: return "StoreLocal";
        case Op::Call: return "Call";
        case Op::Return: return "Return";
        case Op::Jump: return "Jump";
        case Op::JumpIfTrue: return "JumpIfTrue";
        case Op::Builtin: return "Builtin";
        case Op::Add: return "Add";
        case Op::Subtract: return "Subtract";
        case Op::Multiply: return "Multiply";
        case Op::Divide: return "Divide";
        case Op::Remainder: return "Remainder";
        case Op::Equal: return "Equal";
        case Op::LessThan: return "LessThan";
        case Op::And: return "And";
        case Op::Or: return "Or";
        case Op::Xor: return "Xor";
        case Op::Not: return "Not";
        case Op::SourceMap: return "SourceMap";
        /* clang-format on */
        default:
            return std::to_string(value);
    }
}

auto json::tok_typ_to_string(json::TokTyp typ) -> std::string
{
    using namespace json;
    
    switch (typ) {
        case TokTyp::Eof:
            return "Eof";
        case TokTyp::String:
            return "String";
        case TokTyp::Float:
            return "Float";
        case TokTyp::False:
            return "False";
        case TokTyp::True:
            return "True";
        case TokTyp::Null:
            return "Null";
        case TokTyp::LBrace:
            return "LBrace";
        case TokTyp::RBrace:
            return "RBrace";
        case TokTyp::LBracket:
            return "LBracket";
        case TokTyp::RBracket:
            return "RBracket";
        case TokTyp::Comma:
            return "Comma";
        case TokTyp::Colon:
            return "Colon";
    }
    std::unreachable();
}