#include <stdbool.h>
#include <string.h>

#include "tokenizer/Token.h"

const char* tGetName(Token token) {
    switch(token) {
        case T_VOID: return "void";
        case T_INT: return "int";
        case T_BOOL: return "bool";
        case T_FLOAT: return "float";
        case T_CONST_INT: return "const int";
        case T_CONST_FLOAT: return "const float";
        case T_TEXT: return "text";
        case T_NULL: return "null";
        case T_TRUE: return "true";
        case T_FALSE: return "false";
        case T_ADD: return "+";
        case T_SUB: return "-";
        case T_MUL: return "*";
        case T_DIV: return "/";
        case T_MOD: return "%";
        case T_LESS: return "<";
        case T_LESS_EQUAL: return "<=";
        case T_GREATER: return ">";
        case T_GREATER_EQUAL: return ">=";
        case T_EQUAL: return "==";
        case T_NOT_EQUAL: return "!=";
        case T_NOT: return "!";
        case T_AND: return "&&";
        case T_OR: return "||";
        case T_BIT_NOT: return "~";
        case T_BIT_AND: return "&";
        case T_BIT_OR: return "|";
        case T_BIT_XOR: return "^";
        case T_LEFT_SHIFT: return "<<";
        case T_RIGHT_SHIFT: return ">>";
        case T_SET: return "=";
        case T_ADD_SET: return "+=";
        case T_SUB_SET: return "-=";
        case T_MUL_SET: return "*=";
        case T_DIV_SET: return "/=";
        case T_MOD_SET: return "%=";
        case T_BIT_AND_SET: return "&=";
        case T_BIT_OR_SET: return "|=";
        case T_BIT_XOR_SET: return "^=";
        case T_LEFT_SHIFT_SET: return "<<=";
        case T_RIGHT_SHIFT_SET: return ">>=";
        case T_INCREMENT: return "++";
        case T_DECREMENT: return "--";
        case T_LITERAL: return "literal";
        case T_PRINT: return "print";
        case T_IF: return "if";
        case T_ELSE: return "else";
        case T_WHILE: return "while";
        case T_FOR: return "for";
        case T_BREAK: return "break";
        case T_CONTINUE: return "continue";
        case T_RETURN: return "return";
        case T_STRUCT: return "struct";
        case T_COMMA: return ",";
        case T_SEMICOLON: return ";";
        case T_OPEN_BRACKET: return "(";
        case T_CLOSE_BRACKET: return ")";
        case T_OPEN_CURVED_BRACKET: return "{";
        case T_CLOSE_CURVED_BRACKET: return "}";
        case T_POINT: return ".";
        case T_OPEN_SQUARE_BRACKET: return "[";
        case T_CLOSE_SQUARE_BRACKET: return "]";
        case T_END: return "end";
    }
    return "unknown";
}

#define MATCH_TOKEN(tokenName, token)                                          \
    if(strcmp(name, tokenName) == 0) {                                         \
        return token;                                                          \
    }

Token tFromName(const char* name) {
    MATCH_TOKEN("print", T_PRINT);
    MATCH_TOKEN("null", T_NULL);
    MATCH_TOKEN("true", T_TRUE);
    MATCH_TOKEN("false", T_FALSE);
    MATCH_TOKEN("return", T_RETURN);
    MATCH_TOKEN("if", T_IF);
    MATCH_TOKEN("else", T_ELSE);
    MATCH_TOKEN("while", T_WHILE);
    MATCH_TOKEN("for", T_FOR);
    MATCH_TOKEN("break", T_BREAK);
    MATCH_TOKEN("continue", T_CONTINUE);
    MATCH_TOKEN("int", T_INT);
    MATCH_TOKEN("void", T_VOID);
    MATCH_TOKEN("bool", T_BOOL);
    MATCH_TOKEN("float", T_FLOAT);
    MATCH_TOKEN("struct", T_STRUCT);
    return T_END;
}