1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
16 #ifndef SQUIRRELJME_TOKENUTILS_H
17 #define SQUIRRELJME_TOKENUTILS_H
19 #include "sjme/config.h"
20 #include "sjme/stdTypes.h"
24 #ifndef SJME_CXX_IS_EXTERNED
25 #define SJME_CXX_IS_EXTERNED
26 #define SJME_CXX_SQUIRRELJME_TOKENUTILS_H
29 #endif /* #ifdef SJME_CXX_IS_EXTERNED */
30 #endif /* #ifdef __cplusplus */
32 /*--------------------------------------------------------------------------*/
35 * Pastes two tokens together.
37 * @param a The first token.
38 * @param b The second token.
41 #define SJME_TOKEN_PASTE(a, b) a##b
44 * Pasting two tokens but with preprocessing.
46 * @param a The first token.
47 * @param b The second token.
50 #define SJME_TOKEN_PASTE_PP(a, b) SJME_TOKEN_PASTE(a, b)
53 * Pastes three tokens together.
55 * @param a The first token.
56 * @param b The second token.
57 * @param c The third token.
60 #define SJME_TOKEN_PASTE3(a, b, c) a##b##c
63 * Pasting three tokens but with preprocessing.
65 * @param a The first token.
66 * @param b The second token.
67 * @param c The third token.
70 #define SJME_TOKEN_PASTE3_PP(a, b, c) SJME_TOKEN_PASTE3(a, b, c)
73 * Pastes four tokens together.
75 * @param a The first token.
76 * @param b The second token.
77 * @param c The third token.
78 * @param d The fourth token.
81 #define SJME_TOKEN_PASTE4(a, b, c, d) a##b##c##d
84 * Pasting four tokens but with preprocessing.
86 * @param a The first token.
87 * @param b The second token.
88 * @param c The third token.
89 * @param d The fourth token.
92 #define SJME_TOKEN_PASTE4_PP(a, b, c, d) SJME_TOKEN_PASTE4(a, b, c, d)
95 * Pastes five tokens together.
97 * @param a The first token.
98 * @param b The second token.
99 * @param c The third token.
100 * @param d The fourth token.
101 * @param e The fifth token.
104 #define SJME_TOKEN_PASTE5(a, b, c, d, e) a##b##c##d##e
107 * Pasting five tokens but with preprocessing.
109 * @param a The first token.
110 * @param b The second token.
111 * @param c The third token.
112 * @param d The fourth token.
113 * @param e The fifth token.
116 #define SJME_TOKEN_PASTE5_PP(a, b, c, d, e) SJME_TOKEN_PASTE5(a, b, c, d, e)
119 * Pastes six tokens together.
121 * @param a The first token.
122 * @param b The second token.
123 * @param c The third token.
124 * @param d The fourth token.
125 * @param e The fifth token.
126 * @param f The sixth token.
129 #define SJME_TOKEN_PASTE6(a, b, c, d, e, f) a##b##c##d##e##f
132 * Pasting six tokens but with preprocessing.
134 * @param a The first token.
135 * @param b The second token.
136 * @param c The third token.
137 * @param d The fourth token.
138 * @param e The fifth token.
139 * @param f The sixth token.
142 #define SJME_TOKEN_PASTE6_PP(a, b, c, d, e, f) \
143 SJME_TOKEN_PASTE6(a, b, c, d, e, f)
146 * Stringifies the given token.
148 * @param s The token to stringify.
151 #define SJME_TOKEN_STRING(s) #s
154 * Stringifies the given token.
156 * @param s The token to stringify.
159 #define SJME_TOKEN_STRING_PP(s) SJME_TOKEN_STRING(s)
162 * Represents a single token.
164 * @param t The token to resolve.
167 #define SJME_TOKEN_SINGLE(t) t
169 #define SJME_TOKEN_STARS_0
170 #define SJME_TOKEN_STARS_1 *
171 #define SJME_TOKEN_STARS_2 **
172 #define SJME_TOKEN_STARS_3 ***
173 #define SJME_TOKEN_STARS_4 ****
174 #define SJME_TOKEN_STARS_5 *****
175 #define SJME_TOKEN_STARS_6 ******
176 #define SJME_TOKEN_STARS_7 *******
177 #define SJME_TOKEN_STARS_8 ********
178 #define SJME_TOKEN_STARS_9 *********
180 #define SJME_TOKEN_STARS_C0
181 #define SJME_TOKEN_STARS_C1 P
182 #define SJME_TOKEN_STARS_C2 PP
183 #define SJME_TOKEN_STARS_C3 PPP
184 #define SJME_TOKEN_STARS_C4 PPPP
185 #define SJME_TOKEN_STARS_C5 PPPPP
186 #define SJME_TOKEN_STARS_C6 PPPPPP
187 #define SJME_TOKEN_STARS_C7 PPPPPPP
188 #define SJME_TOKEN_STARS_C8 PPPPPPPP
189 #define SJME_TOKEN_STARS_C9 PPPPPPPPP
191 #define SJME_TOKEN_STARS_H0 0
192 #define SJME_TOKEN_STARS_H1 1
193 #define SJME_TOKEN_STARS_H2 1
194 #define SJME_TOKEN_STARS_H3 1
195 #define SJME_TOKEN_STARS_H4 1
196 #define SJME_TOKEN_STARS_H5 1
197 #define SJME_TOKEN_STARS_H6 1
198 #define SJME_TOKEN_STARS_H7 1
199 #define SJME_TOKEN_STARS_H8 1
200 #define SJME_TOKEN_STARS_H9 1
203 * Generic pointer star types.
205 * @param type The type used.
206 * @param numPointerStars The number of pointer stars.
209 #define SJME_TOKEN_TYPE(type, numPointerStars) \
210 type SJME_TOKEN_SINGLE(SJME_TOKEN_STARS_##numPointerStars)
217 #define SJME_TOKEN_SEMI ;
220 * Does this have pointer stars?
222 * @param numPointerStars The number of pointer stars.
225 #define SJME_TOKEN_HAS_STARS(numPointerStars) \
226 SJME_TOKEN_SINGLE(SJME_TOKEN_STARS_H##numPointerStars)
228 /** SquirrelJME version string. */
229 #define SQUIRRELJME_VERSION SJME_TOKEN_STRING_PP(SQUIRRELJME_VERSION_TRIM)
231 /** Description of NanoCoat. */
232 #define SQUIRRELJME_VERSION_NANOCOAT \
233 "Stack caching interpreter"
236 * Calculates the size of a struct member.
238 * @param type The type of the struct.
239 * @param member The member to check.
240 * @return The size of the given member.
243 #define SJME_SIZEOF_STRUCT_MEMBER(type, member) \
244 (sizeof((*((type*)0)).member))
247 * Returns the basic type ID of the given type.
249 * @param type The type to get the basic type of.
252 #define SJME_TYPEOF_BASIC(type) SJME_TOKEN_PASTE_PP(SJME_TYPEOF_BASIC_, type)
255 * Returns the java type ID of the given type.
257 * @param type The type to get the basic type of.
260 #define SJME_TYPEOF_JAVA(type) SJME_TOKEN_PASTE_PP(SJME_TYPEOF_JAVA_, type)
262 #define SJME_TYPEOF_IS_POINTER_X00 0
263 #define SJME_TYPEOF_IS_POINTER_X10 1
264 #define SJME_TYPEOF_IS_POINTER_X01 1
265 #define SJME_TYPEOF_IS_POINTER_X11 1
268 * Is the given type a pointer?
270 * @param type The type used.
271 * @param numPointerStars The number of pointer stars.
272 * @return If this is a pointer or not.
275 #define SJME_TYPEOF_IS_POINTER(type, numPointerStars) \
276 SJME_TOKEN_SINGLE(SJME_TOKEN_PASTE3_PP(SJME_TYPEOF_IS_POINTER_X, \
277 SJME_TOKEN_PASTE_PP(SJME_TYPEOF_IS_POINTER_, type), \
278 SJME_TOKEN_PASTE_PP(SJME_TOKEN_STARS_H, numPointerStars)))
280 #define SJME_TYPEOF_IS_NOT_POINTER_X0 1
281 #define SJME_TYPEOF_IS_NOT_POINTER_X1 0
284 * Is the given type not a pointer?
286 * @param type The type used.
287 * @param numPointerStars The number of pointer stars.
288 * @return If this is not a pointer or it is one.
291 #define SJME_TYPEOF_IS_NOT_POINTER(type, numPointerStars) \
292 SJME_TOKEN_SINGLE(SJME_TOKEN_PASTE_PP(SJME_TYPEOF_IS_NOT_POINTER_X, \
293 SJME_TYPEOF_IS_POINTER(type, numPointerStars)))
295 #define SJME_TYPEOF_IF_POINTER_X0(snippet)
296 #define SJME_TYPEOF_IF_POINTER_X1(snippet) snippet
299 * If the type is a pointer, place the given snippet.
301 * @param type The type used.
302 * @param numPointerStars The number of pointer stars
303 * @param snippet The snippet to place.
304 * @return Either @c snippet or nothing.
307 #define SJME_TYPEOF_IF_POINTER(type, numPointerStars, snippet) \
308 SJME_TOKEN_PASTE_PP(SJME_TYPEOF_IF_POINTER_X, \
309 SJME_TYPEOF_IS_POINTER(type, numPointerStars))(snippet)
312 * If the type is not a pointer, place the given snippet.
314 * @param type The type used.
315 * @param numPointerStars The number of pointer stars
316 * @param snippet The snippet to place.
317 * @return Either @c snippet or nothing.
320 #define SJME_TYPEOF_IF_NOT_POINTER(type, numPointerStars, snippet) \
321 SJME_TOKEN_PASTE_PP(SJME_TYPEOF_IF_POINTER_X, \
322 SJME_TYPEOF_IS_NOT_POINTER(type, numPointerStars))(snippet)
324 #define SJME_TYPEOF_IF_POINTER_ORX0(snippet, orSnippet) orSnippet
325 #define SJME_TYPEOF_IF_POINTER_ORX1(snippet, orSnippet) snippet
328 * If the type is a pointer, place the given snippet.
330 * @param type The type used.
331 * @param numPointerStars The number of pointer stars
332 * @param snippet The snippet to place.
333 * @param orSnippet The snippet if it is a pointer.
334 * @return Either @c snippet or nothing.
337 #define SJME_TYPEOF_IF_POINTER_OR(type, numPointerStars, snippet, orSnippet) \
338 SJME_TOKEN_PASTE_PP(SJME_TYPEOF_IF_POINTER_ORX, \
339 SJME_TYPEOF_IS_POINTER(type, numPointerStars))(snippet, orSnippet)
342 * If the type is not a pointer, place the given snippet.
344 * @param type The type used.
345 * @param numPointerStars The number of pointer stars
346 * @param snippet The snippet to place.
347 * @param orSnippet The snippet if it is a pointer.
348 * @return Either @c snippet or nothing.
351 #define SJME_TYPEOF_IF_NOT_POINTER_OR(type, numPointerStars, snippet, \
353 SJME_TOKEN_PASTE_PP(SJME_TYPEOF_IF_POINTER_ORX, \
354 SJME_TYPEOF_IS_NOT_POINTER(type, numPointerStars))(snippet, orSnippet)
356 /*--------------------------------------------------------------------------*/
360 #ifdef SJME_CXX_SQUIRRELJME_TOKENUTILS_H
362 #undef SJME_CXX_SQUIRRELJME_TOKENUTILS_H
363 #undef SJME_CXX_IS_EXTERNED
364 #endif /* #ifdef SJME_CXX_SQUIRRELJME_TOKENUTILS_H */
365 #endif /* #ifdef __cplusplus */
367 #endif /* SQUIRRELJME_TOKENUTILS_H */