cst_val_const.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*************************************************************************/
  2. /* */
  3. /* Language Technologies Institute */
  4. /* Carnegie Mellon University */
  5. /* Copyright (c) 2001 */
  6. /* All Rights Reserved. */
  7. /* */
  8. /* Permission is hereby granted, free of charge, to use and distribute */
  9. /* this software and its documentation without restriction, including */
  10. /* without limitation the rights to use, copy, modify, merge, publish, */
  11. /* distribute, sublicense, and/or sell copies of this work, and to */
  12. /* permit persons to whom this work is furnished to do so, subject to */
  13. /* the following conditions: */
  14. /* 1. The code must retain the above copyright notice, this list of */
  15. /* conditions and the following disclaimer. */
  16. /* 2. Any modifications must be clearly marked as such. */
  17. /* 3. Original authors' names are not deleted. */
  18. /* 4. The authors' names are not used to endorse or promote products */
  19. /* derived from this software without specific prior written */
  20. /* permission. */
  21. /* */
  22. /* CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK */
  23. /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
  24. /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
  25. /* SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE */
  26. /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
  27. /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
  28. /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
  29. /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
  30. /* THIS SOFTWARE. */
  31. /* */
  32. /*************************************************************************/
  33. /* Author: Alan W Black (awb@cs.cmu.edu) */
  34. /* Date: January 2001 */
  35. /*************************************************************************/
  36. /* */
  37. /* Const Vals, and macros to define them */
  38. /* */
  39. /* Before you give up in disgust bear with me on this. Every single */
  40. /* line in this file has been *very* carefully decided on after much */
  41. /* thought, experimentation and reading more specs of the C language */
  42. /* than most people even thought existed. However inspite of that, the */
  43. /* result is still unsatisfying from an elegance point of view but the */
  44. /* given all the constraints this is probably the best compromise. */
  45. /* */
  46. /* This file offers macros for defining const cst_vals. I know many */
  47. /* are already laughing at me for wanting runtime types on objects and */
  48. /* will use this code as exemplars of why this should be done in C++, I */
  49. /* say good luck to them with their 4M footprint while I go for my */
  50. /* 50K footprint. But I *will* do cst_vals in 8 bytes and I *will* */
  51. /* have them defined const so they are in the text segment */
  52. /* */
  53. /* The problem here is that there is not yet a standard way to do */
  54. /* initialization of unions. There is one in the C99 standard and GCC */
  55. /* already supports it, but other compilers do not so I can't use that */
  56. /* */
  57. /* So I need a way to make an object that will have the right 8 bytes */
  58. /* for ints, floats, strings and cons cells that will work on any C */
  59. /* compiler and will be of type const cst_val. That unfortunately */
  60. /* isn't trivial. */
  61. /* */
  62. /* For the time being ignoring byte order, and address size, which */
  63. /* will be ignored in the particular discuss (though dealt with below) */
  64. /* I'd like to do something like */
  65. /* */
  66. /* const cst_val fredi = { CST_VAL_TYPE_INT,-1, 42 }; */
  67. /* const cst_val fredf = { CST_VAL_TYPE_FLOAT,-1, 4.2 }; */
  68. /* const cst_val freds = { CST_VAL_TYPE_STRING,-1, "42" }; */
  69. /* */
  70. /* Even if you accept warnings this isn't going to work, if you add */
  71. /* extra {} you can get rid of some warnings but the fval/ival/ *vval */
  72. /* part isn't going to work, the compiler *may* try to take the value */
  73. /* and assign it using the type of the first field defined in the */
  74. /* union. This could be made to work for ints and void* as pointers */
  75. /* can be used as ints (even of 64 bit architectures) but the float */
  76. /* isn't going to work. Casting will cause the float to be changed to */
  77. /* an int by CPP which isn't what you want, what you want is that the */
  78. /* four byte region gets filled with the four bytes that represent the */
  79. /* float itself. Now you could get the four byte represention of the */
  80. /* float and pretend that is an int (0xbfff9a4 for 4.2 on intel), that */
  81. /* would work but that doesn't seem satifying and I'd need to have a */
  82. /* preprocessor that could convert that. You could make atoms always */
  83. /* have a pointer to another piece of memory, but that would take up */
  84. /* another 4 bytes not just for these constants but all other cst_vals */
  85. /* create */
  86. /* */
  87. /* So you could do */
  88. /* */
  89. /* const cst_val_int fredi = { CST_VAL_TYPE_INT,-1, 42 }; */
  90. /* const cst_val_float fredf = { CST_VAL_TYPE_FLOAT,-1, 4.2 }; */
  91. /* const cst_val_string freds = { CST_VAL_TYPE_STRING,-1, "42" }; */
  92. /* */
  93. /* Though that's a slippery slope I don't want to have these explicit */
  94. /* new types, the first short defines the type perfectly adequately */
  95. /* and the whole point of runtime types is that there is one object */
  96. /* type. */
  97. /* */
  98. /* Well just initialize them at runtime, but, that isn't thread safe, */
  99. /* slows down startup, requires a instance implicitly in the code and */
  100. /* on the heap. As these are const, they should go in ROM. */
  101. /* */
  102. /* At this moment, I think the second version is the least problematic */
  103. /* though it makes defining val_consts more unpleasant than they should */
  104. /* be and forces changes elsewhere in the code even when the compiler */
  105. /* does support initialization of unions */
  106. /* */
  107. /* */
  108. /*************************************************************************/
  109. #ifndef _CST_VAL_CONSTS_H__
  110. #define _CST_VAL_CONSTS_H__
  111. #include "cst_val_defs.h"
  112. /* There is built-in int to string conversions here for numbers */
  113. /* up to 20, note if you make this bigger you have to hand change */
  114. /* other things too */
  115. #define CST_CONST_INT_MAX 19
  116. #ifndef NO_UNION_INITIALIZATION
  117. /* This is the simple way when initialization of unions is supported */
  118. #define DEF_CONST_VAL_INT(N,V) const cst_val N = {{.a={.type=CST_VAL_TYPE_INT,.ref_count=-1,.v={.ival=V}}}}
  119. #define DEF_CONST_VAL_STRING(N,S) const cst_val N = {{.a={.type=CST_VAL_TYPE_STRING,.ref_count=-1,.v={.vval= (void *)S}}}}
  120. #define DEF_CONST_VAL_FLOAT(N,F) const cst_val N = {{.a={.type=CST_VAL_TYPE_FLOAT,.ref_count=-1,.v={.fval=F}}}}
  121. #define DEF_CONST_VAL_CONS(N,A,D) const cst_val N = {{.cc={.car=A,.cdr=D }}}
  122. extern const cst_val val_int_0;
  123. extern const cst_val val_int_1;
  124. extern const cst_val val_int_2;
  125. extern const cst_val val_int_3;
  126. extern const cst_val val_int_4;
  127. extern const cst_val val_int_5;
  128. extern const cst_val val_int_6;
  129. extern const cst_val val_int_7;
  130. extern const cst_val val_int_8;
  131. extern const cst_val val_int_9;
  132. extern const cst_val val_int_10;
  133. extern const cst_val val_int_11;
  134. extern const cst_val val_int_12;
  135. extern const cst_val val_int_13;
  136. extern const cst_val val_int_14;
  137. extern const cst_val val_int_15;
  138. extern const cst_val val_int_16;
  139. extern const cst_val val_int_17;
  140. extern const cst_val val_int_18;
  141. extern const cst_val val_int_19;
  142. extern const cst_val val_int_20;
  143. extern const cst_val val_int_21;
  144. extern const cst_val val_int_22;
  145. extern const cst_val val_int_23;
  146. extern const cst_val val_int_24;
  147. extern const cst_val val_string_0;
  148. extern const cst_val val_string_1;
  149. extern const cst_val val_string_2;
  150. extern const cst_val val_string_3;
  151. extern const cst_val val_string_4;
  152. extern const cst_val val_string_5;
  153. extern const cst_val val_string_6;
  154. extern const cst_val val_string_7;
  155. extern const cst_val val_string_8;
  156. extern const cst_val val_string_9;
  157. extern const cst_val val_string_10;
  158. extern const cst_val val_string_11;
  159. extern const cst_val val_string_12;
  160. extern const cst_val val_string_13;
  161. extern const cst_val val_string_14;
  162. extern const cst_val val_string_15;
  163. extern const cst_val val_string_16;
  164. extern const cst_val val_string_17;
  165. extern const cst_val val_string_18;
  166. extern const cst_val val_string_19;
  167. extern const cst_val val_string_20;
  168. extern const cst_val val_string_21;
  169. extern const cst_val val_string_22;
  170. extern const cst_val val_string_23;
  171. extern const cst_val val_string_24;
  172. #else
  173. /* Only GCC seems to currently support the C99 standard for giving */
  174. /* explicit names for fields for initializing unions, because we want */
  175. /* things to be const, and to be small structures this is really useful */
  176. /* thus for compilers not supporting no_union_initization we use other */
  177. /* structure that we know (hope ?) are the same size and use agressive */
  178. /* casting. The goal here is wholly justified but the method here isn't */
  179. /* pretty */
  180. /* These structures are defined *solely* to get round initialization */
  181. /* problems if you need to use these in any code you are using, you are */
  182. /* unquestionably doing the wrong thing */
  183. typedef struct cst_val_atom_struct_float {
  184. #ifdef WORDS_BIGENDIAN
  185. short ref_count;
  186. short type; /* order is here important */
  187. #else
  188. #if (defined(__x86_64__) || defined(_M_X64))
  189. int type; /* order is here important */
  190. int ref_count;
  191. #else
  192. short type; /* order is here important */
  193. short ref_count;
  194. #endif
  195. #endif
  196. #if (defined(__x86_64__) || defined(_M_X64))
  197. double fval;
  198. #else
  199. float fval;
  200. #endif
  201. } cst_val_float;
  202. typedef struct cst_val_atom_struct_int {
  203. #ifdef WORDS_BIGENDIAN
  204. short ref_count;
  205. short type; /* order is here important (and unintuitive) */
  206. #else
  207. #if (defined(__x86_64__) || defined(_M_X64))
  208. int type; /* order is here important */
  209. int ref_count;
  210. #else
  211. short type; /* order is here important */
  212. short ref_count;
  213. #endif
  214. #endif
  215. #if (defined(__x86_64__) || defined(_M_X64))
  216. long long ival;
  217. #else
  218. int ival;
  219. #endif
  220. } cst_val_int;
  221. typedef struct cst_val_atom_struct_void {
  222. #ifdef WORDS_BIGENDIAN
  223. short ref_count;
  224. short type; /* order is here important */
  225. #else
  226. #if (defined(__x86_64__) || defined(_M_X64))
  227. int type; /* order is here important */
  228. int ref_count;
  229. #else
  230. short type; /* order is here important */
  231. short ref_count;
  232. #endif
  233. #endif
  234. void *vval;
  235. } cst_val_void;
  236. #ifdef WORDS_BIGENDIAN
  237. #define DEF_CONST_VAL_INT(N,V) const cst_val_int N={-1, CST_VAL_TYPE_INT, V}
  238. #define DEF_CONST_VAL_STRING(N,S) const cst_val_void N={-1,CST_VAL_TYPE_STRING,(void *)S}
  239. #define DEF_CONST_VAL_FLOAT(N,F) const cst_val_float N={-1,CST_VAL_TYPE_FLOAT,(float)F}
  240. #else
  241. #define DEF_CONST_VAL_INT(N,V) const cst_val_int N={CST_VAL_TYPE_INT,-1,V}
  242. #define DEF_CONST_VAL_STRING(N,S) const cst_val_void N={CST_VAL_TYPE_STRING,-1,(void *)S}
  243. #define DEF_CONST_VAL_FLOAT(N,F) const cst_val_float N={CST_VAL_TYPE_FLOAT,-1,(float)F}
  244. #endif
  245. #define DEF_CONST_VAL_CONS(N,A,D) const cst_val_cons N={A,D}
  246. /* in the non-union intialization version we these consts have to be */
  247. /* more typed than need, we'll cast the back later */
  248. extern const cst_val_int val_int_0;
  249. extern const cst_val_int val_int_1;
  250. extern const cst_val_int val_int_2;
  251. extern const cst_val_int val_int_3;
  252. extern const cst_val_int val_int_4;
  253. extern const cst_val_int val_int_5;
  254. extern const cst_val_int val_int_6;
  255. extern const cst_val_int val_int_7;
  256. extern const cst_val_int val_int_8;
  257. extern const cst_val_int val_int_9;
  258. extern const cst_val_int val_int_10;
  259. extern const cst_val_int val_int_11;
  260. extern const cst_val_int val_int_12;
  261. extern const cst_val_int val_int_13;
  262. extern const cst_val_int val_int_14;
  263. extern const cst_val_int val_int_15;
  264. extern const cst_val_int val_int_16;
  265. extern const cst_val_int val_int_17;
  266. extern const cst_val_int val_int_18;
  267. extern const cst_val_int val_int_19;
  268. extern const cst_val_int val_int_20;
  269. extern const cst_val_int val_int_21;
  270. extern const cst_val_int val_int_22;
  271. extern const cst_val_int val_int_23;
  272. extern const cst_val_int val_int_24;
  273. extern const cst_val_void val_string_0;
  274. extern const cst_val_void val_string_1;
  275. extern const cst_val_void val_string_2;
  276. extern const cst_val_void val_string_3;
  277. extern const cst_val_void val_string_4;
  278. extern const cst_val_void val_string_5;
  279. extern const cst_val_void val_string_6;
  280. extern const cst_val_void val_string_7;
  281. extern const cst_val_void val_string_8;
  282. extern const cst_val_void val_string_9;
  283. extern const cst_val_void val_string_10;
  284. extern const cst_val_void val_string_11;
  285. extern const cst_val_void val_string_12;
  286. extern const cst_val_void val_string_13;
  287. extern const cst_val_void val_string_14;
  288. extern const cst_val_void val_string_15;
  289. extern const cst_val_void val_string_16;
  290. extern const cst_val_void val_string_17;
  291. extern const cst_val_void val_string_18;
  292. extern const cst_val_void val_string_19;
  293. extern const cst_val_void val_string_20;
  294. extern const cst_val_void val_string_21;
  295. extern const cst_val_void val_string_22;
  296. extern const cst_val_void val_string_23;
  297. extern const cst_val_void val_string_24;
  298. #endif
  299. #define DEF_STATIC_CONST_VAL_INT(N,V) static DEF_CONST_VAL_INT(N,V)
  300. #define DEF_STATIC_CONST_VAL_STRING(N,S) static DEF_CONST_VAL_STRING(N,S)
  301. #define DEF_STATIC_CONST_VAL_FLOAT(N,F) static DEF_CONST_VAL_FLOAT(N,F)
  302. #define DEF_STATIC_CONST_VAL_CONS(N,A,D) static DEF_CONST_VAL_CONS(N,A,D)
  303. /* Some actual val consts */
  304. /* The have casts as in the non-union intialize case the casts are necessary */
  305. /* but in the union initial case these casts are harmless */
  306. #define VAL_INT_0 (cst_val *)&val_int_0
  307. #define VAL_INT_1 (cst_val *)&val_int_1
  308. #define VAL_INT_2 (cst_val *)&val_int_2
  309. #define VAL_INT_3 (cst_val *)&val_int_3
  310. #define VAL_INT_4 (cst_val *)&val_int_4
  311. #define VAL_INT_5 (cst_val *)&val_int_5
  312. #define VAL_INT_6 (cst_val *)&val_int_6
  313. #define VAL_INT_7 (cst_val *)&val_int_7
  314. #define VAL_INT_8 (cst_val *)&val_int_8
  315. #define VAL_INT_9 (cst_val *)&val_int_9
  316. #define VAL_INT_10 (cst_val *)&val_int_10
  317. #define VAL_INT_11 (cst_val *)&val_int_11
  318. #define VAL_INT_12 (cst_val *)&val_int_12
  319. #define VAL_INT_13 (cst_val *)&val_int_13
  320. #define VAL_INT_14 (cst_val *)&val_int_14
  321. #define VAL_INT_15 (cst_val *)&val_int_15
  322. #define VAL_INT_16 (cst_val *)&val_int_16
  323. #define VAL_INT_17 (cst_val *)&val_int_17
  324. #define VAL_INT_18 (cst_val *)&val_int_18
  325. #define VAL_INT_19 (cst_val *)&val_int_19
  326. #define VAL_INT_20 (cst_val *)&val_int_20
  327. #define VAL_INT_21 (cst_val *)&val_int_21
  328. #define VAL_INT_22 (cst_val *)&val_int_22
  329. #define VAL_INT_23 (cst_val *)&val_int_23
  330. #define VAL_INT_24 (cst_val *)&val_int_24
  331. const cst_val *val_int_n(int n);
  332. #define VAL_STRING_0 (cst_val *)&val_string_0
  333. #define VAL_STRING_1 (cst_val *)&val_string_1
  334. #define VAL_STRING_2 (cst_val *)&val_string_2
  335. #define VAL_STRING_3 (cst_val *)&val_string_3
  336. #define VAL_STRING_4 (cst_val *)&val_string_4
  337. #define VAL_STRING_5 (cst_val *)&val_string_5
  338. #define VAL_STRING_6 (cst_val *)&val_string_6
  339. #define VAL_STRING_7 (cst_val *)&val_string_7
  340. #define VAL_STRING_8 (cst_val *)&val_string_8
  341. #define VAL_STRING_9 (cst_val *)&val_string_9
  342. #define VAL_STRING_10 (cst_val *)&val_string_10
  343. #define VAL_STRING_11 (cst_val *)&val_string_11
  344. #define VAL_STRING_12 (cst_val *)&val_string_12
  345. #define VAL_STRING_13 (cst_val *)&val_string_13
  346. #define VAL_STRING_14 (cst_val *)&val_string_14
  347. #define VAL_STRING_15 (cst_val *)&val_string_15
  348. #define VAL_STRING_16 (cst_val *)&val_string_16
  349. #define VAL_STRING_17 (cst_val *)&val_string_17
  350. #define VAL_STRING_18 (cst_val *)&val_string_18
  351. #define VAL_STRING_19 (cst_val *)&val_string_19
  352. #define VAL_STRING_20 (cst_val *)&val_string_20
  353. #define VAL_STRING_21 (cst_val *)&val_string_21
  354. #define VAL_STRING_22 (cst_val *)&val_string_22
  355. #define VAL_STRING_23 (cst_val *)&val_string_23
  356. #define VAL_STRING_24 (cst_val *)&val_string_24
  357. const cst_val *val_string_n(int n);
  358. #endif