graph.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. #include "bem.h"
  6. #ifndef NORSCID
  7. static char rcs_id[] = "$Id$" ;
  8. #endif
  9. List *forwardlabel=0;
  10. Linerecord *firstline,
  11. *currline,
  12. *lastline;
  13. List *newlist()
  14. {
  15. List *l;
  16. /* NOSTRICT */ l = (List *) salloc(sizeof(List));
  17. return(l);
  18. }
  19. /* Line management is handled here */
  20. Linerecord *srchline(nr)
  21. int nr;
  22. {
  23. Linerecord *l;
  24. for(l=firstline;l && l->linenr<=nr;l= l->nextline)
  25. if ( l->linenr== nr) return(l);
  26. return(0);
  27. }
  28. List *srchforward(nr)
  29. int nr;
  30. {
  31. List *l;
  32. for(l=forwardlabel;l ;l=l->nextlist)
  33. if ( l->linenr== nr) return(l);
  34. return(0);
  35. }
  36. linewarnings()
  37. {
  38. List *l;
  39. extern int errorcnt;
  40. l= forwardlabel;
  41. while (l)
  42. {
  43. if ( !srchline(l->linenr))
  44. {
  45. fprint(STDERR, "ERROR: line %d not defined\n",l->linenr);
  46. errorcnt++;
  47. }
  48. l=l->nextlist;
  49. }
  50. }
  51. newblock(nr)
  52. int nr;
  53. {
  54. Linerecord *l;
  55. List *frwrd;
  56. if ( debug) print("newblock at %d\n",nr);
  57. if ( nr>0 && currline && currline->linenr>= nr)
  58. {
  59. if ( debug) print("old line:%d\n",currline->linenr);
  60. error("Lines out of sequence");
  61. }
  62. frwrd=srchforward(nr);
  63. if ( frwrd && debug) print("forward found %d\n",frwrd->emlabel);
  64. l= srchline(nr);
  65. if ( l)
  66. {
  67. error("Line redefined");
  68. nr= -genlabel();
  69. }
  70. /* make new EM block structure */
  71. /* NOSTRICT */ l= (Linerecord *) salloc(sizeof(*l));
  72. l->emlabel= frwrd ? frwrd->emlabel : genlabel();
  73. l->linenr= nr;
  74. /* insert this record */
  75. if ( firstline)
  76. {
  77. currline->nextline=l;
  78. l->prevline= currline;
  79. lastline= currline=l;
  80. } else
  81. firstline = lastline =currline=l;
  82. }
  83. gotolabel(nr)
  84. int nr;
  85. {
  86. /* simulate a goto statement in the line record table */
  87. Linerecord *l1;
  88. List *ll;
  89. if (debug) print("goto label %d\n",nr);
  90. /* update currline */
  91. ll= newlist();
  92. ll-> linenr=nr;
  93. ll-> nextlist= currline->gotos;
  94. currline->gotos= ll;
  95. /* try to generate code */
  96. l1= srchline(nr);
  97. if ( (ll=srchforward(nr))!=0)
  98. nr= ll->emlabel;
  99. else
  100. if ( l1==0)
  101. {
  102. /* declare forward label */
  103. if (debug) print("declare forward %d\n",nr);
  104. ll= newlist();
  105. ll->emlabel= genlabel();
  106. ll-> linenr=nr;
  107. ll->nextlist= forwardlabel;
  108. forwardlabel= ll;
  109. nr= ll->emlabel;
  110. } else nr= l1->emlabel;
  111. return(nr);
  112. }
  113. gotostmt(nr)
  114. int nr;
  115. {
  116. C_bra((label) gotolabel(nr));
  117. }
  118. /* GOSUB-return, assume that proper entries are made to subroutines
  119. only. The return statement is triggered by a fake constant label */
  120. List *gosubhead, *gotail;
  121. int gosubcnt=1;
  122. List *gosublabel()
  123. {
  124. List *l;
  125. l= newlist();
  126. l->nextlist=0;
  127. l->emlabel=genlabel();
  128. if ( gotail){
  129. gotail->nextlist=l;
  130. gotail=l;
  131. } else gotail= gosubhead=l;
  132. gosubcnt++;
  133. return(l);
  134. }
  135. gosubstmt(lab)
  136. int lab;
  137. {
  138. List *l;
  139. int nr,n;
  140. n=gosubcnt;
  141. l= gosublabel();
  142. nr=gotolabel(lab);
  143. /*return index */
  144. C_loc((arith) n);
  145. /* administer legal return */
  146. C_cal("_gosub");
  147. C_asp((arith) BEMINTSIZE);
  148. C_bra((label) nr);
  149. C_df_ilb((label)l->emlabel);
  150. }
  151. genreturns()
  152. {
  153. int nr;
  154. nr= genlabel();
  155. C_df_dnam("returns");
  156. C_rom_ilb((label) nr);
  157. C_rom_cst((arith)1);
  158. C_rom_cst((arith) (gosubcnt-1));
  159. while ( gosubhead)
  160. {
  161. C_rom_ilb((label) gosubhead->emlabel);
  162. gosubhead= gosubhead->nextlist;
  163. }
  164. C_df_ilb((label) nr);
  165. C_loc((arith) 1);
  166. C_cal("error");
  167. }
  168. returnstmt()
  169. {
  170. C_cal("_retstmt");
  171. C_lfr((arith) BEMINTSIZE);
  172. C_lae_dnam("returns",(arith)0);
  173. C_csa((arith) BEMINTSIZE);
  174. }
  175. /* compound goto-gosub statements */
  176. List *jumphead,*jumptail;
  177. int jumpcnt;
  178. jumpelm(nr)
  179. int nr;
  180. {
  181. List *l;
  182. l= newlist();
  183. l->emlabel= gotolabel(nr);
  184. l->nextlist=0;
  185. if ( jumphead==0) jumphead = jumptail = l;
  186. else {
  187. jumptail->nextlist=l;
  188. jumptail=l;
  189. }
  190. jumpcnt++;
  191. }
  192. ongotostmt(type)
  193. int type;
  194. {
  195. /* generate the code itself, index in on top of the stack */
  196. /* blurh, store the number of entries in the descriptor */
  197. int firstlabel;
  198. int descr;
  199. List *l;
  200. /* create descriptor first */
  201. descr= genlabel();
  202. firstlabel=genlabel();
  203. C_df_dlb((label)descr);
  204. C_rom_ilb((label)firstlabel);
  205. C_rom_cst((arith) 1);
  206. C_rom_cst((arith)(jumpcnt-1));
  207. l= jumphead;
  208. while (l)
  209. {
  210. C_rom_ilb((label)l->emlabel);
  211. l= l->nextlist;
  212. }
  213. jumphead= jumptail=0; jumpcnt=0;
  214. if (debug) print("ongotst:%d labels\n", jumpcnt);
  215. conversion(type,INTTYPE);
  216. C_dup((arith) BEMINTSIZE);
  217. C_zlt(err_goto_label);
  218. C_lae_dlb((label) descr,(arith) 0);
  219. C_csa((arith) BEMINTSIZE);
  220. C_df_ilb((label)firstlabel);
  221. }
  222. ongosubstmt(type)
  223. int type;
  224. {
  225. List *l;
  226. int firstlabel;
  227. int descr;
  228. /* create descriptor first */
  229. descr= genlabel();
  230. firstlabel=genlabel();
  231. C_df_dlb((label)descr);
  232. C_rom_ilb((label)firstlabel);
  233. C_rom_cst((arith)1);
  234. C_rom_cst((arith)(jumpcnt-1));
  235. l= jumphead;
  236. while (l)
  237. {
  238. C_rom_ilb((label)l->emlabel);
  239. l= l->nextlist;
  240. }
  241. jumphead= jumptail=0;
  242. jumpcnt=0;
  243. l= newlist();
  244. l->nextlist=0;
  245. l->emlabel=firstlabel;
  246. if ( gotail){
  247. gotail->nextlist=l;
  248. gotail=l;
  249. } else gotail=gosubhead=l;
  250. /* save the return point of the gosub */
  251. C_loc((arith) gosubcnt);
  252. C_cal("_gosub");
  253. C_asp((arith) BEMINTSIZE);
  254. gosubcnt++;
  255. /* generate gosub */
  256. conversion(type,INTTYPE);
  257. C_dup((arith) BEMINTSIZE);
  258. C_zlt(err_goto_label);
  259. C_lae_dlb((label) descr,(arith) 0);
  260. C_csa((arith) BEMINTSIZE);
  261. C_df_ilb((label)firstlabel);
  262. }
  263. /* REGION ANALYSIS and FINAL VERSION GENERATION */