3 ms·
You do not need an interpreter to evaluate macros. You can compile the code of the macro, same as you would any regular function, and call into it that way.
by moonchild 5y ago
You do not need an interpreter to evaluate macros. You can compile the code of the macro, same as you would any regular function, and call into it that way.
- dan-robertson 5y agoI think you’re missing something: if I compile the macro to JavaScript, I don’t have a way to run it because I am cross compiling. I can’t simply use the host lisps compiler because of reasons mentioned above.
- louai 5y agoMacro 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 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/SICL/environments.pdf http://metamodular.com/clostrum.pdf http://metamodular.com/clostrum.pdf
- dan-robertson 5y agoEither 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.
- moonchild 5y agoThat the runtime environment and the compilation environment, insofar as they are distinct, are not able to communicate seems like a deficiency in the implementation. Lisp is meant to be interactive. Do you not expect to be able to implement 'eval'?
- dan-robertson 5y agoTo a large extent, they can communicate: the compile time environment when compiling one form depends on the runtime environment modifications made by evaluating the previous form. This is what makes cross compiling lisp hard.