

MACRO                          05/20/78                          MACRO


NAME
       macro - process macro definitions

SYNOPSIS
       macro [file] ...

DESCRIPTION
       Macro  reads  the  source  file(s) and writes onto the standard
       output a new file with the macro definitions  deleted  and  the
       macro references expanded.  If no file names are specified, the
       standard input is read.
       
       Macros are generally used to extend some underlying language to
       perform  a translation from one language to another; that is, a
       macro processor allows one to define symbolic constants so that
       subsequent occurrences of the  constant  are  replaced  by  the
       defining string of characters. The general format is:
       
                       define(name,replacement text) 
       
       All  subsequent  occurrences  of  "name"  in  the  file will be
       replaced by "replacement text".  Blanks are significant and may
       occur only inside the replacement text. Upper  and  lower  case
       letters   are  also  significant.  Nesting  of  definitions  is
       allowed, as is recursion. The definition may be more  than  one
       line long.
       
       An elementary example of a macro is:
       
                               define(EOF,-1) 
       
       Thereafter,  all  occurrences  of  "EOF"  in  the file would be
       replaced by "-1".
       
       Macros with arguments may also be specified.  Any occurrence in
       the replacement text of "$n", where n is between 1 and 9,  will
       be  replaced  by  the  nth  argument when the macro is actually
       called.  For example,
       
                define(copen,$3 = open($1,$2)
                             if ($3 == ERR)
                                  call cant($1))
       
       would define a macro which, when called by  "copen(name,  READ,
       fd)" would expand into:
       
                fd = open(name,READ)
                if (fd == ERR)
                     call cant(name)
       
       If  a  macro  definition  asks  for  an  argument  that  wasn't


                                 -1-                                  


MACRO                          05/20/78                          MACRO


       supplied, the "$n" will be ignored.
       
       Macros  can  be  nested,  and  any  macros  encountered  during
       argument  collection  are expanded immediately--unless they are
       surrounded by brackets "[]".  That is, any input surrounded  by
       [ and  ]  is  left absolutely alone, except that one level of [
       and ] is stripped off. Thus it is possible to write  the  macro
       "d" as
       
                         define(d,[define($1,$2)]) 
       
       The  replacement  text  for  "d",  protected by the brackets is
       literally "define($1,$2)" so one could say
       
                                  d(a,bc) 
       
       and be assured that "a" would be defined to be  "bc".  Brackets
       must also be used when it is desired to redefine an identifier:
       
                                define(x,y) 
                                define(x,z) 
       
       would define "y" in the second line, instead of redefining "x".
       To avoid redefining "y", the operation must be expressed as
       
                                 define(x,y)
                                 define([x],z)
       
       The  macro processor also includes a conditional test, with the
       built-in function "ifelse".  The input
       
                              ifelse(a,b,c,d) 
       
       compares "a" and "b" as character strings.   If  they  are  the
       same, "c" is pushed back onto the input; if they differ, "d" is
       pushed back.  As a simple example,
       
                   define(compare,[ifelse($1,$2,yes,no)]) 
       
       defines  "compare"  as  a two-argument macro returning "yes" if
       its arguments are the same, and  "no"  if  they  are  not.  The
       brackets prevent the "ifelse" from being evaluated too soon.
       
       Another  built-in  function  available  is  "incr".   "incr(x)"
       converts the string "x" to  a  number,  adds  one  to  it,  and
       returns  that  as its replacement text (as a character string).
       "x" had better be numeric, or the results may be  undesireable.
       "incr" can be used for tasks like
       
                   define(MAXCARD,80)
                   define(MAXLINE,[incr(MAXCARD)])


                                 -2-                                  


MACRO                          05/20/78                          MACRO


       
       which makes two parameters with values 80 and 81.
       
       The third built-in function available in the macro processor is
       a function to take substrings of strings.
       
                              substr(s, m, n) 
       
       produces  the  substring  of  "s"  which starts at position "m"
       (with origin one), of length "n".  If "n"  is  omitted  or  too
       big,  the  rest  of  the string is used, while if "m" is out of
       range the result is a null string. For example,
       
                             substr(abc, 2, 1) 
       
       results in "b",
       
                               substr(abc, 2) 
       
       results in "bc", and
       
                               substr(abc,4) 
       
       is empty.
       
       
       The last built-in function available in the macro processor  is
       one to perform simple arithmetic functions:
       
                         arith(operand1,op,operand2)
       
       where  the  operation  specified  by  'op'  may  be  + (add), -
       (subtract), * (multiply), or / (divide). Negative  numbers  are
       not handled yet. Thus,
       
                           define(add,[arith($1,+,$2)])
                           add(5,3)
       
       would produce the result '8'.
       
       As  a  final example, here is a macro which computes the length
       of a character string:
       
           define(len,[ifelse($1,,0,[incr(len(substr($1,2)))])]) 
       
       Note the recursion, which is perfectly permissible.  The  outer
       layer  of brackets prevents all evaluation as the definition is
       being copied into an internal table.  The inner layer  prevents
       the "incr" construction from being done as the arguments of the
       "ifelse"  are  collected.  The value of a macro call "len(abc)"
       would be 3.


                                 -3-                                  


MACRO                          05/20/78                          MACRO


FILES
       None

SEE ALSO
       Kernighan and Plauger's "Software Tools", pages 251-283 

DIAGNOSTICS
       arg stack overflow
           The maximum number of total arguments  has  been  exceeded.
           Currently this is 100.
           
       call stack overflow
           The  maximum  level  of  nesting  of  definitions  has been
           exceeded. Currently this is 130.
           
       EOF in string
           An end-of-file has  been  encountered  before  a  bracketed
           string has been terminated.
           
       evaluation stack overflow
           The  total  number  of characters for name, definition, and
           arguments has been exceeded.  Currently this is 500.
           
       unexpected EOF
           An end-of-file was reached before the macro definition  was
           terminated.
           
       filename: cant open
           For  some  reason,  the file specified could not be opened.
           This is an unlikely error to occur; if it does show  up  it
           probably  indicates a problem with the low-level primitives
           being used by the system.

AUTHORS
       From "Software Tools" by  Kernighan  and  Plauger,  with  minor
       modifications by Debbie Scherrer.

BUGS/DEFICIENCIES
       There   can   be   no   space  between  the  "define"  and  the
       left-parenthesis following it.
       
       Keywords (e.g. define, ifelse, etc.) in the input file must  be
       surrounded   by   brackets   if   they   are   not  part  of  a
       macro--otherwise they will be stripped out  by  the  processor.
       Likewise,  if  brackets  are desired anywhere in the input file
       other than in a macro, they  must  be  surrounded  by  brackets
       themselves.
       
       The  error  messages  generated  by  the  ratfor  compiler when
       processing macros do not seem to show  up  in  this  processor.
       Examples  are "definition too long", "missing comma in define",


                                 -4-                                  


MACRO                          05/20/78                          MACRO


       and "non-alphanumeric name".




















































                                 -5-                                  

