Hello again,
This message was sent friday or so, it took a while to get to the
mailing-list. Meanwhile, I've implemented this with some changes.
Read on.
On 2006-feb-10, at 15:48, I wrote:
Generic Functions:
(macroexpand-type-to-foreign value-form var body type)
(macroexpand-type-from-foreign value type)
(macroexpand-to-foreign value-form var body type)
(macroexpand-from-foreign value-form type)
A few questions:
- maybe expand-* instead of macroexpand-*?
I've changed 'macroexpand' to 'expand' as it was getting a bit verbose.
- *-to-foreign, as you can see is the equivalent to the previous
:to-c-dynamic translation. Would we want to provide the equivalent
of :to-c too?
Turns out that we really need to provide this, namely for the
translation we do for callbacks' return values. So the generic
functions are now:
(expand-type-to-foreign-dyn value-form var body type)
(expand-type-to-foreign value-form type)
(expand-type-from-foreign value-form type)
(expand-to-foreign-dyn value-form var body type)
(expand-to-foreign value-form type)
(expand-from-foreign value-form type)
If a to-foreign-dyn translation doesn't exist, it'll try to use to-
foreign. (but not the other way around, of course).
As I said, I'm trying to keep this simple, so the way this works
now is
that one of these translators completely hijacks the normal
translators. Namely, it wouldn't follow the typedef chain and apply
all
translators (what would it use the run-time ones? the
macroexpanion-time ones? Also this would make it a bit harder to
determine whether a given type has a translator. Right now, what I
do is
call macroexpansion-{to,from}-foreign and one of the default methods
will return 'no-expansion if no method was specialized on the type.)
Apropos of this, I had a new idea. Providing a way to bail out of the
expander similar to a compiler macro's "&whole form". The easiest way
to do this would be with an :around method for the expand-type-* GFs
binding a special variable to the usual form that calls the
translators at runtime.
So, a silly optimization for the :string type could be something like
this...
(defmethod expand-to-foreign-dyn (value var body (type (eql :string)))
(if (and (constantp value) (stringp (eval value)))
`(with-foreign-string (,var ,value)
,@body)
*runtime-translator-form*))
... while still keeping the flexibility of the runtime translators
for this type (eg. dispatching based on value).
One final question. We can guarantee that these are used in defcfun,
foreign-funcall, defcallback. However, we can't make such
guarantees for
foreign-slot-value (or mem-ref/mem-aref). Would it be a good idea
to use
these translators in the respective compiler macros? I'm inclined
to say
yes.
I'm even more inclined to say yes. :-)
--
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
Equipa Portuguesa do Translation Project
http://www.iro.umontreal.ca/translation/registry.cgi?team=pt
_______________________________________________
cffi-devel mailing list
cffi-devel@common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel