Exemplo n.º 1
0
        private void ReadIdentifierOrKeyword()
        {
            while (char.IsLetter(Current))
            {
                Next();
            }
            var length = _position - _start;
            var text   = _text.ToString(_start, length);

            _kind = SyntaxFacts.GetKeywordKind(text);
            switch (_kind)
            {
            case SyntaxKind.LetKeyword:
            case SyntaxKind.VarKeyword:
            case SyntaxKind.IfKeyword:
            case SyntaxKind.ElseKeyword:
            case SyntaxKind.Identifier:
            case SyntaxKind.WhileKeyword:
            case SyntaxKind.ForKeyword:
            case SyntaxKind.ToKeyword:
                _value = text;
                break;

            case SyntaxKind.TrueKeyword:
                _value = true;
                break;

            case SyntaxKind.FalseKeyword:
                _value = false;
                break;

            default:
                throw new Exception("Unknown identifier");
            }
        }
Exemplo n.º 2
0
        private void ReadIdentifierOrKeyword()
        {
            while (char.IsLetter(Current))
            {
                _position++;
            }

            var length = _position - _start;
            var text   = _text.ToString(_start, length);

            _kind = SyntaxFacts.GetKeywordKind(text);
        }
Exemplo n.º 3
0
        private void ReadIdentifierOrKeyword()
        {
            while (char.IsLetter(Current))
            {
                position++;
            }

            var length = position - start;
            var t      = text.ToString(start, length);

            kind = SyntaxFacts.GetKeywordKind(t);
        }
Exemplo n.º 4
0
        public SyntaxToken Lex()
        {
            if (_position >= _text.Length)
            {
                return(new SyntaxToken(SyntaxKind.EndOfFileToken, _position, "\0", null));
            }

            if (char.IsDigit(Current))
            {
                var start = _position;

                while (char.IsDigit(Current))
                {
                    Next();
                }

                var length = _position - start;
                var text   = _text.Substring(start, length);
                if (!int.TryParse(text, out var value))
                {
                    _diagnostics.Add($"The number {_text} isn't valid Int32.");
                }

                return(new SyntaxToken(SyntaxKind.NumberToken, start, text, value));
            }

            if (char.IsWhiteSpace(Current))
            {
                var start = _position;

                while (char.IsWhiteSpace(Current))
                {
                    Next();
                }

                var length = _position - start;
                var text   = _text.Substring(start, length);
                return(new SyntaxToken(SyntaxKind.WhitespaceToken, start, text, null));
            }

            if (char.IsLetter(Current))
            {
                var start = _position;

                while (char.IsLetter(Current))
                {
                    Next();
                }

                var length = _position - start;
                var text   = _text.Substring(start, length);
                var kind   = SyntaxFacts.GetKeywordKind(text);
                return(new SyntaxToken(kind, start, text, null));
            }

            switch (Current)
            {
            case '+':
                return(new SyntaxToken(SyntaxKind.PlusToken, _position++, "+", null));

            case '-':
                return(new SyntaxToken(SyntaxKind.MinusToken, _position++, "-", null));

            case '*':
                return(new SyntaxToken(SyntaxKind.StarToken, _position++, "*", null));

            case '/':
                return(new SyntaxToken(SyntaxKind.SlashToken, _position++, "/", null));

            case '(':
                return(new SyntaxToken(SyntaxKind.OpenParenthesisToken, _position++, "(", null));

            case ')':
                return(new SyntaxToken(SyntaxKind.CloseParenthesisToken, _position++, ")", null));

            case '&':
                if (Lookahead == '&')
                {
                    return(new SyntaxToken(SyntaxKind.AmpersandAmpersandToken, _position += 2, "&&", null));
                }
                break;

            case '|':
                if (Lookahead == '|')
                {
                    return(new SyntaxToken(SyntaxKind.PipePipeToken, _position += 2, "||", null));
                }
                break;

            case '=':
                if (Lookahead == '=')
                {
                    return(new SyntaxToken(SyntaxKind.EqualsEqualsToken, _position += 2, "==", null));
                }
                break;

            case '!':
                if (Lookahead == '=')
                {
                    return(new SyntaxToken(SyntaxKind.BangEqualsToken, _position += 2, "!=", null));
                }
                else
                {
                    return(new SyntaxToken(SyntaxKind.BangToken, _position++, "!", null));
                }
            }

            _diagnostics.Add($"ERROR: bad character input: '{Current}'");
            return(new SyntaxToken(SyntaxKind.BadToken, _position++, _text.Substring(_position - 1, 1), null));
        }
