calc: Conditionals in Macros

 
 18.2.2 Conditionals in Keyboard Macros
 --------------------------------------
 
 The ‘Z [’ (‘calc-kbd-if’) and ‘Z ]’ (‘calc-kbd-end-if’) commands allow
 you to put simple tests in a keyboard macro.  When Calc sees the ‘Z [’,
 it pops an object from the stack and, if the object is a non-zero value,
 continues executing keystrokes.  But if the object is zero, or if it is
 not provably nonzero, Calc skips ahead to the matching ‘Z ]’ keystroke.
 SeeLogical Operations, for a set of commands for performing tests
 which conveniently produce 1 for true and 0 for false.
 
    For example, ‘<RET> 0 a < Z [ n Z ]’ implements an absolute-value
 function in the form of a keyboard macro.  This macro duplicates the
 number on the top of the stack, pushes zero and compares using ‘a <’
 (‘calc-less-than’), then, if the number was less than zero, executes ‘n’
 (‘calc-change-sign’).  Otherwise, the change-sign command is skipped.
 
    To program this macro, type ‘C-x (’, type the above sequence of
 keystrokes, then type ‘C-x )’.  Note that the keystrokes will be
 executed while you are making the definition as well as when you later
 re-execute the macro by typing ‘X’.  Thus you should make sure a
 suitable number is on the stack before defining the macro so that you
 don’t get a stack-underflow error during the definition process.
 
    Conditionals can be nested arbitrarily.  However, there should be
 exactly one ‘Z ]’ for each ‘Z [’ in a keyboard macro.
 
    The ‘Z :’ (‘calc-kbd-else’) command allows you to choose between two
 keystroke sequences.  The general format is ‘COND Z [ THEN-PART Z :
 ELSE-PART Z ]’.  If COND is true (i.e., if the top of stack contains a
 non-zero number after COND has been executed), the THEN-PART will be
 executed and the ELSE-PART will be skipped.  Otherwise, the THEN-PART
 will be skipped and the ELSE-PART will be executed.
 
    The ‘Z |’ (‘calc-kbd-else-if’) command allows you to choose between
 any number of alternatives.  For example, ‘COND1 Z [ PART1 Z : COND2 Z |
 PART2 Z : PART3 Z ]’ will execute PART1 if COND1 is true, otherwise it
 will execute PART2 if COND2 is true, otherwise it will execute PART3.
 
    More precisely, ‘Z [’ pops a number and conditionally skips to the
 next matching ‘Z :’ or ‘Z ]’ key.  ‘Z ]’ has no effect when actually
 executed.  ‘Z :’ skips to the next matching ‘Z ]’.  ‘Z |’ pops a number
 and conditionally skips to the next matching ‘Z :’ or ‘Z ]’; thus, ‘Z [’
 and ‘Z |’ are functionally equivalent except that ‘Z [’ participates in
 nesting but ‘Z |’ does not.
 
    Calc’s conditional and looping constructs work by scanning the
 keyboard macro for occurrences of character sequences like ‘Z:’ and
 ‘Z]’.  One side-effect of this is that if you use these constructs you
 must be careful that these character pairs do not occur by accident in
 other parts of the macros.  Since Calc rarely uses shift-‘Z’ for any
 purpose except as a prefix character, this is not likely to be a
 problem.  Another side-effect is that it will not work to define your
 own custom key bindings for these commands.  Only the standard shift-‘Z’
 bindings will work correctly.
 
    If Calc gets stuck while skipping characters during the definition of
 a macro, type ‘Z C-g’ to cancel the definition.  (Typing plain ‘C-g’
 actually adds a ‘C-g’ keystroke to the macro.)