aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxutil/sxpr.h
blob: b90083139cf3c58d268c97f0a7e608e2c2032351 (plain)
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
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
/*
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the
 * License, or  (at your option) any later version. This library is 
 * distributed in the  hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */
#ifndef _XEN_LIB_SXPR_H_
#define _XEN_LIB_SXPR_H_

#include <stdint.h>

#include "hash_table.h"
#include "iostream.h"
#include "allocate.h"

/** @file
 * Definitions for rules and sxprs.
 */

#ifndef NULL
#define NULL 0
#endif

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

/** Sxpr type. */
typedef int16_t TypeCode;

/** A typed sxpr handle.*/
typedef struct Sxpr {
    /** Sxpr type. */
    TypeCode type;
    union {
	/** Sxpr value. */
        unsigned long ul;
	/** Pointer. */
        void *ptr;
    } v;
} Sxpr;

/** Sxpr type to indicate out of memory. */
#define T_NOMEM      ((TypeCode)-1)
/** The 'unspecified' sxpr. */
#define T_NONE       ((TypeCode)0)
/** The empty list. */
#define T_NULL       ((TypeCode)1)
/** Unsigned integer. */
#define T_UINT       ((TypeCode)2)
/** A string. */
#define T_STRING     ((TypeCode)3)
/** An atom. */
#define T_ATOM       ((TypeCode)4)
/** A boolean. */
#define T_BOOL       ((TypeCode)5)

/** A cons (pair or list). */
#define T_CONS       ((TypeCode)10)

/** An error. */
#define T_ERR        ((TypeCode)40)

/** An atom. */
typedef struct ObjAtom {
    Sxpr name;
    Hashcode hashcode;
    int interned;
} ObjAtom;

/** A cons (pair). */
typedef struct ObjCons {
    Sxpr car;
    Sxpr cdr;
} ObjCons;

/** A vector. */
typedef struct ObjVector {
    int n;
    Sxpr data[0];
} ObjVector;

/** Flags for sxpr printing. */
enum PrintFlags {
    PRINT_RAW           = 0x001,
    PRINT_TYPE          = 0x002,
    PRINT_PRETTY        = 0x004,
    PRINT_NUM           = 0x008,
};

/** An integer sxpr.
 *
 * @param ty type
 * @param val integer value
 */
#define OBJI(ty, val) (Sxpr){ type: (ty), v: { ul: (val) }}

/** A pointer sxpr.
 * If the pointer is non-null, returns an sxpr containing it.
 * If the pointer is null, returns ONOMEM.
 *
 * @param ty type
 * @param val pointer
 */
#define OBJP(ty, val) ((val) ? (Sxpr){ type: (ty), v: { ptr: (val) }} : ONOMEM)

/** Make an integer sxpr containing a pointer.
 *
 * @param val pointer
 */
#define PTR(val) OBJP(T_UINT, (void*)(val))

/** Make an integer sxpr.
 * @param x value
 */
#define OINT(x)       OBJI(T_UINT,  x)

/** Make an error sxpr.
 *
 * @param x value
 */
#define OERR(x)       OBJI(T_ERR,   x)

/** Out of memory constant. */
#define ONOMEM        OBJI(T_NOMEM, 0)

/** The `unspecified' constant. */
#define ONONE         OBJI(T_NONE,  0)

/** Empty list constant. */
#define ONULL         OBJI(T_NULL,  0)

/** False constant. */
#define OFALSE        OBJI(T_BOOL,  0)

/** True constant. */
#define OTRUE         OBJI(T_BOOL,  1)

/* Recognizers for the various sxpr types.  */
#define ATOMP(obj)        has_type(obj, T_ATOM)
#define BOOLP(obj)        has_type(obj, T_BOOL)
#define CONSP(obj)        has_type(obj, T_CONS)
#define ERRP(obj)         has_type(obj, T_ERR)
#define INTP(obj)         has_type(obj, T_UINT)
#define NOMEMP(obj)       has_type(obj, T_NOMEM)
#define NONEP(obj)        has_type(obj, T_NONE)
#define NULLP(obj)        has_type(obj, T_NULL)
#define STRINGP(obj)      has_type(obj, T_STRING)

