#pragma once // lexer.h -- Token types, tokenizer interface, and color scheme // // Follows the Focus editor pattern: a universal Token_Type enum shared by all // languages, a per-byte token-type array on each buffer, and language-specific // tokenizer functions that fill that array. #include "base/base_core.h" //////////////////////////////// // Token types (universal across all languages) // // The enum value doubles as an index into the color map, so CODE_DEFAULT // must be 0. Keep this list ordered -- rendering indexes directly. typedef enum Token_Type { TOK_DEFAULT = 0, TOK_COMMENT, TOK_MULTILINE_COMMENT, TOK_STRING_LITERAL, TOK_CHAR_LITERAL, TOK_NUMBER, TOK_IDENTIFIER, TOK_FUNCTION, TOK_KEYWORD, TOK_TYPE, TOK_VALUE, // true, false, NULL, nullptr TOK_MODIFIER, // const, static, volatile, extern ... TOK_DIRECTIVE, // #include, #define, ... TOK_PUNCTUATION, TOK_OPERATION, TOK_INVALID, TOK_COUNT } Token_Type; //////////////////////////////// // Language enum typedef enum Lang { LANG_PLAIN_TEXT = 0, LANG_C, LANG_GO, LANG_JS, LANG_LUA, LANG_SQL, LANG_COUNT } Lang; // Human-readable language names (indexed by Lang) extern const char *g_lang_names[LANG_COUNT]; //////////////////////////////// // Tokenizer state (shared by all language tokenizers) typedef struct Tokenizer { const char *buf; // start of buffer data const char *t; // current scan cursor const char *max_t; // one past end const char *start_t; // cursor at start of current token } Tokenizer; //////////////////////////////// // Token (returned by get_next_token functions) typedef struct Token { S32 start; // byte offset into buffer S32 len; // byte length of token Token_Type type; } Token; //////////////////////////////// // Language tokenizer function signature // // A tokenizer function takes a buffer's data + length, and writes token types // into the `out_tokens` array (one byte per source byte, same length as data). // This is the Focus "paint the token array" approach. typedef void (*LexerTokenizeFn)(const char *data, S32 length, U8 *out_tokens); // Get the tokenizer function for a language. static LexerTokenizeFn lexer_get_tokenize_fn(Lang lang); // Detect language from a file name / extension. static Lang lexer_detect_lang(const char *filename); //////////////////////////////// // Common tokenizer helpers (usable by all language tokenizers) static void tokenizer_init(Tokenizer *tok, const char *data, S32 length); static void tokenizer_eat_whitespace(Tokenizer *tok); static void tokenizer_eat_until_newline(Tokenizer *tok);