1
1
/******************************************************************************************************
2
2
Title : ExpressionEvaluator (https://github.com/codingseb/ExpressionEvaluator)
3
3
Version : 1.3.0.1
4
- (if last digit not zero version is an intermediate version and can be unstable)
4
+ (if last digit is not a zero, the version is an intermediate version and can be unstable)
5
5
6
6
Author : Coding Seb
7
7
Licence : MIT (https://github.com/codingseb/ExpressionEvaluator/blob/master/LICENSE.md)
@@ -43,7 +43,7 @@ public class ExpressionEvaluator
43
43
private static readonly Regex lambdaExpressionRegex = new Regex ( @"^\s*(?<args>(\s*[(]\s*([" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9]*\s*([,]\s*[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9]*\s*)*)?[)])|[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9]*)\s*=>(?<expression>.*)$" , RegexOptions . Singleline ) ;
44
44
private static readonly Regex lambdaArgRegex = new Regex ( @"[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9]*" ) ;
45
45
46
- private static readonly string instanceCreationWithNewKeywordRegexPattern = @"^new\s+(?<name>[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9.]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?( ?<isfunction>[(])?" ;
46
+ private static readonly string instanceCreationWithNewKeywordRegexPattern = @"^new\s+(?<name>[" + diactiticsKeywordsRegexPattern + @"][" + diactiticsKeywordsRegexPattern + @"0-9.]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?\s*(( ?<isfunction>[(])|(?<isArray>\[) )?" ;
47
47
private Regex instanceCreationWithNewKeywordRegex = new Regex ( instanceCreationWithNewKeywordRegexPattern ) ;
48
48
private static readonly string primaryTypesRegexPattern = @"(?<=^|[^" + diactiticsKeywordsRegexPattern + @"])(?<primaryType>object|string|bool[?]?|byte[?]?|char[?]?|decimal[?]?|double[?]?|short[?]?|int[?]?|long[?]?|sbyte[?]?|float[?]?|ushort[?]?|uint[?]?|void)(?=[^a-zA-Z_]|$)" ;
49
49
private Regex primaryTypesRegex = new Regex ( primaryTypesRegexPattern ) ;
@@ -803,7 +803,7 @@ bool TryParseStringAndParenthisAndCurlyBrackets(ref int index)
803
803
else if ( script [ index ] == '(' )
804
804
{
805
805
index ++ ;
806
- GetExpressionsBetweenParenthis ( script , ref index , false ) ;
806
+ GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( script , ref index , false ) ;
807
807
}
808
808
else if ( script [ index ] == '{' )
809
809
{
@@ -906,7 +906,7 @@ void ExecuteBlocksStacks()
906
906
{
907
907
i += blockKeywordsBeginingMatch . Success ? blockKeywordsBeginingMatch . Length : blockKeywordsWithoutParenthesesBeginningMatch . Length ;
908
908
string keyword = blockKeywordsBeginingMatch . Success ? blockKeywordsBeginingMatch . Groups [ "keyword" ] . Value . Replace ( " " , "" ) . Replace ( "\t " , "" ) : ( blockKeywordsWithoutParenthesesBeginningMatch ? . Groups [ "keyword" ] . Value ?? string . Empty ) ;
909
- List < string > keywordAttributes = blockKeywordsBeginingMatch . Success ? GetExpressionsBetweenParenthis ( script , ref i , true , ";" ) : null ;
909
+ List < string > keywordAttributes = blockKeywordsBeginingMatch . Success ? GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( script , ref i , true , ";" ) : null ;
910
910
911
911
if ( blockKeywordsBeginingMatch . Success )
912
912
i ++ ;
@@ -1021,7 +1021,7 @@ void ExecuteBlocksStacks()
1021
1021
&& blockKeywordsBeginingMatch . Groups [ "keyword" ] . Value . ManageCasing ( OptionCaseSensitiveEvaluationActive ) . Equals ( "while" ) )
1022
1022
{
1023
1023
i += blockKeywordsBeginingMatch . Length ;
1024
- keywordAttributes = GetExpressionsBetweenParenthis ( script , ref i , true , ";" ) ;
1024
+ keywordAttributes = GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( script , ref i , true , ";" ) ;
1025
1025
1026
1026
i ++ ;
1027
1027
@@ -1245,7 +1245,7 @@ public object Evaluate(string expression)
1245
1245
else if ( s2 . Equals ( "(" ) )
1246
1246
{
1247
1247
j ++ ;
1248
- GetExpressionsBetweenParenthis ( restOfExpression , ref j , false ) ;
1248
+ GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( restOfExpression , ref j , false ) ;
1249
1249
}
1250
1250
else if ( s2 . Equals ( ":" ) )
1251
1251
{
@@ -1348,21 +1348,39 @@ private bool EvaluateInstanceCreationWithNewKeyword(string expr, string restOfEx
1348
1348
|| stack . Peek ( ) is ExpressionOperator ) )
1349
1349
{
1350
1350
string completeName = instanceCreationMatch . Groups [ "name" ] . Value ;
1351
+ Type type = GetTypeByFriendlyName ( completeName , true ) ;
1351
1352
1352
1353
i += instanceCreationMatch . Length ;
1353
1354
1354
- if ( ! instanceCreationMatch . Groups [ "isfunction" ] . Success )
1355
- throw new ExpressionEvaluatorSyntaxErrorException ( $ "No '(' found after { instanceCreationMatch . Value } ") ;
1355
+ if ( instanceCreationMatch . Groups [ "isfunction" ] . Success )
1356
+ {
1357
+ List < string > constructorArgs = GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( expr , ref i , true ) ;
1356
1358
1357
- List < string > constructorArgs = GetExpressionsBetweenParenthis ( expr , ref i , true ) ;
1359
+ if ( type == null )
1360
+ throw new ExpressionEvaluatorSyntaxErrorException ( $ "type or class { completeName } is unknown") ;
1358
1361
1359
- Type type = GetTypeByFriendlyName ( completeName , true ) ;
1362
+ List < object > cArgs = constructorArgs . ConvertAll ( arg => Evaluate ( arg ) ) ;
1363
+ stack . Push ( Activator . CreateInstance ( type , cArgs . ToArray ( ) ) ) ;
1364
+ }
1365
+ else if ( instanceCreationMatch . Groups [ "isArray" ] . Success )
1366
+ {
1367
+ List < string > arrayArgs = GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( expr , ref i , true , "," , "[" , "]" ) ;
1368
+
1369
+ if ( arrayArgs . Count > 0 )
1370
+ {
1371
+ stack . Push ( Array . CreateInstance ( type , arrayArgs . ConvertAll ( subExpression => ( int ) Evaluate ( subExpression ) ) . ToArray ( ) ) ) ;
1372
+ }
1373
+ else
1374
+ {
1375
+ //int[,] test = new int[4, 2];
1360
1376
1361
- if ( type == null )
1362
- throw new ExpressionEvaluatorSyntaxErrorException ( $ "type or class { completeName } is unknown") ;
1377
+ //Array.CreateInstance()
1363
1378
1364
- List < object > cArgs = constructorArgs . ConvertAll ( arg => Evaluate ( arg ) ) ;
1365
- stack . Push ( Activator . CreateInstance ( type , cArgs . ToArray ( ) ) ) ;
1379
+ //test[0, 1] = 3;
1380
+ }
1381
+ }
1382
+ else
1383
+ throw new ExpressionEvaluatorSyntaxErrorException ( $ "A new expression requires that type be followed by (), [], or { "{}" } (Check : { instanceCreationMatch . Value } )") ;
1366
1384
1367
1385
return true ;
1368
1386
}
@@ -1388,7 +1406,7 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
1388
1406
1389
1407
if ( varFuncMatch . Groups [ "isfunction" ] . Success )
1390
1408
{
1391
- List < string > funcArgs = GetExpressionsBetweenParenthis ( expr , ref i , true ) ;
1409
+ List < string > funcArgs = GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( expr , ref i , true ) ;
1392
1410
if ( varFuncMatch . Groups [ "inObject" ] . Success )
1393
1411
{
1394
1412
if ( stack . Count == 0 || stack . Peek ( ) is ExpressionOperator )
@@ -1833,7 +1851,7 @@ private bool EvaluateParenthis(string expr, string s, Stack<object> stack, ref i
1833
1851
1834
1852
if ( stack . Count > 0 && stack . Peek ( ) is InternalDelegate )
1835
1853
{
1836
- List < string > expressionsInParenthis = GetExpressionsBetweenParenthis ( expr , ref i , true ) ;
1854
+ List < string > expressionsInParenthis = GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( expr , ref i , true ) ;
1837
1855
1838
1856
InternalDelegate lambdaDelegate = stack . Pop ( ) as InternalDelegate ;
1839
1857
@@ -1843,7 +1861,7 @@ private bool EvaluateParenthis(string expr, string s, Stack<object> stack, ref i
1843
1861
{
1844
1862
CorrectStackWithUnaryPlusOrMinusBeforeParenthisIfNecessary ( stack ) ;
1845
1863
1846
- List < string > expressionsInParenthis = GetExpressionsBetweenParenthis ( expr , ref i , false ) ;
1864
+ List < string > expressionsInParenthis = GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( expr , ref i , false ) ;
1847
1865
1848
1866
stack . Push ( Evaluate ( expressionsInParenthis [ 0 ] ) ) ;
1849
1867
}
@@ -2418,7 +2436,7 @@ string GetScriptBetweenCurlyBrackets(string parentScript, ref int index)
2418
2436
return currentScript ;
2419
2437
}
2420
2438
2421
- private List < string > GetExpressionsBetweenParenthis ( string expr , ref int i , bool checkSeparator , string separator = "," )
2439
+ private List < string > GetExpressionsBetweenParenthesesOrOtherImbricableBrackets ( string expr , ref int i , bool checkSeparator , string separator = "," , string startChar = "(" , string endChar = ") ")
2422
2440
{
2423
2441
List < string > expressionsList = new List < string > ( ) ;
2424
2442
@@ -2446,9 +2464,9 @@ private List<string> GetExpressionsBetweenParenthis(string expr, ref int i, bool
2446
2464
{
2447
2465
s = expr . Substring ( i , 1 ) ;
2448
2466
2449
- if ( s . Equals ( "(" ) ) bracketCount ++ ;
2467
+ if ( s . Equals ( startChar ) ) bracketCount ++ ;
2450
2468
2451
- if ( s . Equals ( ")" ) )
2469
+ if ( s . Equals ( endChar ) )
2452
2470
{
2453
2471
bracketCount -- ;
2454
2472
if ( bracketCount == 0 )
@@ -2472,7 +2490,7 @@ private List<string> GetExpressionsBetweenParenthis(string expr, ref int i, bool
2472
2490
if ( bracketCount > 0 )
2473
2491
{
2474
2492
string beVerb = bracketCount == 1 ? "is" : "are" ;
2475
- throw new Exception ( $ "{ bracketCount } ') ' character { beVerb } missing in expression : [{ expr } ]") ;
2493
+ throw new Exception ( $ "{ bracketCount } '{ endChar } ' character { beVerb } missing in expression : [{ expr } ]") ;
2476
2494
}
2477
2495
2478
2496
return expressionsList ;
0 commit comments