[ < ] | [ > ] | [ << ] | [Plus haut] | [ >> ] | [Top] | [Table des matières] | [Index] | [ ? ] |
Lisp primitives are Lisp functions implemented in C. The details of interfacing the C function so that Lisp can call it are handled by a few C macros. The only way to really understand how to write new C code is to read the source, but we can explain some things here.
An example of a special form is the definition of or
, from
‘eval.c’. (An ordinary function would have the same general
appearance.)
DEFUN ("or", For, Sor, 0, UNEVALLED, 0, doc: /* Eval args until one of them yields non-nil, then return that value. The remaining args are not evalled at all. If all args return nil, return nil. usage: (or CONDITIONS ...) */) (args) Lisp_Object args; { register Lisp_Object val = Qnil; struct gcpro gcpro1; GCPRO1 (args); while (CONSP (args)) { val = Feval (XCAR (args)); if (!NILP (val)) break; args = XCDR (args); } UNGCPRO; return val; } |
Let's start with a precise explanation of the arguments to the DEFUN
macro. Here is a template for them:
DEFUN (lname, fname, sname, min, max, interactive, doc) |
This is the name of the Lisp symbol to define as the function name; in the
example above, it is or
.
This is the C function name for this function. This is the name that is
used in C code for calling the function. The name is, by convention,
‘F’ prepended to the Lisp name, with all dashes (‘-’) in the Lisp
name changed to underscores. Thus, to call this function from C code, call
For
. Remember that the arguments must be of type Lisp_Object
;
various macros and functions for creating values of type Lisp_Object
are declared in the file ‘lisp.h’.
This is a C variable name to use for a structure that holds the data for the subr object that represents the function in Lisp. This structure conveys the Lisp symbol name to the initialization routine that will create the symbol and store the subr object as its definition. By convention, this name is always fname with ‘F’ replaced with ‘S’.
This is the minimum number of arguments that the function requires. The
function or
allows a minimum of zero arguments.
This is the maximum number of arguments that the function accepts, if there
is a fixed maximum. Alternatively, it can be UNEVALLED
, indicating a
special form that receives unevaluated arguments, or MANY
, indicating
an unlimited number of evaluated arguments (the equivalent of
&rest
). Both UNEVALLED
and MANY
are macros. If
max is a number, it may not be less than min and it may not be
greater than eight.
This is an interactive specification, a string such as might be used as the
argument of interactive
in a Lisp function. In the case of
or
, it is 0 (a null pointer), indicating that or
cannot be
called interactively. A value of ""
indicates a function that should
receive no arguments when called interactively.
This is the documentation string. It uses C comment syntax rather than C string syntax because comment syntax requires nothing special to include multiple lines. The ‘doc:’ identifies the comment that follows as the documentation string. The ‘/*’ and ‘*/’ delimiters that begin and end the comment are not part of the documentation string.
If the last line of the documentation string begins with the keyword ‘usage:’, the rest of the line is treated as the argument list for documentation purposes. This way, you can use different argument names in the documentation string from the ones used in the C code. ‘usage:’ is required if the function has an unlimited number of arguments.
All the usual rules for documentation strings in Lisp code (voir la section Tips for Documentation Strings) apply to C code documentation strings too.
After the call to the DEFUN
macro, you must write the argument name
list that every C function must have, followed by ordinary C declarations
for the arguments. For a function with a fixed maximum number of arguments,
declare a C argument for each Lisp argument, and give them all type
Lisp_Object
. When a Lisp function has no upper limit on the number
of arguments, its implementation in C actually receives exactly two
arguments: the first is the number of Lisp arguments, and the second is the
address of a block containing their values. They have types int
and
Lisp_Object *
.
Within the function For
itself, note the use of the macros
GCPRO1
and UNGCPRO
. GCPRO1
is used to “protect” a
variable from garbage collection—to inform the garbage collector that it
must look in that variable and regard its contents as an accessible object.
GC protection is necessary whenever you call Feval
or anything that
can directly or indirectly call Feval
. At such a time, any Lisp
object that this function may refer to again must be protected somehow.
It suffices to ensure that at least one pointer to each object is
GC-protected; that way, the object cannot be recycled, so all pointers to it
remain valid. Thus, a particular local variable can do without protection
if it is certain that the object it points to will be preserved by some
other pointer (such as another local variable which has a
GCPRO
)(12). Otherwise, the local variable needs a GCPRO
.
The macro GCPRO1
protects just one local variable. If you want to
protect two variables, use GCPRO2
instead; repeating GCPRO1
will not work. Macros GCPRO3
, GCPRO4
, GCPRO5
, and
GCPRO6
also exist. All these macros implicitly use local variables
such as gcpro1
; you must declare these explicitly, with type
struct gcpro
. Thus, if you use GCPRO2
, you must declare
gcpro1
and gcpro2
. Alas, we can't explain all the tricky
details here.
UNGCPRO
cancels the protection of the variables that are protected in
the current function. It is necessary to do this explicitly.
Built-in functions that take a variable number of arguments actually accept
two arguments at the C level: the number of Lisp arguments, and a
Lisp_Object *
pointer to a C vector containing those Lisp arguments.
This C vector may be part of a Lisp vector, but it need not be. The
responsibility for using GCPRO
to protect the Lisp arguments from GC
if necessary rests with the caller in this case, since the caller allocated
or found the storage for them.
You must not use C initializers for static or global variables unless the variables are never written once Emacs is dumped. These variables with initializers are allocated in an area of memory that becomes read-only (on certain operating systems) as a result of dumping Emacs. Voir la section Pure Storage.
Do not use static variables within functions—place all static variables at
top level in the file. This is necessary because Emacs on some operating
systems defines the keyword static
as a null macro. (This definition
is used because those systems put all variables declared static in a place
that becomes read-only after dumping, whether they have initializers or
not.)
Defining the C function is not enough to make a Lisp primitive available; you must also create the Lisp symbol for the primitive and store a suitable subr object in its function cell. The code looks like this:
defsubr (&subr-structure-name); |
Here subr-structure-name is the name you used as the third argument to
DEFUN
.
If you add a new primitive to a file that already has Lisp primitives
defined in it, find the function (near the end of the file) named
syms_of_something
, and add the call to defsubr
there.
If the file doesn't have this function, or if you create a new file, add to
it a syms_of_filename
(e.g., syms_of_myfile
). Then find
the spot in ‘emacs.c’ where all of these functions are called, and add
a call to syms_of_filename
there.
The function syms_of_filename
is also the place to define any C
variables that are to be visible as Lisp variables. DEFVAR_LISP
makes a C variable of type Lisp_Object
visible in Lisp.
DEFVAR_INT
makes a C variable of type int
visible in Lisp with
a value that is always an integer. DEFVAR_BOOL
makes a C variable of
type int
visible in Lisp with a value that is either t
or
nil
. Note that variables defined with DEFVAR_BOOL
are
automatically added to the list byte-boolean-vars
used by the byte
compiler.
If you define a file-scope C variable of type Lisp_Object
, you must
protect it from garbage-collection by calling staticpro
in
syms_of_filename
, like this:
staticpro (&variable); |
Here is another example function, with more complicated arguments. This comes from the code in ‘window.c’, and it demonstrates the use of macros and functions to manipulate Lisp objects.
DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, Scoordinates_in_window_p, 2, 2, "xSpecify coordinate pair: \nXExpression which evals to window: ", "Return non-nil if COORDINATES is in WINDOW.\n\ COORDINATES is a cons of the form (X . Y), X and Y being distances\n\ ... If they are on the border between WINDOW and its right sibling,\n\ `vertical-line' is returned.") (coordinates, window) register Lisp_Object coordinates, window; { int x, y; CHECK_LIVE_WINDOW (window, 0); CHECK_CONS (coordinates, 1); x = XINT (Fcar (coordinates)); y = XINT (Fcdr (coordinates)); switch (coordinates_in_window (XWINDOW (window), &x, &y)) { case 0: /* NOT in window at all. */ return Qnil; case 1: /* In text part of window. */ return Fcons (make_number (x), make_number (y)); case 2: /* In mode line of window. */ return Qmode_line; case 3: /* On right border of window. */ return Qvertical_line; default: abort (); } } |
Note that C code cannot call functions by name unless they are defined in
C. The way to call a function written in Lisp is to use Ffuncall
,
which embodies the Lisp function funcall
. Since the Lisp function
funcall
accepts an unlimited number of arguments, in C it takes two:
the number of Lisp-level arguments, and a one-dimensional array containing
their values. The first Lisp-level argument is the Lisp function to call,
and the rest are the arguments to pass to it. Since Ffuncall
can
call the evaluator, you must protect pointers from garbage collection around
the call to Ffuncall
.
The C functions call0
, call1
, call2
, and so on, provide
handy ways to call a Lisp function conveniently with a fixed number of
arguments. They work by calling Ffuncall
.
‘eval.c’ is a very good file to look through for examples; ‘lisp.h’ contains the definitions for some important macros and functions.
If you define a function which is side-effect free, update the code in
‘byte-opt.el’ which binds side-effect-free-fns
and
side-effect-and-error-free-fns
so that the compiler optimizer knows
about it.
[ < ] | [ > ] | [ << ] | [Plus haut] | [ >> ] | [Top] | [Table des matières] | [Index] | [ ? ] |
Ce document a été généré par Eric Reinbold le 13 Octobre 2007 en utilisant texi2html 1.78.