!Stack

From NSIS Wiki
Jump to navigationJump to search

About

The following is an experiment to create a pseudo stack implementation for use within a precompiler context.

Usage

Example

;!define !Stack_AllowRedefine
;!define !Stack_Delimiter ¤
!include "!Stack.nsh"
 
${!Push} TestStack 0            # Stack(TestStack): 0 
${!Push} TestStack 1            # Stack(TestStack): 1 0
${!Push} TestStack 2            # Stack(TestStack): 2 1 0
${!Push} TestStack 3            # Stack(TestStack): 3 2 1 0
${!Push} TestStack 4            # Stack(TestStack): 4 3 2 1 0
 
${!Exch} TestStack 1            # Stack(TestStack): 3 4 2 1 0
 
!define  ValueTmp 5
${!Exch} TestStack ValueTmp     # Stack(TestStack): 5 4 2 1 0
${!Push} TestStack ${ValueTmp}  # Stack(TestStack): 3 5 4 2 1 0
 
${!Exch} TestStack 2            # Stack(TestStack): 4 5 3 2 1 0
${!Exch} TestStack 1            # Stack(TestStack): 5 4 3 2 1 0
 
${!Pop}  TestStack Value5       # Stack(TestStack): 4 3 2 1 0
${!Pop}  TestStack Value4       # Stack(TestStack): 3 2 1 0
${!Peek} TestStack Value3       # Stack(TestStack): 3 2 1 0
${!Pop}  TestStack Value3       # Stack(TestStack): 2 1 0
${!Pop}  TestStack Value2       # Stack(TestStack): 1 0
${!Pop}  TestStack Value1       # Stack(TestStack): 0
${!Pop}  TestStack Value0       # Stack(TestStack): EMPTY
;${!Pop}  TestStack ValueE       # Stack(TestStack): ERROR! Stack is Empty!
 
!echo `5=${Value5}`
!echo `4=${Value4}`
!echo `3=${Value3}`
!echo `2=${Value2}`
!echo `1=${Value1}`
!echo `0=${Value0}`
;!echo `E=${ValueE}`

Source

## !include "!Stack.nsh"
 
!verbose push
!verbose 0
 
!ifndef ___!Stack_NSH___
!define ___!Stack_NSH___
 
/*#### PreCompiler Stack #########################################################################
    The following is a Psudo Stack implementation for use within a precompiler context.
    This may be useful when attempting to process across #includes.
    Imagine allowing a precompiler to know when a previous macro has enabled a feature ect.
    Be creative and use your imagination.  I'm sure you'll think of somethng.  ;o)
 
    FUNCTIONS:
        ${!Push}
        ${!Pop}
        ${!Peek}
        ${!Exch}
 
    FLAGS:
        !Stack_Delimiter
        !Stack_AllowRedefine
 
    As a possible guideline, I recommend using the intended library's filename.
        EXAMPLE:
            ${!Push} !Stack.nsh "Value to Store"
 
    Future Enhancments:
        * Expand the !Exch stack_index range beyond 13
            If I could implement a !For !Loop it would make this a snap!
        * Add commands:
            !Flush - Use to remove a certian number of elements from the stack
################################################################################################## */
 
/*#### Defines the Stack Delimiter ########
    You can change this to suite your needs.
    EXAMPLE:
     If you want to change the delimiter to a comma use...
        !define !Stack_Delimiter ,
########################################### */
        !ifndef !Stack_Delimiter
            !define !Stack_Delimiter ¤
        !endif
 
/*#### Allows for Redefinition ############
    By default, if a define previously exists then a compiler time error will occur.
    Add this flag to enable automatic redefines to prevent this error.
########################################### */
;       !define !Stack_AllowRedefine
 
