/// Author: Max Hamulyak
 /// Date: 	19-06-2015
 /// <summary>
 /// Parses the call to a user function.
 /// </summary>
 /// <returns>The function call.</returns>
 /// <param name="tokensAtCurrentLine">Tokens at current line.</param>
 protected virtual FunctionBlockExecute ParseFunctionCall(List<Token> tokensAtCurrentLine)
 {
     Token tokenToParse = tokensAtCurrentLine.First ();
     tokensAtCurrentLine.Remove (tokenToParse);
     tokensAtCurrentLine.RemoveAll (x => x.Type == ETokenType.CommentLine || x.Type == ETokenType.EOL || x.Type == ETokenType.WhiteSpace);
     if (tokensAtCurrentLine.Count > 0) {
         throw TokenAfterFunctionCall (tokenToParse.Position.Line, tokenToParse.Value, tokensAtCurrentLine.First ().Value);
     }
     string functionName = tokenToParse.Value.TrimEnd ("()".ToCharArray()).Trim();
     FunctionBlockExecute executeFunction = new FunctionBlockExecute (functionName);
     executeFunction.LineNumber = tokenToParse.Position.Line;
     return executeFunction;
 }
 protected override FunctionBlockExecute ParseFunctionCall(List<Token> tokensAtCurrentLine)
 {
     Token tokenToParse = tokensAtCurrentLine.First ();
     int headerLineNumber = tokenToParse.Position.Line;
     tokensAtCurrentLine.RemoveAll (x => x.Type == ETokenType.CommentLine || x.Type == ETokenType.EOL || x.Type == ETokenType.WhiteSpace);
     Token semicolonToken = tokensAtCurrentLine.FirstOrDefault (x => x.Value == ";");
     if (semicolonToken == null) {
         throw MissingSemicolonException (tokenToParse.Position.Line, tokenToParse.Value);
     } else {
         int myIndex = tokensAtCurrentLine.IndexOf (semicolonToken);
         List<Token> tokensTillRange = tokensAtCurrentLine.GetRange (1, myIndex - 1);
         List<Token> tokensAfterRange = tokensAtCurrentLine.GetRange (myIndex + 1, tokensAtCurrentLine.Count - myIndex - 1);
         Token errorToken = null;
         if (tokensTillRange.Count != 0) {
             errorToken = tokensTillRange.First ();
             throw ValueBeforeSemicolon (headerLineNumber,tokenToParse, errorToken);
         } else if (tokensAfterRange.Count != 0) {
             errorToken = tokensAfterRange.First ();
             throw ValueAfterSemicolon (headerLineNumber,tokenToParse, errorToken);
         }
         tokensAtCurrentLine.Remove (tokenToParse);
         string functionName = tokenToParse.Value.TrimEnd ("()".ToCharArray ()).Trim ();
         FunctionBlockExecute executeFunction = new FunctionBlockExecute (functionName);
         executeFunction.LineNumber = tokenToParse.Position.Line;
         return executeFunction;
     }
 }