Baremetal Lisp interpreter and compiler for low-resource devices
修订版 | 04a05b78b3b72e9e218e1c621b0f695e7365dd55 (tree) |
---|---|
时间 | 2020-09-13 06:39:50 |
作者 | AlaskanEmily <emily@alas...> |
Commiter | AlaskanEmily |
Add pointers and protocols to the S-expression library
@@ -4,7 +4,7 @@ | ||
4 | 4 | # Unix makefile. |
5 | 5 | |
6 | 6 | CC=cc |
7 | -CFLAGS=-g -Wall -Wextra -pedantic -Werror -ansi -Wshadow -Wno-old-style-declaration -Wno-unknown-warning-option | |
7 | +CFLAGS=-g -Wall -Wextra -pedantic -Werror -ansi -Wshadow -Wno-old-style-declaration -Wno-unknown-warning-option -DSL_S_ENABLE_POINTERS -DSL_S_ENABLE_PROTOCOLS | |
8 | 8 | COMPILEFLAG=-c |
9 | 9 | COUT=-o |
10 | 10 |
@@ -78,19 +78,26 @@ extern "C"{ | ||
78 | 78 | * If SL_S_DO_NOT_STRIP_BITS is set, then the tag bits will not be stripped |
79 | 79 | * from the pointers on unpacking. This is useful for hardware with mirrored |
80 | 80 | * RAM, although it is likely not useful when SL_S_TAG_LSB is set. |
81 | + * | |
82 | + * Note that the settings for SL_S_ENABLE_PROTOCOLS and SL_S_ENABLE_POINTERS | |
83 | + * will affect the defaults as well. | |
81 | 84 | */ |
82 | 85 | /*****************************************************************************/ |
83 | 86 | |
84 | 87 | #if !((defined SL_S_TAG_LSB) || (defined SL_S_TAG_MSB)) |
85 | -#define SL_S_TAG_LSB | |
88 | +# define SL_S_TAG_LSB | |
86 | 89 | #elif (defined SL_S_TAG_LSB) && (defined SL_S_TAG_MSB) |
87 | -#error Invalid configuration: both SL_S_TAG_LSB and SL_S_TAG_MSB are set. | |
90 | +# error Invalid configuration: both SL_S_TAG_LSB and SL_S_TAG_MSB are set. | |
88 | 91 | #endif |
89 | 92 | |
90 | 93 | #ifndef SL_S_NUM_TAG_BITS |
91 | -#define SL_S_NUM_TAG_BITS 1 | |
94 | +# if (defined SL_S_ENABLE_PROTOCOLS) || (defined SL_D_ENABLE_POINTERS) | |
95 | +# define SL_S_NUM_TAG_BITS 2 | |
96 | +# else | |
97 | +# define SL_S_NUM_TAG_BITS 1 | |
98 | +# endif | |
92 | 99 | #elif SL_S_NUM_TAG_BITS < 1 |
93 | -#error Invalid configuration: SL_S_TAG_BITS must be greater than zero. | |
100 | +# error Invalid configuration: SL_S_TAG_BITS must be greater than zero. | |
94 | 101 | #endif |
95 | 102 | |
96 | 103 | /*****************************************************************************/ |
@@ -100,6 +107,15 @@ extern "C"{ | ||
100 | 107 | #define SL_S_LIST_TAG 0 |
101 | 108 | #define SL_S_ATOM_TAG 1 |
102 | 109 | |
110 | +#ifdef SL_S_ENABLE_PROTOCOLS | |
111 | +# define SL_S_PROTOCOL_TAG 2 | |
112 | +# define SL_S_PROTO_TAG SL_S_PROTOCOL_TAG | |
113 | +#endif | |
114 | + | |
115 | +#ifdef SL_S_ENABLE_POINTERS | |
116 | +# define SL_S_POINTER_TAG 3 | |
117 | +#endif | |
118 | + | |
103 | 119 | #define SL_S_PTR_BITS (sizeof(void*)<<3) |
104 | 120 | |
105 | 121 | #ifdef SL_S_TAG_LSB |
@@ -150,11 +166,37 @@ extern "C"{ | ||
150 | 166 | #define SL_S_IS_LIST(X) (SL_S_PTR_TAG((X), SL_S_NUM_TAG_BITS) == SL_S_LIST_TAG) |
151 | 167 | #define SL_S_IS_ATOM(X) (SL_S_PTR_TAG((X), SL_S_NUM_TAG_BITS) == SL_S_ATOM_TAG) |
152 | 168 | |
169 | +#ifdef SL_S_ENABLE_PROTOCOLS | |
170 | +# define SL_S_IS_PROTOCOL(X) \ | |
171 | + (SL_S_PTR_TAG((X), SL_S_NUM_TAG_BITS) == SL_S_PROTOCOL_TAG) | |
172 | +# define SL_S_IS_PROTO SL_S_IS_PROTOCOL | |
173 | +#endif | |
174 | + | |
175 | +#ifdef SL_S_ENABLE_POINTERS | |
176 | +# define SL_S_IS_POINTER(X) \ | |
177 | + (SL_S_PTR_TAG((X), SL_S_NUM_TAG_BITS) == SL_S_POINTER_TAG) | |
178 | +# define SL_S_IS_PTR SL_S_IS_POINTER | |
179 | +#endif | |
180 | + | |
153 | 181 | #define SL_S_MK_LIST(X) SL_S_TAG_PTR((X), SL_S_LIST_TAG) |
154 | 182 | #define SL_S_MK_ATOM(X) (SL_S_IS_NIL((X)) ? \ |
155 | 183 | SL_S_NIL : \ |
156 | 184 | SL_S_TAG_PTR((X), SL_S_ATOM_TAG)) |
157 | 185 | |
186 | +#ifdef SL_S_ENABLE_PROTOCOLS | |
187 | +# define SL_S_MK_PROTOCOL(X) (SL_S_IS_NIL(X) ? \ | |
188 | + SL_S_NIL : \ | |
189 | + SL_S_TAG_PTR((X), SL_S_PROTOCOL_TAG)) | |
190 | +# define SL_S_MK_PROTO SL_S_MK_PROTOCOL | |
191 | +#endif | |
192 | + | |
193 | +#ifdef SL_S_ENABLE_POINTERS | |
194 | +# define SL_S_MK_POINTER(X) (SL_S_IS_NIL(X) ? \ | |
195 | + SL_S_NIL : \ | |
196 | + SL_S_TAG_PTR((X), SL_S_POINTER_TAG)) | |
197 | +# define SL_S_MK_PTR SL_S_MK_POINTER | |
198 | +#endif | |
199 | + | |
158 | 200 | /*****************************************************************************/ |
159 | 201 | /* Len/Refcount typedefs */ |
160 | 202 |
@@ -261,6 +303,51 @@ struct SL_S_List{ | ||
261 | 303 | }; |
262 | 304 | |
263 | 305 | /*****************************************************************************/ |
306 | + | |
307 | +#ifdef SL_S_ENABLE_PROTOCOLS | |
308 | + | |
309 | +/*****************************************************************************/ | |
310 | +/** Represents an protocol object. */ | |
311 | +struct SL_S_Protocol{ | |
312 | + sl_s_ref_t ref; | |
313 | +#ifndef SL_S_NO_PARSER_INFO | |
314 | + sl_s_len_t line; | |
315 | +#endif | |
316 | + SL_S_FUNC_PTR(void, destroy)(struct SL_S_Protocol *that); | |
317 | +}; | |
318 | + | |
319 | +/*****************************************************************************/ | |
320 | + | |
321 | +#endif | |
322 | + | |
323 | +/*****************************************************************************/ | |
324 | + | |
325 | +#ifdef SL_S_ENABLE_POINTERS | |
326 | + | |
327 | +/*****************************************************************************/ | |
328 | +/** Holds a boxed pointer. | |
329 | + * | |
330 | + * Sadly, for use in Sapphire Lisp, all pointers must be boxed to work properly | |
331 | + * with tag bits. | |
332 | + * | |
333 | + * NULL (in C) can still be represented as an unboxed NIL, and SL_S_MK_PTR will | |
334 | + * actually cause this to happen when possible. | |
335 | + * | |
336 | + * The ref-count only applies to the pointer's box. | |
337 | + */ | |
338 | +struct SL_S_Pointer{ | |
339 | + sl_s_ref_t ref; | |
340 | +#ifndef SL_S_NO_PARSER_INFO | |
341 | + sl_s_len_t line; | |
342 | +#endif | |
343 | + void *data; | |
344 | +}; | |
345 | + | |
346 | +/*****************************************************************************/ | |
347 | + | |
348 | +#endif | |
349 | + | |
350 | +/*****************************************************************************/ | |
264 | 351 | /** Shared struct to allow access to refcount without conditional casts */ |
265 | 352 | struct SL_S_Ref{ |
266 | 353 | sl_s_ref_t ref; |