private void HandleString() { while (Peek() != '"' && !IsAtEnd()) { if (Peek() == '\n') { line++; } Advance(); } if (IsAtEnd()) { // we've hit the end before we found the closing quotes CsLox.Error(line, "Unterminated string"); return; } // consume the closing quotes Advance(); // trim the surrounding quotes away string value = source.Substring(start + 1, current - 1); AddToken(TokenType.String, value); }
private void ScanToken() { char c = Advance(); switch (c) { case '(': AddToken(TokenType.LeftParen); break; case ')': AddToken(TokenType.RightParen); break; case '{': AddToken(TokenType.LeftBrace); break; case '}': AddToken(TokenType.RightBrace); break; case ',': AddToken(TokenType.Comma); break; case '.': AddToken(TokenType.Dot); break; case '-': AddToken(TokenType.Minus); break; case '+': AddToken(TokenType.Plus); break; case ';': AddToken(TokenType.Semicolon); break; case '*': AddToken(TokenType.Star); break; case '!': AddToken(FollowedBy('=') ? TokenType.BangEqual : TokenType.Bang); break; case '=': AddToken(FollowedBy('=') ? TokenType.EqualEqual : TokenType.Equal); break; case '<': AddToken(FollowedBy('=') ? TokenType.LessEqual : TokenType.Less); break; case '>': AddToken(FollowedBy('=') ? TokenType.GreaterEqual : TokenType.Greater); break; case '/': if (FollowedBy('/')) { // a comment goes until the end of the line while (Peek() != '\n' && !IsAtEnd()) { Advance(); } } else { AddToken(TokenType.Slash); } break; case ' ': case '\r': case '\t': // ignore whitespaces break; case '\n': line++; break; case '"': HandleString(); break; default: if (IsDigit(c)) { HandleNumber(); } else if (IsAlpha(c)) { HandleIdentifier(); } else { CsLox.Error(line, $"Unexpected character '{c}'."); } break; } }