#define TRUEP(obj)    get_ul(obj)

/** Convert an sxpr to an unsigned integer. */
#define OBJ_UINT(x)   get_ul(x)
/** Convert an sxpr to an integer. */
#define OBJ_INT(x)    (int)get_ul(x)

/* Conversions of sxprs to their values.
 * No checking is done.
 */
#define OBJ_STRING(x)  ((char*)get_ptr(x))
#define OBJ_CONS(x)    ((ObjCons*)get_ptr(x))
#define OBJ_ATOM(x)    ((ObjAtom*)get_ptr(x))
#define OBJ_SET(x)     ((ObjSet*)get_ptr(x))
#define CAR(x)         (OBJ_CONS(x)->car)
#define CDR(x)         (OBJ_CONS(x)->cdr)

#define CAAR(x)        (CAR(CAR(x)))
#define CADR(x)        (CAR(CDR(x)))
#define CDAR(x)        (CDR(CAR(x)))
#define CDDR(x)        (CDR(CDR(x)))

/** Get the integer value from an sxpr.
 *
 * @param obj sxpr
 * @return value
 */
static inline unsigned long get_ul(Sxpr obj){
    return obj.v.ul;
}

/** Get the pointer value from an sxpr.
 *
 * @param obj sxpr
 * @return value
 */
static inline void * get_ptr(Sxpr obj){
    return obj.v.ptr;
}

/** Create an sxpr containing a pointer.
 *
 * @param type typecode
 * @param val pointer
 * @return sxpr
 */
static inline Sxpr obj_ptr(TypeCode type, void *val){
    return (Sxpr){ type: type, v: { ptr: val } };
}

/** Create an sxpr containing an integer.
 *
 * @param type typecode
 * @param val integer
 * @return sxpr
 */
static inline Sxpr obj_ul(TypeCode type, unsigned long val){
    return (Sxpr){ type: type, v: { ul: val } };
}

/** Get the type of an sxpr.
 *
 * @param obj sxpr
 * @return type
 */
static inline TypeCode get_type(Sxpr obj){
    return obj.type;
}

/** Check the type of an sxpr.
 *
 * @param obj sxpr
 * @param type to check
 * @return 1 if has the type, 0 otherwise
 */
static inline int has_type(Sxpr obj, TypeCode type){
    return get_type(obj) == type;
}

/** Compare sxprs for literal equality of type and value.
 *
 * @param x sxpr to compare
 * @param y sxpr to compare
 * @return 1 if equal, 0 otherwise
 */
static inline int eq(Sxpr x, Sxpr y){
    return ((get_type(x) == get_type(y)) && (get_ul(x) == get_ul(y)));
}

/** Checked version of CAR
 *
 * @param x sxpr
 * @return CAR if a cons, x otherwise
 */
static inline Sxpr car(Sxpr x){
    return (CONSP(x) ? CAR(x) : x);
}

/** Checked version of CDR.
 *
 * @param x sxpr
 * @return CDR if a cons, null otherwise
 */
static inline Sxpr cdr(Sxpr x){
    return (CONSP(x) ? CDR(x) : ONULL);
}

/** Allocate some memory and return an sxpr containing it.
 * Returns ONOMEM if allocation failed.
 *
 * @param n number of bytes to allocate
 * @param ty typecode
 * @return sxpr
 */
static inline Sxpr halloc(size_t n,  TypeCode ty){
    return OBJP(ty, allocate(n));
}

/** Allocate an sxpr containing a pointer to the given type.
 *
 * @param ty type (uses sizeof to determine how many bytes to allocate)
 * @param code typecode
 * @return sxpr, ONOMEM if allocation failed
 */
#define HALLOC(ty, code) halloc(sizeof(ty), code)

