File: object.h

package info (click to toggle)
elk 3.0-8.1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 4,088 kB
  • ctags: 3,115
  • sloc: ansic: 20,686; lisp: 5,232; makefile: 411; awk: 91; sh: 19
file content (328 lines) | stat: -rw-r--r-- 8,630 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
/* The Scheme object representation, and a few other important
 * data types.
 */

typedef struct {
    unsigned long data;
    int tag;
} Object;

#define FIXBITS         (8 * sizeof(int))
#define SIGNBIT         ((unsigned)1 << (FIXBITS-1))
#define CONSTBIT        1
#define TYPEBITS        (8 * sizeof(int) - 1)
#define MAX_TYPE        ((1 << TYPEBITS) - 1)

#define UFIXNUM_FITS(i) (((i) & SIGNBIT) == 0)
#define FIXNUM_FITS(i)  1

#define TYPE(x)         ((x).tag >> 1)

#define FIXNUM(x)       ((int)(x).data)
#define CHAR(x)         ((int)(x).data)

#define POINTER(x)      ((x).data)
#define SETPOINTER(x,p) ((x).data = (unsigned long)(p))
#define SET(x,t,p)      ((x).tag = (int)t << 1, (x).data = (unsigned long)(p))

#define ISCONST(x)      ((x).tag & CONSTBIT)
#define SETCONST(x)     ((x).tag |= CONSTBIT)

#define EQ(x,y)         ((x).data == (y).data && (x).tag == (y).tag)

/* GC related macros:
 */
#define WAS_FORWARDED(obj) (TYPE(*(Object *)POINTER(obj)) == T_Broken_Heart)
#define UPDATE_OBJ(obj)    SETPOINTER(obj, POINTER(*(Object *)POINTER(obj)))

#ifdef GENERATIONAL_GC

   typedef int  gcspace_t;            /* type used for space and type arrays */
   typedef unsigned long gcptr_t;     /* type used for pointers */
   typedef unsigned long pageno_t;    /* type used for page numbers */
   typedef unsigned long addrarith_t; /* type used for address arithmetic */

   extern gcspace_t *space;
   extern gcspace_t current_space;
   C_LINKAGE_BEGIN
   extern Visit P_((Object*));       /* required for REVIVE_OBJ below */
   C_LINKAGE_END

#  ifdef ARRAY_BROKEN
   extern pageno_t pagebase;
#  else
#  define pagebase ((pageno_t)0)
#  endif

#  define PAGEBYTES        512
#  define PAGE_TO_OBJ(p)   ((Object *) (((p) + pagebase) * PAGEBYTES))
#  define OBJ_TO_PAGE(p)   ((((gcptr_t)POINTER(p)) / PAGEBYTES) - pagebase)
#  define STABLE(x)        ((~space[(x)]) & 1)
#  define MAKEOBJ(o,t,p)   (SET(o, t, p))
#  define IS_ALIVE(obj)    ((WAS_FORWARDED(obj)) || \
                            (STABLE(OBJ_TO_PAGE(obj))) || \
			    (space[OBJ_TO_PAGE(obj)] == current_space))
#  define REVIVE_OBJ(obj)  Visit (&obj);
#else
#  define IS_ALIVE(obj)    WAS_FORWARDED(obj)
#  define REVIVE_OBJ(obj)
#endif

/* Fixed types.  Cannot use enum, because the set of types is extensible:
 */
#define T_Fixnum          0      /* Must be 0 */
#define T_Bignum          1
#define T_Flonum          2
#define T_Null            3      /* empty list */
#define T_Boolean         4      /* #t (1) and #f (0) */
#define T_Unbound         5      /* only used internally */
#define T_Special         6      /* only used internally */
#define T_Character       7
#define T_Symbol          8
#define T_Pair            9
#define T_Environment    10      /* A pair */
#define T_String         11
#define T_Vector         12
#define T_Primitive      13      /* Primitive procedure */
#define T_Compound       14      /* Compound procedure */
#define T_Control_Point  15
#define T_Promise        16      /* Result of (delay expression) */
#define T_Port           17
#define T_End_Of_File    18
#define T_Autoload       19
#define T_Macro          20
#define T_Broken_Heart   21      /* only used internally */
#ifdef GENERATIONAL_GC
#  define T_Align_8Byte  22      /* only used internally */
#  define T_Freespace    23      /* only used internally */
#endif

#define BIGNUM(x)   ((struct S_Bignum *)POINTER(x))
#define FLONUM(x)   ((struct S_Flonum *)POINTER(x))
#define STRING(x)   ((struct S_String *)POINTER(x))
#define VECTOR(x)   ((struct S_Vector *)POINTER(x))
#define SYMBOL(x)   ((struct S_Symbol *)POINTER(x))
#define PAIR(x)     ((struct S_Pair *)POINTER(x))
#define PRIM(x)     ((struct S_Primitive *)POINTER(x))
#define COMPOUND(x) ((struct S_Compound *)POINTER(x))
#define CONTROL(x)  ((struct S_Control *)POINTER(x))
#define PROMISE(x)  ((struct S_Promise *)POINTER(x))
#define PORT(x)     ((struct S_Port *)POINTER(x))
#define AUTOLOAD(x) ((struct S_Autoload *)POINTER(x))
#define MACRO(x)    ((struct S_Macro *)POINTER(x))

