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 César 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) << 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