Next: , Up: Rules When Writing New C Code   [Contents][Index]


8.1 A Readers Guide to SXEmacs Coding Conventions

Of course the low-level implementation language of SXEmacs is C, but much of that uses the Lisp engine to do its work. However, because the code is “inside” of the protective containment shell around the “reactor core,” you’ll see lots of complex “plumbing” needed to do the work and “safety mechanisms,” whose failure results in a meltdown. This section provides a quick overview (or review) of the various components of the implementation of Lisp objects.

Two typographic conventions help to identify C objects that implement Lisp objects. The first is that capitalized identifiers, especially beginning with the letters ‘Q’, ‘V’, ‘F’, and ‘S’, for C variables and functions, and C macros with beginning with the letter ‘X’, are used to implement Lisp. The second is that where Lisp uses the hyphen ‘-’ in symbol names, the corresponding C identifiers use the underscore ‘_’. Of course, since SXEmacs Lisp contains interfaces to many external libraries, those external names will follow the coding conventions their authors chose, and may overlap the “SXEmacs name space.” However these cases are usually pretty obvious.

All Lisp objects are handled indirectly. The Lisp_Object type is usually a pointer to a structure, except for a very small number of types with immediate representations (currently characters and integers). However, these types cannot be directly operated on in C code, either, so they can also be considered indirect. Types that do not have an immediate representation always have a C typedef Lisp_type for a corresponding structure.

In older code, it was common practice to pass around pointers to Lisp_type, but this is now deprecated in favor of using Lisp_Object for all function arguments and return values that are Lisp objects. The Xtype macro is used to extract the pointer and cast it to (Lisp_type *) for the desired type.

Convention: macros whose names begin with ‘X’ operate on Lisp_Objects and do no type-checking. Many such macros are type extractors, but others implement Lisp operations in C (e.g., XCAR implements the Lisp car function). These are unsafe, and must only be used where types of all data have already been checked. Such macros are only applied to Lisp_Objects. In internal implementations where the pointer has already been converted, the structure is operated on directly using the C -> member access operator.

The typeP, CHECK_type, and CONCHECK_type macros are used to test types. The first returns a Boolean value, and the latter signal errors. (The ‘CONCHECK’ variety allows execution to be CONtinued under some circumstances, thus the name.) Functions which expect to be passed user data invariably call ‘CHECK’ macros on arguments.

There are many types of specialized Lisp objects implemented in C, but the most pervasive type is the symbol. Symbols are used as identifiers, variables, and functions.

Convention: Global variables whose names begin with ‘Q’ are constants whose value is a symbol. The name of the variable should be derived from the name of the symbol using the same rules as for Lisp primitives. Such variables allow the C code to check whether a particular Lisp_Object is equal to a given symbol. Symbols are Lisp objects, so these variables may be passed to Lisp primitives. (An alternative to the use of ‘Q...’ variables is to call the intern function at initialization in the vars_of_module function, which is hardly less efficient.)

Convention: Global variables whose names begin with ‘V’ are variables that contain Lisp objects. The convention here is that all global variables of type Lisp_Object begin with ‘V’, and no others do (not even integer and boolean variables that have Lisp equivalents). Most of the time, these variables have equivalents in Lisp, which are defined via the ‘DEFVAR’ family of macros, but some don’t. Since the variable’s value is a Lisp_Object, it can be passed to Lisp primitives.

The implementation of Lisp primitives is more complex. Convention: Global variables with names beginning with ‘S’ contain a structure that allows the Lisp engine to identify and call a C function. In modern versions of SXEmacs, these identifiers are almost always completely hidden in the DEFUN and SUBR macros, but you will encounter them if you look at very old versions of SXEmacs or at GNU Emacs. Convention: Functions with names beginning with ‘F’ implement Lisp primitives. Of course all their arguments and their return values must be Lisp_Objects. (This is hidden in the DEFUN macro.)


Next: , Up: Rules When Writing New C Code   [Contents][Index]