/* =====================================
 * Generated by Mod-c 0.26.5
 * HEADER Lexer MODULE
 * ===================================== */

#ifndef MODC_MODULE_Lexer_H
#define MODC_MODULE_Lexer_H

#include <stdint.h>
#include <stdbool.h>
#include <assert.h>

#define nil ((void *)0)
#define NIL nil
typedef uint8_t byte;
typedef const char* string;
typedef int integer;
typedef unsigned int cardinal;
typedef float real;

/**
 * Mod-c
 * By M. Scott Reynolds
 * Date 27 July 2026
 *
 * lexer.mc - Lexer/tokenizer for Mod-c source code
 * 27 July 2026 - Conversion to .mc started.
 */

/* === IMPORT === */
#include "stdio.h"

/* === IMPORT === */
#include "string.h"

/* === IMPORT === */
#include "stddef.h"

/* === IMPORT === */
#include "stdbool.h"

/* === IMPORT === */
#include "ctype.h"

/**
 * Token kinds recognized by the TMod-c lexer.
 * Ordered roughly by category for readability.
 * Updated 28 March 2026 for grammar 0.6.2
 */

/* === TYPE EXPORT === */
typedef enum {
    TOK_EOF = 0,
    TOK_IDENT = 1,
    TOK_NUMBER = 2,
    TOK_REAL = 3,
    TOK_CHAR = 4,
    TOK_STRING = 5,
    TOK_PREPROCESSOR = 6,
    TOK_COMMENT = 7,
    TOK_COMMENT_SINGLE = 8,
    TOK_COMMENT_MULTI = 9,
    TOK_COMMENT_PASCAL = 10,
    TOK_DOC_COMMENT = 11,
    TOK_SEMICOLON = 12,
    TOK_COLON = 13,
    TOK_COLON_COLON = 14,
    TOK_COLON_EQ = 15,
    TOK_COMMA = 16,
    TOK_LPAREN = 17,
    TOK_RPAREN = 18,
    TOK_LBRACKET = 19,
    TOK_RBRACKET = 20,
    TOK_LBRACE = 21,
    TOK_RBRACE = 22,
    TOK_NEWLINE = 23,
    TOK_QUESTION = 24,
    TOK_ADD = 25,
    TOK_SUB = 26,
    TOK_MUL = 27,
    TOK_DIV = 28,
    TOK_MOD = 29,
    TOK_EQ = 30,
    TOK_EQ_EQ = 31,
    TOK_LESS_EQ = 32,
    TOK_LESS = 33,
    TOK_GREATER_EQ = 34,
    TOK_GREATER = 35,
    TOK_NOT_EQ = 36,
    TOK_DOT = 37,
    TOK_DOT_DOT = 38,
    TOK_DOT_DOT_DOT = 39,
    TOK_NOT = 40,
    TOK_POWER = 41,
    TOK_CARET = 42,
    TOK_AT = 43,
    TOK_MUL_EQ = 44,
    TOK_DIV_EQ = 45,
    TOK_MOD_EQ = 46,
    TOK_ADD_EQ = 47,
    TOK_SUB_EQ = 48,
    TOK_LSHIFT_EQ = 49,
    TOK_RSHIFT_EQ = 50,
    TOK_AND_EQ = 51,
    TOK_OR_EQ = 52,
    TOK_BITWISE_NOT_EQ = 53,
    TOK_KEYWORD_BEGIN = 54,
    TOK_KEYWORD_END = 55,
    TOK_KEYWORD_IF = 56,
    TOK_KEYWORD_THEN = 57,
    TOK_KEYWORD_ELSE = 58,
    TOK_KEYWORD_ELSIF = 59,
    TOK_KEYWORD_FOR = 60,
    TOK_KEYWORD_TO = 61,
    TOK_KEYWORD_BY = 62,
    TOK_KEYWORD_DO = 63,
    TOK_KEYWORD_DOWNTO = 64,
    TOK_KEYWORD_PROGRAM = 65,
    TOK_KEYWORD_MODULE = 66,
    TOK_KEYWORD_HEADER = 67,
    TOK_KEYWORD_IMPORT = 68,
    TOK_KEYWORD_FROM = 69,
    TOK_KEYWORD_PROCEDURE = 70,
    TOK_KEYWORD_FUNCTION = 71,
    TOK_KEYWORD_FORWARD = 72,
    TOK_KEYWORD_EXPORT = 73,
    TOK_KEYWORD_VAR = 74,
    TOK_KEYWORD_LET = 75,
    TOK_KEYWORD_LEN = 76,
    TOK_KEYWORD_CONST = 77,
    TOK_KEYWORD_WHILE = 78,
    TOK_KEYWORD_LOOP = 79,
    TOK_KEYWORD_REPEAT = 80,
    TOK_KEYWORD_UNTIL = 81,
    TOK_KEYWORD_INC = 82,
    TOK_KEYWORD_DEC = 83,
    TOK_KEYWORD_TYPE = 84,
    TOK_KEYWORD_AS = 85,
    TOK_KEYWORD_CAST = 86,
    TOK_KEYWORD_DIV = 87,
    TOK_KEYWORD_MOD = 88,
    TOK_KEYWORD_AND = 89,
    TOK_KEYWORD_OR = 90,
    TOK_KEYWORD_NOT = 91,
    TOK_KEYWORD_XOR = 92,
    TOK_KEYWORD_REQUIRE = 93,
    TOK_KEYWORD_ENSURE = 94,
    TOK_KEYWORD_INVARIANT = 95,
    TOK_KEYWORD_SWITCH = 96,
    TOK_KEYWORD_CASE = 97,
    TOK_KEYWORD_DEFAULT = 98,
    TOK_KEYWORD_BREAK = 99,
    TOK_KEYWORD_CONTINUE = 100,
    TOK_KEYWORD_RETURN = 101,
    TOK_KEYWORD_DEFER = 102,
    TOK_KEYWORD_DEBUG = 103,
    TOK_KEYWORD_RECURSIVE = 104,
    TOK_KEYWORD_STRUCT = 105,
    TOK_KEYWORD_EXTENDS = 106,
    TOK_KEYWORD_UNION = 107,
    TOK_KEYWORD_ARRAY = 108,
    TOK_KEYWORD_POINTER = 109,
    TOK_KEYWORD_OPAQUE = 110,
    TOK_KEYWORD_REF = 111,
    TOK_KEYWORD_IN = 112,
    TOK_KEYWORD_IS = 113,
    TOK_KEYWORD_OF = 114,
    TOK_KEYWORD_ENUM = 115,
    TOK_KEYWORD_ASSERT = 116,
    TOK_KEYWORD_SIZEOF = 117,
    TOK_KEYWORD_EXTERN = 118,
    TOK_KEYWORD_PACKED = 119,
    TOK_KEYWORD_STATIC = 120,
    TOK_BITWISE_AND = 121,
    TOK_BITWISE_OR = 122,
    TOK_BITWISE_NOT = 123,
    TOK_BITWISE_LSHIFT = 124,
    TOK_BITWISE_RSHIFT = 125,
    TOK_ERROR = 126
} TokenKind;

