#ifndef LEXER_H
#define LEXER_H

#include "ccc.h"

enum token_type {
    TK_NOT_FOUND = 0,
    TK_IDENT = 1,
    TK_INT_LIT = 2,
    TK_FLOAT_LIT = 3,
    TK_CHAR_LIT = 4,
    TK_STR_LIT = 5,
    TK_HASHTAG = 6,
    TK_LPAREN = 7,
    TK_RPAREN = 8,
    TK_LCURLY = 9,
    TK_RCURLY = 10,
    TK_LSQUARE = 11,
    TK_RSQUARE = 12,
    TK_COLON = 13,
    TK_SEMI = 14,
    TK_COMMA = 15,
    TK_DOT = 16,
    TK_QMARK = 17,
    TK_NOT = 18,
    TK_NEQ = 19,
    TK_XOR = 20,
    TK_XEQ = 21,
    TK_AMP = 22,
    TK_LOG_AND = 23,
    TK_AND_EQ = 24,
    TK_STAR = 25,
    TK_MUL_EQ = 26,
    TK_NEG = 27,
    TK_NEG_EQ = 28,
    TK_ARROW = 29,
    TK_ASSIGN = 30,
    TK_TEST_EQ = 31,
    TK_PLUS = 32,
    TK_PLUS_EQ = 33,
    TK_BSLASH = 34,
    TK_PIPE = 35,
    TK_LOG_PIPE = 36,
    TK_PIPE_EQ = 37,
    TK_DIV = 38,
    TK_DIV_EQ = 39,
    TK_MOD = 40,
    TK_MOD_EQ = 41,
    TK_LT = 42,
    TK_GT = 43,
    TK_LEQ = 44,
    TK_GEQ = 45,
    TK_SHR = 46,
    TK_SHR_EQ = 47,
    TK_SHL = 48,
    TK_SHL_EQ = 49,
};
extern const char* token_labels[];

struct token {
    enum token_type type;
    union {
        char* ident;
        integral_t int_lit;
        floating_t float_lit;
        char char_lit;
        char* str_lit;
        void* unused;
    } data;

    const char* PATH;
    unsigned long LINE;
    unsigned long COL;
};

void lexer_load(const char* path);
void lexer_close();
bool lexer_peek(struct token* p_token);
bool lexer_pop(struct token* p_token);

#endif
