Fri May 23 09:36:28 CEST 2008

The use of macros in Scheme

In this message Matthias Felleisen talks about 3 cases of Scheme macro
use.  I'll give some examples of these below.



The use of macros as a _data sublanguage_ is visible in the assembler
generator.  It will create a representation (as functions) of a
machine code specification typically found in a microcontroller data
sheet.  Here is an excerpt from the PIC18F assembler:

 (addwf   (f d a) "0010 01da ffff ffff")
 (addwfc  (f d a) "0010 00da ffff ffff")
 (andwf   (f d a) "0001 01da ffff ffff")
 (clrf    (f a)   "0110 101a ffff ffff"))

If you can stylize data entry macros such that what you are actually
typing in the end can't be concentrated any further, then you basicly
have a configuration file encoding your domain knowledge in a natural


In the PIC18 compiler, a nice example of introduction of new _binding
constructs_ is the 'patterns macro, which provides an RPN pattern
matching syntax to specify machine code transformation.  It destructs
machine instructions and makes their operands available as lexical
Scheme names.

(patterns (macro)
   ;; Define '-' to subtract two numbers
   (([qw a] [qw b] -)              ([qw (target: a b -)]))
   (([addlw a] [qw b] -)           ([addlw (target: a b -)]))
   (([qw a] -)                     ([addlw (target: a -1 *)]))
   (([save] [movf a 0 0] -)        ([bpf 0 STATUS 0 0] [subfwb a 0 0]))
   ((-)                            ([subwf POSTDEC0 0 0]))

The input patterns on the left are assembly code sequences, and the
output is again an assembly code sequence.  The 'qw' pseudo operation
Quotes a data Word: it pushes a number to the data stack.  Here the
'-' subtraction operation is either is optimized away, which means the
computation performed at compile time either fully or partially, or
compiled as a PIC18 [subwf] instruction.


Change of evaluation order is present in the 'target: macro above,
which constructs assembly time expressions.  During compilation, code
and data addresses are not assigned yet, meaning that computations
depending on them need to be delayed until all the data is available
at assembly time.  Note that due to multipass relaxation in the
assembler, these expressions will end up being evaluated multiple time
with possibly different input addresses.