D
David
Hmmm. Yes, that does seem a sensible solution. Thanks for the pointers.Thomas said:Since your system is self-hosting, that shouldn't be a problem. Do
you have something like Common Lisp's eval-when? If not, you should
read the page in the spec
http://www.lispworks.com/reference/HyperSpec/Body/s_eval_w.htm#eval-when
especially the Notes section at the bottom. In CL, forms like defun
and defmacro (when they're toplevel) cause the function to be known at
compile time by using eval-when. It also lets you write your own
forms of this type.
Actually, I think the answer is probably having a clearer concept of
time(s) in your Lisp dialect. When the compiler sees a toplevel form
that macroexpands into (eval-when (compile) ...), it should
recursively invoke itself, to deal with the eval-when, evaluate that
in the Perl interpreter, then get back to the job at hand.
It seems messy. You should be able to start Perl, load all the
functions that your macros use, compile the files defining and using
them, then quit Perl and load the resulting .pl files. Using a
CL-like concept of times (compile/macroexpand, load, and eval) would
help keep things cleaner.
(In my system, the macros are run in the hosting Common Lisp, so my
issues were different. You define Perl functions with perlisp:defun,
but they're not available at compile-time. Macros can use functions
defined with common-lisp:defun).
I think I get the general idea of (eval-when). Its _sort of_ how I've
implemented function definitions at the moment - some things macro
expand to a special form which is evaluated at compile time as well as
runtime. I might just implement something closer to the common lisp
eval-when approach (seems a bit cleaner than what I did).
My main concern with all this was how to ensure that I can handle
dependencies between lisp files. If a file of lisp code uses macros
defined in another file then clearly the macro file must be loaded into
the compiler before the first one can be compiled. I wanted to try and
make sure that the required files would be recompiled as necessary (if
they had changed) and then loaded.
Perhaps, though, the thing to do is, as you say, just to load the
required files into the running lisp/perl interpreter by hand before
attempting to compile something which uses them. I wondered how common
lisp handles these sort of things (essentially: building of projects)
and it seems that it doesn't natively. I noticed that there are lisp
libraries for handling this sort of problem, which make it possible to
write build scripts (sort of like make files I guess).
I suppose, then, that the thing to do for a complex, multi file project
is to have a lisp program whose job it is to build the thing, which it
would do by compiling (if required) and loading the lisp source code in
the required order so that macros are defined before they are used.
Then, in my case, the ultimate product of the compilation (a perl
script) would be generated by running that compilation program (with a
repl, say).
Would that be a sensible approach, or am I missing something obvious?
I can see the point of 2 namespaces by the way (particularly when it
comes to macros). I may change to that, or do something like check the
lexical scope to implement some kind of hybrid approach. I thought there
must be a reason for it.