/*#### !Push ##############################
 
       Usage:
       ------
        ${!Push} stackName value
 
        This command will Push a value onto a stack named "stackName".
 
       Example:
       --------
        ${!Push} ExampleStack "5"
        ${!Pop}  ExampleStack MyValue
        !Echo "${MyValue}"
        ;!echo: 5
 
########################################### */
        !define !Push `!insertmacro _!Push`
        !macro _!Push _StackName _Value
            !verbose push
            !verbose 2
            !ifndef `_Stack_${_StackName}`
                ## First refereance to stack
                    !define `_Stack_${_StackName}` `${_Value}${!Stack_Delimiter}`
                    !define `_Stack_${_StackName}_Size` 0
            !else
                ## Push Value onto stack
                    !define _tmp_Stack `${_Value}${!Stack_Delimiter}${_Stack_${_StackName}}`
                    !undef `_Stack_${_StackName}`
                    !define `_Stack_${_StackName}` `${_tmp_Stack}`
                    !undef _tmp_Stack
 
                ## Increment Stack Size Counter
                    !define /math _tmp_Stack `${_Stack_${_StackName}_Size}` + 1
                    !undef `_Stack_${_StackName}_Size`
                    !define `_Stack_${_StackName}_Size` `${_tmp_Stack}`
                    !undef _tmp_Stack
            !endif
            !verbose pop
            ;!warning `STACK= ${_Stack_${_StackName}}`
        !macroend
 
/*#### !Pop ###############################
 
       Usage:
       ------
        ${!Pop} stackName gflag
 
        This command will Pop a value from the stack named "stackName".  The popped value will be defined as "gflag".  If "gflag" allready exists then it will be replaced without errors.
 
       Example:
       --------
        ${!Push} ExampleStack "5"
        ${!Pop}  ExampleStack MyValue
        !Echo "${MyValue}"
        ;!echo: 5
 
########################################### */
        !define !Pop `!insertmacro _!Pop`
        !macro _!Pop _StackName _RetDef
            !verbose push
            !verbose 2
 
            !ifndef `_Stack_${_StackName}`
                !error `Requested stack dosn't exist: StackName=${_StackName}`
            !else if `${_Stack_${_StackName}}` == ``
                !error `Stack is Empty: StackName=${_StackName}`
            !else if `${_Stack_${_StackName}_Size}` < 0
                !error `Not enough stack elements to handle request: !Pop ${_RetDef}$\nStack Name=${_StackName}$\nStack Size=${_Stack_${_StackName}_Size}+1`
            !endif
 
            ${!Peek} `${_StackName}` `${_RetDef}`
 
            !undef `_Stack_${_StackName}`
            !define `_Stack_${_StackName}` `${_tmp_Stack}`
            !undef _tmp_Stack
 
            ## Decrement Stack Size Counter
                !define /math _tmp_Stack `${_Stack_${_StackName}_Size}` - 1
                !undef `_Stack_${_StackName}_Size`
                !define `_Stack_${_StackName}_Size` `${_tmp_Stack}`
                !undef _tmp_Stack
 
            !verbose pop
            ;!warning `STACK= ${_Stack_${_StackName}}`
        !macroend
 
/*#### !Peek ##############################
 
       Usage:
       ------
        ${!Peek} stackName gflag
 
        This command will Read a value from the stack named "stackName".  The read value will be defined as "gflag".  If "gflag" allready exists then it will be replaced without errors.
        This command is similar to the !Pop command but dose not remove the value from the stack.  Also if the stack is empty !Peek will return "!EMPTY" as it's value.
 
       Example:
       --------
        ${!Push} ExampleStack "5"
        ${!Peek} ExampleStack MyValue
        !Echo "${MyValue}"
        ;!echo: 5
 
        ${!Pop}  ExampleStack MyValue
        !Echo "${MyValue}"
        ;!echo: 5
 
        ${!Peek} ExampleStack MyValue
        !Echo "${MyValue}"
        ;!echo: !EMPTY
 
########################################### */
        !define !Peek `!insertmacro _!Peek`
        !macro _!Peek _StackName _RetDef
            !verbose push
            !verbose 2
            !ifdef `${_RetDef}`
                !ifdef !Stack_AllowRedefine
                    !undef `${_RetDef}`
                !else
                    !error `Previously Defined: ${_RetDef}$\nEnable the "!Stack_AllowRedefine" flag to ignore this error.`
                !endif
            !endif
            !ifndef `_Stack_${_StackName}`
                !error `Requested stack dosn't exist: StackName=${_StackName}`
            !else if `${_Stack_${_StackName}}` == ``
                !warning `Stack is Empty: ${_StackName}`
                !define `${_RetDef}` `!EMPTY`
            !else
                !ifdef _tmp_Stack
                    !undef _tmp_Stack
                !endif
                !searchparse /noerrors `${_Stack_${_StackName}}` "" `${_RetDef}` `${!Stack_Delimiter}` _tmp_Stack
            !endif
            !verbose pop
            ;!warning `STACK= ${_Stack_${_StackName}}`
        !macroend
 
