[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: load-foreign

Todd.Kaufmann@NL.CS.CMU.EDU writes:
> I just ported some C & foreign call out to C (from Lucid/Allegro defintions)
> to CMU CL, and I found it a little confusing and inconsistent.

Only a little confusing and inconsistent?  Whenever I've tried to use
the def-c-stuff, etc, I've found it very confusing and very
inconsistent (and I'm one of the people who is supposed to be
maintaining it).  In our ``Grand Plans'' we have a re-write of the
alien/c-call stuff, but we've been working on more important stuff up
to now.  I have some fairly complete ideas about what I want the C
interface stuff to look like, and Rob has some ideas about what the
alien interface should evolve into, but nothing has been finalized to
the point where someone could start writing code.

Actually, now might be a good time to solicit input.  To start things
off, I'll append my current notes about the c-call rewrite (which can be
found in .../clisp/new-compiler/wlott/work/c-call-notes.txt) to this


Most of my thoughts have been centered on redesigning (completely
rewriting?) the c-call stuff.  I could implement all my ideas on top of the
current alien stuff, but if I'm going to stick my hands it that stuff, I
might as well clean everything up.

Anyway, my ideas about the c-call stuff a driven primarily by two goals:
make it more similar to real C code, and to make easier to use.

First of all, I want to get rid of all the different type defining macros,
def-c-type, def-c-pointer, def-c-butt-plug, etc, and replace them with a
general recursive list structure similar to how types are defined in C:

    struct foo { int x, y; }; <=> (struct foo (int x) (int y))
    int *foo[20]; <=> (array (* int) 20)

Def-c-type will be a macro that parses a type (noting any structs or
unions) and optional associates it with a name.

I haven't decided if I want to access fields in structs and unions
defstruct like (a new function per struct/slot combination):
	(foo-x foo)
or a single function that takes the structure and the slot:
	(slot foo 'x)
The advantage of the many functions is that it looks better, but structures
can be anonymous.  I guess we could source-transform foo-x to (slot foo 'x)
and ignore the issue.  For convenience, the structure could really be a
pointer to the structure, and the compiler would do the correct thing.

(I don't like the slot name being quoted, 'cause that implies that it is
evaluated.  I guess I could make slot a special form that did not evaluate
it's second arg.  Or let it be evaluated; if it's not constant at compile
time, you lose.)

Slots that have corresponding lisp types (e.g. ints) would return a lisp
object of that type when accessed.  Slots that contain other C types would
return whatever is necessary to allow direct use of other C ops.  For
example, if you had a C variable foo of type (struct ((struct (int i)) x))
then you could access the int in the middle with (slot (slot foo 'x) 'i).
Unlike the current noise where you have to add buttloads of alien-accesses

Pointers and arrays would be indirected using the deref function.  Deref
would take the pointer or array and a set of indicies.  Pointers could be
given either zero or one index, and arrays must be given the same number of
indices as dimensions.  Again, if the element can be represented with a
lisp object, it is (no alien-access necessary).

There would all be functions pointer-inc and pointer-diff that could be
used to add a constant to a pointer and determine the difference between
two pointers.

The function addr would mimic the C operator &.

Automatic (stack) variables can be allocated using the macro
with-c-variable that takes a name and a type and does the obvious thing.
If alien-value is still necessary, it is hidden using symbol-macros.
Globals variables can be defined using some other macro at top level that
takes an optional initial value.

If you supply a (symbol string) list instead of just a symbol for the name,
then the string is used as the C name for the variable.  The C name does
not have to already exist.  If it does not, new memory is allocated and it
is entered in the table of foreign symbols.  For locals, this corresponds
to declaring a variable ``extern''.

C routines are just C variables with a function type.  Def-c-routine just
builds whatever junk is necessary to process special arg types (e.g.
:in-out).  Invoking c functions directly might be a problem, because we
need to know the types of the arguments at compile time.