-
Notifications
You must be signed in to change notification settings - Fork 8
6.1.1 Macro Functions
A macro is a function that is applied at compile time to replace a piece of code with another. Macro functions in LispE are based on the same principle as pattern programming as demonstrated with defpat functions.
A macro can be divided into different functions, each with its own set of parameters.
Note that the $
operator in macros are used both in the parameter list and as a macro operator in the code.
A macro is a way to replace code with a more complex definition.
; this macro computes the cube of a number:
(defmacro cube(x) (* x x x))
If we apply this macro in a piece of code:
(cube 10)
cube will be replaced with its definition:
(* 10 10 10)
The patterns that are available for defpat are also available for defmacro.
(defmacro tantque (x $ z)
(while x $ z)
)
(setq x 0)
(tantque (< x 11) (+= x 1) (println x))
The $
operator is used here twice.
- In the pattern definition, it is used to extract the final list of elements.
- In the function definition, it is used to insert the content of this final list into the code.
Let's compare with and without the $
in the macro body:
; Without the $
(defmacro tantque (x $ z)
(while x z)
)
; the extended code is now:
; (note the surrounding list around (+= x &) (println x)
(while (< x 11) ((+= x 1) (println x)))
; With the $
(defmacro tantque (x $ z)
(while x $ z)
)
; the extended code is now:
(while (< x 11) (+= x 1) (println x)
Basically, the $
extends the code with the content of the list that was extracted by the pattern.
Note that you can add elements after the $ z
:
(defmacro tantque (x $ z)
(while x $ z (println x))
)
You can also use multiple patterns to introduce some variety in your code:
; The only difference is how the range is created
; Here it is an upward range
(defmacro tang(('< x y) $ z)
(loop x (range 0 y 1) $ z)
)
; Here the range is downward
(defmacro tang(('> x y) $ z)
(loop x (range y 0 -1) $ z)
)
if we apply these macros to:
(defun tst1(x)
(tang (< x 5) (println (* 2 x)))
)
(defun tst2(x)
(tang (> x 5) (println (* 2 x)))
)
We get:
; The first function contains a "<" and matches with the first macro
(defun tst1 (x) (loop x (range 0 5 1) (println (* 2 x))))
; The second function contains a ">" and matches with the second macro
(defun tst2 (x) (loop x (range 5 0 -1) (println (* 2 x))))