typedef int ObjPrintFn(IOStream *io, Sxpr obj, unsigned flags);
typedef int ObjEqualFn(Sxpr obj, Sxpr other);
typedef void ObjFreeFn(Sxpr obj);

/** An sxpr type definition. */
typedef struct SxprType {
    TypeCode type;
    char *name;
    int pointer;
    ObjPrintFn *print;
    ObjEqualFn *equal;
    ObjFreeFn *free;
} SxprType;


extern SxprType *get_sxpr_type(int ty);

/** Free the pointer in an sxpr.
 *
 * @param x sxpr containing a pointer
 */
static inline void hfree(Sxpr x){
    deallocate(get_ptr(x));
}

extern int objprint(IOStream *io, Sxpr x, unsigned flags);
extern int objequal(Sxpr x, Sxpr y);
extern void objfree(Sxpr x);

extern void cons_free_cells(Sxpr obj);
extern Sxpr intern(char *s);

extern Sxpr assoc(Sxpr k, Sxpr l);
extern Sxpr assocq(Sxpr k, Sxpr l);
extern Sxpr acons(Sxpr k, Sxpr v, Sxpr l);
extern Sxpr nrev(Sxpr l);
extern Sxpr cons_member(Sxpr l, Sxpr x);
extern Sxpr cons_member_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
extern int cons_subset(Sxpr s, Sxpr t);
extern int cons_set_equal(Sxpr s, Sxpr t);

#ifdef USE_GC
extern Sxpr cons_remove(Sxpr l, Sxpr x);
extern Sxpr cons_remove_if(Sxpr l, ObjEqualFn *test_fn, Sxpr v);
#endif

extern Sxpr atom_new(char *name);
extern char * atom_name(Sxpr obj);

extern Sxpr string_new(char *s);
extern char * string_string(Sxpr obj);
extern int string_length(Sxpr obj);

extern Sxpr cons_new(Sxpr car, Sxpr cdr);
extern int cons_push(Sxpr *list, Sxpr elt);
extern int cons_length(Sxpr obj);

Sxpr sxpr_name(Sxpr obj);
int sxpr_is(Sxpr obj, char *s);
int sxpr_elementp(Sxpr obj, Sxpr name);
Sxpr sxpr_attributes(Sxpr obj);
Sxpr sxpr_attribute(Sxpr obj, Sxpr key, Sxpr def);
Sxpr sxpr_children(Sxpr obj);
Sxpr sxpr_child(Sxpr obj, Sxpr name, Sxpr def);
Sxpr sxpr_child0(Sxpr obj, Sxpr def);
Sxpr sxpr_child_value(Sxpr obj, Sxpr name, Sxpr def);

/** Create a new atom.
 *
 * @param s atom name
 * @return new atom
 */
static inline Sxpr mkatom(char *s){
    return atom_new(s);
}

/** Create a new string sxpr.
 *
 * @param s string bytes (copied)
 * @return new string
 */
static inline Sxpr mkstring(char *s){
    return string_new(s);
}

/** Create an integer sxpr.
 *
 * @param i value
 * @return sxpr
 */
static inline Sxpr mkint(int i){
    return OBJI(T_UINT, i);
}

/** Create a boolean sxpr.
 *
 * @param b value
 * @return sxpr
 */
static inline Sxpr mkbool(int b){
    return OBJI(T_BOOL, (b ? 1 : 0));
}

/* Constants used in parsing and printing. */
#define k_list_open    "("
#define c_list_open    '('
#define k_list_close   ")"
#define c_list_close   ')'
#define k_true         "true"
#define k_false        "false"

#define c_var          '$'
#define c_escape       '\\'
#define c_single_quote '\''
#define c_double_quote '"'
#define c_string_open  c_double_quote
#define c_string_close c_double_quote
#define c_data_open    '['
#define c_data_close   ']'
#define c_binary       '*'
#define c_eval         '!'
#define c_concat_open  '{'
#define c_concat_close '}'

#endif /* ! _XEN_LIB_SXPR_H_ */