diff options
Diffstat (limited to 'devdocs/elisp/writing-emacs-primitives.html')
| -rw-r--r-- | devdocs/elisp/writing-emacs-primitives.html | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/devdocs/elisp/writing-emacs-primitives.html b/devdocs/elisp/writing-emacs-primitives.html new file mode 100644 index 00000000..9fed903b --- /dev/null +++ b/devdocs/elisp/writing-emacs-primitives.html @@ -0,0 +1,124 @@ + <h3 class="section"> Writing Emacs Primitives</h3> <p>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. </p> <p>An example of a special form is the definition of <code>or</code>, from <samp>eval.c</samp>. (An ordinary function would have the same general appearance.) </p> <div class="example"> <pre class="example">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. +</pre> +<pre class="example">usage: (or CONDITIONS...) */) + (Lisp_Object args) +{ + Lisp_Object val = Qnil; +</pre> + +<pre class="example"> while (CONSP (args)) + { + val = eval_sub (XCAR (args)); + if (!NILP (val)) + break; + args = XCDR (args); + maybe_quit (); + } +</pre> + +<pre class="example"> return val; +} +</pre> +</div> <p>Let’s start with a precise explanation of the arguments to the <code>DEFUN</code> macro. Here is a template for them: </p> <div class="example"> <pre class="example">DEFUN (<var>lname</var>, <var>fname</var>, <var>sname</var>, <var>min</var>, <var>max</var>, <var>interactive</var>, <var>doc</var>) +</pre> +</div> <dl compact> <dt><var>lname</var></dt> <dd> +<p>This is the name of the Lisp symbol to define as the function name; in the example above, it is <code>or</code>. </p> </dd> <dt><var>fname</var></dt> <dd> +<p>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, ‘<samp>F</samp>’ prepended to the Lisp name, with all dashes (‘<samp>-</samp>’) in the Lisp name changed to underscores. Thus, to call this function from C code, call <code>For</code>. </p> </dd> <dt><var>sname</var></dt> <dd> +<p>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 <var>fname</var> with ‘<samp>F</samp>’ replaced with ‘<samp>S</samp>’. </p> </dd> <dt><var>min</var></dt> <dd> +<p>This is the minimum number of arguments that the function requires. The function <code>or</code> allows a minimum of zero arguments. </p> </dd> <dt><var>max</var></dt> <dd> +<p>This is the maximum number of arguments that the function accepts, if there is a fixed maximum. Alternatively, it can be <code>UNEVALLED</code>, indicating a special form that receives unevaluated arguments, or <code>MANY</code>, indicating an unlimited number of evaluated arguments (the equivalent of <code>&rest</code>). Both <code>UNEVALLED</code> and <code>MANY</code> are macros. If <var>max</var> is a number, it must be more than <var>min</var> but less than 8. </p> </dd> <dt><var>interactive</var></dt> <dd> +<p>This is an interactive specification, a string such as might be used as the argument of <code>interactive</code> in a Lisp function (see <a href="using-interactive">Using Interactive</a>). In the case of <code>or</code>, it is <code>0</code> (a null pointer), indicating that <code>or</code> cannot be called interactively. A value of <code>""</code> indicates a function that should receive no arguments when called interactively. If the value begins with a ‘<samp>"(</samp>’, the string is evaluated as a Lisp form. For example: </p> <div class="example"> <pre class="example">DEFUN ("foo", Ffoo, Sfoo, 0, 3, + "(list (read-char-by-name \"Insert character: \")\ + (prefix-numeric-value current-prefix-arg)\ + t)", + doc: /* … */) +</pre> +</div> </dd> <dt><var>doc</var></dt> <dd> +<p>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 ‘<samp>doc:</samp>’ identifies the comment that follows as the documentation string. The ‘<samp>/*</samp>’ and ‘<samp>*/</samp>’ delimiters that begin and end the comment are not part of the documentation string. </p> <p>If the last line of the documentation string begins with the keyword ‘<samp>usage:</samp>’, 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. ‘<samp>usage:</samp>’ is required if the function has an unlimited number of arguments. </p> <p>Some primitives have multiple definitions, one per platform (e.g., <code>x-create-frame</code>). In such cases, rather than writing the same documentation string in each definition, only one definition has the actual documentation. The others have placeholders beginning with ‘<samp>SKIP</samp>’, which are ignored by the function that parses the <samp>DOC</samp> file. </p> <p>All the usual rules for documentation strings in Lisp code (see <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Documentation-Tips.html">Documentation Tips</a>) apply to C code documentation strings too. </p> <p>The documentation string can be followed by a list of C function attributes for the C function that implements the primitive, like this: </p> <div class="example"> <pre class="example">DEFUN ("bar", Fbar, Sbar, 0, UNEVALLED, 0 + doc: /* … */ + attributes: <var>attr1</var> <var>attr2</var> …) +</pre> +</div> <p>You can specify more than a single attribute, one after the other. Currently, only the following attributes are recognized: </p> <dl compact> <dt><code>noreturn</code></dt> <dd> +<p>Declares the C function as one that never returns. This corresponds to the C11 keyword <code>_Noreturn</code> and to <code><span class="nolinebreak">__attribute__</span> <span class="nolinebreak">((__noreturn__))</span></code> attribute of GCC (see <a href="https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes">Function Attributes</a> in <cite>Using the GNU Compiler Collection</cite>). </p> </dd> <dt><code>const</code></dt> <dd> +<p>Declares that the function does not examine any values except its arguments, and has no effects except the return value. This corresponds to <code><span class="nolinebreak">__attribute__</span> <span class="nolinebreak">((__const__))</span></code> attribute of GCC. </p> </dd> <dt><code>noinline</code></dt> <dd><p>This corresponds to <code><span class="nolinebreak">__attribute__</span> <span class="nolinebreak">((__noinline__))</span></code> attribute of GCC, which prevents the function from being considered for inlining. This might be needed, e.g., to countermand effects of link-time optimizations on stack-based variables. </p></dd> </dl> </dd> </dl> <p>After the call to the <code>DEFUN</code> macro, you must write the argument list for the C function, including the types for the arguments. If the primitive accepts a fixed maximum number of Lisp arguments, there must be one C argument for each Lisp argument, and each argument must be of type <code>Lisp_Object</code>. (Various macros and functions for creating values of type <code>Lisp_Object</code> are declared in the file <samp>lisp.h</samp>.) If the primitive is a special form, it must accept a Lisp list containing its unevaluated Lisp arguments as a single argument of type <code>Lisp_Object</code>. If the primitive has no upper limit on the number of evaluated Lisp arguments, it must have exactly two C arguments: the first is the number of Lisp arguments, and the second is the address of a block containing their values. These have types <code>ptrdiff_t</code> and <code><span class="nolinebreak">Lisp_Object</span> *</code>, respectively. Since <code>Lisp_Object</code> can hold any Lisp object of any data type, you can determine the actual data type only at run time; so if you want a primitive to accept only a certain type of argument, you must check the type explicitly using a suitable predicate (see <a href="type-predicates">Type Predicates</a>). </p> <p>Within the function <code>For</code> itself, the local variable <code>args</code> refers to objects controlled by Emacs’s stack-marking garbage collector. Although the garbage collector does not reclaim objects reachable from C <code>Lisp_Object</code> stack variables, it may move some of the components of an object, such as the contents of a string or the text of a buffer. Therefore, functions that access these components must take care to refetch their addresses after performing Lisp evaluation. This means that instead of keeping C pointers to string contents or buffer text, the code should keep the buffer or string position, and recompute the C pointer from the position after performing Lisp evaluation. Lisp evaluation can occur via calls to <code>eval_sub</code> or <code>Feval</code>, either directly or indirectly. </p> <p>Note the call to <code>maybe_quit</code> inside the loop: this function checks whether the user pressed <kbd>C-g</kbd>, and if so, aborts the processing. You should do that in any loop that can potentially require a large number of iterations; in this case, the list of arguments could be very long. This increases Emacs responsiveness and improves user experience. </p> <p>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 <a href="pure-storage">Pure Storage</a>. </p> <p>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: </p> <div class="example"> <pre class="example">defsubr (&<var>sname</var>); +</pre> +</div> <p>Here <var>sname</var> is the name you used as the third argument to <code>DEFUN</code>. </p> <p>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 <code>syms_of_<var>something</var></code>, and add the call to <code>defsubr</code> there. If the file doesn’t have this function, or if you create a new file, add to it a <code>syms_of_<var>filename</var></code> (e.g., <code>syms_of_myfile</code>). Then find the spot in <samp>emacs.c</samp> where all of these functions are called, and add a call to <code>syms_of_<var>filename</var></code> there. </p> <p>The function <code>syms_of_<var>filename</var></code> is also the place to define any C variables that are to be visible as Lisp variables. <code>DEFVAR_LISP</code> makes a C variable of type <code>Lisp_Object</code> visible in Lisp. <code>DEFVAR_INT</code> makes a C variable of type <code>int</code> visible in Lisp with a value that is always an integer. <code>DEFVAR_BOOL</code> makes a C variable of type <code>int</code> visible in Lisp with a value that is either <code>t</code> or <code>nil</code>. Note that variables defined with <code>DEFVAR_BOOL</code> are automatically added to the list <code>byte-boolean-vars</code> used by the byte compiler. </p> <p>These macros all expect three arguments: </p> <dl compact> <dt><code>lname</code></dt> <dd><p>The name of the variable to be used by Lisp programs. </p></dd> <dt><code>vname</code></dt> <dd><p>The name of the variable in the C sources. </p></dd> <dt><code>doc</code></dt> <dd><p>The documentation for the variable, as a C comment. See <a href="documentation-basics">Documentation Basics</a>, for more details. </p></dd> </dl> <p>By convention, when defining variables of a “native” type (<code>int</code> and <code>bool</code>), the name of the C variable is the name of the Lisp variable with <code>-</code> replaced by <code>_</code>. When the variable has type <code>Lisp_Object</code>, the convention is to also prefix the C variable name with <code>V</code>. i.e. </p> <div class="example"> <pre class="example">DEFVAR_INT ("my-int-variable", my_int_variable, + doc: /* An integer variable. */); + +DEFVAR_LISP ("my-lisp-variable", Vmy_lisp_variable, + doc: /* A Lisp variable. */); +</pre> +</div> <p>There are situations in Lisp where you need to refer to the symbol itself rather than the value of that symbol. One such case is when temporarily overriding the value of a variable, which in Lisp is done with <code>let</code>. In C sources, this is done by defining a corresponding, constant symbol, and using <code>specbind</code>. By convention, <code>Qmy_lisp_variable</code> corresponds to <code>Vmy_lisp_variable</code>; to define it, use the <code>DEFSYM</code> macro. i.e. </p> <div class="example"> <pre class="example">DEFSYM (Qmy_lisp_variable, "my-lisp-variable"); +</pre> +</div> <p>To perform the actual binding: </p> <div class="example"> <pre class="example">specbind (Qmy_lisp_variable, Qt); +</pre> +</div> <p>In Lisp symbols sometimes need to be quoted, to achieve the same effect in C you again use the corresponding constant symbol <code>Qmy_lisp_variable</code>. For example, when creating a buffer-local variable (see <a href="buffer_002dlocal-variables">Buffer-Local Variables</a>) in Lisp you would write: </p> <div class="example"> <pre class="example">(make-variable-buffer-local 'my-lisp-variable) +</pre> +</div> <p>In C the corresponding code uses <code>Fmake_variable_buffer_local</code> in combination with <code>DEFSYM</code>, i.e. </p> <div class="example"> <pre class="example">DEFSYM (Qmy_lisp_variable, "my-lisp-variable"); +Fmake_variable_buffer_local (Qmy_lisp_variable); +</pre> +</div> <p>If you want to make a Lisp variable that is defined in C behave like one declared with <code>defcustom</code>, add an appropriate entry to <samp>cus-start.el</samp>. See <a href="variable-definitions">Variable Definitions</a>, for a description of the format to use. </p> <p>If you directly define a file-scope C variable of type <code>Lisp_Object</code>, you must protect it from garbage-collection by calling <code>staticpro</code> in <code>syms_of_<var>filename</var></code>, like this: </p> <div class="example"> <pre class="example">staticpro (&<var>variable</var>); +</pre> +</div> <p>Here is another example function, with more complicated arguments. This comes from the code in <samp>window.c</samp>, and it demonstrates the use of macros and functions to manipulate Lisp objects. </p> <div class="example"> <pre class="example">DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, + Scoordinates_in_window_p, 2, 2, 0, + doc: /* Return non-nil if COORDINATES are in WINDOW. + … +</pre> +<pre class="example"> or `right-margin' is returned. */) + (register Lisp_Object coordinates, Lisp_Object window) +{ + struct window *w; + struct frame *f; + int x, y; + Lisp_Object lx, ly; +</pre> + +<pre class="example"> w = decode_live_window (window); + f = XFRAME (w->frame); + CHECK_CONS (coordinates); + lx = Fcar (coordinates); + ly = Fcdr (coordinates); + CHECK_NUMBER (lx); + CHECK_NUMBER (ly); + x = FRAME_PIXEL_X_FROM_CANON_X (f, lx) + FRAME_INTERNAL_BORDER_WIDTH (f); + y = FRAME_PIXEL_Y_FROM_CANON_Y (f, ly) + FRAME_INTERNAL_BORDER_WIDTH (f); +</pre> + +<pre class="example"> switch (coordinates_in_window (w, x, y)) + { + case ON_NOTHING: /* NOT in window at all. */ + return Qnil; +</pre> +<pre class="example"> + + … + +</pre> +<pre class="example"> case ON_MODE_LINE: /* In mode line of window. */ + return Qmode_line; +</pre> +<pre class="example"> + + … + +</pre> +<pre class="example"> case ON_SCROLL_BAR: /* On scroll-bar of window. */ + /* Historically we are supposed to return nil in this case. */ + return Qnil; +</pre> + +<pre class="example"> default: + emacs_abort (); + } +} +</pre> +</div> <p>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 <code>Ffuncall</code>, which embodies the Lisp function <code>funcall</code>. Since the Lisp function <code>funcall</code> 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. </p> <p>The C functions <code>call0</code>, <code>call1</code>, <code>call2</code>, and so on, provide handy ways to call a Lisp function conveniently with a fixed number of arguments. They work by calling <code>Ffuncall</code>. </p> <p><samp>eval.c</samp> is a very good file to look through for examples; <samp>lisp.h</samp> contains the definitions for some important macros and functions. </p> <p>If you define a function which is side-effect free or pure, give it a non-<code>nil</code> <code>side-effect-free</code> or <code>pure</code> property, respectively (see <a href="standard-properties">Standard Properties</a>). </p><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br> + <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Writing-Emacs-Primitives.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Writing-Emacs-Primitives.html</a> + </p> +</div> |
