89 lines
2.1 KiB
C++
89 lines
2.1 KiB
C++
#ifndef CAMELLYA_LEXER_H
|
|
#define CAMELLYA_LEXER_H
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <optional>
|
|
#include <variant>
|
|
|
|
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<std::monostate, double, std::string> 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<typename T>
|
|
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<Token> tokenize();
|
|
|
|
private:
|
|
std::string source_;
|
|
size_t start_ = 0;
|
|
size_t current_ = 0;
|
|
int line_ = 1;
|
|
int column_ = 1;
|
|
std::vector<Token> 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<std::monostate, double, std::string> 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
|