@@ -903,7 +903,7 @@ protected virtual BindingFlags StaticBindingFlag
903903
904904 #endregion
905905
906- #region Custom and on the fly variables and methods
906+ #region Custom and on the fly evaluation
907907
908908 /// <summary>
909909 /// If set, this object is used to use it's fields, properties and methods as global variables and functions
@@ -959,12 +959,6 @@ public IDictionary<string, object> Variables
959959 /// </summary>
960960 public event EventHandler < FunctionEvaluationEventArg > EvaluateFunction ;
961961
962- /// <summary>
963- /// Is fired if no indexing were found.
964- /// Allow to define an indexing and the corresponding value on the fly.
965- /// </summary>
966- public event EventHandler < IndexingEvaluationEventArg > EvaluateIndexing ;
967-
968962 /// <summary>
969963 /// Is fired when a parameter is not of the correct type for the function.
970964 /// Allow to define a custom parameter cast to make the function call work on the fly.
@@ -1554,7 +1548,7 @@ public T Evaluate<T>(string expression)
15541548 EvaluateOperators ,
15551549 EvaluateChar ,
15561550 EvaluateParenthis ,
1557- EvaluateIndexingOperator ,
1551+ EvaluateIndexing ,
15581552 EvaluateString ,
15591553 EvaluateTernaryConditionalOperator ,
15601554 } ) ;
@@ -2644,7 +2638,7 @@ protected virtual void CorrectStackWithUnaryPlusOrMinusBeforeParenthisIfNecessar
26442638 }
26452639 }
26462640
2647- protected virtual bool EvaluateIndexingOperator ( string expression , Stack < object > stack , ref int i )
2641+ protected virtual bool EvaluateIndexing ( string expression , Stack < object > stack , ref int i )
26482642 {
26492643 if ( ! OptionIndexingActive )
26502644 return false ;
@@ -2700,58 +2694,69 @@ protected virtual bool EvaluateIndexingOperator(string expression, Stack<object>
27002694 return true ;
27012695 }
27022696
2703- // IndexingPreEvaluationEventArg indexingPreEvaluationEventArg = new IndexingPreEvaluationEventArg(innerExp.ToString(), this, left);
2697+ IndexingPreEvaluationEventArg indexingPreEvaluationEventArg = new IndexingPreEvaluationEventArg ( innerExp . ToString ( ) , this , left ) ;
27042698
2705- // PreEvaluateIndexing?.Invoke(this, indexingPreEvaluationEventArg);
2699+ PreEvaluateIndexing ? . Invoke ( this , indexingPreEvaluationEventArg ) ;
27062700
2707- dynamic right = Evaluate ( innerExp . ToString ( ) ) ;
2708- ExpressionOperator op = indexingBeginningMatch . Length == 2 ? ExpressionOperator . IndexingWithNullConditional : ExpressionOperator . Indexing ;
2701+ if ( indexingPreEvaluationEventArg . CancelEvaluation )
2702+ {
2703+ throw new ExpressionEvaluatorSyntaxErrorException ( $ "[{ left . GetType ( ) } ] can not be indexed.") ;
2704+ }
2705+ else if ( indexingPreEvaluationEventArg . HasValue )
2706+ {
2707+ stack . Push ( indexingPreEvaluationEventArg . Value ) ;
2708+ }
2709+ else
2710+ {
2711+ dynamic right = Evaluate ( innerExp . ToString ( ) ) ;
2712+ ExpressionOperator op = indexingBeginningMatch . Length == 2 ? ExpressionOperator . IndexingWithNullConditional : ExpressionOperator . Indexing ;
27092713
2710- if ( OptionForceIntegerNumbersEvaluationsAsDoubleByDefault && right is double && Regex . IsMatch ( innerExp . ToString ( ) , @"^\d+$" ) )
2711- right = ( int ) right ;
2714+ if ( OptionForceIntegerNumbersEvaluationsAsDoubleByDefault && right is double && Regex . IsMatch ( innerExp . ToString ( ) , @"^\d+$" ) )
2715+ right = ( int ) right ;
27122716
2713- Match assignationOrPostFixOperatorMatch = null ;
2717+ Match assignationOrPostFixOperatorMatch = null ;
27142718
2715- dynamic valueToPush = null ;
2719+ dynamic valueToPush = null ;
27162720
2717- if ( OptionIndexingAssignationActive && ( assignationOrPostFixOperatorMatch = assignationOrPostFixOperatorRegex . Match ( expression . Substring ( i + 1 ) ) ) . Success )
2718- {
2719- i += assignationOrPostFixOperatorMatch . Length + 1 ;
2721+ if ( OptionIndexingAssignationActive && ( assignationOrPostFixOperatorMatch = assignationOrPostFixOperatorRegex . Match ( expression . Substring ( i + 1 ) ) ) . Success )
2722+ {
2723+ i += assignationOrPostFixOperatorMatch . Length + 1 ;
27202724
2721- bool postFixOperator = assignationOrPostFixOperatorMatch . Groups [ "postfixOperator" ] . Success ;
2722- string exceptionContext = postFixOperator ? "++ or -- operator" : "an assignation" ;
2725+ bool postFixOperator = assignationOrPostFixOperatorMatch . Groups [ "postfixOperator" ] . Success ;
2726+ string exceptionContext = postFixOperator ? "++ or -- operator" : "an assignation" ;
27232727
2724- if ( stack . Count > 1 )
2725- throw new ExpressionEvaluatorSyntaxErrorException ( $ "The left part of { exceptionContext } must be a variable, a property or an indexer.") ;
2728+ if ( stack . Count > 1 )
2729+ throw new ExpressionEvaluatorSyntaxErrorException ( $ "The left part of { exceptionContext } must be a variable, a property or an indexer.") ;
27262730
2727- if ( op == ExpressionOperator . IndexingWithNullConditional )
2728- throw new ExpressionEvaluatorSyntaxErrorException ( $ "Null conditional is not usable left to { exceptionContext } ") ;
2731+ if ( op == ExpressionOperator . IndexingWithNullConditional )
2732+ throw new ExpressionEvaluatorSyntaxErrorException ( $ "Null conditional is not usable left to { exceptionContext } ") ;
27292733
2730- if ( postFixOperator )
2731- {
2732- if ( left is IDictionary < string , object > dictionaryLeft )
2733- valueToPush = assignationOrPostFixOperatorMatch . Groups [ "postfixOperator" ] . Value . Equals ( "++" ) ? dictionaryLeft [ right ] ++ : dictionaryLeft [ right ] -- ;
2734+ if ( postFixOperator )
2735+ {
2736+ if ( left is IDictionary < string , object > dictionaryLeft )
2737+ valueToPush = assignationOrPostFixOperatorMatch . Groups [ "postfixOperator" ] . Value . Equals ( "++" ) ? dictionaryLeft [ right ] ++ : dictionaryLeft [ right ] -- ;
2738+ else
2739+ valueToPush = assignationOrPostFixOperatorMatch . Groups [ "postfixOperator" ] . Value . Equals ( "++" ) ? left [ right ] ++ : left [ right ] -- ;
2740+ }
27342741 else
2735- valueToPush = assignationOrPostFixOperatorMatch . Groups [ "postfixOperator" ] . Value . Equals ( "++" ) ? left [ right ] ++ : left [ right ] -- ;
2742+ {
2743+ valueToPush = ManageKindOfAssignation ( expression , ref i , assignationOrPostFixOperatorMatch , ( ) => OperatorsEvaluations [ 0 ] [ op ] ( left , right ) ) ;
2744+
2745+ if ( left is IDictionary < string , object > dictionaryLeft )
2746+ dictionaryLeft [ right ] = valueToPush ;
2747+ else
2748+ left [ right ] = valueToPush ;
2749+
2750+ stack . Clear ( ) ;
2751+ }
27362752 }
27372753 else
27382754 {
2739- valueToPush = ManageKindOfAssignation ( expression , ref i , assignationOrPostFixOperatorMatch , ( ) => OperatorsEvaluations [ 0 ] [ op ] ( left , right ) ) ;
2740-
2741- if ( left is IDictionary < string , object > dictionaryLeft )
2742- dictionaryLeft [ right ] = valueToPush ;
2743- else
2744- left [ right ] = valueToPush ;
2745-
2746- stack . Clear ( ) ;
2755+ valueToPush = OperatorsEvaluations [ 0 ] [ op ] ( left , right ) ;
27472756 }
2748- }
2749- else
2750- {
2751- valueToPush = OperatorsEvaluations [ 0 ] [ op ] ( left , right ) ;
2752- }
27532757
2754- stack . Push ( valueToPush ) ;
2758+ stack . Push ( valueToPush ) ;
2759+ }
27552760
27562761 return true ;
27572762 }
@@ -4428,12 +4433,13 @@ public FunctionPreEvaluationEventArg(string name, List<string> args = null, Expr
44284433 public bool CancelEvaluation { get ; set ; }
44294434 }
44304435
4436+
44314437 /// <summary>
44324438 /// Infos about the indexing that is currently evaluate
44334439 /// </summary>
4434- public partial class IndexingEvaluationEventArg : EventArgs
4440+ public partial class IndexingPreEvaluationEventArg : EventArgs
44354441 {
4436- public IndexingEvaluationEventArg ( string arg , ExpressionEvaluator evaluator , object onInstance )
4442+ public IndexingPreEvaluationEventArg ( string arg , ExpressionEvaluator evaluator , object onInstance )
44374443 {
44384444 Arg = arg ;
44394445 This = onInstance ;
@@ -4492,16 +4498,6 @@ public T EvaluateArg<T>()
44924498 {
44934499 return Evaluator . Evaluate < T > ( Arg ) ;
44944500 }
4495- }
4496-
4497- /// <summary>
4498- /// Infos about the indexing that is currently evaluate
4499- /// </summary>
4500- public partial class IndexingPreEvaluationEventArg : IndexingEvaluationEventArg
4501- {
4502- public IndexingPreEvaluationEventArg ( string arg , ExpressionEvaluator evaluator , object onInstance )
4503- : base ( arg , evaluator , onInstance )
4504- { }
45054501
45064502 /// <summary>
45074503 /// If set to true cancel the evaluation of the current function or method and throw an exception that the function does not exists
0 commit comments