Exemplo n.º 5
0
        internal SyntaxToken Lex()
        {
            _start = _position;
            _kind  = SyntaxKind.BadToken;
            _value = null;

            switch (Current)
            {
            case '\0':
            {
                _kind = SyntaxKind.EndOfFileToken;
                break;
            }

            case '+':
            {
                MoveNext();
                _kind = SyntaxKind.PlusToken;
                break;
            }

            case '-':
            {
                MoveNext();
                _kind = SyntaxKind.MinusToken;
                break;
            }

            case '*':
            {
                MoveNext();
                _kind = SyntaxKind.StarToken;
                break;
            }

            case '/':
            {
                MoveNext();
                _kind = SyntaxKind.ForwardSlashToken;
                break;
            }

            case '(':
            {
                MoveNext();
                _kind = SyntaxKind.OpenParenthesisToken;
                break;
            }

            case ')':
            {
                MoveNext();
                _kind = SyntaxKind.CloseParenthesisToken;
                break;
            }

            case '{':
            {
                MoveNext();
                _kind = SyntaxKind.OpenBraceToken;
                break;
            }

            case '}':
            {
                MoveNext();
                _kind = SyntaxKind.CloseBraceToken;
                break;
            }

            case '~':
            {
                MoveNext();
                _kind = SyntaxKind.TildeToken;
                break;
            }

            case '^':
            {
                MoveNext();
                _kind = SyntaxKind.HatToken;
                break;
            }

            case '!':
            {
                if (LookAhead == '=')
                {
                    MoveNext(2);
                    _kind = SyntaxKind.BangEqualsToken;
                }
                else
                {
                    MoveNext();
                    _kind = SyntaxKind.BangToken;
                }
                break;
            }

            case '&':
            {
                if (LookAhead == '&')
                {
                    MoveNext(2);
                    _kind = SyntaxKind.AndAndToken;
                }
                else
                {
                    MoveNext();
                    _kind = SyntaxKind.AndToken;
                }
                break;
            }

            case '|':
            {
                if (LookAhead == '|')
                {
                    MoveNext(2);
                    _kind = SyntaxKind.PipePipeToken;
                }
                else
                {
                    MoveNext();
                    _kind = SyntaxKind.PipeToken;
                }
                break;
            }

            case '=':
            {
                if (LookAhead == '=')
                {
                    MoveNext(2);
                    _kind = SyntaxKind.EqualsEqualsToken;
                }
                else
                {
                    MoveNext();
                    _kind = SyntaxKind.EqualsToken;
                }
                break;
            }

            case '<':
            {
                if (LookAhead == '=')
                {
                    MoveNext(2);
                    _kind = SyntaxKind.LessOrEqualsToken;
                }
                else
                {
                    MoveNext();
                    _kind = SyntaxKind.LessToken;
                }
                break;
            }

            case '>':
            {
                if (LookAhead == '=')
                {
                    MoveNext(2);
                    _kind = SyntaxKind.GreaterOrEqualsToken;
                }
                else
                {
                    MoveNext();
                    _kind = SyntaxKind.GreaterToken;
                }
                break;
            }

            case '"':
            {
                ReadString();
                break;
            }

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
            {
                ReadNumbersToken();
                break;
            }

            case ' ':
            case '\t':
            {
                ReadWhitespaceTokens();
                break;
            }

            default:
            {
                if (char.IsLetter(Current))
                {
                    ReadLettersToken();
                }
                else if (char.IsWhiteSpace(Current))
                {
                    ReadWhitespaceTokens();
                }
                else
                {
                    _diagnostics.ReportBadCharacter(_position, Current);
                    MoveNext();
                }
                break;
            }
            }

            {
                var text   = SyntaxFacts.GetText(_kind);
                var length = _position - _start;
                if (text is null)
                {
                    text = _text.ToString(_start, length);
                }

                return(new SyntaxToken(_kind, _start, text, _value));
            }

            void ReadNumbersToken()
            {
                do
                {
                    MoveNext();
                }while (char.IsDigit(Current));

                var length = _position - _start;
                var text   = _text.ToString(_start, length);

                if (!int.TryParse(text, out var value))
                {
                    _diagnostics.ReportInvalidNumber(new TextSpan(_start, length), text, TypeSymbol.Int);
                }

                _kind  = SyntaxKind.NumberToken;
                _value = value;
            }

            void ReadLettersToken()
            {
                do
                {
                    MoveNext();
                }while (char.IsLetter(Current));

                var text = _text.ToString(_start, _position - _start);

                _kind = SyntaxFacts.GetKeywordKind(text);
            }

            void ReadWhitespaceTokens()
            {
                do
                {
                    MoveNext();
                }while (char.IsWhiteSpace(Current));

                _kind = SyntaxKind.WhiteSpaceToken;
            }

            void ReadString()
            {
                MoveNext();

                var done    = false;
                var builder = new StringBuilder();

                while (!done)
                {
                    switch (Current)
                    {
                    case '\0':
                    case '\r':
                    case '\n':
                        var span = new TextSpan(_start, 1);
                        Diagnostics.ReportUnterminatedString(span);
                        done = true;
                        break;

                    case '\\':
                    {
                        if (LookAhead == '"')
                        {
                            MoveNext();
                        }
                        builder.Append(Current);
                        MoveNext();
                        break;
                    }

                    case '"':
                    {
                        done = true;
                        MoveNext();
                        break;
                    }

                    default:
                    {
                        builder.Append(Current);
                        MoveNext();
                        break;
                    }
                    }
                }

                _kind  = SyntaxKind.StringToken;
                _value = builder.ToString();
            }
        }