internal.h revision f14f4646
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 */
47typedef 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), 0)
82#define LSTRING(str, size)	LispNewString(str, size, 0)
83
84	/* string must be from the LispXXX allocation functions,
85	 * and LispMused not yet called on it */
86#define STRING2(str)		LispNewString(str, strlen(str), 1)
87#define LSTRING2(str, size)	LispNewString(str, size, 1)
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), 0)
96#define STRINGSTREAM2(str, flag)		\
97	LispNewStringStream(str, flag, strlen(str), 1)
98#define LSTRINGSTREAM(str, flag, length)	\
99	LispNewStringStream(str, flag, length, 0)
100#define LSTRINGSTREAM2(str, flag, length)	\
101	LispNewStringStream(str, flag, length, 1)
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 */
481typedef struct _LispObj LispObj;
482typedef struct _LispAtom LispAtom;
483typedef struct _LispBuiltin LispBuiltin;
484typedef struct _LispModuleData LispModuleData;
485typedef struct _LispFile LispFile;
486typedef struct _LispString LispString;
487typedef struct _LispPackage LispPackage;
488typedef struct _LispBytecode LispBytecode;
489typedef struct _LispHashTable LispHashTable;
490
491/* Bytecode compiler data */
492typedef struct _LispCom LispCom;
493
494typedef hash_key *Atom_id;
495
496typedef 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
534typedef enum _LispFunType {
535    LispLambda,
536    LispFunction,
537    LispMacro,
538    LispSetf
539} LispFunType;
540
541typedef enum _LispStreamType {
542    LispStreamString,
543    LispStreamFile,
544    LispStreamStandard,
545    LispStreamPipe
546} LispStreamType;
547
548typedef 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
562struct _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
660typedef	LispObj *(*LispFunPtr)(LispBuiltin*);
661typedef void (*LispComPtr)(LispCom*, LispBuiltin*);
662
663struct _LispBuiltin {
664    /* these fields must be set */
665    LispFunType type;
666    LispFunPtr function;
667    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
682typedef int (*LispLoadModule)(void);
683typedef int (*LispUnloadModule)(void);
684
685#define LISP_MODULE_VERSION		1
686struct _LispModuleData {
687    int version;
688    LispLoadModule load;
689    LispUnloadModule unload;
690};
691
692/*
693 * Prototypes
694 */
695LispObj *LispEval(LispObj*);
696LispObj *LispFuncall(LispObj*, LispObj*, int);
697LispObj *LispApply1(LispObj*, LispObj*);
698LispObj *LispApply2(LispObj*, LispObj*, LispObj*);
699LispObj *LispApply3(LispObj*, LispObj*, LispObj*, LispObj*);
700
701LispObj *LispNew(LispObj*, LispObj*);
702LispObj *LispNewSymbol(LispAtom*);
703LispObj *LispNewAtom(char*, int);
704LispObj *LispNewFunction(LispObj*);
705LispObj *LispNewFunctionQuote(LispObj*);
706LispObj *LispNewStaticAtom(char*);
707LispObj *LispNewDFloat(double);
708LispObj *LispNewString(char*, long, int);
709LispObj *LispNewInteger(long);
710LispObj *LispNewRatio(long, long);
711LispObj *LispNewVector(LispObj*);
712LispObj *LispNewQuote(LispObj*);
713LispObj *LispNewBackquote(LispObj*);
714LispObj *LispNewComma(LispObj*, int);
715LispObj *LispNewCons(LispObj*, LispObj*);
716LispObj *LispNewLambda(LispObj*, LispObj*, LispObj*, LispFunType);
717LispObj *LispNewStruct(LispObj*, LispObj*);
718LispObj *LispNewComplex(LispObj*, LispObj*);
719LispObj *LispNewOpaque(void*, int);
720LispObj *LispNewKeyword(char*);
721LispObj *LispNewPathname(LispObj*);
722LispObj *LispNewStringStream(char*, int, long, int);
723LispObj *LispNewFileStream(LispFile*, LispObj*, int);
724LispObj *LispNewPipeStream(LispPipe*, LispObj*, int);
725LispObj *LispNewBignum(mpi*);
726LispObj *LispNewBigratio(mpr*);
727
728LispAtom *LispGetAtom(char*);
729
730/* This function does not allocate a copy of it's argument, but the argument
731 * itself. The argument string should never change. */
732LispAtom *LispGetPermAtom(char*);
733
734void *LispMalloc(size_t);
735void *LispCalloc(size_t, size_t);
736void *LispRealloc(void*, size_t);
737char *LispStrdup(char*);
738void LispFree(void*);
739/* LispMused means memory is now safe from LispDestroy, and should not be
740 * freed in case of an error */
741void LispMused(void*);
742
743void LispGC(LispObj*, LispObj*);
744
745char *LispStrObj(LispObj*);
746
747#ifdef __GNUC__
748#define PRINTF_FORMAT	__attribute__ ((format (printf, 1, 2)))
749#else
750#define PRINTF_FORMAT	/**/
751#endif
752void LispDestroy(char *fmt, ...) PRINTF_FORMAT;
753	/* continuable error */
754void LispContinuable(char *fmt, ...) PRINTF_FORMAT;
755void LispMessage(char *fmt, ...) PRINTF_FORMAT;
756void LispWarning(char *fmt, ...) PRINTF_FORMAT;
757#undef PRINTF_FORMAT
758
759LispObj *LispSetVariable(LispObj*, LispObj*, char*, int);
760
761int LispRegisterOpaqueType(char*);
762
763int LispPrintString(LispObj*, char*);
764
765void LispProtect(LispObj*, LispObj*);
766void LispUProtect(LispObj*, LispObj*);
767
768/* this function should be called when a module is loaded, and is called
769 * when loading the interpreter */
770void LispAddBuiltinFunction(LispBuiltin*);
771
772/*
773 * Initialization
774 */
775extern LispObj *UNBOUND;
776extern int gcpro;
777
778extern LispObj *Okey, *Orest, *Ooptional, *Oaux, *Olambda;
779extern Atom_id Snil, St, Skey, Srest, Soptional, Saux;
780extern Atom_id Sand, Sor, Snot;
781extern Atom_id Satom, Ssymbol, Sinteger, Scharacter, Sstring, Slist,
782	       Scons, Svector, Sarray, Sstruct, Skeyword, Sfunction, Spathname,
783	       Srational, Sfloat, Scomplex, Sopaque, Sdefault;
784
785extern LispObj *Ocomplex, *Oformat, *Kunspecific;
786
787extern LispObj *Omake_array, *Kinitial_contents, *Osetf;
788extern Atom_id Svariable, Sstructure, Stype, Ssetf;
789
790extern Atom_id Smake_struct, Sstruct_access, Sstruct_store, Sstruct_type;
791extern LispObj *Omake_struct, *Ostruct_access, *Ostruct_store, *Ostruct_type;
792
793extern LispObj *Oparse_namestring, *Kerror, *Kabsolute, *Krelative, *Oopen,
794	       *Oclose, *Kif_does_not_exist;
795
796extern LispObj *Oequal_;
797
798extern LispFile *Stdout, *Stdin, *Stderr;
799
800#endif /* Lisp_internal_h */
801