#ifndef CAMELLYA_LEXER_H #define CAMELLYA_LEXER_H #include #include #include #include namespace camellya { enum class TokenType { // Keywords CLASS, FUNC, NUMBER, STRING, BOOL, LIST, MAP, IF, ELSE, WHILE, FOR, RETURN, VAR, TRUE, FALSE, NIL, THIS, // Operators PLUS, MINUS, STAR, SLASH, PERCENT, EQUAL, EQUAL_EQUAL, BANG_EQUAL, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL, AND, OR, BANG, // Delimiters LEFT_PAREN, RIGHT_PAREN, LEFT_BRACE, RIGHT_BRACE, LEFT_BRACKET, RIGHT_BRACKET, COMMA, DOT, SEMICOLON, COLON, ARROW, // Literals IDENTIFIER, NUMBER_LITERAL, STRING_LITERAL, // Special END_OF_FILE, INVALID }; struct Token { TokenType type; std::string lexeme; std::variant literal; int line; int column; Token(TokenType type, std::string lexeme, int line, int column) : type(type), lexeme(std::move(lexeme)), line(line), column(column) {} template Token(TokenType type, std::string lexeme, T literal, int line, int column) : type(type), lexeme(std::move(lexeme)), literal(std::move(literal)), line(line), column(column) {} }; class Lexer { public: explicit Lexer(std::string source); std::vector tokenize(); private: std::string source_; size_t start_ = 0; size_t current_ = 0; int line_ = 1; int column_ = 1; std::vector tokens_; bool is_at_end() const { return current_ >= source_.length(); } char advance(); char peek() const; char peek_next() const; bool match(char expected); void skip_whitespace(); void skip_comment(); void scan_token(); void add_token(TokenType type); void add_token(TokenType type, std::variant literal); void scan_string(); void scan_number(); void scan_identifier(); TokenType get_keyword_type(const std::string& text) const; }; } // namespace camellya #endif // CAMELLYA_LEXER_H