@@ -14,6 +14,7 @@ public class ExpressionEvaluator
14
14
private static Regex varOrFunctionRegEx = new Regex ( @"^((?<sign>[+-])|(?<inObject>(?<nullConditional>[?])?\.)?)(?<name>[a-zA-Z_][a-zA-Z0-9_]*)\s*(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?" , RegexOptions . IgnoreCase ) ;
15
15
private static Regex numberRegex = new Regex ( @"^(?<sign>[+-])?\d+(?<hasdecimal>\.?\d+(e[+-]?\d+)?)?(?<type>ul|[fdulm])?" , RegexOptions . IgnoreCase ) ;
16
16
private static Regex stringBeginningRegex = new Regex ( "^(?<interpolated>[$])?(?<escaped>[@])?[\" ]" ) ;
17
+ private static Regex internalCharRegex = new Regex ( @"^['](\\[']|[^'])*[']" ) ;
17
18
private static Regex castRegex = new Regex ( @"^\(\s*(?<typeName>[a-zA-Z_][a-zA-Z0-9_\.\[\]<>]*[?]?)\s*\)" ) ;
18
19
private static Regex indexingBeginningRegex = new Regex ( @"^[?]?\[" ) ;
19
20
private static Regex endOfStringWithDollar = new Regex ( "^[^\" {]*[\" {]" ) ;
@@ -495,7 +496,8 @@ public object Evaluate(string expr)
495
496
{
496
497
string s = expr . Substring ( i , 1 ) ;
497
498
498
- if ( EvaluateParenthis ( expr , s , stack , ref i )
499
+ if ( EvaluateChar ( expr , s , stack , ref i )
500
+ || EvaluateParenthis ( expr , s , stack , ref i )
499
501
|| EvaluateIndexing ( expr , s , stack , ref i )
500
502
|| EvaluateString ( expr , s , restOfExpression , stack , ref i ) )
501
503
{ }
@@ -723,7 +725,6 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
723
725
{
724
726
throw new ExpressionEvaluatorSyntaxErrorException ( $ "The call of the method \" { varFuncName } \" on type [{ objType . ToString ( ) } ] generate this error : { ( ex . InnerException ? . Message ?? ex . Message ) } ", ex ) ;
725
727
}
726
-
727
728
}
728
729
}
729
730
else if ( DefaultFunctions ( varFuncName , funcArgs , out object funcResult ) )
@@ -847,6 +848,51 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
847
848
}
848
849
}
849
850
851
+ private bool EvaluateChar ( string expr , string s , Stack < object > stack , ref int i )
852
+ {
853
+ if ( s . Equals ( "'" ) )
854
+ {
855
+ i ++ ;
856
+
857
+ if ( expr . Substring ( i , 1 ) . Equals ( @"\" ) )
858
+ {
859
+ i ++ ;
860
+ char escapedChar = expr [ i ] ;
861
+
862
+ if ( charEscapedCharDict . ContainsKey ( escapedChar ) )
863
+ {
864
+ stack . Push ( charEscapedCharDict [ escapedChar ] ) ;
865
+ i ++ ;
866
+ }
867
+ else
868
+ {
869
+ throw new ExpressionEvaluatorSyntaxErrorException ( "Not known escape sequence in literal character" ) ;
870
+ }
871
+
872
+ }
873
+ else if ( expr . Substring ( i , 1 ) . Equals ( "'" ) )
874
+ {
875
+ throw new ExpressionEvaluatorSyntaxErrorException ( "Empty literal character is not valid" ) ;
876
+ }
877
+ else
878
+ {
879
+ stack . Push ( expr [ i ] ) ;
880
+ i ++ ;
881
+ }
882
+
883
+ if ( expr . Substring ( i , 1 ) . Equals ( "'" ) )
884
+ {
885
+ return true ;
886
+ }
887
+ else
888
+ {
889
+ throw new ExpressionEvaluatorSyntaxErrorException ( "Too much characters in the literal character" ) ;
890
+ }
891
+ }
892
+ else
893
+ return false ;
894
+ }
895
+
850
896
private bool EvaluateTwoCharsOperators ( string expr , Stack < object > stack , ref int i )
851
897
{
852
898
if ( i < expr . Length - 1 )
@@ -1020,7 +1066,6 @@ private bool EvaluateString(string expr, string s, string restOfExpression, Stac
1020
1066
}
1021
1067
else
1022
1068
{
1023
-
1024
1069
s = expr . Substring ( i , 1 ) ;
1025
1070
1026
1071
if ( s . Equals ( "{" ) ) bracketCount ++ ;
@@ -1312,13 +1357,19 @@ private List<string> GetExpressionsBetweenParenthis(string expr, ref int i, bool
1312
1357
for ( ; i < expr . Length ; i ++ )
1313
1358
{
1314
1359
Match internalStringMatch = stringBeginningRegex . Match ( expr . Substring ( i ) ) ;
1360
+ Match internalCharMatch = internalCharRegex . Match ( expr . Substring ( i ) ) ;
1315
1361
1316
1362
if ( internalStringMatch . Success )
1317
1363
{
1318
1364
string innerString = internalStringMatch . Value + GetCodeUntilEndOfString ( expr . Substring ( i + internalStringMatch . Length ) , internalStringMatch ) ;
1319
1365
currentExpression += innerString ;
1320
1366
i += innerString . Length - 1 ;
1321
1367
}
1368
+ else if ( internalCharMatch . Success )
1369
+ {
1370
+ currentExpression += internalCharMatch . Value ;
1371
+ i += internalCharMatch . Length - 1 ;
1372
+ }
1322
1373
else
1323
1374
{
1324
1375
s = expr . Substring ( i , 1 ) ;
@@ -1723,4 +1774,4 @@ public object Value
1723
1774
/// Otherwise is set to null.
1724
1775
/// </summary>
1725
1776
public object This { get ; private set ; } = null ;
1726
- }
1777
+ }
0 commit comments