예제 #1
0
            private static List <AssertionError> AssertReturnStatementSyntax(StatementParseResultBuilderState currentState)
            {
                var nextToken = currentState.Tokens.Skip(currentState.Position + Skip.Return).Take(1).FirstOrDefault();
                var errors    = new List <AssertionError>();

                if (nextToken == default(Token) || nextToken.Kind == SyntaxKind.Semicolon || nextToken.Kind == SyntaxKind.EOF)
                {
                    return(errors);
                }

                var info = new ErrorInfo
                {
                    Kind     = ErrorKind.InvalidToken,
                    Position = currentState.Position + Skip.Return,
                    Source   = ErrorSource.Parser,
                    Tokens   = currentState.Tokens
                };

                if (!IsExpressionToken(nextToken))
                {
                    info.Code = ErrorCode.InvalidReturnExpression;
                    info.Kind = ErrorKind.InvalidToken;
                    errors.Add(Error.Create(info));
                }

                return(errors);
            }
예제 #2
0
 public StatementParseResultBuilder(StatementParseResult currentState)
 {
     internalState = new StatementParseResultBuilderState
     {
         Errors   = currentState.Errors,
         Position = currentState.Position,
         Tokens   = currentState.Tokens
     };
 }
예제 #3
0
        private static bool IsIfElseExpression(StatementParseResultBuilderState currentState, int position)
        {
            var nextToken = currentState.Tokens.Skip(position + Skip.Brace).Take(1).FirstOrDefault();

            if (nextToken != null && nextToken.Kind == SyntaxKind.Else)
            {
                return(true);
            }

            return(false);
        }
예제 #4
0
            internal static List <AssertionError> Syntax(StatementParseResultBuilderState currentState)
            {
                switch (currentState.Kind)
                {
                case NodeKind.Let:
                    return(AssertLetStatementSyntax(currentState));

                case NodeKind.Return:
                    return(AssertReturnStatementSyntax(currentState));

                default:
                    return(new List <AssertionError>());
                }
            }
예제 #5
0
        private int DetermineTokenRangeInternal(StatementParseResultBuilderState state)
        {
            var noOfLeftBraces  = 0;
            var noOfRightBraces = 0;
            var position        = state.Position;
            var ignoreSemicolon = false;

            while (position < state.Tokens.Count)
            {
                var currentToken = state.Tokens.Skip(position).Take(1).FirstOrDefault();

                // Enable parsing of simple expressions, eg. '1 + 1' without semicolon
                if (currentToken.Kind == SyntaxKind.EOF)
                {
                    return(position);
                }
                // Top-level semicolons, eg. let a = 42;<< or if (true) { 1; };<<
                else if (currentToken.Kind == SyntaxKind.Semicolon && !ignoreSemicolon && noOfLeftBraces == noOfRightBraces)
                {
                    return(position + Include.Semicolon - state.Position);
                }
                // Brace after consequence body in If-Else expression, eg. if (true) { 1 }<< else...
                if (currentToken.Kind == SyntaxKind.RightBrace && IsIfElseExpression(state, position))
                {
                    noOfRightBraces++;
                    position++;
                }
                // Inside the block, ie. { ...<< }
                else if (currentToken.Kind == SyntaxKind.RightBrace && noOfLeftBraces != noOfRightBraces)
                {
                    ignoreSemicolon = false;
                    noOfRightBraces++;
                    position++;
                }
                // Block opening, eg. {<< ... }. We ignore semicolons inside blocks
                else if (currentToken.Kind == SyntaxKind.LeftBrace)
                {
                    ignoreSemicolon = true;
                    noOfLeftBraces++;
                    position++;
                }
                // Everything else
                else
                {
                    position++;
                }
            }

            return(-1);
        }
예제 #6
0
            private static List <AssertionError> AssertLetStatementSyntax(StatementParseResultBuilderState currentState)
            {
                var identifierToken = currentState.Tokens
                                      .Skip(currentState.Position + Skip.Let)
                                      .Take(1)
                                      .FirstOrDefault();

                var assignToken = currentState.Tokens
                                  .Skip(currentState.Position + Skip.Let + Skip.Identifier)
                                  .Take(1)
                                  .FirstOrDefault();

                var expressionToken = currentState.Tokens
                                      .Skip(currentState.Position + Skip.Let + Skip.Identifier + Skip.Assign)
                                      .Take(1)
                                      .FirstOrDefault();

                var errors = new List <AssertionError>();

                var info = new ErrorInfo
                {
                    Kind     = ErrorKind.UnexpectedToken,
                    Position = currentState.Position + Skip.Let,
                    Source   = ErrorSource.Parser,
                    Tokens   = currentState.Tokens
                };

                if (identifierToken == default(Token) || identifierToken.Kind == SyntaxKind.EOF)
                {
                    info.Code = ErrorCode.MissingLetIdentifierToken;
                    info.Kind = ErrorKind.MissingToken;
                    errors.Add(Error.Create(info));
                    return(errors);
                }

                if (assignToken == default(Token) || assignToken.Kind == SyntaxKind.EOF)
                {
                    info.Code     = ErrorCode.MissingLetAssignToken;
                    info.Kind     = ErrorKind.MissingToken;
                    info.Position = currentState.Position + Skip.Let + Skip.Identifier;
                    errors.Add(Error.Create(info));
                    return(errors);
                }

                if (identifierToken.Kind != SyntaxKind.Identifier)
                {
                    info.Code = ErrorCode.InvalidLetIdentifierToken;
                    info.Kind = ErrorKind.InvalidToken;
                    errors.Add(Error.Create(info));
                }

                if (assignToken.Kind != SyntaxKind.Assign)
                {
                    info.Code     = ErrorCode.InvalidLetAssignToken;
                    info.Kind     = ErrorKind.InvalidToken;
                    info.Position = info.Position + Skip.Identifier;
                    errors.Add(Error.Create(info));
                }

                if (expressionToken == default(Token) || expressionToken.Kind == SyntaxKind.EOF)
                {
                    info.Code     = ErrorCode.MissingExpressionToken;
                    info.Kind     = ErrorKind.MissingToken;
                    info.Position = currentState.Position + Skip.Let + Skip.Identifier + Skip.Assign;
                    errors.Add(Error.Create(info));
                    return(errors);
                }

                if (!IsExpressionToken(expressionToken))
                {
                    info.Code     = ErrorCode.InvalidLetExpression;
                    info.Kind     = ErrorKind.InvalidToken;
                    info.Position = currentState.Position + Skip.Let + Skip.Identifier + Skip.Assign;
                    errors.Add(Error.Create(info));
                }

                return(errors);
            }