@@ -105,20 +105,20 @@ private bool ProcessFunctionCall()
105105
106106 if ( foundNull )
107107 {
108- StorePreComputed ( functionStartIndex , functionEndIndex , null ) ;
108+ StorePlaceholder ( functionStartIndex , functionEndIndex , null ) ;
109109 return true ;
110110 }
111111 else if ( Utility . IsNativeFunction ( foundFunction ) )
112112 {
113113 double functionResult = Utility . ComputeNativeFunction ( foundFunction , parameters . ToArray ( ) ) ;
114- StorePreComputed ( functionStartIndex , functionEndIndex , functionResult ) ;
114+ StorePlaceholder ( functionStartIndex , functionEndIndex , functionResult ) ;
115115 }
116116 else
117117 {
118118 if ( _parentExpression . ExpressionFunctions . TryGetValue ( foundFunction , out var customFunction ) )
119119 {
120120 var functionResult = customFunction . Invoke ( parameters . ToArray ( ) ) ?? _parentExpression . Options . DefaultNullValue ;
121- StorePreComputed ( functionStartIndex , functionEndIndex , functionResult ) ;
121+ StorePlaceholder ( functionStartIndex , functionEndIndex , functionResult ) ;
122122 }
123123 else
124124 {
@@ -156,124 +156,33 @@ internal string Compute(bool isCacheable)
156156 //Pre-first-order:
157157 while ( ( operatorIndex = GetFreestandingNotOperation ( out _ ) ) != - 1 )
158158 {
159- if ( _parentExpression . State . TryGetComputedStep ( out ComputedStepItem cachedObj ) )
160- {
161- StorePreComputed ( cachedObj . BeginPosition , cachedObj . EndPosition , cachedObj . ParsedValue ) ;
162- }
163- else
164- {
165- var rightValue = GetRightValue ( operatorIndex + 1 , out int outParsedLength , out bool isOperationCacheable ) ;
166- int ? calculatedResult = rightValue == null ? null : ( rightValue == 0 ) ? 1 : 0 ;
167- StorePreComputed ( operatorIndex , operatorIndex + outParsedLength , calculatedResult ) ;
159+ var rightValue = GetRightValue ( operatorIndex + 1 , out int outParsedLength , out bool isOperationCacheable ) ;
160+ int ? calculatedResult = rightValue == null ? null : ( rightValue == 0 ) ? 1 : 0 ;
168161
169- if ( isCacheable && isOperationCacheable )
170- {
171- var parsedNumber = new ComputedStepItem
172- {
173- ParsedValue = calculatedResult ,
174- BeginPosition = operatorIndex ,
175- EndPosition = operatorIndex + outParsedLength
176- } ;
177- _parentExpression . State . StoreComputedStep ( parsedNumber ) ;
178- }
179- else
180- {
181- _parentExpression . State . IncrementComputedStep ( ) ;
182- }
183- }
162+ StorePlaceholder ( operatorIndex , operatorIndex + outParsedLength , calculatedResult ) ;
184163 }
185164
186165 //First order operations:
187166 operatorIndex = GetIndexOfOperation ( Utility . FirstOrderOperations , out string operation ) ;
188167 if ( operatorIndex > 0 )
189168 {
190- var calculatedResult = GetLeftAndRightValues ( operation , operatorIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isOperationCacheable ) ;
191-
192- if ( _parentExpression . State . TryGetComputedStep ( out ComputedStepItem cachedObj ) )
193- {
194- StorePreComputed ( cachedObj . BeginPosition , cachedObj . EndPosition , cachedObj . ParsedValue ) ;
195- }
196- else
197- {
198- StorePreComputed ( beginPosition , endPosition , calculatedResult ) ;
199- if ( isCacheable && isOperationCacheable )
200- {
201- var parsedNumber = new ComputedStepItem
202- {
203- ParsedValue = calculatedResult ,
204- BeginPosition = beginPosition ,
205- EndPosition = endPosition
206- } ;
207- _parentExpression . State . StoreComputedStep ( parsedNumber ) ;
208- }
209- else
210- {
211- _parentExpression . State . IncrementComputedStep ( ) ;
212- }
213- }
214-
169+ CollapseRightAndLeft ( operation , operatorIndex ) ;
215170 continue ;
216171 }
217172
218173 //Second order operations:
219174 operatorIndex = GetIndexOfOperation ( Utility . SecondOrderOperations , out operation ) ;
220175 if ( operatorIndex > 0 )
221176 {
222- var calculatedResult = GetLeftAndRightValues ( operation , operatorIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isOperationCacheable ) ;
223-
224- if ( _parentExpression . State . TryGetComputedStep ( out ComputedStepItem cachedObj ) )
225- {
226- StorePreComputed ( cachedObj . BeginPosition , cachedObj . EndPosition , cachedObj . ParsedValue ) ;
227- }
228- else
229- {
230- StorePreComputed ( beginPosition , endPosition , calculatedResult ) ;
231- if ( isCacheable && isOperationCacheable )
232- {
233- var parsedNumber = new ComputedStepItem
234- {
235- ParsedValue = calculatedResult ,
236- BeginPosition = beginPosition ,
237- EndPosition = endPosition
238- } ;
239- _parentExpression . State . StoreComputedStep ( parsedNumber ) ;
240- }
241- else
242- {
243- _parentExpression . State . IncrementComputedStep ( ) ;
244- }
245- }
177+ CollapseRightAndLeft ( operation , operatorIndex ) ;
246178 continue ;
247179 }
248180
249181 //Third order operations:
250182 operatorIndex = GetIndexOfOperation ( Utility . ThirdOrderOperations , out operation ) ;
251183 if ( operatorIndex > 0 )
252184 {
253- var calculatedResult = GetLeftAndRightValues ( operation , operatorIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isOperationCacheable ) ;
254-
255- if ( _parentExpression . State . TryGetComputedStep ( out ComputedStepItem cachedObj ) )
256- {
257- StorePreComputed ( cachedObj . BeginPosition , cachedObj . EndPosition , cachedObj . ParsedValue ) ;
258- }
259- else
260- {
261- StorePreComputed ( beginPosition , endPosition , calculatedResult ) ;
262- if ( isCacheable && isOperationCacheable )
263- {
264- var parsedNumber = new ComputedStepItem
265- {
266- ParsedValue = calculatedResult ,
267- BeginPosition = beginPosition ,
268- EndPosition = endPosition
269- } ;
270- _parentExpression . State . StoreComputedStep ( parsedNumber ) ;
271- }
272- else
273- {
274- _parentExpression . State . IncrementComputedStep ( ) ;
275- }
276- }
185+ CollapseRightAndLeft ( operation , operatorIndex ) ;
277186 continue ;
278187 }
279188
@@ -289,7 +198,7 @@ internal string Compute(bool isCacheable)
289198 return _parentExpression . State . StorePlaceholderCacheItem ( _parentExpression . StringToDouble ( Text ) ) ;
290199 }
291200
292- internal void StorePreComputed ( int startIndex , int endIndex , double ? value )
201+ internal void StorePlaceholder ( int startIndex , int endIndex , double ? value )
293202 {
294203 var cacheKey = _parentExpression . State . StorePlaceholderCacheItem ( value ) ;
295204 Text = _parentExpression . ReplaceRange ( Text , startIndex , endIndex , cacheKey ) ;
@@ -310,26 +219,43 @@ internal void TruncateParenthesizes()
310219 /// Gets the numbers to the left and right of an operator.
311220 /// Returns FALSE when NULL is found for either value.
312221 /// </summary>
313- private double ? GetLeftAndRightValues ( string operation ,
314- int operationBeginIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isCacheable )
222+ private void CollapseRightAndLeft ( string operation , int operationBeginIndex )
315223 {
316224 var left = GetLeftValue ( operationBeginIndex , out int leftParsedLength , out bool isLeftCacheable ) ;
317225 var right = GetRightValue ( operationBeginIndex + operation . Length , out int rightParsedLength , out bool isRightCacheable ) ;
318226
319- leftValue = left ?? 0 ;
320- rightValue = right ?? 0 ;
321-
322- beginPosition = operationBeginIndex - leftParsedLength ;
323- endPosition = operationBeginIndex + rightParsedLength + ( operation . Length - 1 ) ;
324-
325- isCacheable = isLeftCacheable && isRightCacheable ;
227+ var beginPosition = operationBeginIndex - leftParsedLength ;
228+ var endPosition = operationBeginIndex + rightParsedLength + ( operation . Length - 1 ) ;
326229
327- if ( left != null && right != null )
230+ if ( _parentExpression . State . TryGetComputedStep ( out ComputedStepItem cachedObj ) )
328231 {
329- return Utility . ComputePrivative ( leftValue , operation , rightValue ) ;
232+ StorePlaceholder ( cachedObj . BeginPosition , cachedObj . EndPosition , cachedObj . ParsedValue ) ;
330233 }
234+ else
235+ {
236+ double ? result = null ;
331237
332- return null ;
238+ if ( left != null && right != null )
239+ {
240+ result = Utility . ComputePrivative ( left ?? 0 , operation , right ?? 0 ) ;
241+ }
242+
243+ StorePlaceholder ( beginPosition , endPosition , result ) ;
244+ if ( isLeftCacheable && isRightCacheable )
245+ {
246+ var parsedNumber = new ComputedStepItem
247+ {
248+ ParsedValue = result ,
249+ BeginPosition = beginPosition ,
250+ EndPosition = endPosition
251+ } ;
252+ _parentExpression . State . StoreComputedStep ( parsedNumber ) ;
253+ }
254+ else
255+ {
256+ _parentExpression . State . IncrementComputedStep ( ) ;
257+ }
258+ }
333259 }
334260
335261 private double ? GetLeftValue ( int operationIndex , out int outParsedLength , out bool isCacheable )
@@ -357,7 +283,7 @@ internal void TruncateParenthesizes()
357283 outParsedLength = ( operationIndex - i ) - 1 ;
358284 var cacheKey = span . Slice ( operationIndex - outParsedLength + 1 , outParsedLength - 2 ) ;
359285 var cachedItem = _parentExpression . State . GetPlaceholderCacheItem ( cacheKey ) ;
360- isCacheable = false ;
286+ isCacheable = ! cachedItem . IsVariable ;
361287 _parentExpression . State . IncrementScanStep ( ) ;
362288 return cachedItem . ComputedValue ;
363289 }
@@ -419,7 +345,7 @@ internal void TruncateParenthesizes()
419345 i ++ ;
420346 outParsedLength = i ;
421347 var cachedItem = _parentExpression . State . GetPlaceholderCacheItem ( span . Slice ( 1 , i - 2 ) ) ;
422- isCacheable = false ;
348+ isCacheable = ! cachedItem . IsVariable ;
423349 _parentExpression . State . IncrementScanStep ( ) ;
424350 return cachedItem . ComputedValue ;
425351 }
0 commit comments