init.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. /*
  2. * GTools C compiler
  3. * =================
  4. * source file :
  5. * initialisations
  6. *
  7. * Copyright 2001-2004 Paul Froissart.
  8. * Credits to Christoph van Wuellen and Matthew Brandt.
  9. * All commercial rights reserved.
  10. *
  11. * This compiler may be redistributed as long there is no
  12. * commercial interest. The compiler must not be redistributed
  13. * without its full sources. This notice must stay intact.
  14. */
  15. #include "define.h"
  16. _FILE(__FILE__)
  17. #include "c.h"
  18. #include "expr.h"
  19. #include "gen.h"
  20. #define USE_MEMMGT
  21. #include "cglbdec.h"
  22. long inittype(TYP *,TYP **);
  23. static long initstruct(TYP *,TYP **), initarray(TYP *,TYP **), initunion(TYP *,TYP **);
  24. static int initchar(), initshort(), initlong(), initpointer();
  25. #ifndef NOFLOAT
  26. static int initfloat();
  27. #ifdef DOUBLE
  28. static int initdouble();
  29. #endif
  30. #endif
  31. static struct enode *constexpr();
  32. extern TYP *copy_type(TYP *s);
  33. TYP *copy_type_global(TYP *tp) {
  34. TYP *tp2;
  35. temp_local++;
  36. global_flag++;
  37. tp2=copy_type(tp);
  38. global_flag--;
  39. temp_local--;
  40. return tp2;
  41. }
  42. void doinit(struct sym *sp, int align) {
  43. nl();
  44. if (lastst != assign)
  45. genstorage(sp, align);
  46. else {
  47. struct slit *strtab_old=strtab;
  48. int glob = global_flag;
  49. int no_locblk = !locblk;
  50. /* if (lineid>=0x100)
  51. bkpt();*/
  52. strtab = 0;
  53. global_flag = 0;
  54. tmp_use();
  55. temp_local++;
  56. global_strings++;
  57. dseg(); /* select data segment */
  58. put_align(align);
  59. #ifndef AS
  60. if (sp->storage_class == sc_static)
  61. put_label((unsigned int) sp->value.i);
  62. else
  63. g_strlab(sp->name);
  64. #else
  65. #ifdef PC
  66. #define gnu_hook(x,y) ((x)?(x):(y))
  67. #else
  68. #define gnu_hook(x,y) ((x)?:(y))
  69. #endif
  70. if (sp->storage_class == sc_static) {
  71. extern int glblabel;
  72. put_label(gnu_hook(sp->value.splab,sp->value.splab=nxtglabel()));
  73. } else
  74. put_label(splbl(sp));
  75. #endif
  76. getsym();
  77. (void) inittype(sp->tp,&sp->tp);
  78. /* if (strtab)
  79. bkpt();*/
  80. if (strtab)
  81. dumplits();
  82. global_strings--;
  83. temp_local--;
  84. tmp_free(); /* just in case, but shouldn't get used because of temp_local */
  85. if (no_locblk && locblk)
  86. rel_local();
  87. global_flag = glob;
  88. strtab = strtab_old;
  89. }
  90. }
  91. long inittype(TYP *tp,TYP **tpp) {
  92. int brace_seen = 0;
  93. long nbytes;
  94. if (lastst == begin) {
  95. brace_seen = 1;
  96. getsym();
  97. }
  98. switch (tp->type) {
  99. case bt_char:
  100. case bt_uchar:
  101. nbytes = initchar();
  102. break;
  103. case bt_short:
  104. case bt_ushort:
  105. nbytes = initshort();
  106. break;
  107. case bt_pointer:
  108. if (tp->val_flag)
  109. nbytes = initarray(tp,tpp);
  110. else {
  111. nbytes = initpointer();
  112. }
  113. break;
  114. case bt_ulong:
  115. case bt_long:
  116. nbytes = initlong();
  117. break;
  118. #ifndef NOFLOAT
  119. case bt_float:
  120. nbytes = initfloat();
  121. break;
  122. #ifdef DOUBLE
  123. case bt_double:
  124. nbytes = initdouble();
  125. break;
  126. #endif
  127. #endif
  128. case bt_struct:
  129. nbytes = initstruct(tp,tpp);
  130. break;
  131. case bt_union:
  132. nbytes = initunion(tp,tpp);
  133. break;
  134. default:
  135. error(ERR_NOINIT);
  136. nbytes = 0;
  137. }
  138. if (brace_seen)
  139. needpunc(end);
  140. return nbytes;
  141. }
  142. /*void modf_btp(TYP *new_btp,TYP *tp) {
  143. tp=copy_type(tp);
  144. tp->btp=new_btp;
  145. modf(tp,modfp);
  146. }*/
  147. extern unsigned int pos;
  148. static long initarray(TYP *tp,TYP **tpp) {
  149. long nbytes;
  150. char *p;
  151. int len;
  152. #ifdef AS
  153. unsigned int max_pos=pos;
  154. #endif
  155. // tmp_use();
  156. nbytes = 0;
  157. if (lastst == sconst && (tp->btp->type == bt_char ||
  158. tp->btp->type == bt_uchar)) {
  159. len = lstrlen;
  160. nbytes = len;
  161. p = laststr;
  162. while (len--)
  163. genbyte(*p++);
  164. if (!tp->size) /* if tp->size!=0, then the padding stuff takes care of it */
  165. genbyte(0), nbytes++;
  166. while (nbytes < tp->size)
  167. genbyte(0), nbytes++;
  168. getsym(); /* skip sconst */
  169. } else if (lastst == kw_incbin) {
  170. FILE *fp; int size;
  171. #ifndef PC
  172. unsigned char type;
  173. #endif
  174. /* getsym();
  175. if (lastst!=sconst)
  176. error(ERR_SYNTAX);*/
  177. skipspace();
  178. if (lastch!='"')
  179. error(ERR_SYNTAX);
  180. getch();
  181. getidstr();
  182. if (lastch!='"')
  183. error(ERR_SYNTAX);
  184. getch();
  185. getsym();
  186. fp=fopen(lastid,"rb");
  187. if (!fp)
  188. uerr(ERR_CANTOPEN,lastid);
  189. #ifdef PC
  190. p=malloc(100000);
  191. size=fread(p,1,100000,fp);
  192. #else
  193. p=*(char **)fp;
  194. size=*(unsigned short *)p;
  195. type=p[size+1];
  196. if (type==0xF3 || type==0xE0) size--;
  197. else if (type==0xF8) { size--; do size--; while (p[size+1]); }
  198. #endif
  199. if (tp->size && size>tp->size) size=tp->size;
  200. nbytes=size;
  201. while (size--) genbyte(*p++);
  202. while (nbytes<tp->size) {
  203. genbyte(0);
  204. nbytes++;
  205. }
  206. } else if (lastst == end)
  207. goto pad;
  208. else {
  209. int i,additional,size;
  210. for (i=0;;) {
  211. additional=0;
  212. if (lastst == openbr) {
  213. getsym(); {
  214. int j=intexpr();
  215. long diff=tp->btp->size*(j-i);
  216. if (lastst == dots) {
  217. getsym();
  218. additional=intexpr()-j;
  219. }
  220. if (lastst != closebr) error(ERR_SYNTAX);
  221. else {
  222. getsym();
  223. if (lastst == assign) getsym();
  224. if (i<j) {
  225. nbytes += diff;
  226. while (diff--)
  227. genbyte(0);
  228. i=j;
  229. } else if (j<i) {
  230. #ifdef AS
  231. move_pos(diff); nbytes+=diff; i=j;
  232. #else
  233. // uwarn("brackets not supported in non-AS mode");
  234. #endif
  235. }
  236. }
  237. }}
  238. if (additional>=0) {
  239. nbytes += (size=inittype(tp->btp,NULL)); i++;
  240. #ifdef AS
  241. while (additional--) rewrite(size), nbytes+=size, i++;
  242. #endif
  243. }
  244. #ifdef AS
  245. if (pos>max_pos) max_pos=pos;
  246. #endif
  247. if (lastst == comma)
  248. getsym();
  249. if (lastst == end || lastst == semicolon) {
  250. pad:
  251. #ifdef AS
  252. if (pos<max_pos) move_pos(max_pos-pos), nbytes+=max_pos-pos;
  253. #endif
  254. while (nbytes < tp->size) {
  255. genbyte(0);
  256. nbytes++;
  257. }
  258. break;
  259. }
  260. if (tp->size > 0 && nbytes >= tp->size)
  261. break;
  262. }
  263. }
  264. #if 0
  265. if (tp->size == 0)
  266. tp->size = nbytes;
  267. if (nbytes > tp->size)
  268. error(ERR_INITSIZE);
  269. #else
  270. if (tp->size && nbytes > tp->size)
  271. error(ERR_INITSIZE);
  272. if (tp->size != nbytes && tpp)
  273. /* fix the symbol's size, unless tpp=0 (item of a struct/union or array) */
  274. tp = copy_type_global(tp),
  275. *tpp = tp,
  276. tp->size = nbytes; // we need this for the 'sizeof' operator...
  277. #endif
  278. // tmp_free();
  279. return nbytes;
  280. }
  281. static long initunion(TYP *tp,TYP **tpp) {
  282. struct sym *sp;
  283. long nbytes;
  284. int brace_seen = 0;
  285. if (lastst == begin) {
  286. brace_seen = 1;
  287. getsym();
  288. }
  289. sp = tp->lst.head;
  290. /*
  291. * Initialize the first branch
  292. */
  293. if (sp == 0)
  294. return 0;
  295. nbytes = inittype(sp->tp,NULL);
  296. while (nbytes < tp->size) {
  297. genbyte(0);
  298. nbytes++;
  299. }
  300. if (tp->size != nbytes && tpp)
  301. tp = copy_type_global(tp),
  302. *tpp = tp,
  303. tp->size = nbytes; // we need this for the 'sizeof' operator...
  304. if (brace_seen)
  305. needpunc(end);
  306. }
  307. static long initstruct(TYP *tp,TYP **tpp) {
  308. struct sym *sp;
  309. long nbytes;
  310. nbytes = 0;
  311. sp = tp->lst.head; /* start at top of symbol table */
  312. if (lastst != end)
  313. while (sp != 0) {
  314. while (nbytes < sp->value.i) { /* align properly */
  315. nbytes++;
  316. genbyte(0);
  317. }
  318. nbytes += inittype(sp->tp,NULL);
  319. if (lastst == comma)
  320. getsym();
  321. if (lastst == end || lastst == semicolon)
  322. break;
  323. sp = sp->next;
  324. }
  325. while (nbytes < tp->size) {
  326. genbyte(0);
  327. nbytes++;
  328. }
  329. if (tp->size != nbytes && tpp)
  330. tp = copy_type_global(tp),
  331. *tpp = tp,
  332. tp->size = nbytes; // we need this for the 'sizeof' operator...
  333. return tp->size;
  334. }
  335. static int initchar() {
  336. genbyte((int) intexpr());
  337. return 1;
  338. }
  339. static int initshort() {
  340. genword((int) intexpr());
  341. return 2;
  342. }
  343. static int initlong() {
  344. /*
  345. * We allow longs to be initialized with pointers now.
  346. * Thus, we call constexpr() instead of intexpr.
  347. */
  348. #if 0
  349. /*
  350. * This is more strict
  351. */
  352. genlong(intexpr());
  353. return 4;
  354. #endif
  355. genptr(constexpr());
  356. return 4;
  357. }
  358. #ifndef NOFLOAT
  359. static int initfloat() {
  360. #ifndef NOFLOAT
  361. double floatexpr();
  362. #ifdef PC
  363. genfloat(floatexpr());
  364. #else
  365. #ifndef BCDFLT
  366. genptr(floatexpr());
  367. #else
  368. genfloat(floatexpr());
  369. #endif
  370. #endif
  371. #endif
  372. #ifdef NOFLOAT
  373. genptr(0l);
  374. #endif
  375. return 4;
  376. }
  377. #ifdef DOUBLE
  378. static int initdouble() {
  379. #ifdef NOFLOAT
  380. int i;
  381. for (i=0; i< tp_double.size; i++)
  382. genbyte(0);
  383. #endif
  384. #ifndef NOFLOAT
  385. double floatexpr();
  386. gendouble(floatexpr());
  387. #endif
  388. return tp_double.size;
  389. }
  390. #endif
  391. #endif
  392. static int initpointer() {
  393. genptr(constexpr());
  394. return 4;
  395. }
  396. static struct enode *constexpr() {
  397. struct enode *ep;
  398. struct typ *tp;
  399. /* if (lineid==0x1e0)
  400. bkpt();*/
  401. tp=exprnc(&ep);
  402. if (tp == 0) {
  403. error(ERR_EXPREXPECT);
  404. return 0;
  405. }
  406. opt0(&ep);
  407. if (!tst_const(ep)) {
  408. error(ERR_CONSTEXPECT);
  409. return 0;
  410. }
  411. return ep;
  412. }
  413. // vim:ts=4:sw=4