Chapter 16.4
This commit is contained in:
parent
eb6f33a2b2
commit
350a5cc4e3
1 changed files with 74 additions and 0 deletions
|
@ -18,6 +18,10 @@ void initScanner(const char *source) {
|
|||
scanner.line = 1;
|
||||
}
|
||||
|
||||
static bool isAlpha(char c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
|
||||
}
|
||||
|
||||
static bool isDigit(char c) { return c >= '0' && c <= '9'; }
|
||||
|
||||
static bool isAtEnd() { return *scanner.current == '\0'; }
|
||||
|
@ -91,6 +95,73 @@ static void skipWhitespace() {
|
|||
}
|
||||
}
|
||||
|
||||
static TokenType checkKeyword(int start, int length, const char *rest,
|
||||
TokenType type) {
|
||||
if (scanner.current - scanner.start == start + length &&
|
||||
memcmp(scanner.start + start, rest, length) == 0) {
|
||||
return type;
|
||||
}
|
||||
|
||||
return TOKEN_IDENTIFIER;
|
||||
}
|
||||
|
||||
static TokenType identifierType() {
|
||||
switch (scanner.start[0]) {
|
||||
case 'a':
|
||||
return checkKeyword(1, 2, "nd", TOKEN_AND);
|
||||
case 'c':
|
||||
return checkKeyword(1, 4, "lass", TOKEN_CLASS);
|
||||
case 'e':
|
||||
return checkKeyword(1, 3, "lse", TOKEN_ELSE);
|
||||
case 'f':
|
||||
if (scanner.current - scanner.start > 1) {
|
||||
switch (scanner.start[1]) {
|
||||
case 'a':
|
||||
return checkKeyword(2, 3, "lse", TOKEN_FALSE);
|
||||
case 'o':
|
||||
return checkKeyword(2, 1, "or", TOKEN_FOR);
|
||||
case 'u':
|
||||
return checkKeyword(2, 1, "n", TOKEN_FUN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
return checkKeyword(1, 1, "f", TOKEN_IF);
|
||||
case 'n':
|
||||
return checkKeyword(1, 2, "il", TOKEN_NIL);
|
||||
case 'o':
|
||||
return checkKeyword(1, 1, "r", TOKEN_OR);
|
||||
case 'p':
|
||||
return checkKeyword(1, 4, "rint", TOKEN_PRINT);
|
||||
case 'r':
|
||||
return checkKeyword(1, 5, "eturn", TOKEN_RETURN);
|
||||
case 's':
|
||||
return checkKeyword(1, 4, "uper", TOKEN_SUPER);
|
||||
case 't':
|
||||
if (scanner.current - scanner.start > 1) {
|
||||
switch (scanner.start[1]) {
|
||||
case 'h':
|
||||
return checkKeyword(2, 2, "is", TOKEN_THIS);
|
||||
case 'r':
|
||||
return checkKeyword(2, 2, "ue", TOKEN_TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
return checkKeyword(1, 2, "ar", TOKEN_VAR);
|
||||
case 'w':
|
||||
return checkKeyword(1, 4, "hile", TOKEN_WHILE);
|
||||
}
|
||||
|
||||
return TOKEN_IDENTIFIER;
|
||||
}
|
||||
|
||||
static Token identifier() {
|
||||
while (isAlpha(peek()) || isDigit(peek()))
|
||||
advance();
|
||||
return makeToken(identifierType());
|
||||
}
|
||||
|
||||
static Token number() {
|
||||
while (isDigit(peek()))
|
||||
advance();
|
||||
|
@ -130,6 +201,9 @@ Token scanToken() {
|
|||
return makeToken(TOKEN_EOF);
|
||||
|
||||
char c = advance();
|
||||
|
||||
if (isAlpha(c))
|
||||
return identifier();
|
||||
if (isDigit(c))
|
||||
return number();
|
||||
|
||||
|
|
Loading…
Reference in a new issue