diff options
author | Tom Willemse | 2021-07-08 00:14:31 -0700 |
---|---|---|
committer | Tom Willemse | 2021-07-08 02:25:13 -0700 |
commit | 68a2ebd34fc94488e89ffb82b359ec6e7e152ae9 (patch) | |
tree | 0dbbe26aff8fc38805b4b3780ae7842c433b9522 /src/com/craftinginterpreters/lox/Scanner.java | |
parent | 62bd0f83dc909547a69abb8b0aed40cf098b4c95 (diff) | |
download | crafting-interpreters-68a2ebd34fc94488e89ffb82b359ec6e7e152ae9.tar.gz crafting-interpreters-68a2ebd34fc94488e89ffb82b359ec6e7e152ae9.zip |
Restructure project to make room for clox
Diffstat (limited to 'src/com/craftinginterpreters/lox/Scanner.java')
-rw-r--r-- | src/com/craftinginterpreters/lox/Scanner.java | 207 |
1 files changed, 0 insertions, 207 deletions
diff --git a/src/com/craftinginterpreters/lox/Scanner.java b/src/com/craftinginterpreters/lox/Scanner.java deleted file mode 100644 index e21f701..0000000 --- a/src/com/craftinginterpreters/lox/Scanner.java +++ /dev/null @@ -1,207 +0,0 @@ -package com.craftinginterpreters.lox; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static com.craftinginterpreters.lox.TokenType.*; - -class Scanner { - private final String source; - private final List<Token> tokens = new ArrayList<>(); - private int start = 0; - private int current = 0; - private int line = 1; - private static final Map<String, TokenType> keywords; - - static { - keywords = new HashMap<>(); - keywords.put("and", AND); - keywords.put("class", CLASS); - keywords.put("else", ELSE); - keywords.put("false", FALSE); - keywords.put("for", FOR); - keywords.put("fun", FUN); - keywords.put("if", IF); - keywords.put("nil", NIL); - keywords.put("or", OR); - keywords.put("print", PRINT); - keywords.put("return", RETURN); - keywords.put("super", SUPER); - keywords.put("this", THIS); - keywords.put("true", TRUE); - keywords.put("var", VAR); - keywords.put("while", WHILE); - } - - Scanner(String source) { - this.source = source; - } - - List<Token> scanTokens() { - while (!isAtEnd()) { - // We are at the beginning of the next lexeme. - start = current; - scanToken(); - } - - tokens.add(new Token(EOF, "", null, line)); - return tokens; - } - - private void scanToken() { - char c = advance(); - - switch (c) { - case '(': addToken(LEFT_PAREN); break; - case ')': addToken(RIGHT_PAREN); break; - case '{': addToken(LEFT_BRACE); break; - case '}': addToken(RIGHT_BRACE); break; - case ',': addToken(COMMA); break; - case '.': addToken(DOT); break; - case '-': addToken(MINUS); break; - case '+': addToken(PLUS); break; - case ';': addToken(SEMICOLON); break; - case '*': addToken(STAR); break; - case '!': - addToken(match('=') ? BANG_EQUAL : BANG); - break; - case '=': - addToken(match('=') ? EQUAL_EQUAL : EQUAL); - break; - case '<': - addToken(match('=') ? LESS_EQUAL : LESS); - break; - case '>': - addToken(match('=') ? GREATER_EQUAL : GREATER); - break; - case '/': - if (match('/')) { - // A comment goes until the end of the line. - while (peek() != '\n' && !isAtEnd()) advance(); - } else { - addToken(SLASH); - } - break; - - case ' ': - case '\r': - case '\t': - // Ignore whitespace. - break; - - // I guess this code isn't meant to run on Mac OS 9 and before. - case '\n': - line++; - break; - - case '"': string(); break; - - default: - if (isDigit(c)) { - number(); - } else if (isAlpha(c)) { - identifier(); - } else { - Lox.error(line, "Unexpected character."); - } - break; - } - } - - private void identifier() { - while (isAlphaNumeric(peek())) advance(); - - String text = source.substring(start, current); - TokenType type = keywords.get(text); - if (type == null) type = IDENTIFIER; - addToken(type); - } - - private void number() { - while (isDigit(peek())) advance(); - - // Look for a fractional part. - if (peek() == '.' && isDigit(peekNext())) { - // Consume the "." - advance(); - - while (isDigit(peek())) advance(); - } - - addToken(NUMBER, - Double.parseDouble(source.substring(start, current))); - } - - // I guess we won't be able to include escaped characters in the string? At - // least not escaped " characters. - private void string() { - while (peek() != '"' && !isAtEnd()) { - if (peek() == '\n') line++; - advance(); - } - - if (isAtEnd()) { - Lox.error(line, "Unterminated string."); - return; - } - - // The closing ". - advance(); - - // Trim the surrounding quotes. - String value = source.substring(start + 1, current - 1); - addToken(STRING, value); - } - - private boolean match(char expected) { - if (isAtEnd()) return false; - if (source.charAt(current) != expected) return false; - - current++; - return true; - } - - private char peek() { - if (isAtEnd()) return '\0'; - return source.charAt(current); - } - - private char peekNext() { - if (current + 1 >= source.length()) return '\0'; - return source.charAt(current + 1); - } - - private boolean isAlpha(char c) { - return (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - c == '_'; - } - - private boolean isAlphaNumeric(char c) { - return isAlpha(c) || isDigit(c); - } - - private boolean isDigit(char c) { - return c >= '0' && c <= '9'; - } - - private boolean isAtEnd() { - return current >= source.length(); - } - - private char advance() { - current++; - return source.charAt(current - 1); - } - - private void addToken(TokenType type) { - addToken(type, null); - } - - private void addToken(TokenType type, Object literal) { - String text = source.substring(start, current); - tokens.add(new Token(type, text, literal, line)); - } -} |