Macro language and environment¶
Definition and usage¶
A macro is defined using the define-transformer
form, specified with a name and the transformer function.
The transformer function is a Racket expression which is evaluated immediately, at compile time.
Normally, this will be a lambda
form.
Whenever the macro is used, the transformer receives the arguments specified at the usage site. Note that these are syntax objects. They can represent Propel code, Racket code, or an arbitrary other language – it is entirely up to the transformer to interpret them (though they must parse as valid S-expressions).
(define-transformer emit-palette-array (lambda (name)
(define the-palette (list 1 2 3 4))
`(def ,name (make-array-with-type int ,@the-palette))
))
(emit-palette-array my-palette)
Macro namespace¶
Macros execute in a macro namespace which is private to each Propel module. racket/base
can be assumed to be available.
Importing other modules¶
Use (for-syntax (require ...))
at the top level. Relative requires are resolved relative to the directory containing the source file.
Loading files¶
Build systems need to be aware of a source file’s transitive dependencies.
To this end, an explicit function should be provided as a substitute for open-input-file
et al.