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); }
public StatementParseResultBuilder(StatementParseResult currentState) { internalState = new StatementParseResultBuilderState { Errors = currentState.Errors, Position = currentState.Position, Tokens = currentState.Tokens }; }
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); }
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>()); } }
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); }
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); }