Hacker News new | ask | show | jobs
by louai 1856 days ago
Macro expansion is done in the host environment, not the target environment. You can compile the macro definition to a function taking a form and an environment. This would be something you arrange for within your compiler.

CLTL2 specifies a function `parse-macro ` which is available in most implementations. Portably you can call it using the `trivial-cltl2` package:

https://github.com/Zulu-Inuoe/trivial-cltl2

Robert Strandh has written both papers and code for handling environments:

http://metamodular.com/SICL/environments.pdf http://metamodular.com/clostrum.pdf

1 comments

Either you are describing something that doesn’t work for cross-compilation or you are missing the point. Common Lisp is a hard language to compile because of macros. Consider the following code you might see in bootstrapping:

  (defmacro defun ...)
  (defun ...)
To macroexpand the second line you must have an environment with the defun macro definition from the previous line, which means that the code to modify the environment with that definition must have been evaluated too. This must be evaluated in the (emulated) target environment because (1) the host environment would otherwise clash with it, and (2) you need to write down the target environment as a build artefact. Evaluating these environment-modifying forms requires an interpreter you can run on the host. If you want a good programming experience for your standard library then this needs to be a reasonably capable interpreter.

But you also need an interpreter to evaluate code during macroexpansion. Three reasons:

1. You must emulate the target environment for correctness, eg JavaScript only has one type of float.

2. You cannot sufficiently interact with the host environment to use its own macroexpander (if you want to be portable). This is because compiling a macrolet requires extending the lexical environment with the macro definition so that calls (from eg the expander for setf) to macroexpand can use the definition. The only portable thing on the host that can evaluate a macrolet is the compiler/interpreter

3. You probably can’t use native types for things like symbols so the built in macro expansion is not sufficient.