I have (defun compile-frame (frame-as-cons) ...) which takes a list
formatted as a property-list and returns an object of class mt-prop
(internally, it could be hash tables or other data structures).
Using (compile-frame '(part-of-speech verb form "book" tense
past)) in a program causes the list to be converted to an mt-prop at
runtime. I'd like to do this at compile-time, somewhat the way (quote
...) can give an already-prepared list.
So (quote-frame '(part-of-speech verb form "book" tense past))
should return an object of type mt-prop.
The only way I can think of doing this is with
(defmacro quote-frame (frame-as-cons)
(let (a (gensym))
(setf (symbol-value a) (compile-frame frame-as-cons))
(symbol-name a)))
i.e. create a new symbol, compile the value and assign it to the symbol,
then return the symbol's name from the macro.
(a bad side effect of this is while in a lisp session, if I re-evaluate
a function several times, new symbols are created for it, and the old
ones just accumulate).
1. Are there other flaws in this method?
2. Will this method work even if I compile my main programs?
3. Does anyone have other methods of doing this?
Masoud Pirnazar <··········@poboxes.com> writes:
> I have (defun compile-frame (frame-as-cons) ...) which takes a list
> formatted as a property-list and returns an object of class mt-prop
> (internally, it could be hash tables or other data structures).
>
> Using (compile-frame '(part-of-speech verb form "book" tense
> past)) in a program causes the list to be converted to an mt-prop at
> runtime. I'd like to do this at compile-time, somewhat the way (quote
> ...) can give an already-prepared list.
>
> So (quote-frame '(part-of-speech verb form "book" tense past))
> should return an object of type mt-prop.
>
> The only way I can think of doing this is with
> (defmacro quote-frame (frame-as-cons)
> (let (a (gensym))
> (setf (symbol-value a) (compile-frame frame-as-cons))
> (symbol-name a)))
> i.e. create a new symbol, compile the value and assign it to the symbol,
> then return the symbol's name from the macro.
>
> (a bad side effect of this is while in a lisp session, if I re-evaluate
> a function several times, new symbols are created for it, and the old
> ones just accumulate).
> 1. Are there other flaws in this method?
It won't work if you `dump' the compiled file. QUOTE-FRAME, being a
macro, should return a lisp form. In your example, it does, it
returns a literal string (the symbol name of a gensym). If you were
to dump this out to a file, the literal string would be saved, but you
wouldn't get your compiled frame dumped.
> 2. Will this method work even if I compile my main programs?
See above.
> 3. Does anyone have other methods of doing this?
There are a couple of ways I can think of doing this. You could
output a call to the constructor for MT-PROP objects:
(defmacro quote-frame (frame-as-cons)
(let ((compiled (compile-frame frame-as-cons)))
`(MAKE-INSTANCE 'MT-CLASS :slot-a ,(mt-class-slot-a compiled)
:slot-b ,(mt-class-slot-b compiled))))
If MT-PROP has a CREATE-LOAD-FORM method, then you should be able to
dump it directly:
(defmacro quote-frame (frame-as-cons)
(let ((compiled (compile-frame frame-as-cons)))
`(QUOTE ,compiled)))
Masoud Pirnazar <··········@poboxes.com> wrote:
>
> I have (defun compile-frame (frame-as-cons) ...) which takes a list
> formatted as a property-list and returns an object of class mt-prop
> (internally, it could be hash tables or other data structures).
>
> Using (compile-frame '(part-of-speech verb form "book" tense past))
> in a program causes the list to be converted to an mt-prop at
> runtime. I'd like to do this at compile-time, somewhat the way
> (quote ...) can give an already-prepared list.
>
> [snipped...]
Look at DEFINE-COMPILER-MACRO, MAKE-LOAD-FORM, and LOAD-TIME-VALUE.
Are the compiled frames stored in such a way that they can be looked
up using a unique ID? If so, then the following idea may work.
First, define a compiler macro that performs the frame compilation at
compile-time when the argument is a constant. Don't forget that the
file compiler will call MAKE-LOAD-FORM to determine how to write the
resulting MT-PROP object to a file, so you must also define a method
for MAKE-LOAD-FORM specialized on MT-PROP.
(define-compiler-macro compile-frame (&whole form frame-as-cons)
"Compiles a constant frame at run-time."
(if (constantp frame-as-cons)
(compile-frame (eval frame-as-cons))
form))
(defmethod make-load-form ((mt-prop mt-prop) &optional environment)
"Returns a form that performs the lookup at load-time."
(declare (ignore environment))
`(find-mt-prop ,(unique-id mt-prop)))
OTOH, you may want a compiler macro that just wraps LOAD-TIME-VALUE
around the whole form when the argument is a constant:
(define-compiler-macro compile-frame (&whole form frame-as-cons)
"Arranges for load-time evaluate if the frame is constant."
(if (constantp frame-as-cons)
;; You can add T as a second argument here (READ-ONLY-P) if the
;; resulting object will never be modified.
`(load-time-value ,form)
form))
Any comments from the wizards on the relative merits and drawbacks of
these two approaches?
Phil Stubblefield
Rockwell Palo Alto Laboratory 206/655-3204
http://www.rpal.rockwell.com/~phil ····@rpal.rockwell.com