diff --git a/cclox_src/scanner.cc b/cclox_src/scanner.cc index dc62654..457a4f0 100644 --- a/cclox_src/scanner.cc +++ b/cclox_src/scanner.cc @@ -33,6 +33,38 @@ void Scanner::scan_token() { case '+': add_token(TokenType::PLUS); break; case ';': add_token(TokenType::SEMICOLON); break; case '*': add_token(TokenType::STAR); break; + case '!': + add_token(match('=') ? TokenType::BANG_EQUAL : TokenType::BANG); + break; + case '=': + add_token(match('=') ? TokenType::EQUAL_EQUAL : TokenType::EQUAL); + break; + case '<': + add_token(match('=') ? TokenType::LESS_EQUAL : TokenType::LESS); + break; + case '>': + add_token(match('=') ? TokenType::GREATER_EQUAL : TokenType::GREATER); + break; + case '/': + if (match('/')) { + while (peek() != '\n' && !is_at_end()) { + advance(); + } + } else { + add_token(TokenType::SLASH); + } + + break; + case ' ': + case '\r': + case '\t': + break; + case '\n': + ++line; + break; + case '"': + string(); + break; default: error_handler.error(line, "Unexpected character."); break; @@ -43,6 +75,23 @@ char Scanner::advance() { return code.at(current++); } +bool Scanner::match(char expected) { + if (is_at_end() || peek() != expected) { + return false; + } + + current++; + return true; +} + +char Scanner::peek() { + if (is_at_end()) { + return '\0'; + } + + return code.at(current); +} + void Scanner::add_token(TokenType type) { add_token(type, Object{}); } @@ -51,3 +100,22 @@ void Scanner::add_token(TokenType type, Object literal) { std::string text = code.substr(start, current - start); tokens.push_back(Token(type, text, literal, line)); } + +void Scanner::string() { + while (peek() != '"' && !is_at_end()) { + if (peek() == '\n') line++; + advance(); + } + + if (is_at_end()) { + error_handler.error(line, "Unterminated string."); + return; + } + + // The closing ". + advance(); + + // Trim the surrounding quotes. + std::string value = code.substr(start + 1, current - 1); + add_token(TokenType::STRING, Object(StringObjectType::LITERAL, value)); +} diff --git a/cclox_src/scanner.hh b/cclox_src/scanner.hh index 5931a4f..639c563 100644 --- a/cclox_src/scanner.hh +++ b/cclox_src/scanner.hh @@ -10,8 +10,11 @@ struct Scanner { bool is_at_end(); void scan_token(); char advance(); + bool match(char expected); + char peek(); void add_token(TokenType type); void add_token(TokenType type, Object literal); + void string(); std::string code; std::vector tokens;