/*#### !Exch ##############################
 
       Usage:
       ------
        ${!Exch} stackName gflag|stack_index[1 To 13]
 
        When a number parameter is provided, !Exch will swap the item on the top of the stack with the item that is specified by the offset from the top of the stack in the parameter.
        The provided stack_index value must range from 1 to 13.  If there are not enough items on the stack to accomplish the exchange, a compiler error will occur (to help you debug your code :).
        When a gflag name is provided, !Exch will exchanges the top element of the stack with the gflag's value.
 
       Example:
       --------
        ${!Push} ExampleStack "World"
        ${!Push} ExampleStack "Hello"
 
        ## Stack is now: Hello,World
 
        ${!Exch} ExampleStack 1 ; Swap Top two stack elements
 
        ## Stack is now: World,Hello
 
        !define MyValue "NSIS"
        ${!Exch} ExampleStack MyValue
 
        ## Stack is now: NSIS,Hello
        ## ${MyValue} = "World"
 
########################################### */
        !define !Exch `!insertmacro _!Exch`
        !macro _!Exch _StackName _RetDef
            !verbose push
            !verbose 2
 
            ## Validate Stack
                !ifndef `_Stack_${_StackName}`
                    !error `Requested stack dosn't exist: StackName=${_StackName}`
                !else if `${_Stack_${_StackName}}` == ``
                    !error `Stack is Empty: StackName=${_StackName}`
                !else if `${_Stack_${_StackName}_Size}` < 0
                    !error `Not enough stack elements to handle request: !Exch ${_RetDef}$\nStack Name=${_StackName}$\nStack Size=${_Stack_${_StackName}_Size}+1`
                !else if `${_RetDef}` > 0
                    ## Index Value Provided
                    !if `${_RetDef}` > `${_Stack_${_StackName}_Size}`
                        !error `Not enough stack elements to handle request: !Exch ${_RetDef}$\nStack Name=${_StackName}$\nStack Size=${_Stack_${_StackName}_Size}+1`
                    !endif
                !endif
 
            ## CleanUp (Just in case)
                !ifdef _tmp_Stack_Exch00
                    !undef _tmp_Stack_Exch00
                !endif
                !ifdef _tmp_Stack_Exch01
                    !undef _tmp_Stack_Exch01
                !endif
                !ifdef _tmp_Stack_Exch02
                    !undef _tmp_Stack_Exch02
                !endif
                !ifdef _tmp_Stack_Exch03
                    !undef _tmp_Stack_Exch03
                !endif
                !ifdef _tmp_Stack_Exch04
                    !undef _tmp_Stack_Exch04
                !endif
                !ifdef _tmp_Stack_Exch05
                    !undef _tmp_Stack_Exch05
                !endif
                !ifdef _tmp_Stack_Exch06
                    !undef _tmp_Stack_Exch06
                !endif
                !ifdef _tmp_Stack_Exch07
                    !undef _tmp_Stack_Exch07
                !endif
                !ifdef _tmp_Stack_Exch08
                    !undef _tmp_Stack_Exch08
                !endif
                !ifdef _tmp_Stack_Exch09
                    !undef _tmp_Stack_Exch09
                !endif
                !ifdef _tmp_Stack_Exch10
                    !undef _tmp_Stack_Exch10
                !endif
                !ifdef _tmp_Stack_Exch11
                    !undef _tmp_Stack_Exch11
                !endif
                !ifdef _tmp_Stack_Exch12
                    !undef _tmp_Stack_Exch12
                !endif
                !ifdef _tmp_Stack_Exch13
                    !undef _tmp_Stack_Exch13
                !endif
                !ifdef _tmp_Stack_Exch14
                    !undef _tmp_Stack_Exch14
                !endif      
 
            ## Same as Exch
                !if `${_RetDef}` == ``
                    !undef _RetDef
                    !define _RetDef 1
                !endif
 
            ## Index Provided
                !if `${_RetDef}` > 0
 
                 ## No support for exchange indexes greater than 13
                    !if `${_RetDef}` > 13
                        !error `Exchanging stack by index > 13 is not yet implemented`
 
                ## Same as Exch
                    !else if `${_RetDef}` == 1
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch02}`
 
                ## Same as Exch 2
                    !else if `${_RetDef}` == 2
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch03}`
 
                ## Same as Exch 3
                    !else if `${_RetDef}` == 3
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch04}`
 
                ## Same as Exch 4
                    !else if `${_RetDef}` == 4
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch05}`
 
                ## Same as Exch 5
                    !else if `${_RetDef}` == 5
                         !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch06
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch05}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch06}`
 
                ## Same as Exch 6
                    !else if `${_RetDef}` == 6
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch06 `${!Stack_Delimiter}` _tmp_Stack_Exch07
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch06}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch05}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch07}`
 
                ## Same as Exch 7
                    !else if `${_RetDef}` == 7
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch06 `${!Stack_Delimiter}` _tmp_Stack_Exch07 `${!Stack_Delimiter}` _tmp_Stack_Exch08
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch07}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch05}${!Stack_Delimiter}${_tmp_Stack_Exch06}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch08}`
 
                ## Same as Exch 8
                    !else if `${_RetDef}` == 8
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch06 `${!Stack_Delimiter}` _tmp_Stack_Exch07 `${!Stack_Delimiter}` _tmp_Stack_Exch08 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch09
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch08}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch05}${!Stack_Delimiter}${_tmp_Stack_Exch06}${!Stack_Delimiter}${_tmp_Stack_Exch07}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch09}`
 
                ## Same as Exch 9
                    !else if `${_RetDef}` == 9
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch06 `${!Stack_Delimiter}` _tmp_Stack_Exch07 `${!Stack_Delimiter}` _tmp_Stack_Exch08 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch09 `${!Stack_Delimiter}` _tmp_Stack_Exch10
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch09}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch05}${!Stack_Delimiter}${_tmp_Stack_Exch06}${!Stack_Delimiter}${_tmp_Stack_Exch07}${!Stack_Delimiter}${_tmp_Stack_Exch08}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch10}`
 
                ## Same as Exch 10
                    !else if `${_RetDef}` == 10
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch06 `${!Stack_Delimiter}` _tmp_Stack_Exch07 `${!Stack_Delimiter}` _tmp_Stack_Exch08 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch09 `${!Stack_Delimiter}` _tmp_Stack_Exch10 `${!Stack_Delimiter}` _tmp_Stack_Exch11
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch10}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch05}${!Stack_Delimiter}${_tmp_Stack_Exch06}${!Stack_Delimiter}${_tmp_Stack_Exch07}${!Stack_Delimiter}${_tmp_Stack_Exch08}${!Stack_Delimiter}${_tmp_Stack_Exch09}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch11}`
 
                ## Same as Exch 11
                    !else if `${_RetDef}` == 11
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch06 `${!Stack_Delimiter}` _tmp_Stack_Exch07 `${!Stack_Delimiter}` _tmp_Stack_Exch08 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch09 `${!Stack_Delimiter}` _tmp_Stack_Exch10 `${!Stack_Delimiter}` _tmp_Stack_Exch11 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch12
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch11}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch05}${!Stack_Delimiter}${_tmp_Stack_Exch06}${!Stack_Delimiter}${_tmp_Stack_Exch07}${!Stack_Delimiter}${_tmp_Stack_Exch08}${!Stack_Delimiter}${_tmp_Stack_Exch09}${!Stack_Delimiter}${_tmp_Stack_Exch10}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch12}`
 
                ## Same as Exch 12
                    !else if `${_RetDef}` == 12
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch06 `${!Stack_Delimiter}` _tmp_Stack_Exch07 `${!Stack_Delimiter}` _tmp_Stack_Exch08 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch09 `${!Stack_Delimiter}` _tmp_Stack_Exch10 `${!Stack_Delimiter}` _tmp_Stack_Exch11 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch12 `${!Stack_Delimiter}` _tmp_Stack_Exch13
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch12}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch05}${!Stack_Delimiter}${_tmp_Stack_Exch06}${!Stack_Delimiter}${_tmp_Stack_Exch07}${!Stack_Delimiter}${_tmp_Stack_Exch08}${!Stack_Delimiter}${_tmp_Stack_Exch09}${!Stack_Delimiter}${_tmp_Stack_Exch10}${!Stack_Delimiter}${_tmp_Stack_Exch11}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch13}`
 
                ## Same as Exch 13
                    !else if `${_RetDef}` == 13
                        !searchparse /noerrors `${_Stack_${_StackName}}` "" \
                            _tmp_Stack_Exch00 `${!Stack_Delimiter}` _tmp_Stack_Exch01 `${!Stack_Delimiter}` _tmp_Stack_Exch02 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch03 `${!Stack_Delimiter}` _tmp_Stack_Exch04 `${!Stack_Delimiter}` _tmp_Stack_Exch05 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch06 `${!Stack_Delimiter}` _tmp_Stack_Exch07 `${!Stack_Delimiter}` _tmp_Stack_Exch08 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch09 `${!Stack_Delimiter}` _tmp_Stack_Exch10 `${!Stack_Delimiter}` _tmp_Stack_Exch11 `${!Stack_Delimiter}` \
                            _tmp_Stack_Exch12 `${!Stack_Delimiter}` _tmp_Stack_Exch13 `${!Stack_Delimiter}` _tmp_Stack_Exch14
 
                        !undef  `_Stack_${_StackName}`
                        !define `_Stack_${_StackName}` `${_tmp_Stack_Exch13}${!Stack_Delimiter}${_tmp_Stack_Exch01}${!Stack_Delimiter}${_tmp_Stack_Exch02}${!Stack_Delimiter}${_tmp_Stack_Exch03}${!Stack_Delimiter}${_tmp_Stack_Exch04}${!Stack_Delimiter}${_tmp_Stack_Exch05}${!Stack_Delimiter}${_tmp_Stack_Exch06}${!Stack_Delimiter}${_tmp_Stack_Exch07}${!Stack_Delimiter}${_tmp_Stack_Exch08}${!Stack_Delimiter}${_tmp_Stack_Exch09}${!Stack_Delimiter}${_tmp_Stack_Exch10}${!Stack_Delimiter}${_tmp_Stack_Exch11}${!Stack_Delimiter}${_tmp_Stack_Exch12}${!Stack_Delimiter}${_tmp_Stack_Exch00}${!Stack_Delimiter}${_tmp_Stack_Exch14}`
 
                ## Invalix Syntax
                    !else
                        !error `Syntax Invalid: "${_RetDef}"`
                    !endif
 
            ## Same as Exch $0
                !else
                    !ifdef _tmp_Stack_Exch00
                        !undef _tmp_Stack_Exch00
                    !endif
                    !define _tmp_Stack_Exch00 `${${_RetDef}}`
                    !ifndef !Stack_AllowRedefine
                        !define !Stack_AllowRedefine
                        ${!Pop} `${_StackName}` `${_RetDef}`
                        !undef !Stack_AllowRedefine
                    !endif
                    ${!Push} `${_StackName}` `${_tmp_Stack_Exch00}`
                !endif
 
            ## Clean Up
                !ifdef _tmp_Stack_Exch00
                    !undef _tmp_Stack_Exch00
                !endif
                !ifdef _tmp_Stack_Exch01
                    !undef _tmp_Stack_Exch01
                !endif
                !ifdef _tmp_Stack_Exch02
                    !undef _tmp_Stack_Exch02
                !endif
                !ifdef _tmp_Stack_Exch03
                    !undef _tmp_Stack_Exch03
                !endif
                !ifdef _tmp_Stack_Exch04
                    !undef _tmp_Stack_Exch04
                !endif
                !ifdef _tmp_Stack_Exch05
                    !undef _tmp_Stack_Exch05
                !endif
                !ifdef _tmp_Stack_Exch06
                    !undef _tmp_Stack_Exch06
                !endif
                !ifdef _tmp_Stack_Exch07
                    !undef _tmp_Stack_Exch07
                !endif
                !ifdef _tmp_Stack_Exch08
                    !undef _tmp_Stack_Exch08
                !endif
                !ifdef _tmp_Stack_Exch09
                    !undef _tmp_Stack_Exch09
                !endif
                !ifdef _tmp_Stack_Exch10
                    !undef _tmp_Stack_Exch10
                !endif
                !ifdef _tmp_Stack_Exch11
                    !undef _tmp_Stack_Exch11
                !endif
                !ifdef _tmp_Stack_Exch12
                    !undef _tmp_Stack_Exch12
                !endif
                !ifdef _tmp_Stack_Exch13
                    !undef _tmp_Stack_Exch13
                !endif
                !ifdef _tmp_Stack_Exch14
                    !undef _tmp_Stack_Exch14
                !endif 
 
            !verbose pop
        !macroend
 
!endif # ___!Stack_NSH___
 
!verbose pop