/**
 * Single token produced by the lexer.
 * Points into the original source buffer (no copying of text).
 * For TOK_ERROR, error_msg points to a static or pre-allocated error string.
 */

/* === TYPE EXPORT === */
typedef struct TToken TToken;
typedef struct TToken {
    TokenKind kind;
    const char* start;
    size_t length;
    int line;
    int column;
    const char* error_msg;
} TToken;

/* === TYPE EXPORT === */
typedef TToken* pToken;

/**
 * Lexer state.
 * Non-owning pointer to source buffer; does not copy or modify it.
 */

/* === TYPE EXPORT === */
typedef struct TLexer TLexer;
typedef struct TLexer {
    const char* start;
    const char* current;
    int line;
    int column;
} TLexer;

/* === TYPE EXPORT === */
typedef TLexer* pLexer;

/**
 * Initialize lexer state with source buffer.
 * Source must remain valid for the lifetime of the lexer.
 *
 * @param lexer 			Lexer state to initialize
 * @param source 			Null-terminated source code buffer.
 */

/* === PROC/FUNC EXPORT === */
void TLexer__init(TLexer* lexer, const char* source);

/**
 * Get the next token from the source.
 * Advance internal position; returns TOK_EOF when exhausted.
 * Sets error_msg on TOK_ERROR.
 */

/* === PROC/FUNC EXPORT === */
TToken TLexer__next(TLexer* lexer);

/**
 * Debug: return human-readable string for a TokenKind.
 */

/* === PROC/FUNC EXPORT === */
const char* TokenKind__string(TokenKind k);

/**
 * Debug print a token (kind, location, text snippet).
 * For debugging and error reporting.
 */

/* === PROC/FUNC EXPORT === */
void TToken__print(TToken* tok);

/**
 * Lookup keyword by case-insensitive comparison.
 * Keywords in table are UPPERCASE.
 * Returns TOK_IDENT if no match (preserves original case for identifiers).
 */

/**
 * Advance offsets to the next character, updating line/column.
 */

/**
 * Peek at the current character (safe).
 */

/**
 * Peek at the next character (safe at EOF).
 */

/**
 * Is character valid start of identifier?
 */

/**
 * Is character valid inside identifier?
 */

/**
 * Check for line continuation: \ followed by newline.
 */

/**
 * Match expected character and advance if it matches.
 */

/**
 * Create a zero-length token (used for single-char tokens).
 */

/**
 * Create token with explicit length.
 */

/**
 * Create error token.
 */

/**
 * Initialize lexer state.
 */

/* === PROC/FUNC EXPORT === */
void TLexer__init(TLexer* l, const char* source);

/**
 * Return the next token from source
 */

/* === PROC/FUNC EXPORT === */
TToken TLexer__next(TLexer* l);

/**
 * Return human-readable string for TokenKind.
 */

/* === PROC/FUNC EXPORT === */
const char* TokenKind__string(const TokenKind k);

/**
 * Print token info.
 */

/* === PROC/FUNC EXPORT === */
void TToken__print(TToken* t);

void Lexer(TLexer* lexer, const char* source);

#endif /* MODC_MODULE_Lexer_H */
