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)
or.
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.
or allows a minimum of zero arguments.
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.
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. If the value
begins with a ‘(’, the string is evaluated as a Lisp form.
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 (see Documentation Tips) 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)1. 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. See 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 (⁖,
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.
[1] Formerly, strings were a special
exception; in older Emacs versions, every local variable that might
point to a string needed a GCPRO.