typedef unsigned short gran_t;	/* Granularity of bignums */

struct S_Bignum {
    Object minusp;
    unsigned size;		/* Number of ushorts allocated */
    unsigned usize;		/* Number of ushorts actually used */
    gran_t data[1];		/* Data, lsw first */
};

struct S_Flonum {
    Object tag;               /* Each S_Foo must start with an Object */
    double val;
};

struct S_Symbol {
    Object value;
    Object next;
    Object name;               /* A string */
    Object plist;
};

struct S_Pair {
    Object car, cdr;
};

struct S_String {
    Object tag;
    int size;
    char data[1];
};

struct S_Vector {
    Object tag;
    int size;
    Object data[1];
};

enum discipline { EVAL, NOEVAL, VARARGS };
struct S_Primitive {
    Object tag;
    Object (*fun) P_((ELLIPSIS));
    const char *name;
    int minargs;
    int maxargs;    /* Or MANY */
    enum discipline disc;
};
#define MANY    100

struct S_Compound {
    Object closure;     /* (lambda (args) form ...) */
    Object env;         /* Procedure's environment */
    int min_args, max_args;
    int numforms;
    Object name;
};

typedef struct wind {
    struct wind *next, *prev;
    Object inout;                  /* Pair of thunks */
} WIND;

typedef struct funct {
    struct funct *next;
    char *name;
    void (*func) P_((void));
} FUNCT;

typedef struct gcnode {
    struct gcnode *next;
    int gclen;
    Object *gcobj;
} GCNODE;

typedef struct mem_node {
    struct mem_node *next;
    unsigned len;
    unsigned long refcnt;
} MEM_NODE;

#if defined(vax) || defined(__vax__)
   typedef int jmp_buf[17];
#else
#  include <setjmp.h>
#endif

struct S_Control {
    Object env;
    GCNODE *gclist;
    MEM_NODE *memlist;
    Object memsave;             /* string */
    Object gcsave;              /* vector */
    WIND *firstwind, *lastwind;
    int tailcall;
    unsigned delta;
#ifdef GENERATIONAL_GC
    int reloc;
#endif
    jmp_buf j;
    int size;
    unsigned long intrlevel;
    char stack[1];    /* must be word aligned */
};

struct S_Promise {
    Object env;
    Object thunk;
    int done;
};

struct S_Port {
    Object name;    /* string */
    short flags;
    char unread;
    int ptr;
    FILE *file;
    unsigned lno;
    int (*closefun) P_((FILE*));
};
#define P_OPEN    1 /* flags */
#define P_INPUT   2
#define P_STRING  4
#define P_UNREAD  8
#define P_BIDIR  16

#define IS_INPUT(port)   (PORT(port)->flags & (P_INPUT|P_BIDIR))
#define IS_OUTPUT(port) ((PORT(port)->flags & (P_INPUT|P_BIDIR)) != P_INPUT)

struct S_Autoload {
    Object files;
    Object env;
};

struct S_Macro {
    Object body;
    int min_args, max_args;
    Object name;
};


/* "size" is called with one object and returns the size of the object.
 *    If "size" is NOFUNC, then "const_size" is taken instead.
 * "eqv" and "equal" are called with two objects and return 0 or 1.
 *    NOFUNC may be passed instead (then eqv and equal always return #f).
 * "print" is called with an object, a port, a flag indicating whether
 *    the object is to be printed "raw" (a la display), the print-depth,
 *    and the print-length.
 * "visit" is called with a pointer to an object and a function.
 *    For each component of the object, the function must be called with
 *    a pointer to the component.  NOFUNC may be supplied.
 */
typedef struct {
    int haspointer;
    const char *name;
    int (*size) P_((Object));
    int const_size;
    int (*eqv) P_((Object, Object));
    int (*equal) P_((Object, Object));
    int (*print) P_((Object, Object, int, int, int));
    int (*visit) P_((Object*, int (*)(Object*)));
} TYPEDESCR;

#ifdef ELK_USE_PROTOTYPES
#  define NOFUNC 0
#else
#  define NOFUNC ((int (*)())0)
#endif


typedef struct sym {
    struct sym *next;
    char *name;
    unsigned long value;
} SYM;

typedef struct {
    SYM *first;
    char *strings;
} SYMTAB;

typedef struct {
    char *name;
    int type;
} SYMPREFIX;

#define PR_EXTENSION     0   /* Elk extension initializers/finalizers */
#define PR_CONSTRUCTOR   1   /* C++ static constructors/destructors */


/* PFO, GENERIC, and MATCHFUN exist for backwards compatibility
 */
typedef Object (*PFO) P_((Object));
typedef int (*MATCHFUN) P_((ELLIPSIS));
#define GENERIC char*

typedef struct weak_node {
    struct weak_node *next;
    Object obj;
    PFO term;
    GENERIC group;
    char flags;
} WEAK_NODE;

/* flags */
#define WK_LEADER 1


typedef struct {
    char *name;
    unsigned long val;
} SYMDESCR;


/* Function that can be registered as a reader by Define_Reader():
 */
typedef Object (*READFUN) P_((Object, int, int));