Path: archiver1.google.com!news2.google.com!fu-berlin.de!newsfeed.stueberl.de!proxad.net!proxad.net!news-hub.cableinet.net!blueyonder!internal-news-hub.cableinet.net!news-binary.blueyonder.co.uk!53ab2750!not-for-mail From: David User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.6b) Gecko/20031205 Thunderbird/0.4 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.perl.misc,comp.lang.lisp,comp.lang.scheme Subject: Re: Lisp2Perl - Lisp to perl compiler References: <9s_Ob.178$ff5.141@news-binary.blueyonder.co.uk> In-Reply-To: Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Lines: 116 Message-ID: Date: Tue, 27 Jan 2004 23:39:41 +0000 NNTP-Posting-Host: 80.235.129.117 X-Complaints-To: abuse@blueyonder.co.uk X-Trace: news-binary.blueyonder.co.uk 1075246703 80.235.129.117 (Tue, 27 Jan 2004 23:38:23 GMT) NNTP-Posting-Date: Tue, 27 Jan 2004 23:38:23 GMT Organization: blueyonder (post doesn't reflect views of blueyonder) Thomas F. Burdick wrote: > David writes: > > >>Thomas F. Burdick wrote: >> >> >>>I'm sitting on it, pending my thinking about how much time/effort it >>>would take to make it useful to the general public, and if there's a >>>market for it or not. And it's a mess of unfactored hacks, because I >>>was concentrating on the systems I was supposed to be writing, not the >>>compiler itself. >> >>I know the feeling. There are lots of improvements I want to make to >>mine as well. For one thing I want to change the way the whole thing >>works as I've used a bit of a hack to get things like this to work:- >> >>(define (f x) >> ...some function of x...) >> >>(defmacro my-macro (a b) >> (list 'foo a (f b))) >> >>Basically, in order that the macro can use the function defined before >>it the function must be evaluated at compile time as well as runtime. > > > 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. > > >>I >>think the root of this problem is that I want to be able to translate >>the lisp code into a perl script which can be executed in the normal >>way. I don't want to have to read in the lisp code and translate and >>execute each form one by one. This means that the macro definitions must >>executed at compile time (obviously) hence function definitions must be >>executed at compile time. I don't think there should really be such a >>distinction between compile time and runtime. > > > 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. > > >>I have found a solution >>though, which lies in having an intermediate lisp representation which >>is just fully macro expanded lisp code which is generated as a side >>effect of 'running' a lisp file. This means that you can't just compile >>the lisp to perl as such, you have to run it, and it gets compiled >>(partially) as a side effect. Separate modules could then be linked, and >>fully translated to perl, later. Of course, running a file is not a >>problem if all it does is define things (functions and macros). >> >>Does this seem sane? > > > 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). > > Hmmm. Yes, that does seem a sensible solution. Thanks for the pointers. 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.