Macros

If you are repeating a section of code multiple times in a program, you might want to create a macro to simplify program creation and maintenance. Simple text replacement is better accomplished using constants.

Essentially, a macro is just a method for creating a shorthand reference that will later be replaced by a larger piece of code as specified in the macro definition. For example, if you want to include a piece of debugging code, you could create a macro that contains that code, and instead of typing the full code every time you need it, you could simply use the shorthand version that you have defined in the macro. Not only does this reduce the time required to create a program (by cutting down on typing), it also reduces the number of potential typos. Additionally, if the code should change, rather than searching through an entire program to replace each occurrence, you need only change the text contained in the macro, and it will automatically be changed in the rest of the program.

A macro is created using the macro and macro-end keywords. The macro-end keyword is required because a macro can contain any text or code, so there is no other way for the program to know where the macro definition ends and the rest of the program begins. A particularly useful example of how a macro might be used is to create a character class:

   macro hexadecimal-digits is
       [digit | "ABCDEF"]
   macro-end

Although the following macro definition looks significantly more complex, the basic principles are the same:

  ; Macro to dump a switch shelf (for debugging purposes)
  ;
  macro Dump Switch token s is
     do
        output "Switch %@(s) has " || "d" % number of s || " items%n"
        repeat over s
           output "  %@(s) item %d(#item)"
           output " key " || key of s when s is keyed
           output " = "
           do when s
              output "true"
           else
              output "false"
           done
           output "%n"
        again
     done
  macro-end
  global switch input-jacks size 3
  global switch output-jacks size 3
  
  process
     set input-jacks[2] to true
     set key of input-jacks[1] to "green"
     set key of input-jacks[2] to "red"
     set key of input-jacks[3] to "yellow"
     set output-jacks[1] to true
     set key of output-jacks[1] to "left-amp"
     set key of output-jacks[2] to "right-amp"
     set key of output-jacks[3] to "monitor"
     Dump Switch input-jacks
     Dump Switch output-jacks

This macro will replace each occurrence of the macro name "Dump Switch" with the code that appears between the keywords "is" and "macro-end" in the macro definition. The example shows two shelves of switches, input-jacks and output-jacks, whose contents are output by the program.

Once defined, macros are very simple to use.

   macro hexadecimal-digits is
       [digit | "ABCDEF"]
   macro-end
  
  find "#" hexadecimal-digits {6} 

Macros don't have to be exact repetitions of a chunk of text. Macros can take "arguments", which are simply values given to the macro and used to change slightly the text that replaces the shorthand reference. The macro "Switch Dump", shown above, takes one token argument ("s").