// // Helper function to extract an expression term from a token stream. // // Returns true if a term was found, and passes out the index of the // next token to examine. No tokens should be popped if this helper // returns false. // // Note that in cases where a terminating token is present, such as // a closing parenthesis or a comma, this will return false; however // this does not indicate a syntax error. // private static bool ParseExpressionTerm(ParseSession parser, bool atstart, int starttoken, out int consumedtokens, out bool matchedstatement) { matchedstatement = false; int totaltokens = starttoken; consumedtokens = totaltokens; if (parser.PeekToken(totaltokens) == null) { return(false); } if (parser.CheckToken(totaltokens, ")")) { return(false); } if (parser.CheckToken(totaltokens, ",")) { return(false); } if (parser.CheckToken(totaltokens, "(")) { ++totaltokens; if (Parse(parser, totaltokens, out totaltokens) != null) { ++totaltokens; consumedtokens = totaltokens; return(true); } return(false); } if (parser.CheckToken(totaltokens, "!")) { ++totaltokens; var ret = ParseExpressionTerm(parser, atstart, totaltokens, out totaltokens, out matchedstatement); if (matchedstatement && parser.CheckToken(totaltokens, ")")) { ++totaltokens; } consumedtokens = totaltokens; return(ret); } // The following check is a tiny optimization. Instead of trying to parse // a statement first and then eventually giving up, we first try checking // for common literals. This makes code with literals parse a fractional, // almost insignificant amount faster. It's actually a relic from the way // the compiler implements this logic. Maybe it makes sense to remove it, // and aim for simplicity over ideal efficiency. Profiling data is so far // insufficient to decide for sure, so this stays in the interim. if (parser.CheckToken(totaltokens, "false") || parser.CheckToken(totaltokens, "true") || parser.CheckToken(totaltokens, "0") || parser.CheckToken(totaltokens, "0.0")) { ++totaltokens; } else if (parser.ParsePreopStatement(totaltokens, out totaltokens)) { consumedtokens = totaltokens; return(true); } else if (parser.ParseStatement(totaltokens, out totaltokens)) { matchedstatement = true; consumedtokens = totaltokens; return(true); } else { ++totaltokens; } consumedtokens = totaltokens; return(true); }