nl_tokens: Helper function for replacing regular expressions with the result of a function application in String . prototype . replace .
pl_tokens: function StringReplaceGlobalRegExpWithFunction ( <mask> , regexp , replace ) { var resultArray = reusableReplaceArray ; if ( resultArray ) { reusableReplaceArray = null ; } else { // Inside a nested replace (replace called from the replacement function // of another replace) or we have failed to set the reusable array // back due to an exception in a replacement function. Create a new // array to use in the future, or until the original is written back. resultArray = new InternalArray ( 16 ) ; } var res = % RegExpExecMultiple ( regexp , subject , RegExpLastMatchInfo , resultArray ) ; regexp . lastIndex = 0 ; if ( IS_NULL ( res ) ) { // No matches at all. reusableReplaceArray = resultArray ; return subject ; } var len = res . length ; if ( NUMBER_OF_CAPTURES ( RegExpLastMatchInfo ) == 2 ) { // If the number of captures is two then there are no explicit captures in // the regexp, just the implicit capture that captures the whole match.  In // this case we can simplify quite a bit and end up with something faster. // The builder will consist of some integers that indicate slices of the // input string and some replacements that were returned from the replace // function. var match_start = 0 ; for ( var i = 0 ; i < len ; i ++ ) { var elem = res [ i ] ; if ( % _IsSmi ( elem ) ) { // Integers represent slices of the original string. if ( elem > 0 ) { match_start = ( elem >> 11 ) + ( elem & 0x7ff ) ; } else { match_start = res [ ++ i ] - elem ; } } else { var func_result = replace ( elem , match_start , subject ) ; // Overwrite the i'th element in the results with the string we got // back from the callback function. res [ i ] = TO_STRING ( func_result ) ; match_start += elem . length ; } } } else { for ( var i = 0 ; i < len ; i ++ ) { var elem = res [ i ] ; if ( ! % _IsSmi ( elem ) ) { // elem must be an Array. // Use the apply argument as backing for global RegExp properties. var func_result = % reflect_apply ( replace , UNDEFINED , elem ) ; // Overwrite the i'th element in the results with the string we got // back from the callback function. res [ i ] = TO_STRING ( func_result ) ; } } } var result = % StringBuilderConcat ( res , len , subject ) ; resultArray . length = 0 ; reusableReplaceArray = resultArray ; return result ; }