| [ < ] | [ > ] | [ << ] | [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.