@@ -14,6 +14,7 @@ public class ExpressionEvaluator
1414 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 ) ;
1515 private static Regex numberRegex = new Regex ( @"^(?<sign>[+-])?\d+(?<hasdecimal>\.?\d+(e[+-]?\d+)?)?(?<type>ul|[fdulm])?" , RegexOptions . IgnoreCase ) ;
1616 private static Regex stringBeginningRegex = new Regex ( "^(?<interpolated>[$])?(?<escaped>[@])?[\" ]" ) ;
17+ private static Regex internalCharRegex = new Regex ( @"^['](\\[']|[^'])*[']" ) ;
1718 private static Regex castRegex = new Regex ( @"^\(\s*(?<typeName>[a-zA-Z_][a-zA-Z0-9_\.\[\]<>]*[?]?)\s*\)" ) ;
1819 private static Regex indexingBeginningRegex = new Regex ( @"^[?]?\[" ) ;
1920 private static Regex endOfStringWithDollar = new Regex ( "^[^\" {]*[\" {]" ) ;
@@ -495,7 +496,8 @@ public object Evaluate(string expr)
495496 {
496497 string s = expr . Substring ( i , 1 ) ;
497498
498- if ( EvaluateParenthis ( expr , s , stack , ref i )
499+ if ( EvaluateChar ( expr , s , stack , ref i )
500+ || EvaluateParenthis ( expr , s , stack , ref i )
499501 || EvaluateIndexing ( expr , s , stack , ref i )
500502 || EvaluateString ( expr , s , restOfExpression , stack , ref i ) )
501503 { }
@@ -723,7 +725,6 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
723725 {
724726 throw new ExpressionEvaluatorSyntaxErrorException ( $ "The call of the method \" { varFuncName } \" on type [{ objType . ToString ( ) } ] generate this error : { ( ex . InnerException ? . Message ?? ex . Message ) } ", ex ) ;
725727 }
726-
727728 }
728729 }
729730 else if ( DefaultFunctions ( varFuncName , funcArgs , out object funcResult ) )
@@ -847,6 +848,51 @@ private bool EvaluateVarOrFunc(string expr, string restOfExpression, Stack<objec
847848 }
848849 }
849850
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+
850896 private bool EvaluateTwoCharsOperators ( string expr , Stack < object > stack , ref int i )
851897 {
852898 if ( i < expr . Length - 1 )
@@ -1020,7 +1066,6 @@ private bool EvaluateString(string expr, string s, string restOfExpression, Stac
10201066 }
10211067 else
10221068 {
1023-
10241069 s = expr . Substring ( i , 1 ) ;
10251070
10261071 if ( s . Equals ( "{" ) ) bracketCount ++ ;
@@ -1312,13 +1357,19 @@ private List<string> GetExpressionsBetweenParenthis(string expr, ref int i, bool
13121357 for ( ; i < expr . Length ; i ++ )
13131358 {
13141359 Match internalStringMatch = stringBeginningRegex . Match ( expr . Substring ( i ) ) ;
1360+ Match internalCharMatch = internalCharRegex . Match ( expr . Substring ( i ) ) ;
13151361
13161362 if ( internalStringMatch . Success )
13171363 {
13181364 string innerString = internalStringMatch . Value + GetCodeUntilEndOfString ( expr . Substring ( i + internalStringMatch . Length ) , internalStringMatch ) ;
13191365 currentExpression += innerString ;
13201366 i += innerString . Length - 1 ;
13211367 }
1368+ else if ( internalCharMatch . Success )
1369+ {
1370+ currentExpression += internalCharMatch . Value ;
1371+ i += internalCharMatch . Length - 1 ;
1372+ }
13221373 else
13231374 {
13241375 s = expr . Substring ( i , 1 ) ;
@@ -1723,4 +1774,4 @@ public object Value
17231774 /// Otherwise is set to null.
17241775 /// </summary>
17251776 public object This { get ; private set ; } = null ;
1726- }
1777+ }
0 commit comments