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;
|
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 isDigit(char c) { return c >= '0' && c <= '9'; }
|
||||||
|
|
||||||
static bool isAtEnd() { return *scanner.current == '\0'; }
|
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() {
|
static Token number() {
|
||||||
while (isDigit(peek()))
|
while (isDigit(peek()))
|
||||||
advance();
|
advance();
|
||||||
|
@ -130,6 +201,9 @@ Token scanToken() {
|
||||||
return makeToken(TOKEN_EOF);
|
return makeToken(TOKEN_EOF);
|
||||||
|
|
||||||
char c = advance();
|
char c = advance();
|
||||||
|
|
||||||
|
if (isAlpha(c))
|
||||||
|
return identifier();
|
||||||
if (isDigit(c))
|
if (isDigit(c))
|
||||||
return number();
|
return number();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue