Beispiel #1
0
        /// <summary>
        /// Skip through a block comment.
        /// </summary>
        private void SkipBlockComment()
        {
            // Stop when (Peek == * && PeekNext == /) ---> (Peek != * || PeekNext != /)
            // Keep moving through the comment until it reaches */
            while ((Peek() != '*' || PeekNext() != '/') && IsAtEnd() == false)
            {
                // Allow multi-line block comments
                if (Peek() == '\n')
                {
                    line++;
                }

                Advance();
            }

            // Unterminated comment
            if (IsAtEnd())
            {
                Min.Error(line, "Unterminated block comment.");
                return;
            }

            // Move past the closing comment */
            Advance();
            Advance();
        }
Beispiel #2
0
        /// <summary>
        /// Read a full string between quotes " and add it as a token.
        /// </summary>
        private void ReadString()
        {
            // Keep moving through the string until it reaches "
            while (Peek() != '"' && IsAtEnd() == false)
            {
                // Allow multi-line strings
                if (Peek() == '\n')
                {
                    line++;
                }

                Advance();
            }

            // Unterminated string
            if (IsAtEnd())
            {
                Min.Error(line, "Unterminated string.");
                return;
            }

            // Move past the closing quote (")
            Advance();

            // Trim the surrounding quotes
            string value = source.Substring(start + 1, current - 2 - start);

            // TODO: Support escape sequences (unescape them here)

            AddToken(TokenType.STRING, value);
        }
Beispiel #3
0
 /// <summary>
 /// Report a Parsing Error at a specific token.
 /// </summary>
 /// <param name="token">The token that encountered an error.</param>
 /// <param name="message">The message of the error.</param>
 /// <returns>The Parsing Error created as a result.</returns>
 private ParseError Error(Token token, string message)
 {
     Min.Error(token, message);
     return(new ParseError());
 }
Beispiel #4
0
        /// <summary>
        ///  Move through the characters to scan one token and add it to the list of tokens.
        /// </summary>
        private void ScanToken()
        {
            char c = Advance();

            switch (c)
            {
            case '(': AddToken(TokenType.LEFT_PAREN); break;

            case ')': AddToken(TokenType.RIGHT_PAREN); break;

            case '{': AddToken(TokenType.LEFT_BRACE); break;

            case '}': AddToken(TokenType.RIGHT_BRACE); break;

            case ',': AddToken(TokenType.COMMA); break;

            case '.': AddToken(TokenType.DOT); break;

            case ';': AddToken(TokenType.SEMICOLON); break;

            case '+': AddToken(TokenType.PLUS); break;

            case '-': AddToken(TokenType.MINUS); break;

            case '*': AddToken(TokenType.STAR); break;

            case '?': AddToken(TokenType.QUESTION); break;

            case ':': AddToken(TokenType.COLON); break;

            case '!': AddToken(Match('=') ? TokenType.BANG_EQUAL : TokenType.BANG); break;

            case '=': AddToken(Match('=') ? TokenType.EQUAL_EQUAL : TokenType.EQUAL); break;

            case '<': AddToken(Match('=') ? TokenType.LESS_EQUAL : TokenType.LESS); break;

            case '>': AddToken(Match('=') ? TokenType.GREATER_EQUAL : TokenType.GREATER); break;

            case '&':
                if (Match('&'))
                {
                    AddToken(TokenType.AND);
                }
                else
                {
                    // TODO: Bitwise "&" does not exist yet.
                    Min.Error(line, $"Unexpected character \"{c}\"");
                }
                break;

            case '|':
                if (Match('|'))
                {
                    AddToken(TokenType.OR);
                }
                else
                {
                    // TODO: Bitwise "|" does not exist yet.
                    Min.Error(line, $"Unexpected character \"{c}\"");
                }
                break;

            case '/':
                // Comment //
                if (Match('/'))
                {
                    // A comment goes until the end of the line, keep consuming characters until then.
                    while (Peek() != '\n' && IsAtEnd() == false)
                    {
                        Advance();
                    }
                }
                // Block comment /*
                else if (Match('*'))
                {
                    SkipBlockComment();
                }
                // Any other slash /
                else
                {
                    AddToken(TokenType.SLASH);
                }

                break;

            case '"':
                ReadString();
                break;

            case ' ':
            case '\r':
            case '\t':
                // Ignore whitespace
                break;

            case '\n':
                line++;
                break;

            default:
                // Have to go through default because bools/methods don't work in switch/case
                if (IsDigit(c))
                {
                    ReadNumber();
                }
                else if (IsAlpha(c))
                {
                    ReadIdentifier();
                }
                else
                {
                    Min.Error(line, $"Unexpected character \"{c}\"");
                }
                break;
            }
        }