diff options
-rw-r--r-- | include/lexer.h | 1 | ||||
-rw-r--r-- | include/token.h | 10 | ||||
-rw-r--r-- | src/lexer.cc | 21 |
3 files changed, 31 insertions, 1 deletions
diff --git a/include/lexer.h b/include/lexer.h index 8122848..4605142 100644 --- a/include/lexer.h +++ b/include/lexer.h @@ -27,6 +27,7 @@ private: private: void string(void); void number(void); + void identifier(void); private: void add_token(token_type_e type); diff --git a/include/token.h b/include/token.h index 176ff27..92106a2 100644 --- a/include/token.h +++ b/include/token.h @@ -45,9 +45,19 @@ #define GENERATE_ENUM(ENUM) ENUM, #define GENERATE_STRING(STRING) #STRING, +#define N_KEYWORDS 16 + typedef enum { FOREACH_TOKEN(GENERATE_ENUM) } token_type_e; static const char *TOKEN_STRING[] = { FOREACH_TOKEN(GENERATE_STRING) }; +static const char *KEYWORD_STRING_MAPPING[N_KEYWORDS] + = { "and", "class", "else", "false", "for", "fun", "if", "nil", + "or", "print", "return", "super", "this", "true", "var", "while" }; + +static const token_type_e KEYWORD_TYPE_MAPPING[N_KEYWORDS] + = { AND, CLASS, ELSE, FALSE, FOR, FUN, IF, NIL, + OR, PRINT, RETURN, SUPER, THIS, TRUE, VAR, WHILE }; + class Token { private: diff --git a/src/lexer.cc b/src/lexer.cc index e2a81cd..e09e187 100644 --- a/src/lexer.cc +++ b/src/lexer.cc @@ -136,6 +136,15 @@ Lexer::number(void) advance(); } + add_token(NUMBER); +} + +void +Lexer::identifier(void) +{ + while (isalnum(peek())) + advance(); + int token_length = m_current - m_start; if (token_length == 0) token_length++; @@ -143,7 +152,14 @@ Lexer::number(void) char *lexeme; asprintf(&lexeme, "%.*s", token_length, m_script + m_start); - add_token(NUMBER); + token_type_e type = IDENTIFIER; + + for (size_t i = 0; i < N_KEYWORDS; i++) { + if (!strcmp(lexeme, KEYWORD_STRING_MAPPING[i])) + type = KEYWORD_TYPE_MAPPING[i]; + } + + add_token(type); } void @@ -238,6 +254,9 @@ Lexer::scan_token(void) if (isdigit(c)) number(); + else if (isalpha(c)) + identifier(); + else { printf("[-] Error: Unexpected character %c in line %lu\n", c, m_line); m_errored = true; |