stmt.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. /*
  2. * GTools C compiler
  3. * =================
  4. * source file :
  5. * statement handling
  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. #include "cglbdec.h"
  21. #ifdef PC
  22. #ifdef SHORT_INT
  23. #undef int
  24. #endif
  25. #include <ctype.h>
  26. #ifdef SHORT_INT
  27. #define int short
  28. #endif
  29. #endif
  30. struct enode *init_node CGLOB;
  31. TYP *lastexpr_tp CGLOB;
  32. int lastexpr_size CGLOB, lastexpr_type CGLOB;
  33. /*
  34. * the statement module handles all of the possible c statements and builds a
  35. * parse tree of the statements.
  36. *
  37. * each routine returns a pointer to a statement parse node which reflects the
  38. * statement just parsed.
  39. */
  40. int start_block(int m) { // used in block() (func.c)
  41. if (m) {
  42. needpunc(begin);
  43. return 1; // we don't care about the result in this case
  44. } else
  45. return lastst==begin;
  46. }
  47. unsigned int getconst(enum(e_sym) s,enum(e_sym) e) {
  48. struct enode *en;
  49. getsym();
  50. if (lastst != s)
  51. error(ERR_EXPREXPECT);
  52. else {
  53. getsym();
  54. if (exprnc(&en) == 0)
  55. error(ERR_EXPREXPECT);
  56. needpunc(e);
  57. opt0(&en);
  58. if (en->nodetype != en_icon)
  59. error(ERR_CONSTEXPECT);
  60. else if ((unsigned long)en->v.i>=65536)
  61. error(ERR_OUTRANGE);
  62. else return en->v.i;
  63. }
  64. return 0; // make the compiler happy
  65. }
  66. unsigned int getconst2(enum(e_sym) e) {
  67. struct enode *en;
  68. if (exprnc(&en) == 0)
  69. error(ERR_EXPREXPECT);
  70. needpunc(e);
  71. opt0(&en);
  72. if (en->nodetype != en_icon)
  73. error(ERR_CONSTEXPECT);
  74. else if ((unsigned long)en->v.i>=65536)
  75. error(ERR_OUTRANGE);
  76. else return en->v.i;
  77. return 0; // make the compiler happy
  78. }
  79. struct snode *whilestmt(void) {
  80. /*
  81. * whilestmt parses the c while statement.
  82. */
  83. struct snode *snp;
  84. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  85. snp->stype = st_while;
  86. snp->count = 3;
  87. getsym();
  88. if (lastst != openpa)
  89. error(ERR_EXPREXPECT);
  90. else {
  91. getsym();
  92. if (expression(&(snp->exp)) == 0)
  93. error(ERR_EXPREXPECT);
  94. #ifdef DB_POSSIBLE
  95. snp->line=lineid;
  96. #endif
  97. needpunc(closepa);
  98. if (lastst == kw_count) snp->count=getconst(openpa,closepa);
  99. snp->s1 = statement();
  100. }
  101. return snp;
  102. }
  103. struct snode *asmstmt();
  104. #if !defined(AS) && !defined(ASM)
  105. struct snode *asmstmt(void) {
  106. /*
  107. * asmstmt parses the gtc c asm statement.
  108. */
  109. struct snode *snp;
  110. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  111. snp->stype = st_asm;
  112. snp->count = 1;
  113. getsym();
  114. if (lastst != openpa)
  115. error(ERR_EXPREXPECT);
  116. else {
  117. getsym();
  118. if (lastst != sconst)
  119. error(ERR_SYNTAX);
  120. snp->v1.i = (long)strsave(laststr);
  121. getsym();
  122. if (lastst == colon) {
  123. getsym();
  124. uwarn("only asm(\"...\") is supported yet");
  125. error(ERR_SYNTAX);
  126. }
  127. needpunc(closepa);
  128. needpunc(semicolon);
  129. }
  130. #ifdef DB_POSSIBLE
  131. snp->line=lineid;
  132. #endif
  133. return snp;
  134. }
  135. #endif
  136. //struct enode lp_one = { en_icon, bt_ushort, 2, {1L}, 0, 0};
  137. xstatic struct enode *lp_one CGLOB;
  138. struct snode *loopstmt(void) {
  139. /*
  140. * loopstmt parses the gtc c loop statement.
  141. */
  142. struct snode *snp; TYP *tp;
  143. struct enode *exp;
  144. int has_count;
  145. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  146. snp->stype = st_loop;
  147. snp->count = 3;
  148. has_count = 0;
  149. getsym();
  150. if (lastst != openpa)
  151. error(ERR_EXPREXPECT);
  152. else {
  153. getsym();
  154. if (lastst != id)
  155. error(ERR_IDEXPECT);
  156. if (!nameref(&(snp->v1.e))) error(ERR_EXPREXPECT);
  157. if (lastst != assign)
  158. error(ERR_SYNTAX);
  159. getsym();
  160. if (!(tp=expression(&(snp->exp))))
  161. error(ERR_EXPREXPECT);
  162. cast_op(&(snp->exp),tp,(TYP *)&tp_ushort);
  163. #ifdef DB_POSSIBLE
  164. snp->line=lineid;
  165. #endif
  166. needpunc(closepa);
  167. if (lastst == kw_count) { snp->count=getconst(openpa,closepa); has_count=1; }
  168. opt0(&(snp->exp));
  169. if (snp->exp->nodetype==en_icon) {
  170. unsigned int c=snp->exp->v.i;
  171. if (has_count) {
  172. if (c!=snp->count)
  173. uwarn("loop has an effective count of %u whereas %u precised",
  174. c,snp->count);
  175. } else snp->count=c;
  176. }
  177. lp_one = mk_icon(1L);
  178. lp_one->etype = bt_ushort; lp_one->esize = 2;
  179. snp->exp = exp = mk_node(en_sub,snp->exp,lp_one);
  180. exp->etype = bt_ushort; exp->esize = 2;
  181. opt4(&(snp->exp));
  182. snp->exp = exp = mk_node(en_assign,snp->v1.e,snp->exp);
  183. exp->etype = bt_ushort; exp->esize = 2;
  184. snp->s1 = statement();
  185. if (lastst == kw_until) {
  186. getsym();
  187. if (!expression(&(snp->v2.e))) error(ERR_EXPREXPECT);
  188. } else snp->v2.e=NULL;
  189. }
  190. return snp;
  191. }
  192. struct snode *dostmt(void) {
  193. /*
  194. * dostmt parses the c do-while construct.
  195. */
  196. struct snode *snp;
  197. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  198. snp->stype = st_do;
  199. snp->count = 3;
  200. getsym();
  201. snp->s1 = statement();
  202. #ifdef DB_POSSIBLE
  203. snp->line=lineid;
  204. #endif
  205. if (lastst != kw_while)
  206. error(ERR_WHILEXPECT);
  207. else {
  208. getsym();
  209. if (lastst != openpa)
  210. error(ERR_EXPREXPECT);
  211. else {
  212. getsym();
  213. if (expression(&(snp->exp)) == 0)
  214. error(ERR_EXPREXPECT);
  215. needpunc(closepa);
  216. if (lastst == kw_count) snp->count=getconst(openpa,closepa);
  217. }
  218. if (lastst != end)
  219. needpunc(semicolon);
  220. }
  221. return snp;
  222. }
  223. struct snode *forstmt(void) {
  224. struct snode *snp;
  225. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  226. snp->stype = st_for;
  227. snp->count = 3;
  228. getsym();
  229. needpunc(openpa);
  230. /*if (*/expression(&(snp->exp))/* == 0)
  231. snp->exp = 0*/;
  232. needpunc(semicolon);
  233. /*if (*/expression(&(snp->v1.e))/* == 0)
  234. snp->v1.e = 0*/;
  235. needpunc(semicolon);
  236. /*if (*/expression(&(snp->v2.e))/* == 0)
  237. snp->v2.e = 0*/;
  238. #ifdef DB_POSSIBLE
  239. snp->line=lineid;
  240. #endif
  241. needpunc(closepa);
  242. if (lastst == kw_count) snp->count=getconst(openpa,closepa);
  243. snp->s1 = statement();
  244. return snp;
  245. }
  246. struct snode *ifstmt(void) {
  247. /*
  248. * ifstmt parses the c if statement and an else clause if one is present.
  249. */
  250. struct snode *snp;
  251. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  252. snp->stype = st_if;
  253. snp->count=32768;
  254. getsym();
  255. if (lastst != openpa)
  256. error(ERR_EXPREXPECT);
  257. else {
  258. getsym();
  259. if (expression(&(snp->exp)) == 0)
  260. error(ERR_EXPREXPECT);
  261. #ifdef DB_POSSIBLE
  262. snp->line=lineid;
  263. #endif
  264. needpunc(closepa);
  265. if (lastst == kw_count) {
  266. unsigned int i=getconst(openpa,comma),j=getconst2(closepa);
  267. snp->count=((unsigned long)i<<16)/(i+j);
  268. }
  269. snp->s1 = statement();
  270. if (lastst == kw_else) {
  271. getsym();
  272. snp->v1.s = statement();
  273. } else {
  274. #ifdef NO_CALLOC
  275. snp->v1.s = 0;
  276. #endif
  277. }
  278. }
  279. return snp;
  280. }
  281. /*
  282. * consider the following piece of code:
  283. *
  284. * switch (i) {
  285. * case 1:
  286. * if (j) {
  287. * .....
  288. * } else
  289. * case 2:
  290. * ....
  291. * }
  292. *
  293. * case statements may be deep inside, so we need a global variable
  294. * last_case to link them
  295. */
  296. xstatic struct snode *last_case CGLOB; /* last case statement within this switch */
  297. struct snode *casestmt(void) {
  298. /*
  299. * cases are returned as seperate statements. for normal cases label is the
  300. * case value and v1.i is zero. for the default case v1.i is nonzero.
  301. */
  302. struct snode *snp,*snp0;
  303. snp0 = snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  304. #ifdef NO_CALLOC
  305. snp->s1 = NIL_SNODE;
  306. #endif
  307. if (lastst == kw_case) {
  308. long v;
  309. getsym();
  310. snp->stype = st_case;
  311. snp->v2.i = v = intexpr();
  312. if (lastst == dots) { // TODO : make only one 'case' label
  313. long max;
  314. getsym();
  315. if ((max = intexpr()) < v) error(ERR_CASERANGE);
  316. else while (v != max) {
  317. last_case = last_case->s1 = snp;
  318. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  319. last_case->v1.s = snp;
  320. #ifdef NO_CALLOC
  321. snp->s1 = NIL_SNODE;
  322. #endif
  323. snp->stype = st_case;
  324. snp->v2.i = ++v;
  325. }
  326. }
  327. } else {
  328. /* lastst is kw_default */
  329. getsym();
  330. /* CVW: statement type needed for analyze etc. */
  331. snp->stype = st_default;
  332. }
  333. last_case = last_case->s1 = snp;
  334. needpunc(colon);
  335. if (lastst != end)
  336. snp->v1.s = statement();
  337. return snp0;
  338. }
  339. int checkcases(struct snode *head) {
  340. /*
  341. * checkcases will check to see if any duplicate cases exist in the case list
  342. * pointed to by head.
  343. */
  344. struct snode *top, *cur;
  345. cur = top = head;
  346. while (top != 0) {
  347. cur = top->s1;
  348. while (cur != 0) {
  349. if (cur->stype != st_default && top->stype != st_default
  350. && cur->v2.i == top->v2.i) {
  351. uwarn("duplicate case label for value %ld", cur->v2.i);
  352. return 1;
  353. }
  354. if (cur->stype == st_default && top->stype == st_default) {
  355. uwarn("duplicate default label");
  356. return 1;
  357. }
  358. cur = cur->s1;
  359. }
  360. top = top->s1;
  361. }
  362. return 0;
  363. }
  364. struct snode *switchstmt(void) {
  365. struct snode *snp;
  366. struct snode *local_last_case;
  367. local_last_case = last_case;
  368. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  369. last_case = snp;
  370. #ifdef NO_CALLOC
  371. snp->s1 = 0;
  372. #endif
  373. snp->stype = st_switch;
  374. getsym();
  375. needpunc(openpa);
  376. if ((expression(&(snp->exp))) == 0)
  377. error(ERR_EXPREXPECT);
  378. #ifdef DB_POSSIBLE
  379. snp->line=lineid;
  380. #endif
  381. needpunc(closepa);
  382. needpunc(begin);
  383. snp->v1.s = compound(1);
  384. if (checkcases(snp->s1))
  385. error(ERR_DUPCASE);
  386. last_case = local_last_case;
  387. return snp;
  388. }
  389. struct snode *retstmt(void) {
  390. struct snode *snp;
  391. TYP *tp;
  392. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  393. snp->stype = st_return;
  394. getsym();
  395. tp = expression(&(snp->exp));
  396. if (snp->exp != 0)
  397. (void) cast_op(&(snp->exp), tp, ret_type);
  398. if (lastst != end)
  399. needpunc(semicolon);
  400. #ifdef DB_POSSIBLE
  401. snp->line=prevlineid;
  402. #endif
  403. return snp;
  404. }
  405. struct snode *breakstmt(void) {
  406. struct snode *snp;
  407. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  408. snp->stype = st_break;
  409. getsym();
  410. if (lastst != end)
  411. needpunc(semicolon);
  412. #ifdef DB_POSSIBLE
  413. snp->line=prevlineid;
  414. #endif
  415. return snp;
  416. }
  417. struct snode *contstmt(void) {
  418. struct snode *snp;
  419. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  420. snp->stype = st_continue;
  421. getsym();
  422. if (lastst != end)
  423. needpunc(semicolon);
  424. #ifdef DB_POSSIBLE
  425. snp->line=prevlineid;
  426. #endif
  427. return snp;
  428. }
  429. struct snode *exprstmt(void) {
  430. /*
  431. * exprstmt is called whenever a statement does not begin with a keyword. the
  432. * statement should be an expression.
  433. */
  434. struct snode *snp;
  435. debug('u');
  436. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  437. snp->stype = st_expr;
  438. /*
  439. * I have a problem here.
  440. * If expression() fails on the first character and does not do a getsym(),
  441. * there may be an infinite loop since we will continue coming up here.
  442. * Since the compiler will stop after MAX_ERROR_COUNT calls to error(),
  443. * this might not be THAT much of a problem.
  444. */
  445. if (!(lastexpr_tp=expression(&(snp->exp))))
  446. error(ERR_EXPREXPECT);
  447. else {
  448. lastexpr_type=snp->exp->etype;
  449. lastexpr_size=snp->exp->esize;
  450. }
  451. debug('v');
  452. if (lastst != end)
  453. needpunc(semicolon);
  454. #ifdef DB_POSSIBLE
  455. snp->line=prevlineid;
  456. #endif
  457. debug('w');
  458. return snp;
  459. }
  460. #ifdef AUTOINIT_PAD
  461. //long auto_init(long offs,TYP *typ,int brace_level,int offmod);
  462. long auto_pad(long offs,int len,int offmod) {
  463. long nbytes=0;
  464. while (len>0) {
  465. int size;
  466. if ((offs+offmod)&1)
  467. size=1;
  468. else if (len<=2)
  469. size=len;
  470. else if (len==3)
  471. size=2;
  472. else size=4;
  473. {
  474. struct enode *ep1,*ep2=mk_icon(0L),*ep3;
  475. ep2->esize = size; /* don't care about the etype, it's set to char */
  476. ep1 = mk_node(en_autocon, NIL_ENODE, NIL_ENODE);
  477. ep1->v.i = offs;
  478. ep1->etype = bt_pointer;
  479. ep1->esize = 4;
  480. ep3 = mk_icon((long)offmod);
  481. ep3->etype = bt_long;
  482. ep3->esize = 4;
  483. ep1 = mk_node(en_add, ep1, ep3);
  484. ep1->etype = bt_pointer;
  485. ep1->esize = 4;
  486. ep1 = mk_node(en_ref, ep1, NIL_ENODE);
  487. ep1->esize = size; /* don't care about the etype, it's set to char */
  488. ep1 = mk_node(en_assign, ep1, ep2);
  489. ep1->esize = size; /* don't care about the etype, it's set to char */
  490. if (init_node == 0) {
  491. init_node = ep1;
  492. } else {
  493. init_node = mk_node(en_void, init_node, ep1);
  494. }
  495. }
  496. len-=size;
  497. nbytes+=size;
  498. offmod+=size;
  499. }
  500. return nbytes;
  501. }
  502. #endif
  503. long auto_init(long offs,TYP *typ,TYP **tpp,int brace_level,int offmod,int stroff) {
  504. /*
  505. * generated assignment statements for initialization of auto and register
  506. * variables. The initialization is generated like comma operators so a
  507. * single statement does all the initializations
  508. */
  509. struct enode *ep1, *ep2;
  510. struct typ *tp;
  511. int brace_seen = 0;
  512. long nbytes = 0;
  513. auto_init_restart:
  514. if (lastst == begin) {
  515. brace_level++;
  516. brace_seen++;
  517. getsym();
  518. }
  519. if (typ->type==bt_struct && brace_level) {
  520. struct sym *sp;
  521. sp = typ->lst.head; /* start at top of symbol table */
  522. while (sp != 0) {
  523. /* infunc("DrawPacmanLogoAndHandleMenu")
  524. bkpt();*/
  525. nbytes+=auto_init(offs,sp->tp,NULL,brace_level,(int)(offmod+sp->value.i),-1);
  526. if (lastst == comma)
  527. getsym();
  528. if (lastst == end || lastst == semicolon)
  529. break;
  530. sp = sp->next;
  531. }
  532. #ifdef AUTOINIT_PAD
  533. nbytes+=auto_pad(offs,(int)(typ->size-nbytes),offmod+nbytes); /* negative args are OK for auto_pad */
  534. #endif
  535. } else if (typ->type==bt_union) {
  536. typ = (typ->lst.head)->tp;
  537. goto auto_init_restart;
  538. } else if (typ->val_flag) {
  539. // if (!brace_level) error(ERR_SYNTAX);
  540. if (lastst != end) {
  541. int stroff=-1;
  542. if (lastst == sconst && !brace_seen)
  543. stroff=0;
  544. while (1) {
  545. nbytes+=auto_init(offs,typ->btp,NULL,brace_level,(int)(offmod+nbytes),stroff);
  546. if (stroff>=0) {
  547. stroff++;
  548. if (stroff>lstrlen || (stroff==lstrlen && typ->size)) {
  549. getsym();
  550. break;
  551. }
  552. } else {
  553. if (lastst == comma)
  554. getsym();
  555. if (lastst == end || lastst == semicolon) break;
  556. }
  557. }
  558. }
  559. if (typ->size && nbytes > typ->size)
  560. error(ERR_INITSIZE);
  561. if (nbytes != typ->size && tpp) {
  562. /* fix the symbol's size, unless tpp=0 (item of a struct/union or array) */
  563. typ = copy_type(typ);
  564. *tpp = typ;
  565. typ->size = nbytes;
  566. }
  567. #ifdef AUTOINIT_PAD
  568. nbytes+=auto_pad(offs,(int)(typ->size-nbytes),offmod+nbytes); /* negative args are OK for auto_pad */
  569. #endif
  570. } else {
  571. if (stroff<0) {
  572. if (!(tp = exprnc(&ep2)))
  573. error(ERR_ILLINIT);
  574. } else
  575. ep2=mk_icon(stroff<lstrlen?laststr[stroff]:0), tp=(TYP *)&tp_char;
  576. (void) cast_op(&ep2, tp, typ);
  577. nbytes=bt_size(typ->type);
  578. /* if (offs==0xfffffe4e)
  579. bkpt();*/
  580. ep1 = mk_node(en_autocon, NIL_ENODE, NIL_ENODE);
  581. ep1->v.i = offs;
  582. /* ep1->etype = typ->type; // this is a ridiculous bug that I spent hours finding...
  583. ep1->esize = typ->size; */
  584. ep1->etype = bt_pointer;
  585. ep1->esize = 4;
  586. if (offmod) {
  587. struct enode *ep3 = mk_icon((long)offmod);
  588. ep3->etype = bt_long;
  589. ep3->esize = 4;
  590. ep1 = mk_node(en_add, ep1, ep3);
  591. ep1->etype = bt_pointer;
  592. ep1->esize = 4;
  593. }
  594. ep1 = mk_node(en_ref, ep1, NIL_ENODE);
  595. ep1->etype = typ->type;
  596. ep1->esize = typ->size;
  597. ep1 = mk_node(en_assign, ep1, ep2);
  598. ep1->etype = typ->type;
  599. ep1->esize = typ->size;
  600. #ifdef MID_DECL_IN_EXPR
  601. if (middle_decl)
  602. md_expr = ep1, md_type = typ;
  603. #error fix needed around here...
  604. else {
  605. #endif
  606. if (init_node == 0) {
  607. init_node = ep1;
  608. } else {
  609. init_node = mk_node(en_void, init_node, ep1);
  610. }
  611. #ifdef MID_DECL_IN_EXPR
  612. }
  613. #endif
  614. }
  615. while (brace_seen--)
  616. needpunc(end);
  617. return nbytes;
  618. }
  619. struct snode *compound(int no_init) {
  620. /*
  621. * compound processes a block of statements and forms a linked list of the
  622. * statements within the block.
  623. *
  624. * compound expects the input pointer to already be past the begin symbol of the
  625. * block.
  626. *
  627. * If no_init is true, auto initializations are not desirable
  628. */
  629. struct snode *head, *tail, *snp;
  630. // struct sym *local_tail, *local_tagtail;
  631. HTABLE old_lsyms,old_ltags;
  632. // hashinit(&symtab);
  633. /* local_tail = lsyms.tail;
  634. local_tagtail = ltags.tail;*/
  635. memcpy(&old_lsyms,&lsyms,sizeof(HTABLE));
  636. memcpy(&old_ltags,&ltags,sizeof(HTABLE));
  637. dodecl(sc_auto);
  638. if (init_node == 0) {
  639. head = tail = 0;
  640. } else {
  641. if (no_init>0) {
  642. uwarn("auto initialization not reached");
  643. }
  644. head = tail = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  645. head->stype = st_expr;
  646. head->exp = init_node;
  647. #ifdef NO_CALLOC
  648. head->next = 0;
  649. #endif
  650. #ifdef DB_POSSIBLE
  651. head->line = prevlineid;
  652. #endif
  653. }
  654. init_node = 0;
  655. while (lastst != end) {
  656. if (head == 0)
  657. head = tail = statement();
  658. else {
  659. tail->next = statement();
  660. if (tail->next != 0)
  661. tail = tail->next;
  662. }
  663. }
  664. if (no_init>=0)
  665. getsym();
  666. #ifdef LISTING
  667. if (list_option) {
  668. /* if (local_tail != lsyms.tail) {
  669. if (local_tail != 0)
  670. symtab.head = local_tail->next;
  671. else
  672. symtab.head = lsyms.head;
  673. symtab.tail = lsyms.tail;
  674. fprintf(list, "\n*** local symbol table ***\n\n");
  675. list_table(&symtab, 0);
  676. fprintf(list, "\n");
  677. }*/
  678. fprintf(list, "\n*** local symbol table ***\n\n");
  679. list_table(&lsyms, 0);
  680. fprintf(list, "\n");
  681. /* if (local_tagtail != ltags.tail) {
  682. if (local_tagtail != 0)
  683. symtab.head = local_tagtail->next;
  684. else
  685. symtab.head = ltags.head;
  686. symtab.tail = ltags.tail;
  687. fprintf(list, "\n*** local structures and unions ***\n\n");
  688. list_table(&symtab, 0);
  689. fprintf(list, "\n");
  690. }*/
  691. fprintf(list, "\n*** local structures and unions ***\n\n");
  692. list_table(&ltags, 0);
  693. fprintf(list, "\n");
  694. }
  695. #endif
  696. /* if (local_tagtail != 0) {
  697. ltags.tail = local_tagtail;
  698. ltags.tail->next = 0;
  699. } else {
  700. ltags.head = 0;
  701. ltags.tail = 0;
  702. }
  703. if (local_tail != 0) {
  704. lsyms.tail = local_tail;
  705. lsyms.tail->next = 0;
  706. } else {
  707. lsyms.head = 0;
  708. lsyms.tail = 0;
  709. }*/
  710. memcpy(&lsyms,&old_lsyms,sizeof(HTABLE));
  711. memcpy(&ltags,&old_ltags,sizeof(HTABLE));
  712. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  713. snp->stype = st_compound;
  714. snp->s1 = head;
  715. #ifdef DB_POSSIBLE
  716. snp->line=lineid;
  717. #endif
  718. return snp;
  719. }
  720. extern unsigned int pos;
  721. struct snode *labelstmt(void) {
  722. /*
  723. * labelstmt processes a label that appears before a statement as a seperate
  724. * statement.
  725. */
  726. struct snode *snp;
  727. struct sym *sp;
  728. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  729. /*if (pos>=0x25C2)
  730. printf("jiotrh");*/
  731. snp->stype = st_label;
  732. if ((sp = search(lastid, lastcrc, &labsyms)) == 0) {
  733. sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM);
  734. sp->name = strsave(lastid);
  735. sp->storage_class = sc_label;
  736. #ifdef NO_CALLOC
  737. sp->tp = 0;
  738. #endif
  739. sp->value.i = nxtlabel();
  740. append(&sp, &labsyms);
  741. } else {
  742. if (sp->storage_class != sc_ulabel)
  743. error(ERR_LABEL);
  744. else
  745. sp->storage_class = sc_label;
  746. }
  747. getsym(); /* get past id */
  748. needpunc(colon);
  749. if (sp->storage_class == sc_label) {
  750. snp->v2.i = sp->value.i;
  751. if (lastst != end)
  752. snp->s1 = statement();
  753. return snp;
  754. }
  755. return 0;
  756. }
  757. struct snode *gotostmt(void) {
  758. /*
  759. * gotostmt processes the goto statement and puts undefined labels into the
  760. * symbol table.
  761. */
  762. struct snode *snp;
  763. struct sym *sp;
  764. getsym();
  765. if (lastst != id) {
  766. error(ERR_IDEXPECT);
  767. return 0;
  768. }
  769. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  770. if ((sp = search(lastid, lastcrc, &labsyms)) == 0) {
  771. sp = (struct sym *) xalloc((int) sizeof(struct sym), _SYM);
  772. sp->name = strsave(lastid);
  773. sp->value.i = nxtlabel();
  774. sp->storage_class = sc_ulabel;
  775. #ifdef NO_CALLOC
  776. sp->tp = 0;
  777. #endif
  778. append(&sp, &labsyms);
  779. }
  780. #ifdef DB_POSSIBLE
  781. snp->line=lineid;
  782. #endif
  783. getsym(); /* get past label name */
  784. if (lastst != end)
  785. needpunc(semicolon);
  786. if (sp->storage_class != sc_label && sp->storage_class != sc_ulabel)
  787. error(ERR_LABEL);
  788. else {
  789. snp->stype = st_goto;
  790. snp->v2.i = sp->value.i;
  791. snp->next = 0;
  792. return snp;
  793. }
  794. return 0;
  795. }
  796. struct snode *statement(void) {
  797. /*
  798. * statement figures out which of the statement processors should be called
  799. * and transfers control to the proper routine.
  800. */
  801. struct snode *snp;
  802. /* if (lineid==0x20A)
  803. bkpt();*/
  804. switch (lastst) {
  805. case semicolon:
  806. getsym();
  807. snp = 0;
  808. break;
  809. case kw_char: case kw_short: case kw_unsigned: case kw_long:
  810. case kw_struct: case kw_union: case kw_enum: case kw_void:
  811. case kw_float: case kw_double: case kw_int: case kw_typeof:
  812. case kw_signed: case kw_const: case kw_volatile:
  813. case kw_register: case kw_auto:
  814. case kw_static: case kw_typedef: case kw_extern:
  815. middle_decl:
  816. if (!(flags & X_MID_DECL)) goto default_decl;
  817. #ifdef OLD_MID_DECL
  818. snp = compound(0);
  819. if ((int)cached_sym IS_VALID) fatal("CACHE"); // will never happen since no caching is
  820. // performed when lastst==begin
  821. /* cached_sym2 = cached_sym;*/
  822. cached_sym = lastst; cached_lineid = lineid;
  823. lastst = end;
  824. break;
  825. #else
  826. #ifdef MID_DECL
  827. /* the following is much cleaner than the old mid_decl handler */
  828. dodecl(sc_auto);
  829. if (init_node) {
  830. snp = (struct snode *) xalloc((int) sizeof(struct snode), SNODE);
  831. snp->stype = st_expr;
  832. snp->exp = init_node;
  833. #ifdef DB_POSSIBLE
  834. snp->line = prevlineid;
  835. #endif
  836. init_node = 0; // compound resets after calling rather than before...
  837. } // I find it pretty weird :) (maybe it should be changed?)
  838. else snp = 0;
  839. break;
  840. #endif
  841. #endif
  842. case begin:
  843. getsym();
  844. snp = compound(0);
  845. break;
  846. case kw_if:
  847. snp = ifstmt();
  848. break;
  849. case kw_while:
  850. snp = whilestmt();
  851. break;
  852. case kw_for:
  853. snp = forstmt();
  854. break;
  855. case kw_return:
  856. snp = retstmt();
  857. break;
  858. case kw_break:
  859. snp = breakstmt();
  860. break;
  861. case kw_goto:
  862. snp = gotostmt();
  863. break;
  864. case kw_continue:
  865. snp = contstmt();
  866. break;
  867. case kw_do:
  868. snp = dostmt();
  869. break;
  870. case kw_switch:
  871. snp = switchstmt();
  872. break;
  873. case kw_case:
  874. case kw_default:
  875. snp = casestmt();
  876. break;
  877. case kw_loop:
  878. snp = loopstmt();
  879. break;
  880. case kw_count:
  881. snp = NULL;
  882. error(ERR_EXPREXPECT);
  883. break;
  884. case kw_asm:
  885. snp = asmstmt();
  886. break;
  887. case id:
  888. if (!getcache(id) && cached_sym==colon) {
  889. snp = labelstmt();
  890. break;
  891. }
  892. #if defined(OLD_MID_DECL) || defined(MID_DECL)
  893. if (lastsp && lastsp->storage_class == sc_typedef)
  894. goto middle_decl;
  895. #endif
  896. default_decl:
  897. /* else fall through to process expression */
  898. default:
  899. snp = exprstmt();
  900. break;
  901. }
  902. if (snp != 0)
  903. snp->next = 0;
  904. return snp;
  905. }
  906. // vim:ts=4:sw=4