This commit is contained in:
2026-01-13 22:52:55 +08:00
commit 211a837468
18 changed files with 2831 additions and 0 deletions

88
lexer.h Normal file
View File

@@ -0,0 +1,88 @@
#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