# ifstack.icn: Object to manage conditional expansion for template.icn #-- $ifndef __IFSTACK_ICN__ $define __IFSTACK_ICN__ $define IF_STACK_REVISION "$Revision: 1.3 $" $define IF_STACK_DATE "$Date: 1995/11/16 18:52:45 $" #================================================================ # Class IfStack: Represents the state of all currently open # conditional expansion tokens in a template, that is, all # "%ifnext;" and similar conditionals for which we have not yet # seen the matching "%endif;". #---------------------------------------------------------------- # ifStack := If_Stack_New ( ) # [ returns an empty ifStack object ] #-- # If_Stack_Start ( ifStack, cond ) # [ pushes `cond' onto the ifStack ] #-- # cond := If_Stack_End ( ifStack ) # [ if the ifStack is empty -> fail # | else -> # ifStack := ifStack minus its top condition # returns the (former) top condition # ] #-- # If_Stack_Else ( ifStack ) # [ if the ifStack is empty -> fail # | else -> # ifStack := ifStack with its top condition's .skipping # switch inverted # return ifStack with its top condition's .skipping switch inverted # ] #-- # If_Stack_Is_Skipping ( ifStack ) # [ if the stack of conditions in ifStack implies that we are currently # skipping tokens -> # return &null # | else -> fail # ] #---------------------------------------------------------------- record ifStackTag ( L ) # Pushdown stack of condition objects #================================================================ # INVARIANT: # .L is a list of zero or more `condition' objects #---------------------------------------------------------------- # - - - I f _ S t a c k _ N e w - - - procedure If_Stack_New ( ) local ifStack ifStack := ifStackTag ( ); ifStack.L := []; return ifStack; end # --- If_Stack_New --- # - - - I f _ S t a c k _ S t a r t - - - procedure If_Stack_Start ( ifStack, condition ) push ( ifStack.L, condition ); end # - - - I f _ S t a c k _ E n d - - - procedure If_Stack_End ( ifStack ) if ( * ifStack.L ) = 0 then fail; return pop ( ifStack.L ); end # - - - I f _ S t a c k _ E l s e - - - procedure If_Stack_Else ( ifStack ) local top if ( * ifStack.L ) = 0 then fail; top := ifStack.L[1]; Condition_Else ( top ); return ifStack; end # - - - I f _ S t a c k _ I s _ S k i p p i n g - - - procedure If_Stack_Is_Skipping ( ifStack ) local cond if ( * ifStack.L ) = 0 then fail; # No conditionals in effect -> hence, not skipping every cond := ! ifStack.L do { #-- Check all active conditions if Condition_Is_Skipping ( cond ) then return &null; # At least one conditional is skipping } #-- Check all active conditions fail; # None of the conditionals are skipping end $endif