@@ -136,22 +136,22 @@ internal string Compute(bool isCacheable)
136136 {
137137 TruncateParenthesizes ( ) ;
138138
139+ //Process all function calls from right-to-left.
139140 while ( true )
140141 {
141- int operatorIndex ;
142-
143- //Process all function calls from right-to-left.
144- while ( true )
142+ if ( ProcessFunctionCall ( ) )
145143 {
146- if ( ProcessFunctionCall ( ) )
147- {
148- isCacheable = false ;
149- }
150- else
151- {
152- break ;
153- }
144+ isCacheable = false ;
154145 }
146+ else
147+ {
148+ break ;
149+ }
150+ }
151+
152+ while ( true )
153+ {
154+ int operatorIndex ;
155155
156156 //Pre-first-order:
157157 while ( ( operatorIndex = GetFreestandingNotOperation ( out _ ) ) != - 1 )
@@ -187,18 +187,14 @@ internal string Compute(bool isCacheable)
187187 operatorIndex = GetIndexOfOperation ( Utility . FirstOrderOperations , out string operation ) ;
188188 if ( operatorIndex > 0 )
189189 {
190+ var calculatedResult = GetLeftAndRightValues ( operation , operatorIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isOperationCacheable ) ;
191+
190192 if ( _parentExpression . State . TryGetComputedStep ( out ComputedStepItem cachedObj ) )
191193 {
192194 StorePreComputed ( cachedObj . BeginPosition , cachedObj . EndPosition , cachedObj . ParsedValue ) ;
193195 }
194196 else
195197 {
196- double ? calculatedResult = null ;
197- if ( GetLeftAndRightValues ( operation , operatorIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isOperationCacheable ) )
198- {
199- calculatedResult = Utility . ComputePrivative ( leftValue , operation , rightValue ) ;
200- }
201-
202198 StorePreComputed ( beginPosition , endPosition , calculatedResult ) ;
203199 if ( isCacheable && isOperationCacheable )
204200 {
@@ -223,18 +219,14 @@ internal string Compute(bool isCacheable)
223219 operatorIndex = GetIndexOfOperation ( Utility . SecondOrderOperations , out operation ) ;
224220 if ( operatorIndex > 0 )
225221 {
222+ var calculatedResult = GetLeftAndRightValues ( operation , operatorIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isOperationCacheable ) ;
223+
226224 if ( _parentExpression . State . TryGetComputedStep ( out ComputedStepItem cachedObj ) )
227225 {
228226 StorePreComputed ( cachedObj . BeginPosition , cachedObj . EndPosition , cachedObj . ParsedValue ) ;
229227 }
230228 else
231229 {
232- double ? calculatedResult = null ;
233- if ( GetLeftAndRightValues ( operation , operatorIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isOperationCacheable ) )
234- {
235- calculatedResult = Utility . ComputePrivative ( leftValue , operation , rightValue ) ;
236- }
237-
238230 StorePreComputed ( beginPosition , endPosition , calculatedResult ) ;
239231 if ( isCacheable && isOperationCacheable )
240232 {
@@ -258,19 +250,14 @@ internal string Compute(bool isCacheable)
258250 operatorIndex = GetIndexOfOperation ( Utility . ThirdOrderOperations , out operation ) ;
259251 if ( operatorIndex > 0 )
260252 {
253+ var calculatedResult = GetLeftAndRightValues ( operation , operatorIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isOperationCacheable ) ;
254+
261255 if ( _parentExpression . State . TryGetComputedStep ( out ComputedStepItem cachedObj ) )
262256 {
263257 StorePreComputed ( cachedObj . BeginPosition , cachedObj . EndPosition , cachedObj . ParsedValue ) ;
264258 }
265259 else
266260 {
267- double ? calculatedResult = null ;
268-
269- if ( GetLeftAndRightValues ( operation , operatorIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isOperationCacheable ) )
270- {
271- calculatedResult = Utility . ComputePrivative ( leftValue , operation , rightValue ) ;
272- }
273-
274261 StorePreComputed ( beginPosition , endPosition , calculatedResult ) ;
275262 if ( isCacheable && isOperationCacheable )
276263 {
@@ -323,7 +310,7 @@ internal void TruncateParenthesizes()
323310 /// Gets the numbers to the left and right of an operator.
324311 /// Returns FALSE when NULL is found for either value.
325312 /// </summary>
326- private bool GetLeftAndRightValues ( string operation ,
313+ private double ? GetLeftAndRightValues ( string operation ,
327314 int operationBeginIndex , out double leftValue , out double rightValue , out int beginPosition , out int endPosition , out bool isCacheable )
328315 {
329316 var left = GetLeftValue ( operationBeginIndex , out int leftParsedLength , out bool isLeftCacheable ) ;
@@ -337,66 +324,87 @@ private bool GetLeftAndRightValues(string operation,
337324
338325 isCacheable = isLeftCacheable && isRightCacheable ;
339326
340- return left != null && right != null ;
327+ if ( left != null && right != null )
328+ {
329+ return Utility . ComputePrivative ( leftValue , operation , rightValue ) ;
330+ }
331+
332+ return null ;
341333 }
342334
343335 private double ? GetLeftValue ( int operationIndex , out int outParsedLength , out bool isCacheable )
344336 {
345- var span = Text . AsSpan ( 0 , operationIndex ) ;
346-
347- int i = operationIndex - 1 ;
348-
349- if ( span [ i ] == '$' )
337+ if ( _parentExpression . State . TryGetScanStep ( out var cachedObj ) )
350338 {
351- i -- ; //Skip the cache indicator.
352- while ( span [ i ] != '$' )
353- {
354- i -- ;
355- }
356- i -- ;
357- outParsedLength = ( operationIndex - i ) - 1 ;
358- var cacheKey = span . Slice ( operationIndex - outParsedLength + 1 , outParsedLength - 2 ) ;
359- var cachedItem = _parentExpression . State . GetPlaceholderCacheItem ( cacheKey ) ;
360- isCacheable = false ;
361- return cachedItem . ComputedValue ;
339+ outParsedLength = cachedObj . Length ;
340+ isCacheable = true ;
341+ return cachedObj . Value ;
362342 }
363343 else
364344 {
365- while ( i > - 1 && ( ( span [ i ] - '0' >= 0 && span [ i ] - '0' <= 9 ) || span [ i ] == '.' ) )
345+ var span = Text . AsSpan ( 0 , operationIndex ) ;
346+
347+ int i = operationIndex - 1 ;
348+
349+ if ( span [ i ] == '$' )
366350 {
351+ i -- ; //Skip the cache indicator.
352+ while ( span [ i ] != '$' )
353+ {
354+ i -- ;
355+ }
367356 i -- ;
357+ outParsedLength = ( operationIndex - i ) - 1 ;
358+ var cacheKey = span . Slice ( operationIndex - outParsedLength + 1 , outParsedLength - 2 ) ;
359+ var cachedItem = _parentExpression . State . GetPlaceholderCacheItem ( cacheKey ) ;
360+ isCacheable = false ;
361+ _parentExpression . State . IncrementScanStep ( ) ;
362+ return cachedItem . ComputedValue ;
368363 }
369-
370- //Check for explicit positive or negative sign if the number is not at the start of the expression.
371- if ( i == 0 && ( span [ i ] == '-' || span [ i ] == '+' ) )
364+ else
372365 {
373- i -- ; //Skip the explicit positive or negative sign or cache indicator.
374- }
366+ while ( i > - 1 && ( ( span [ i ] - '0' >= 0 && span [ i ] - '0' <= 9 ) || span [ i ] == '.' ) )
367+ {
368+ i -- ;
369+ }
375370
376- //Check for explicit positive or negative sign when the preceding character is a math character .
377- if ( i > 0 && Utility . IsMathChar ( span [ i - 1 ] ) && ( span [ i ] == '-' || span [ i ] == '+' ) )
378- {
379- i -- ; //Skip the explicit positive or negative sign or cache indicator.
380- }
371+ //Check for explicit positive or negative sign if the number is not at the start of the expression .
372+ if ( i == 0 && ( span [ i ] == '-' || span [ i ] == '+' ) )
373+ {
374+ i -- ; //Skip the explicit positive or negative sign or cache indicator.
375+ }
381376
382- outParsedLength = ( operationIndex - i ) - 1 ;
383- isCacheable = true ;
384- return _parentExpression . StringToDouble ( span . Slice ( operationIndex - outParsedLength , outParsedLength ) ) ;
377+ //Check for explicit positive or negative sign when the preceding character is a math character.
378+ if ( i > 0 && Utility . IsMathChar ( span [ i - 1 ] ) && ( span [ i ] == '-' || span [ i ] == '+' ) )
379+ {
380+ i -- ; //Skip the explicit positive or negative sign or cache indicator.
381+ }
382+
383+ outParsedLength = ( operationIndex - i ) - 1 ;
384+ isCacheable = true ;
385+ var result = _parentExpression . StringToDouble ( span . Slice ( operationIndex - outParsedLength , outParsedLength ) ) ;
386+
387+ _parentExpression . State . StoreScanStep ( new ScanStepItem
388+ {
389+ Value = result ,
390+ Length = outParsedLength
391+ } ) ;
392+
393+ return result ;
394+ }
385395 }
386396 }
387397
388398 private double ? GetRightValue ( int endOfOperationIndex , out int outParsedLength , out bool isCacheable )
389399 {
390- /*
391- if (_parentExpression.State.TryGetComputedStep(out ComputedStepItem cachedObj))
400+ if ( _parentExpression . State . TryGetScanStep ( out var cachedObj ) )
392401 {
393402 outParsedLength = cachedObj . Length ;
394- isCacheable = false ;
395- return cachedObj.ParsedValue ;
403+ isCacheable = true ;
404+ return cachedObj . Value ;
396405 }
397406 else
398407 {
399- */
400408 var span = Text . AsSpan ( endOfOperationIndex ) ;
401409
402410 int i = 0 ;
@@ -412,7 +420,7 @@ private bool GetLeftAndRightValues(string operation,
412420 outParsedLength = i ;
413421 var cachedItem = _parentExpression . State . GetPlaceholderCacheItem ( span . Slice ( 1 , i - 2 ) ) ;
414422 isCacheable = false ;
415- // _parentExpression.State.IncrementComputedStep ();
423+ _parentExpression . State . IncrementScanStep ( ) ;
416424 return cachedItem . ComputedValue ;
417425 }
418426 else
@@ -430,18 +438,16 @@ private bool GetLeftAndRightValues(string operation,
430438 outParsedLength = i ;
431439 isCacheable = true ;
432440 var result = _parentExpression . StringToDouble ( span . Slice ( 0 , i ) ) ;
433- /*
434- _parentExpression.State.StoreComputedStep (new ComputedStepItem
441+
442+ _parentExpression . State . StoreScanStep ( new ScanStepItem
435443 {
436- ParsedValue = result,
437- //BeginPosition = endOfOperationIndex,
438- //EndPosition = endOfOperationIndex + outParsedLength,
444+ Value = result ,
439445 Length = outParsedLength
440446 } ) ;
441- */
447+
442448 return result ;
443449 }
444- // }
450+ }
445451 }
446452
447453 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
0 commit comments