Home | History | Annotate | Line # | Download | only in lisp
      1 /* $XdotOrg: xc/programs/xedit/lisp/internal.h,v 1.2 2004/04/23 19:54:44 eich Exp $ */
      2 /*
      3  * Copyright (c) 2001 by The XFree86 Project, Inc.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be included in
     13  * all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     20  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     21  * SOFTWARE.
     22  *
     23  * Except as contained in this notice, the name of the XFree86 Project shall
     24  * not be used in advertising or otherwise to promote the sale, use or other
     25  * dealings in this Software without prior written authorization from the
     26  * XFree86 Project.
     27  *
     28  * Author: Paulo Csar Pereira de Andrade
     29  */
     30 
     31 /* $XFree86: xc/programs/xedit/lisp/internal.h,v 1.50tsi Exp $ */
     32 
     33 #ifndef Lisp_internal_h
     34 #define Lisp_internal_h
     35 
     36 #include <stdio.h>
     37 #include "lisp/lisp.h"
     38 
     39 #include "mp.h"
     40 #include "re.h"
     41 
     42 #include "util.h"
     43 
     44 /*
     45  * Defines
     46  */
     47 typedef struct _LispMac LispMac;
     48 
     49 #define STREAM_READ		0x01
     50 #define STREAM_WRITE		0x02
     51 #define STREAM_BINARY		0x20
     52 
     53 #define RPLACA(cons, object)	(CAR(cons) = object)
     54 #define RPLACD(cons, object)	(CDR(cons) = object)
     55 
     56 #define	CAR(list)		((list)->data.cons.car)
     57 #define	CAAR(list)		((list)->data.cons.car->data.cons.car)
     58 #define	CADR(list)		((list)->data.cons.cdr->data.cons.car)
     59 #define CDR(list)		((list)->data.cons.cdr)
     60 #define CDAR(list)		((list)->data.cons.car->data.cons.cdr)
     61 #define CDDR(list)		((list)->data.cons.cdr->data.cons.cdr)
     62 #define CONS(car, cdr)		LispNewCons(car, cdr)
     63 #define EVAL(list)		LispEval(list)
     64 #define APPLY(fun, args)	LispFuncall(fun, args, 0)
     65 #define APPLY1(fun, arg)	LispApply1(fun, arg)
     66 #define APPLY2(fun, arg1, arg2)	LispApply2(fun, arg1, arg2)
     67 #define APPLY3(f, a1, a2, a3)	LispApply3(f, a1, a2, a3)
     68 #define EXECUTE(string)		LispExecute(string)
     69 #define SYMBOL(atom)		LispNewSymbol(atom)
     70 #define ATOM(string)		LispNewAtom(string, 1)
     71 #define UNINTERNED_ATOM(string)	LispNewAtom(string, 0)
     72 #define FUNCTION(symbol)	LispNewFunction(symbol)
     73 #define FUNCTION_QUOTE(symbol)	LispNewFunctionQuote(symbol)
     74 
     75 	/* atom string is a static variable */
     76 #define ATOM2(string)		LispNewSymbol(LispGetPermAtom(string))
     77 
     78 	/* make a gc never released variable with a static string argument */
     79 #define STATIC_ATOM(string)	LispNewStaticAtom(string)
     80 
     81 #define STRING(str)		LispNewString(str, strlen(str))
     82 #define LSTRING(str, size)	LispNewString(str, size)
     83 
     84 	/* string must be from the LispXXX allocation functions,
     85 	 * and LispMused not yet called on it */
     86 #define STRING2(str)		LispNewStringAlloced(str, strlen(str))
     87 #define LSTRING2(str, size)	LispNewStringAlloced(str, size)
     88 
     89 #define VECTOR(objects)		LispNewVector(objects)
     90 
     91 	/* STRINGSTREAM2 and LSTRINGSTREAM2 require that the
     92 	 * string be allocated from the LispXXX allocation functions,
     93 	 * and LispMused not yet called on it */
     94 #define STRINGSTREAM(str, flag)			\
     95 	LispNewStringStream(str, flag, strlen(str))
     96 #define STRINGSTREAM2(str, flag)		\
     97 	LispNewStringStreamAlloced(str, flag, strlen(str))
     98 #define LSTRINGSTREAM(str, flag, length)	\
     99 	LispNewStringStream(str, flag, length)
    100 #define LSTRINGSTREAM2(str, flag, length)	\
    101 	LispNewStringStreamAlloced(str, flag, length)
    102 
    103 #define FILESTREAM(file, path, flag)	\
    104 	LispNewFileStream(file, path, flag)
    105 #define PIPESTREAM(file, path, flag)	\
    106 	LispNewPipeStream(file, path, flag)
    107 
    108 #define CHECKO(obj, typ)						\
    109 	((obj)->type == LispOpaque_t && 				\
    110 	 ((obj)->data.opaque.type == typ || (obj)->data.opaque.type == 0))
    111 #define PROTECT(key, list)	LispProtect(key, list)
    112 #define UPROTECT(key, list)	LispUProtect(key, list)
    113 
    114 /* create a new unique static atom string */
    115 #define GETATOMID(string)	LispGetAtomKey(string, 1)
    116 
    117 #define	GCDisable()		++gcpro
    118 #define	GCEnable()		--gcpro
    119 
    120 
    121 /* pointer to something unique to all atoms with the same print representation */
    122 #define ATOMID(object)		(object)->data.atom->key
    123 
    124 
    125 
    126 #define NIL_BIT			0x01
    127 #define FIXNUM_BIT		0x02
    128 #define FIXNUM_MASK		0x03
    129 #define SCHAR_BIT		0x04
    130 #define SCHAR_MASK		0x05
    131 #define BIT_COUNT		4
    132 #define BIT_MASK		0x0f
    133 #define POINTERP(object)						\
    134     (((unsigned long)(object) & NIL_BIT) == 0)
    135 
    136 #define MOST_POSITIVE_FIXNUM	((1L << (sizeof(long) * 8 - 5)) - 1)
    137 #define MOST_NEGATIVE_FIXNUM	(-(1L << (sizeof(long) * 8 - 5)))
    138 
    139 #define SCHAR(value)							\
    140     ((LispObj*)(((long)(value) << BIT_COUNT) | SCHAR_MASK))
    141 #define SCHAR_VALUE(object)	FIXNUM_VALUE(object)
    142 #define SCHARP(object)							\
    143     (((unsigned long)(object) & BIT_MASK) == SCHAR_MASK)
    144 #define CHECK_SCHAR(object)						\
    145     if (!SCHARP(object))						\
    146 	LispDestroy("%s: %s is not a character",			\
    147 		    STRFUN(builtin), STROBJ(object))
    148 
    149 #define XOBJECT_TYPE(object)	((object)->type)
    150 #define OBJECT_TYPE(object)	(POINTERP(object) ?			\
    151 				XOBJECT_TYPE(object) :			\
    152 				(LispType)((long)(object) & BIT_MASK))
    153 
    154 
    155 #define NIL			(LispObj*)0x00000001
    156 #define T			(LispObj*)0x00000011
    157 #define DOT			(LispObj*)0x00000021
    158 /* unmatched ')' */
    159 #define	EOLIST			(LispObj*)0x00000031
    160 #define READLABEL_MASK		0x00000041
    161 /* unspecified argument */
    162 #define UNSPEC			(LispObj*)0x00000051
    163 #define INVALIDP(object)						\
    164     ((object) == NULL || (object) == EOLIST || (object) == DOT)
    165 
    166 
    167 /* cons */
    168 #define XCONSP(object)		((object)->type == LispCons_t)
    169 #define CONSP(object)		(POINTERP(object) && XCONSP(object))
    170 #define CHECK_CONS(object)						\
    171     if (!CONSP(object))							\
    172 	LispDestroy("%s: %s is not of type cons",			\
    173 		    STRFUN(builtin), STROBJ(object))
    174 #define LISTP(object)		(object == NIL || CONSP(object))
    175 #define CHECK_LIST(object)						\
    176     if (!LISTP(object))							\
    177 	LispDestroy("%s: %s is not a list",				\
    178 		    STRFUN(builtin), STROBJ(object))
    179 
    180 /* fixnum */
    181 #define FIXNUM(value)							\
    182     ((LispObj*)(((long)(value) * (1 << BIT_COUNT)) | FIXNUM_MASK))
    183 #define FIXNUM_VALUE(object)	((long)(object) >> BIT_COUNT)
    184 #define FIXNUMP(object)							\
    185     (((unsigned long)(object) & BIT_MASK) == FIXNUM_MASK)
    186 #define CHECK_FIXNUM(object)						\
    187     if (!FIXNUMP(object))						\
    188 	LispDestroy("%s: %s is not a fixnum",				\
    189 		    STRFUN(builtin), STROBJ(object))
    190 #define INDEXP(object)							\
    191     (FIXNUMP(object) && FIXNUM_VALUE(object) >= 0)
    192 #define CHECK_INDEX(object)						\
    193     if (!INDEXP(object))						\
    194 	LispDestroy("%s: %s is not a positive fixnum",			\
    195 		    STRFUN(builtin), STROBJ(object))
    196 
    197 
    198 /* long int integer */
    199 #define XINTP(object)		((object)->type == LispInteger_t)
    200 #define INTP(objet)		(POINTERP(object) && XINTP(object))
    201 #define INT_VALUE(object)	(object)->data.integer
    202 
    203 
    204 /* values that fit in a machine long int but not in a fixnum */
    205 #define LONGINTP(object)						\
    206     (POINTERP(object) ? XINTP(object) : FIXNUMP(object))
    207 #define LONGINT_VALUE(object)						\
    208     (POINTERP(object) ? INT_VALUE(object) : FIXNUM_VALUE(object))
    209 #define CHECK_LONGINT(object)						\
    210     if (!LONGINTP(object))						\
    211 	LispDestroy("%s: %s is not an integer",				\
    212 		    STRFUN(builtin), STROBJ(object))
    213 
    214 
    215 /* bignum */
    216 #define XBIGNUMP(object)	((object)->type == LispBignum_t)
    217 #define BIGNUMP(object)		(POINTERP(object) && XBIGNUMP(object))
    218 #define BIGNUM(object)		LispNewBignum(object)
    219 
    220 
    221 /* generic integer */
    222 #define INTEGER(integer)	LispNewInteger(integer)
    223 #define INTEGERP(object)						\
    224     (POINTERP(object) ? XINTP(object) || XBIGNUMP(object) : FIXNUMP(object))
    225 #define CHECK_INTEGER(object)						\
    226     if (!INTEGERP(object))						\
    227 	LispDestroy("%s: %s is not an integer",				\
    228 		    STRFUN(builtin), STROBJ(object))
    229 
    230 
    231 /* ratio */
    232 #define XRATIOP(object)		((object)->type == LispRatio_t)
    233 #define RATIOP(object)		(POINTERP(object) && XRATIOP(object))
    234 #define RATIO(num, den)		LispNewRatio(num, den)
    235 
    236 
    237 /* bigratio */
    238 #define XBIGRATIOP(object)	((object)->type == LispBigratio_t)
    239 #define BIGRATIOP(object)	(POINTERP(object) && XBIGRATIOP(object))
    240 #define BIGRATIO(ratio)		LispNewBigratio(ratio)
    241 
    242 
    243 /* generic rational */
    244 #define RATIONALP(object)						\
    245     (POINTERP(object) ? XINTP(object) || XRATIOP(object) ||		\
    246 			XBIGNUMP(object) || XBIGRATIOP(object) :	\
    247 			FIXNUMP(object))
    248 
    249 
    250 /* double float */
    251 #define XDFLOATP(object)	((object)->type == LispDFloat_t)
    252 #define DFLOATP(object)		(POINTERP(object) && XDFLOATP(object))
    253 #define DFLOAT_VALUE(object)	(object)->data.dfloat
    254 #define CHECK_DFLOAT(object)						\
    255     if (!DFLOATP(object))						\
    256 	LispDestroy("%s: %s is not a float number",			\
    257 		    STRFUN(builtin), STROBJ(object))
    258 #define DFLOAT(value)		LispNewDFloat(value)
    259 
    260 
    261 /* generic float - currently only double float supported */
    262 #define FLOATP(object)		DFLOATP(object)
    263 
    264 
    265 /* real number */
    266 #define REALP(object)							\
    267     (POINTERP(object) ? XINTP(object) || XDFLOATP(object) ||		\
    268 			XRATIOP(object) || XBIGNUMP(object) ||		\
    269 			XBIGRATIOP(object) :				\
    270 			FIXNUMP(object))
    271 #define CHECK_REAL(object)						\
    272     if (!REALP(object))							\
    273 	LispDestroy("%s: %s is not a real number",			\
    274 		    STRFUN(builtin), STROBJ(object))
    275 
    276 
    277 /* complex */
    278 #define XCOMPLEXP(object)	((object)->type == LispComplex_t)
    279 #define COMPLEXP(object)	(POINTERP(object) && XCOMPLEXP(object))
    280 #define COMPLEX(real, imag)	LispNewComplex(real, imag)
    281 
    282 
    283 /* generic number */
    284 #define NUMBERP(object)							\
    285     (POINTERP(object) ? XINTP(object) || XDFLOATP(object) ||		\
    286 			XRATIOP(object) || XBIGNUMP(object) ||		\
    287 			XBIGRATIOP(object) || XCOMPLEXP(object) :	\
    288 			FIXNUMP(object))
    289 #define CHECK_NUMBER(object)						\
    290     if (!NUMBERP(object))						\
    291 	LispDestroy("%s: %s is not a number",				\
    292 		    STRFUN(builtin), STROBJ(object))
    293 
    294 
    295 /* symbol */
    296 #define XSYMBOLP(object)	((object)->type == LispAtom_t)
    297 #define SYMBOLP(object)		(POINTERP(object) && XSYMBOLP(object))
    298 #define CHECK_SYMBOL(object)						\
    299     if (!SYMBOLP(object))						\
    300 	LispDestroy("%s: %s is not a symbol",				\
    301 		    STRFUN(builtin), STROBJ(object))
    302 
    303 
    304 /* keyword */
    305 #define XKEYWORDP(object)						\
    306     ((object)->data.atom->package == lisp__data.keyword)
    307 #define KEYWORDP(object)						\
    308     (POINTERP(object) && XSYMBOLP(object) && XKEYWORDP(object))
    309 #define KEYWORD(string)		LispNewKeyword(string)
    310 #define CHECK_KEYWORD(object)						\
    311     if (!KEYWORDP(object))						\
    312 	LispDestroy("%s: %s is not a keyword",				\
    313 		    STRFUN(builtin), STROBJ(object))
    314 #define CHECK_CONSTANT(object)						\
    315     if ((object)->data.atom->constant)					\
    316 	LispDestroy("%s: %s is a constant",				\
    317 		    STRFUN(builtin), STROBJ(object))
    318 
    319 #define SETVALUE(atom, object)	((atom)->property->value = object)
    320 
    321 
    322 /* function */
    323 #define XFUNCTIONP(object)	((object)->type == LispFunction_t)
    324 #define FUNCTIONP(object)	(POINTERP(object) && XFUNCTIONP(object))
    325 
    326 
    327 /* lambda */
    328 #define XLAMBDAP(object)	((object)->type == LispLambda_t)
    329 #define LAMBDAP(object)		(POINTERP(object) && XLAMBDAP(object))
    330 
    331 
    332 /* string - currently only simple 8 bit characters */
    333 #define XSTRINGP(object)	((object)->type == LispString_t)
    334 #define STRINGP(object)		(POINTERP(object) && XSTRINGP(object))
    335 #define THESTR(object)		(object)->data.string.string
    336 #define STRLEN(object)		(object)->data.string.length
    337 #define CHECK_STRING(object)						\
    338     if (!STRINGP(object))						\
    339 	LispDestroy("%s: %s is not a string",				\
    340 		    STRFUN(builtin), STROBJ(object))
    341 #define CHECK_STRING_WRITABLE(object)					\
    342     if (!object->data.string.writable)					\
    343 	LispDestroy("%s: %s is readonly",				\
    344 		    STRFUN(builtin), STROBJ(object))
    345 
    346 
    347 /* array/vector */
    348 #define XARRAYP(object)		((object)->type == LispArray_t)
    349 #define ARRAYP(object)		(POINTERP(object) && XARRAYP(object))
    350 #define CHECK_ARRAY(object)						\
    351     if (!ARRAYP(object))						\
    352 	LispDestroy("%s: %s is not an array",				\
    353 		    STRFUN(builtin), STROBJ(object))
    354 
    355 
    356 /* quote */
    357 #define XQUOTEP(object)		((object)->type == LispQuote_t)
    358 #define QUOTEP(object)		(POINTERP(object) && XQUOTEP(object))
    359 #define QUOTE(object)		LispNewQuote(object)
    360 
    361 #define XBACKQUOTEP(object)	((object)->type == LispBackquote_t)
    362 #define BACKQUOTEP(object)	(POINTERP(object) && XBACKQUOTEP(object))
    363 #define BACKQUOTE(object)	LispNewBackquote(object)
    364 
    365 #define XCOMMAP(object)		((object)->type == LispComma_t)
    366 #define COMMAP(object)		(POINTERP(object) && XCOMMAP(object))
    367 #define COMMA(object, at)	LispNewComma(object, at)
    368 
    369 
    370 /* package */
    371 #define XPACKAGEP(object)	((object)->type == LispPackage_t)
    372 #define PACKAGEP(object)	(POINTERP(object) && XPACKAGEP(object))
    373 
    374 
    375 /* pathname */
    376 #define XPATHNAMEP(object)	((object)->type == LispPathname_t)
    377 #define PATHNAMEP(object)	(POINTERP(object) && XPATHNAMEP(object))
    378 #define PATHNAME(object)	LispNewPathname(object)
    379 #define CHECK_PATHNAME(object)						\
    380     if (!PATHNAMEP(object))						\
    381 	LispDestroy("%s: %s is not a pathname",				\
    382 		    STRFUN(builtin), STROBJ(object))
    383 
    384 
    385 /* stream */
    386 #define XSTREAMP(object)	((object)->type == LispStream_t)
    387 #define STREAMP(object)		(POINTERP(object) && XSTREAMP(object))
    388 #define CHECK_STREAM(object)						\
    389     if (!STREAMP(object))						\
    390 	LispDestroy("%s: %s is not a stream",				\
    391 		    STRFUN(builtin), STROBJ(object))
    392 
    393 
    394 /* hastable */
    395 #define XHASHTABLEP(object)	((object)->type == LispHashTable_t)
    396 #define HASHTABLEP(object)	(POINTERP(object) && XHASHTABLEP(object))
    397 #define CHECK_HASHTABLE(object)						\
    398     if (!HASHTABLEP(object))						\
    399 	LispDestroy("%s: %s is not a hash-table",			\
    400 		    STRFUN(builtin), STROBJ(object))
    401 
    402 
    403 /* regex */
    404 #define XREGEXP(object)		((object)->type == LispRegex_t)
    405 #define REGEXP(object)		(POINTERP(object) && XREGEXP(object))
    406 #define CHECK_REGEX(object)						\
    407     if (!REGEXP(object))						\
    408 	LispDestroy("%s: %s is not a regexp",				\
    409 		    STRFUN(builtin), STROBJ(object))
    410 
    411 
    412 /* bytecode */
    413 #define XBYTECODEP(object)	((object)->type == LispBytecode_t)
    414 #define BYTECODEP(object)	(POINTERP(object) && XBYTECODEP(object))
    415 
    416 
    417 /* opaque */
    418 #define XOPAQUEP(object)	((object)->type == LispOpaque_t)
    419 #define OPAQUEP(object)		(POINTERP(object) && XOPAQUEP(object))
    420 #define OPAQUE(data, type)	LispNewOpaque((void*)((long)data), type)
    421 
    422 
    423 
    424 #define SSTREAMP(str)		((str)->data.stream.source.string)
    425 
    426 #define FSTREAMP(str)		((str)->data.stream.source.file)
    427 
    428 #define PSTREAMP(str)		((str)->data.stream.source.program)
    429 #define PIDPSTREAMP(str)	((str)->data.stream.source.program->pid)
    430 #define IPSTREAMP(str)		((str)->data.stream.source.program->input)
    431 #define OPSTREAMP(str)		((str)->data.stream.source.program->output)
    432 #define EPSTREAMP(str)		\
    433 	FSTREAMP((str)->data.stream.source.program->errorp)
    434 
    435 #define LispFileno(file)	((file)->descriptor)
    436 
    437 #define STRFUN(builtin)		ATOMID(builtin->symbol)->value
    438 #define STROBJ(obj)		LispStrObj(obj)
    439 
    440 /* fetch builtin function/macro argument value
    441  */
    442 #define ARGUMENT(index)							\
    443 	lisp__data.stack.values[lisp__data.stack.base + (index)]
    444 
    445 #define RETURN(index)	lisp__data.returns.values[(index)]
    446 #define RETURN_COUNT	lisp__data.returns.count
    447 #define RETURN_CHECK(value)						\
    448     value < MULTIPLE_VALUES_LIMIT ?					\
    449 	value : MULTIPLE_VALUES_LIMIT
    450 
    451 #define GC_ENTER()		int gc__protect = lisp__data.protect.length
    452 
    453 #define GC_PROTECT(object)						\
    454     if (lisp__data.protect.length >= lisp__data.protect.space)		\
    455 	LispMoreProtects();						\
    456     lisp__data.protect.objects[lisp__data.protect.length++] = object
    457 
    458 #define GC_LEAVE()		lisp__data.protect.length = gc__protect
    459 
    460 
    461 #define ERROR_CHECK_SPECIAL_FORM(atom)					\
    462     if ((atom)->property->fun.builtin->compile)				\
    463 	LispDestroy("%s: the special form %s cannot be redefined",	\
    464 		    STRFUN(builtin), (atom)->key->value)
    465 
    466 
    467 
    468 #define CONSTANTP(object)						\
    469     (!POINTERP(object) ||						\
    470      XOBJECT_TYPE(object) < LispAtom_t ||				\
    471      (XSYMBOLP(object) && XKEYWORDP(object)))
    472 
    473 /* slightly faster test, since keywords are very uncommon as eval arguments */
    474 #define NCONSTANTP(object)						\
    475     (OBJECT_TYPE(object) >= LispAtom_t)
    476 
    477 
    478 /*
    479  * Types
    480  */
    481 typedef struct _LispObj LispObj;
    482 typedef struct _LispAtom LispAtom;
    483 typedef struct _LispBuiltin LispBuiltin;
    484 typedef struct _LispModuleData LispModuleData;
    485 typedef struct _LispFile LispFile;
    486 typedef struct _LispString LispString;
    487 typedef struct _LispPackage LispPackage;
    488 typedef struct _LispBytecode LispBytecode;
    489 typedef struct _LispHashTable LispHashTable;
    490 
    491 /* Bytecode compiler data */
    492 typedef struct _LispCom LispCom;
    493 
    494 typedef hash_key *Atom_id;
    495 
    496 typedef enum _LispType {
    497     /* objects encoded in the LispObj pointer */
    498     LispNil_t = 1,
    499     LispFixnum_t = 3,
    500     LispSChar_t = 5,
    501 
    502     /* objects that have a structure */
    503     LispInteger_t = 16,
    504     LispDFloat_t,
    505     LispString_t,
    506     LispRatio_t,
    507     LispOpaque_t,
    508 
    509     /* simple access for marking */
    510     LispBignum_t,
    511     LispBigratio_t,
    512 
    513     LispAtom_t,
    514     LispFunction_t,
    515     LispFunctionQuote_t,
    516 
    517     LispLambda_t,
    518 
    519     LispComplex_t,
    520     LispCons_t,
    521     LispQuote_t,
    522     LispArray_t,
    523     LispStruct_t,
    524     LispStream_t,
    525     LispBackquote_t,
    526     LispComma_t,
    527     LispPathname_t,
    528     LispPackage_t,
    529     LispRegex_t,
    530     LispBytecode_t,
    531     LispHashTable_t
    532 } LispType;
    533 
    534 typedef enum _LispFunType {
    535     LispLambda,
    536     LispFunction,
    537     LispMacro,
    538     LispSetf
    539 } LispFunType;
    540 
    541 typedef enum _LispStreamType {
    542     LispStreamString,
    543     LispStreamFile,
    544     LispStreamStandard,
    545     LispStreamPipe
    546 } LispStreamType;
    547 
    548 typedef struct {
    549     int pid;			/* process id of program */
    550     LispFile *input;		/* if READABLE: stdout of program */
    551     LispFile *output;		/* if WRITABLE: stdin of program */
    552     LispObj *errorp;		/* ALWAYS (ONLY) READABLE: stderr of program */
    553 } LispPipe;
    554 
    555 /* silly IBM compiler */
    556 #ifdef AIXV5 /* probably want !gcc too */
    557 #define LispType int
    558 #define LispFunType int
    559 #define LispStreamType int
    560 #endif
    561 
    562 struct _LispObj {
    563     LispType type : 6;
    564     unsigned int mark : 1;	/* gc protected */
    565     unsigned int prot: 1;	/* protection for constant/unamed variables */
    566     LispFunType funtype : 4;	/* this is subject to change in the future */
    567     union {
    568 	LispAtom *atom;
    569 	struct {
    570 	    char *string;
    571 	    long length;
    572 	    unsigned int writable : 1;
    573 	} string;
    574 	long integer;
    575 	double dfloat;
    576 	LispObj *quote;
    577 	LispObj *pathname;	/* don't use quote generic name,
    578 				 * to avoid confusing code */
    579 	struct {
    580 	    long numerator;
    581 	    long denominator;
    582 	} ratio;
    583 	union {
    584 	    mpi *integer;
    585 	    mpr *ratio;
    586 	} mp;
    587 	struct {
    588 	    LispObj *real;
    589 	    LispObj *imag;
    590 	} complex;
    591 	struct {
    592 	    LispObj *car;
    593 	    LispObj *cdr;
    594 	} cons;
    595 	struct {
    596 	    LispObj *name;
    597 	    LispObj *code;
    598 	    LispObj *data;		/* extra data to protect */
    599 	} lambda;
    600 	struct {
    601 	    LispObj *list;		/* stored as a linear list */
    602 	    LispObj *dim;		/* dimensions of array */
    603 	    unsigned int rank : 8;	/* i.e. array-rank-limit => 256 */
    604 	    unsigned int type : 7;	/* converted to LispType, if not
    605 					 * Lisp_Nil_t only accepts given
    606 					 * type in array fields */
    607 	    unsigned int zero : 1;	/* at least one of the dimensions
    608 					 * is zero */
    609 	} array;
    610 	struct {
    611 	    LispObj *fields;	/* structure fields */
    612 	    LispObj *def;	/* structure definition */
    613 	} struc;
    614 	struct {
    615 	    union {
    616 		LispFile *file;
    617 		LispPipe *program;
    618 		LispString *string;
    619 	    } source;
    620 	    LispObj *pathname;
    621 	    LispStreamType type : 6;
    622 	    unsigned int readable : 1;
    623 	    unsigned int writable : 1;
    624 	} stream;
    625 	struct {
    626 	    void *data;
    627 	    int type;
    628 	} opaque;
    629 	struct {
    630 	    LispObj *eval;
    631 	    int atlist;
    632 	} comma;
    633 	struct {
    634 	    LispObj *name;
    635 	    LispObj *nicknames;
    636 	    LispPackage *package;
    637 	} package;
    638 	struct {
    639 	    re_cod *regex;
    640 	    LispObj *pattern;		/* regex string */
    641 	    int options;		/* regex compile flags */
    642 	} regex;
    643 	struct {
    644 	    LispBytecode *bytecode;
    645 	    LispObj *code;		/* object used to generate bytecode */
    646 	    LispObj *name;		/* name of function, or NIL */
    647 	} bytecode;
    648 	struct {
    649 	    LispHashTable *table;
    650 	    LispObj *test;
    651 	} hash;
    652     } data;
    653 };
    654 #ifdef AIXV5
    655 #undef LispType
    656 #undef LispFunType
    657 #undef LispStreamType
    658 #endif
    659 
    660 typedef	LispObj *(*LispFunPtr)(LispBuiltin*);
    661 typedef void (*LispComPtr)(LispCom*, LispBuiltin*);
    662 
    663 struct _LispBuiltin {
    664     /* these fields must be set */
    665     LispFunType type;
    666     LispFunPtr function;
    667     const char *declaration;
    668 
    669     /* this field is optional, set if the function returns multiple values */
    670     int multiple_values;
    671 
    672     /* this field is also optional, set if the function should not be exported */
    673     int internal;
    674 
    675     /* this optional field points to a function of the bytecode compiler */
    676     LispComPtr compile;
    677 
    678     /* this field is set at runtime */
    679     LispObj *symbol;
    680 };
    681 
    682 typedef int (*LispLoadModule)(void);
    683 typedef int (*LispUnloadModule)(void);
    684 
    685 #define LISP_MODULE_VERSION		1
    686 struct _LispModuleData {
    687     int version;
    688     LispLoadModule load;
    689     LispUnloadModule unload;
    690 };
    691 
    692 /*
    693  * Prototypes
    694  */
    695 LispObj *LispEval(LispObj*);
    696 LispObj *LispFuncall(LispObj*, LispObj*, int);
    697 LispObj *LispApply1(LispObj*, LispObj*);
    698 LispObj *LispApply2(LispObj*, LispObj*, LispObj*);
    699 LispObj *LispApply3(LispObj*, LispObj*, LispObj*, LispObj*);
    700 
    701 LispObj *LispNew(LispObj*, LispObj*);
    702 LispObj *LispNewSymbol(LispAtom*);
    703 LispObj *LispNewAtom(const char*, int);
    704 LispObj *LispNewFunction(LispObj*);
    705 LispObj *LispNewFunctionQuote(LispObj*);
    706 LispObj *LispNewStaticAtom(const char*);
    707 LispObj *LispNewDFloat(double);
    708 LispObj *LispNewString(const char*, long);
    709 LispObj *LispNewStringAlloced(char*, long);
    710 LispObj *LispNewInteger(long);
    711 LispObj *LispNewRatio(long, long);
    712 LispObj *LispNewVector(LispObj*);
    713 LispObj *LispNewQuote(LispObj*);
    714 LispObj *LispNewBackquote(LispObj*);
    715 LispObj *LispNewComma(LispObj*, int);
    716 LispObj *LispNewCons(LispObj*, LispObj*);
    717 LispObj *LispNewLambda(LispObj*, LispObj*, LispObj*, LispFunType);
    718 LispObj *LispNewStruct(LispObj*, LispObj*);
    719 LispObj *LispNewComplex(LispObj*, LispObj*);
    720 LispObj *LispNewOpaque(void*, int);
    721 LispObj *LispNewKeyword(const char*);
    722 LispObj *LispNewPathname(LispObj*);
    723 LispObj *LispNewStringStream(const char*, int, long);
    724 LispObj *LispNewStringStreamAlloced(char*, int, long);
    725 LispObj *LispNewFileStream(LispFile*, LispObj*, int);
    726 LispObj *LispNewPipeStream(LispPipe*, LispObj*, int);
    727 LispObj *LispNewBignum(mpi*);
    728 LispObj *LispNewBigratio(mpr*);
    729 
    730 LispAtom *LispGetAtom(const char*);
    731 
    732 /* This function does not allocate a copy of it's argument, but the argument
    733  * itself. The argument string should never change. */
    734 LispAtom *LispGetPermAtom(const char*);
    735 
    736 void *LispMalloc(size_t);
    737 void *LispCalloc(size_t, size_t);
    738 void *LispRealloc(void*, size_t);
    739 char *LispStrdup(const char*);
    740 void LispFree(void*);
    741 /* LispMused means memory is now safe from LispDestroy, and should not be
    742  * freed in case of an error */
    743 void LispMused(void*);
    744 
    745 void LispGC(LispObj*, LispObj*);
    746 
    747 char *LispStrObj(LispObj*);
    748 
    749 #ifdef __GNUC__
    750 #define PRINTF_FORMAT	__attribute__ ((format (printf, 1, 2)))
    751 #else
    752 #define PRINTF_FORMAT	/**/
    753 #endif
    754 void LispDestroy(const char *fmt, ...) PRINTF_FORMAT;
    755 	/* continuable error */
    756 void LispContinuable(const char *fmt, ...) PRINTF_FORMAT;
    757 void LispMessage(const char *fmt, ...) PRINTF_FORMAT;
    758 void LispWarning(const char *fmt, ...) PRINTF_FORMAT;
    759 #undef PRINTF_FORMAT
    760 
    761 LispObj *LispSetVariable(LispObj*, LispObj*, const char*, int);
    762 
    763 int LispRegisterOpaqueType(const char*);
    764 
    765 void LispProtect(LispObj*, LispObj*);
    766 void LispUProtect(LispObj*, LispObj*);
    767 
    768 /* this function should be called when a module is loaded, and is called
    769  * when loading the interpreter */
    770 void LispAddBuiltinFunction(LispBuiltin*);
    771 
    772 /*
    773  * Initialization
    774  */
    775 extern LispObj *UNBOUND;
    776 extern int gcpro;
    777 
    778 extern LispObj *Okey, *Orest, *Ooptional, *Oaux, *Olambda;
    779 extern Atom_id Snil, St, Skey, Srest, Soptional, Saux;
    780 extern Atom_id Sand, Sor, Snot;
    781 extern Atom_id Satom, Ssymbol, Sinteger, Scharacter, Sstring, Slist,
    782 	       Scons, Svector, Sarray, Sstruct, Skeyword, Sfunction, Spathname,
    783 	       Srational, Sfloat, Scomplex, Sopaque, Sdefault;
    784 
    785 extern LispObj *Ocomplex, *Oformat, *Kunspecific;
    786 
    787 extern LispObj *Omake_array, *Kinitial_contents, *Osetf;
    788 extern Atom_id Svariable, Sstructure, Stype, Ssetf;
    789 
    790 extern Atom_id Smake_struct, Sstruct_access, Sstruct_store, Sstruct_type;
    791 extern LispObj *Omake_struct, *Ostruct_access, *Ostruct_store, *Ostruct_type;
    792 
    793 extern LispObj *Oparse_namestring, *Kerror, *Kabsolute, *Krelative, *Oopen,
    794 	       *Oclose, *Kif_does_not_exist;
    795 
    796 extern LispObj *Oequal_;
    797 
    798 extern LispFile *Stdout, *Stdin, *Stderr;
    799 
    800 #endif /* Lisp_internal_h */
    801