@@ -31,7 +31,7 @@ public partial class ExpressionEvaluator
3131
3232 protected const string primaryTypesRegexPattern = @"(?<=^|[^\p{L}_])(?<primaryType>object|string|bool[?]?|byte[?]?|char[?]?|decimal[?]?|double[?]?|short[?]?|int[?]?|long[?]?|sbyte[?]?|float[?]?|ushort[?]?|uint[?]?|ulong[?]?|void)(?=[^a-zA-Z_]|$)" ;
3333
34- protected static readonly Regex varOrFunctionRegEx = new Regex ( @"^((?<sign>[+-])|(?<prefixOperator>[+][+]|--)|(?<varKeyword>var)\s+|(?<dynamicKeyword>dynamic)\s+|(?<inObject> (?<nullConditional>[?])?\. )?)(?<name>[\p{L}_](?>[\p{L}_0-9]*))(?>\s*)((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>|\?\?)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![\p{L}_0-9]))|((?<isgeneric>[<](?>([\p{L}_](?>[\p{L}_0-9]*)|(?>\s+)|[,\.])+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
34+ protected static readonly Regex varOrFunctionRegEx = new Regex ( @"^((?<sign>[+-])|(?<prefixOperator>[+][+]|--)|(?<varKeyword>var)\s+|(?<dynamicKeyword>dynamic)\s+|((?<nullConditional>[?])?(?<inObject>\.) )?)(?<name>[\p{L}_](?>[\p{L}_0-9]*))(?>\s*)((?<assignationOperator>(?<assignmentPrefix>[+\-*/%&|^]|<<|>>|\?\?)?=(?![=>]))|(?<postfixOperator>([+][+]|--)(?![\p{L}_0-9]))|((?<isgeneric>[<](?>([\p{L}_](?>[\p{L}_0-9]*)|(?>\s+)|[,\.])+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?<isfunction>[(])?))" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
3535
3636 protected const string numberRegexOrigPattern = @"^(?<sign>[+-])?([0-9][0-9_{1}]*[0-9]|\d)(?<hasdecimal>{0}?([0-9][0-9_]*[0-9]|\d)(e[+-]?([0-9][0-9_]*[0-9]|\d))?)?(?<type>ul|[fdulm])?" ;
3737 protected string numberRegexPattern ;
@@ -55,8 +55,7 @@ public partial class ExpressionEvaluator
5555 protected static readonly Regex initInNewBeginningRegex = new Regex ( @"^(?>\s*){" , RegexOptions . Compiled ) ;
5656 protected static readonly Regex functionArgKeywordsRegex = new Regex ( @"^\s*(?<keyword>out|ref|in)\s+((?<typeName>[\p{L}_][\p{L}_0-9\.\[\]<>]*[?]?)\s+(?=[\p{L}_]))?(?<toEval>(?<varName>[\p{L}_](?>[\p{L}_0-9]*))\s*(=.*)?)$" , RegexOptions . Compiled | RegexOptions . IgnoreCase ) ;
5757
58- // Depending on OptionInlineNamespacesEvaluationActive. Initialized in constructor
59- protected string InstanceCreationWithNewKeywordRegexPattern { get { return @"^new(?>\s*)((?<isAnonymous>[{{])|((?<name>[\p{L}_][\p{L}_0-9" + ( OptionInlineNamespacesEvaluationActive ? @"\." : string . Empty ) + @"]*)(?>\s*)(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?>\s*)((?<isfunction>[(])|(?<isArray>\[)|(?<isInit>[{{]))?))" ; } }
58+ protected static readonly Regex instanceCreationWithNewKeywordRegex = new Regex ( @"^new(?>\s*)((?<isAnonymous>[{{])|((?<name>[\p{L}_][\p{L}_0-9\.]*)(?>\s*)(?<isgeneric>[<](?>[^<>]+|(?<gentag>[<])|(?<-gentag>[>]))*(?(gentag)(?!))[>])?(?>\s*)((?<isfunction>[(])|(?<isArray>\[)|(?<isInit>[{{]))?))" , RegexOptions . IgnoreCase | RegexOptions . Compiled ) ;
6059 protected string CastRegexPattern { get { return @"^\((?>\s*)(?<typeName>[\p{L}_][\p{L}_0-9" + ( OptionInlineNamespacesEvaluationActive ? @"\." : string . Empty ) + @"\[\]<>]*[?]?)(?>\s*)\)" ; } }
6160
6261 // To remove comments in scripts based on https://stackoverflow.com/questions/3524317/regex-to-strip-line-comments-from-c-sharp/3524689#3524689
@@ -1724,7 +1723,7 @@ protected virtual bool EvaluateInstanceCreationWithNewKeyword(string expression,
17241723 if ( ! OptionNewKeywordEvaluationActive )
17251724 return false ;
17261725
1727- Match instanceCreationMatch = Regex . Match ( expression . Substring ( i ) , InstanceCreationWithNewKeywordRegexPattern , optionCaseSensitiveEvaluationActive ? RegexOptions . None : RegexOptions . IgnoreCase ) ;
1726+ Match instanceCreationMatch = instanceCreationWithNewKeywordRegex . Match ( expression . Substring ( i ) ) ;
17281727
17291728 if ( instanceCreationMatch . Success
17301729 && ( stack . Count == 0
@@ -1769,9 +1768,11 @@ void InitSimpleObjet(object element, List<string> initArgs)
17691768 {
17701769 string completeName = instanceCreationMatch . Groups [ "name" ] . Value ;
17711770 string genericTypes = instanceCreationMatch . Groups [ "isgeneric" ] . Value ;
1772- Type type = GetTypeByFriendlyName ( completeName , genericTypes ) ;
17731771
1774- if ( type == null )
1772+ int typeIndex = 0 ;
1773+ Type type = EvaluateType ( completeName + genericTypes , ref typeIndex ) ;
1774+
1775+ if ( type == null || typeIndex > 0 && typeIndex < completeName . Length )
17751776 throw new ExpressionEvaluatorSyntaxErrorException ( $ "Type or class { completeName } { genericTypes } is unknown") ;
17761777
17771778 void Init ( object element , List < string > initArgs )
@@ -2439,73 +2440,7 @@ where method.GetParameters()[0].ParameterType == objType // static extMethod(thi
24392440 }
24402441 else
24412442 {
2442- string typeName = $ "{ varFuncName } { ( ( i < expression . Length && expression . Substring ( i ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2443- Type staticType = GetTypeByFriendlyName ( typeName , genericsTypes ) ;
2444-
2445- // For inline namespace parsing
2446- if ( staticType == null && OptionInlineNamespacesEvaluationActive )
2447- {
2448- int subIndex = 0 ;
2449- Match namespaceMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2450-
2451- while ( staticType == null
2452- && namespaceMatch . Success
2453- && ! namespaceMatch . Groups [ "sign" ] . Success
2454- && ! namespaceMatch . Groups [ "assignationOperator" ] . Success
2455- && ! namespaceMatch . Groups [ "postfixOperator" ] . Success
2456- && ! namespaceMatch . Groups [ "isfunction" ] . Success
2457- && i + subIndex < expression . Length
2458- && ! typeName . EndsWith ( "?" ) )
2459- {
2460- subIndex += namespaceMatch . Length ;
2461- typeName += $ ".{ namespaceMatch . Groups [ "name" ] . Value } { ( ( i + subIndex < expression . Length && expression . Substring ( i + subIndex ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2462-
2463- staticType = GetTypeByFriendlyName ( typeName , namespaceMatch . Groups [ "isgeneric" ] . Value ) ;
2464-
2465- if ( staticType != null )
2466- {
2467- i += subIndex ;
2468- break ;
2469- }
2470-
2471- namespaceMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2472- }
2473- }
2474-
2475- // For nested type parsing
2476- if ( staticType != null )
2477- {
2478- int subIndex = 0 ;
2479- Match nestedTypeMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2480- Type nestedType = null ;
2481-
2482- while ( nestedTypeMatch . Success
2483- && ! nestedTypeMatch . Groups [ "sign" ] . Success
2484- && ! nestedTypeMatch . Groups [ "assignationOperator" ] . Success
2485- && ! nestedTypeMatch . Groups [ "postfixOperator" ] . Success
2486- && ! nestedTypeMatch . Groups [ "isfunction" ] . Success
2487- && i + nestedTypeMatch . Length < expression . Length )
2488- {
2489- typeName += $ "+{ nestedTypeMatch . Groups [ "name" ] . Value } ";
2490-
2491- nestedType = GetTypeByFriendlyName ( typeName , nestedTypeMatch . Groups [ "isgeneric" ] . Value ) ;
2492-
2493- if ( nestedType != null )
2494- {
2495- i += nestedTypeMatch . Length ;
2496- staticType = nestedType ;
2497- }
2498- else
2499- {
2500- break ;
2501- }
2502-
2503- nestedTypeMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2504- }
2505- }
2506-
2507- if ( typeName . EndsWith ( "?" ) && staticType != null )
2508- i ++ ;
2443+ Type staticType = EvaluateType ( expression , ref i , varFuncName , genericsTypes ) ;
25092444
25102445 if ( staticType != null )
25112446 {
@@ -2547,6 +2482,79 @@ where method.GetParameters()[0].ParameterType == objType // static extMethod(thi
25472482 }
25482483 }
25492484
2485+ protected virtual Type EvaluateType ( string expression , ref int i , string currentName = "" , string genericsTypes = "" )
2486+ {
2487+ string typeName = $ "{ currentName } { ( ( i < expression . Length && expression . Substring ( i ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2488+ Type staticType = GetTypeByFriendlyName ( typeName , genericsTypes ) ;
2489+
2490+ // For inline namespace parsing
2491+ if ( staticType == null && OptionInlineNamespacesEvaluationActive )
2492+ {
2493+ int subIndex = 0 ;
2494+ Match namespaceMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2495+
2496+ while ( staticType == null
2497+ && namespaceMatch . Success
2498+ && ! namespaceMatch . Groups [ "sign" ] . Success
2499+ && ! namespaceMatch . Groups [ "assignationOperator" ] . Success
2500+ && ! namespaceMatch . Groups [ "postfixOperator" ] . Success
2501+ && ! namespaceMatch . Groups [ "isfunction" ] . Success
2502+ && i + subIndex < expression . Length
2503+ && ! typeName . EndsWith ( "?" ) )
2504+ {
2505+ subIndex += namespaceMatch . Length ;
2506+ typeName += $ "{ namespaceMatch . Groups [ "inObject" ] . Value } { namespaceMatch . Groups [ "name" ] . Value } { ( ( i + subIndex < expression . Length && expression . Substring ( i + subIndex ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2507+
2508+ staticType = GetTypeByFriendlyName ( typeName , namespaceMatch . Groups [ "isgeneric" ] . Value ) ;
2509+
2510+ if ( staticType != null )
2511+ {
2512+ i += subIndex ;
2513+ break ;
2514+ }
2515+
2516+ namespaceMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2517+ }
2518+ }
2519+
2520+ if ( typeName . EndsWith ( "?" ) && staticType != null )
2521+ i ++ ;
2522+
2523+ // For nested type parsing
2524+ if ( staticType != null )
2525+ {
2526+ int subIndex = 0 ;
2527+ Match nestedTypeMatch = varOrFunctionRegEx . Match ( expression . Substring ( i + subIndex ) ) ;
2528+ while ( nestedTypeMatch . Success
2529+ && ! nestedTypeMatch . Groups [ "sign" ] . Success
2530+ && ! nestedTypeMatch . Groups [ "assignationOperator" ] . Success
2531+ && ! nestedTypeMatch . Groups [ "postfixOperator" ] . Success
2532+ && ! nestedTypeMatch . Groups [ "isfunction" ] . Success )
2533+ {
2534+ subIndex = nestedTypeMatch . Length ;
2535+ typeName += $ "+{ nestedTypeMatch . Groups [ "name" ] . Value } { ( ( i + subIndex < expression . Length && expression . Substring ( i + subIndex ) [ 0 ] == '?' ) ? "?" : "" ) } ";
2536+
2537+ Type nestedType = GetTypeByFriendlyName ( typeName , nestedTypeMatch . Groups [ "isgeneric" ] . Value ) ;
2538+ if ( nestedType != null )
2539+ {
2540+ i += subIndex ;
2541+ staticType = nestedType ;
2542+
2543+ if ( typeName . EndsWith ( "?" ) )
2544+ i ++ ;
2545+ }
2546+ else
2547+ {
2548+ break ;
2549+ }
2550+
2551+ nestedTypeMatch = varOrFunctionRegEx . Match ( expression . Substring ( i ) ) ;
2552+ }
2553+ }
2554+
2555+ return staticType ;
2556+ }
2557+
25502558 protected virtual bool EvaluateChar ( string expression , Stack < object > stack , ref int i )
25512559 {
25522560 if ( ! OptionCharEvaluationActive )
0 commit comments