private void ReadString() { while (Peek() != '"' && !IsAtEnd()) { // Supports multiline strings if (Peek() == '\n') { m_Line++; } Advance(); } // Unterminated string if (IsAtEnd()) { Ori.Error(m_Line, "Unterminated string."); return; } // The closing " Advance(); // Trim the surrounding quotes string value = Substring(m_Start + 1, m_Current - 1); // TODO: If want to support escape sequences, do it here AddToken(TokenType.String, value); }
private void ScanToken() { char c = Advance(); switch (c) { // Braces case '(': AddToken(TokenType.LeftParen); break; case ')': AddToken(TokenType.RightParen); break; case '{': AddToken(TokenType.LeftBrace); break; case '}': AddToken(TokenType.RightBrace); break; case '[': AddToken(TokenType.LeftBrace); break; case ']': AddToken(TokenType.RightBrace); break; // Syntax case ',': AddToken(TokenType.Comma); break; case '.': AddToken(TokenType.Dot); break; case ';': AddToken(TokenType.Semicolon); break; // Math case '-': AddToken(TokenType.Minus); break; case '+': AddToken(TokenType.Plus); break; case '*': AddToken(TokenType.Star); break; case '%': AddToken(TokenType.Modulus); break; // Boolean case '!': AddToken(Match('=') ? TokenType.BangEqual : TokenType.Bang); break; case '=': AddToken(Match('=') ? TokenType.EqualEqual : TokenType.Equal); break; case '<': AddToken(Match('=') ? TokenType.LessEqual : TokenType.Less); break; case '>': AddToken(Match('=') ? TokenType.GreaterEqual : TokenType.Greater); break; // TODO: Bitwise would be implemented the same as above with AND &&, and OR, etc. // This would require removing the && and || in the default case '&': { if (Match('&')) { AddToken(TokenType.And); } else { Ori.Error(m_Line, "Bitwise operators are not yet implemented."); } break; } case '|': { if (Match('|')) { AddToken(TokenType.Or); } else { Ori.Error(m_Line, "Bitwise operators are not yet implemented."); } break; } case '"': ReadString(); break; case '/': { // A comment goes until the end of a line if (Match('/')) { while (Peek() != '\n' && !IsAtEnd()) { Advance(); } } else if (Match('*')) { // Keep on reading comment until it reaches */ while (!(Advance() == '*' && Match('/'))) { ; } } else { AddToken(TokenType.Slash); } break; } case ' ': case '\r': case '\t': // Ignore whitespace break; case '\n': m_Line++; break; default: { if (IsDigit(c)) { ReadNumber(); } else if (IsAlpha(c)) { ReadIdentifier(); } else { Ori.Error(m_Line, "Unexpected character."); } break; } } }