macro.lsp

Module index

source download

Module: macro.lsp

Rewrite macros for newLISP

Version: 1.03
Version: 1.04 typo in documentation
Version: 1.1 make it work with default functors
Author: Lutz Mueller 2010

Introduction

This module implements rewrite macros. Rewrite macros take an expression and rewrite it to a different expression:
 (macro (double A) (mul 2 A) ) ; doubles any number in A
 (macro (queue A L) (pop (push A L -1)) ) ; models a queue
(set 'x 3) (double x) => 6 (double (add x 2)) => 10
(set 'lst '(1 2 3)) (queue 'x lst) => 1 lst => (2 3 x)
Whenever newLISP reads a (double A) expression it will translate it to (mul 2 A), expanding A to its content. When specifying macros using the macro function, variable names must start with uppercase. Variables are optional. The rewrite can be a complex, nested functional expression like shown in the queue rewrite.

The module should be loaded using either:
 (module "macro.lsp")
which loads from the NEWLISPDIR/modules standard path, or using:
 (load "/mypath/macro.lsp")
Macro translation will occur whenever newLISP parses source, either caused by a load statement or when using eval-string.

Macros can be used accross contexts as expected. The following will work:
 (module "macro.lsp")
(context 'FOO) (macro (sumsq X Y) (add (pow X 2) (pow Y 2)) ) (context MAIN)
(FOO:sumsq 3 4) => 25
Rewrite macros are faster than fexpr's written with define-macro, because they lack the function call overhead. They also improve readability, making source code appear shorter. Many functions too small to waste lambda function call overhead can be written as efficiently executing macros.

Rewrite macros are cannot be used with map or apply, they are not functions.

Internals

This module uses the reader-event function to intercept newLISP's expression reading and translating process and pre-translates expressions before returning them to newLISP's evaluation routines.

The function macro creates a lambda-macro function, which is used to to create the expansion of the original call pattern. During the rewrite process this expansion function is used to gerenerate a replacemt for the original call pattern.

This version of macro.lsp does not allow rewrite of atomic expressions or rewriting to atomic expressions. Both parts, the original and the rewrite must be functional list expressions. This version allows the usage of macros calls inside macros as long as the macros used have been registered previously.

Macro translation increases the load-time of a program or script.

§

macro

syntax: (macro list-expr list-rewrite)
parameter: list-expr - The list expression od the call pattern.
parameter: list-rewrite - The rewritten call pattern.

return: A function used by the modules rewrite routine.

The function registers a macro. During source translation the call pattern in list-expr is re-written to the expansion in list-rewrite. Local variables in list-expr and list-rewrite must be in uppercase:

Example:
 (module "macro.lsp")

 (macro (square A) (mul A A) ) ; squares any number in A
 (macro (queue A L) (pop (push A L -1)) ) ; models a queue


§

macro:delete

syntax: (macro:delete sym-macro)
parameter: sym-macro - The unquoted symbol of the macro to delete.

Before a macro can be redefined, it must be deleted. Trying do redefine a macro before deleting it will throw an error.

Example:
 (macro:delete cube)


§

macro:resume

syntax: (macro:resume)

Resumes the working of all registered macros.

§

macro:suspend

syntax: (macro:suspend)

Disables all registered macros. To reenable macros use (macro:resume).

- ∂ -

generated with newLISP  and newLISPdoc