@@ -16,37 +16,37 @@ public class ExpressionEvaluator
1616 {
1717 #region Regex declarations
1818
19- private static Regex varOrFunctionRegEx = new Regex ( @"^((?<sign>[+-])|(?<inObject>(?<nullConditional>[?])?\.)?)(?<name>[a-zA-Z_][a-zA-Z0-9_]*)\s*((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![a-zA-Z0-9_]))|((?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
20- private static Regex numberRegex = new Regex ( @"^(?<sign>[+-])?\d+(?<hasdecimal>\.?\d+(e[+-]?\d+)?)?(?<type>ul|[fdulm])?" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
21- private static Regex stringBeginningRegex = new Regex ( "^(?<interpolated>[$])?(?<escaped>[@])?[\" ]" , RegexOptions . Compiled ) ;
22- private static Regex internalCharRegex = new Regex ( @"^['](\\[']|[^'])*[']" , RegexOptions . Compiled ) ;
19+ private static Regex varOrFunctionRegEx = new Regex ( @"^((?<sign>[+-])|(?<inObject>(?<nullConditional>[?])?\.)?)(?<name>[a-zA-Z_][a-zA-Z0-9_]*)\s*((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![a-zA-Z0-9_]))|((?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))" , RegexOptions . IgnoreCase ) ;
20+ private static Regex numberRegex = new Regex ( @"^(?<sign>[+-])?\d+(?<hasdecimal>\.?\d+(e[+-]?\d+)?)?(?<type>ul|[fdulm])?" , RegexOptions . IgnoreCase ) ;
21+ private static Regex stringBeginningRegex = new Regex ( "^(?<interpolated>[$])?(?<escaped>[@])?[\" ]" ) ;
22+ private static Regex internalCharRegex = new Regex ( @"^['](\\[']|[^'])*[']" ) ;
2323 private static Regex castRegex = new Regex ( @"^\(\s*(?<typeName>[a-zA-Z_][a-zA-Z0-9_\.\[\]<>]*[?]?)\s*\)" ) ;
24- private static Regex indexingBeginningRegex = new Regex ( @"^[?]?\[" , RegexOptions . Compiled ) ;
25- private static Regex endOfStringWithDollar = new Regex ( "^[^\" {]*[\" {]" , RegexOptions . Compiled ) ;
26- private static Regex endOfStringWithoutDollar = new Regex ( "^[^\" ]*[\" ]" , RegexOptions . Compiled ) ;
27- private static Regex endOfStringInterpolationRegex = new Regex ( "^[^}\" ]*[}\" ]" , RegexOptions . Compiled ) ;
28- private static Regex stringBeginningForEndBlockRegex = new Regex ( "[$]?[@]?[\" ]$" , RegexOptions . Compiled ) ;
29- private static Regex lambdaExpressionRegex = new Regex ( @"^\s*(?<args>(\s*[(]\s*([a-zA-Z_][a-zA-Z0-9_]*\s*([,]\s*[a-zA-Z_][a-zA-Z0-9_]*\s*)*)?[)])|[a-zA-Z_][a-zA-Z0-9_]*)\s*=>(?<expression>.*)$" , RegexOptions . Singleline | RegexOptions . Compiled ) ;
30- private static Regex lambdaArgRegex = new Regex ( @"[a-zA-Z_][a-zA-Z0-9_]*" , RegexOptions . Compiled ) ;
24+ private static Regex indexingBeginningRegex = new Regex ( @"^[?]?\[" ) ;
25+ private static Regex endOfStringWithDollar = new Regex ( "^[^\" {]*[\" {]" ) ;
26+ private static Regex endOfStringWithoutDollar = new Regex ( "^[^\" ]*[\" ]" ) ;
27+ private static Regex endOfStringInterpolationRegex = new Regex ( "^[^}\" ]*[}\" ]" ) ;
28+ private static Regex stringBeginningForEndBlockRegex = new Regex ( "[$]?[@]?[\" ]$" ) ;
29+ private static Regex lambdaExpressionRegex = new Regex ( @"^\s*(?<args>(\s*[(]\s*([a-zA-Z_][a-zA-Z0-9_]*\s*([,]\s*[a-zA-Z_][a-zA-Z0-9_]*\s*)*)?[)])|[a-zA-Z_][a-zA-Z0-9_]*)\s*=>(?<expression>.*)$" , RegexOptions . Singleline ) ;
30+ private static Regex lambdaArgRegex = new Regex ( @"[a-zA-Z_][a-zA-Z0-9_]*" ) ;
3131
3232 private static readonly string instanceCreationWithNewKeywordRegexPattern = @"^new\s+(?<name>[a-zA-Z_][a-zA-Z0-9_.]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?" ;
33- private Regex instanceCreationWithNewKeywordRegex = new Regex ( instanceCreationWithNewKeywordRegexPattern , RegexOptions . Compiled ) ;
33+ private Regex instanceCreationWithNewKeywordRegex = new Regex ( instanceCreationWithNewKeywordRegexPattern ) ;
3434 private static readonly string primaryTypesRegexPattern = @"(?<=^|[^a-zA-Z_])(?<primaryType>object|string|bool[?]?|byte[?]?|char[?]?|decimal[?]?|double[?]?|short[?]?|int[?]?|long[?]?|sbyte[?]?|float[?]?|ushort[?]?|uint[?]?|void)(?=[^a-zA-Z_]|$)" ;
35- private Regex primaryTypesRegex = new Regex ( primaryTypesRegexPattern , RegexOptions . Compiled ) ;
35+ private Regex primaryTypesRegex = new Regex ( primaryTypesRegexPattern ) ;
3636
3737 // To remove comments in scripts based on https://stackoverflow.com/questions/3524317/regex-to-strip-line-comments-from-c-sharp/3524689#3524689
3838 private static readonly string blockComments = @"/\*(.*?)\*/" ;
3939 private static readonly string lineComments = @"//[^\r\n]*" ;
4040 private static readonly string stringsIgnore = @"""((\\[^\n]|[^""\n])*)""" ;
4141 private static readonly string verbatimStringsIgnore = @"@(""[^""]*"")+" ;
42- private static readonly Regex removeCommentsRegex = new Regex ( $ "{ blockComments } |{ lineComments } |{ stringsIgnore } |{ verbatimStringsIgnore } ", RegexOptions . Singleline | RegexOptions . Compiled ) ;
43- private static readonly Regex newLineCharsRegex = new Regex ( @"\r\n|\r|\n" , RegexOptions . Compiled ) ;
42+ private static readonly Regex removeCommentsRegex = new Regex ( $ "{ blockComments } |{ lineComments } |{ stringsIgnore } |{ verbatimStringsIgnore } ", RegexOptions . Singleline ) ;
43+ private static readonly Regex newLineCharsRegex = new Regex ( @"\r\n|\r|\n" ) ;
4444
4545 // For script only
46- private static readonly Regex blockKeywordsBeginningRegex = new Regex ( @"^\s*(?<keyword>while|for|if|else\s+if)\s*[(]" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
47- private static readonly Regex elseblockKeywordsBeginningRegex = new Regex ( @"^\s*(?<keyword>else)(?![a-zA-Z0-9_])" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
48- private static readonly Regex blockBeginningRegex = new Regex ( @"^\s*[{]" , RegexOptions . Compiled ) ;
49- private static readonly Regex returnKeywordRegex = new Regex ( @"^return(\s+|\()" , RegexOptions . IgnoreCase | RegexOptions . Singleline | RegexOptions . Compiled ) ;
46+ private static readonly Regex blockKeywordsBeginningRegex = new Regex ( @"^\s*(?<keyword>while|for|if|else\s+if)\s*[(]" , RegexOptions . IgnoreCase ) ;
47+ private static readonly Regex elseblockKeywordsBeginningRegex = new Regex ( @"^\s*(?<keyword>else)(?![a-zA-Z0-9_])" , RegexOptions . IgnoreCase ) ;
48+ private static readonly Regex blockBeginningRegex = new Regex ( @"^\s*[{]" ) ;
49+ private static readonly Regex returnKeywordRegex = new Regex ( @"^return(\s+|\()" , RegexOptions . IgnoreCase | RegexOptions . Singleline ) ;
5050
5151 #endregion
5252
@@ -424,8 +424,8 @@ public bool OptionCaseSensitiveEvaluationActive
424424 simpleDoubleMathFuncsDictionary = new Dictionary < string , Func < double , double > > ( simpleDoubleMathFuncsDictionary , StringComparerForCasing ) ;
425425 doubleDoubleMathFuncsDictionary = new Dictionary < string , Func < double , double , double > > ( doubleDoubleMathFuncsDictionary , StringComparerForCasing ) ;
426426 complexStandardFuncsDictionary = new Dictionary < string , Func < ExpressionEvaluator , List < string > , object > > ( complexStandardFuncsDictionary , StringComparerForCasing ) ;
427- instanceCreationWithNewKeywordRegex = new Regex ( instanceCreationWithNewKeywordRegexPattern , ( optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) | RegexOptions . Compiled ) ;
428- primaryTypesRegex = new Regex ( primaryTypesRegexPattern , ( optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) | RegexOptions . Compiled ) ;
427+ instanceCreationWithNewKeywordRegex = new Regex ( instanceCreationWithNewKeywordRegexPattern , ( optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ) ;
428+ primaryTypesRegex = new Regex ( primaryTypesRegexPattern , ( optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ) ;
429429 }
430430 }
431431
@@ -2091,8 +2091,9 @@ private List<string> GetExpressionsBetweenParenthis(string expr, ref int i, bool
20912091 int bracketCount = 1 ;
20922092 for ( ; i < expr . Length ; i ++ )
20932093 {
2094- Match internalStringMatch = stringBeginningRegex . Match ( expr . Substring ( i ) ) ;
2095- Match internalCharMatch = internalCharRegex . Match ( expr . Substring ( i ) ) ;
2094+ string subExpr = expr . Substring ( i ) ;
2095+ Match internalStringMatch = stringBeginningRegex . Match ( subExpr ) ;
2096+ Match internalCharMatch = internalCharRegex . Match ( subExpr ) ;
20962097
20972098 if ( internalStringMatch . Success )
20982099 {
@@ -2233,76 +2234,82 @@ private static object ChangeType(object value, Type conversionType)
22332234 return Convert . ChangeType ( value , conversionType ) ;
22342235 }
22352236
2236- //private string GetCodeUntilEndOfString(string subExpr, Match stringBeginningMatch)
2237- //{
2238- // Match codeUntilEndOfStringMatch = stringBeginningMatch.Value.Contains("$") ? endOfStringWithDollar.Match(subExpr) : endOfStringWithoutDollar.Match(subExpr);
2239- // string result = subExpr;
2237+ private string GetCodeUntilEndOfString ( string subExpr , Match stringBeginningMatch )
2238+ {
2239+ StringBuilder stringBuilder = new StringBuilder ( ) ;
22402240
2241- // if (codeUntilEndOfStringMatch.Success)
2242- // {
2243- // if (codeUntilEndOfStringMatch.Value.EndsWith("\""))
2244- // {
2245- // result = codeUntilEndOfStringMatch.Value;
2246- // }
2247- // else if (codeUntilEndOfStringMatch.Value.EndsWith("{") && codeUntilEndOfStringMatch.Length < subExpr.Length)
2248- // {
2249- // if (subExpr[codeUntilEndOfStringMatch.Length] == '{')
2250- // {
2251- // result = codeUntilEndOfStringMatch.Value + "{"
2252- // + GetCodeUntilEndOfString(subExpr.Substring(codeUntilEndOfStringMatch.Length + 1), stringBeginningMatch);
2253- // }
2254- // else
2255- // {
2256- // string interpolation = GetCodeUntilEndOfStringInterpolation(subExpr.Substring(codeUntilEndOfStringMatch.Length));
2257- // result = codeUntilEndOfStringMatch.Value + interpolation
2258- // + GetCodeUntilEndOfString(subExpr.Substring(codeUntilEndOfStringMatch.Length + interpolation.Length), stringBeginningMatch);
2259- // }
2260- // }
2261- // }
2241+ GetCodeUntilEndOfString ( subExpr , stringBeginningMatch , ref stringBuilder ) ;
22622242
2263- // return result ;
2264- // }
2243+ return stringBuilder . ToString ( ) ;
2244+ }
22652245
2266- private string GetCodeUntilEndOfString ( string subExpr , Match stringBeginningMatch )
2246+ private void GetCodeUntilEndOfString ( string subExpr , Match stringBeginningMatch , ref StringBuilder stringBuilder )
22672247 {
22682248 Match codeUntilEndOfStringMatch = stringBeginningMatch . Value . Contains ( "$" ) ? endOfStringWithDollar . Match ( subExpr ) : endOfStringWithoutDollar . Match ( subExpr ) ;
2269- StringBuilder result = new StringBuilder ( ) ;
22702249
22712250 if ( codeUntilEndOfStringMatch . Success )
22722251 {
22732252 if ( codeUntilEndOfStringMatch . Value . EndsWith ( "\" " ) )
22742253 {
2275- result . Append ( codeUntilEndOfStringMatch . Value ) ;
2254+ stringBuilder . Append ( codeUntilEndOfStringMatch . Value ) ;
22762255 }
22772256 else if ( codeUntilEndOfStringMatch . Value . EndsWith ( "{" ) && codeUntilEndOfStringMatch . Length < subExpr . Length )
22782257 {
22792258 if ( subExpr [ codeUntilEndOfStringMatch . Length ] == '{' )
22802259 {
2281- result . Append ( codeUntilEndOfStringMatch . Value ) ;
2282- result . Append ( "{" ) ;
2283- result . Append ( GetCodeUntilEndOfString ( subExpr . Substring ( codeUntilEndOfStringMatch . Length + 1 ) , stringBeginningMatch ) ) ;
2260+ stringBuilder . Append ( codeUntilEndOfStringMatch . Value ) ;
2261+ stringBuilder . Append ( "{" ) ;
2262+ GetCodeUntilEndOfString ( subExpr . Substring ( codeUntilEndOfStringMatch . Length + 1 ) , stringBeginningMatch , ref stringBuilder ) ;
22842263 }
22852264 else
22862265 {
22872266 string interpolation = GetCodeUntilEndOfStringInterpolation ( subExpr . Substring ( codeUntilEndOfStringMatch . Length ) ) ;
2288- result . Append ( codeUntilEndOfStringMatch . Value ) ;
2289- result . Append ( interpolation ) ;
2290- result . Append ( GetCodeUntilEndOfString ( subExpr . Substring ( codeUntilEndOfStringMatch . Length + interpolation . Length ) , stringBeginningMatch ) ) ;
2267+ stringBuilder . Append ( codeUntilEndOfStringMatch . Value ) ;
2268+ stringBuilder . Append ( interpolation ) ;
2269+ GetCodeUntilEndOfString ( subExpr . Substring ( codeUntilEndOfStringMatch . Length + interpolation . Length ) , stringBeginningMatch , ref stringBuilder ) ;
22912270 }
22922271 }
22932272 else
22942273 {
2295- result . Append ( subExpr ) ;
2274+ stringBuilder . Append ( subExpr ) ;
22962275 }
22972276 }
22982277 else
22992278 {
2300- result . Append ( subExpr ) ;
2279+ stringBuilder . Append ( subExpr ) ;
23012280 }
2302-
2303- return result . ToString ( ) ;
23042281 }
23052282
2283+ //private string GetCodeUntilEndOfStringInterpolation(string subExpr)
2284+ //{
2285+ // Match endOfStringInterpolationMatch = endOfStringInterpolationRegex.Match(subExpr);
2286+ // StringBuilder result = new StringBuilder();
2287+
2288+ // if (endOfStringInterpolationMatch.Success)
2289+ // {
2290+ // if (endOfStringInterpolationMatch.Value.EndsWith("}"))
2291+ // {
2292+ // result.Append(endOfStringInterpolationMatch.Value);
2293+ // }
2294+ // else
2295+ // {
2296+ // Match stringBeginningForEndBlockMatch = stringBeginningForEndBlockRegex.Match(endOfStringInterpolationMatch.Value);
2297+
2298+ // string subString = GetCodeUntilEndOfString(subExpr.Substring(endOfStringInterpolationMatch.Length), stringBeginningForEndBlockMatch);
2299+
2300+ // result.Append(endOfStringInterpolationMatch.Value);
2301+ // result.Append(subString);
2302+ // result.Append(GetCodeUntilEndOfStringInterpolation(subExpr.Substring(endOfStringInterpolationMatch.Length + subString.Length)));
2303+ // }
2304+ // }
2305+ // else
2306+ // {
2307+ // result.Append(subExpr);
2308+ // }
2309+
2310+ // return result.ToString();
2311+ //}
2312+
23062313 private string GetCodeUntilEndOfStringInterpolation ( string subExpr )
23072314 {
23082315 Match endOfStringInterpolationMatch = endOfStringInterpolationRegex . Match ( subExpr ) ;
@@ -2328,6 +2335,7 @@ private string GetCodeUntilEndOfStringInterpolation(string subExpr)
23282335 return result ;
23292336 }
23302337
2338+
23312339 #endregion
23322340
23332341 #region Utils private sub classes for parsing and interpretation
0 commit comments