rmach.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. *
  4. * This product is part of the Amsterdam Compiler Kit.
  5. *
  6. * Permission to use, sell, duplicate or disclose this software must be
  7. * obtained in writing. Requests for such permissions may be sent to
  8. *
  9. * Dr. Andrew S. Tanenbaum
  10. * Wiskundig Seminarium
  11. * Vrije Universiteit
  12. * Postbox 7161
  13. * 1007 MC Amsterdam
  14. * The Netherlands
  15. *
  16. */
  17. #include "ack.h"
  18. #include "../../h/em_path.h"
  19. #include "list.h"
  20. #include "trans.h"
  21. #include "grows.h"
  22. #include "dmach.h"
  23. #include "data.h"
  24. #include <stdio.h>
  25. #ifndef NORCSID
  26. static char rcs_id[] = "$Header$" ;
  27. static char rcs_dmach[] = RCS_DMACH ;
  28. #endif
  29. /************************************************************************/
  30. /* */
  31. /* Read machine definitions and transformations */
  32. /* */
  33. /************************************************************************/
  34. #define COMMENT '#'
  35. #define VAR "var"
  36. #define PASS "name"
  37. #define IN "from"
  38. #define OUT "to"
  39. #define PROG "program"
  40. #define MAPF "mapflag"
  41. #define ARGS "args"
  42. #define PROP "prop"
  43. #define RUNT "rts"
  44. #define NEEDT "need"
  45. #define END "end"
  46. extern growstring scanb();
  47. extern growstring scanvars();
  48. int getline() ;
  49. int getinchar() ;
  50. static char *ty_name ;
  51. static char *bol ;
  52. static char *inname ;
  53. setlist(name) char *name ; {
  54. /* Name is sought in the internal tables,
  55. if not present, the a file of that name is sought
  56. in first the current and then the EM Lib directory
  57. */
  58. inname=name ;
  59. open_in(name) ;
  60. while ( getline() ) {
  61. if ( strcmp(VAR,ty_name)==0 ) {
  62. doassign(bol,(char *)0,0) ;
  63. } else
  64. if ( strcmp(PASS,ty_name)==0 ) {
  65. intrf() ;
  66. } else
  67. error("unknown keyword %s",ty_name) ;
  68. }
  69. close_in();
  70. #ifdef DEBUG
  71. if ( debug>=3 ) vprint("End %s\n",name) ;
  72. #endif
  73. }
  74. intrf() {
  75. register trf *new ;
  76. register char *ptr ;
  77. growstring bline, vline ;
  78. int twice ;
  79. new= (trf *)getcore(sizeof *new) ;
  80. new->t_name= keeps(bol) ;
  81. for (;;) {
  82. if ( !getline() ) {
  83. fuerror("unexpected EOF on %s",inname) ;
  84. }
  85. twice= NO ;
  86. if ( strcmp(ty_name,IN)==0 ) {
  87. if ( new->t_in ) twice=YES ;
  88. new->t_in= keeps(bol);
  89. } else
  90. if ( strcmp(ty_name,OUT)==0 ) {
  91. if ( new->t_out ) twice=YES ;
  92. new->t_out= keeps(bol);
  93. } else
  94. if ( strcmp(ty_name,PROG)==0 ) {
  95. if ( new->t_prog ) twice=YES ;
  96. bline= scanb(bol); /* Scan for \ */
  97. vline= scanvars(gr_start(bline)); /* Scan for {} */
  98. gr_throw(&bline);
  99. new->t_prog= gr_final(&vline);
  100. clr_noscan(new->t_prog);
  101. } else
  102. if ( strcmp(ty_name,MAPF)==0 ) {
  103. /* First read the mapflags line
  104. and scan for backslashes */
  105. bline= scanb(bol) ;
  106. l_add(&new->t_mapf,gr_final(&bline)) ;
  107. } else
  108. if ( strcmp(ty_name,ARGS)==0 ) {
  109. if ( new->t_argd ) twice=YES ;
  110. bline= scanb(bol) ;
  111. new->t_argd= keeps(gr_start(bline)) ;
  112. gr_throw(&bline) ;
  113. } else
  114. if ( strcmp(ty_name,PROP)==0 ) {
  115. for ( ptr=bol ; *ptr ; ptr++ ) {
  116. switch( *ptr ) {
  117. case C_IN: new->t_stdin= YES ; break ;
  118. case C_OUT: new->t_stdout= YES ; break ;
  119. case 'P': new->t_isprep= YES ; break ;
  120. case 'p': new->t_prep= YES ; break ;
  121. case 'm': new->t_prep= MAYBE ; break ;
  122. case 'O': new->t_optim= YES ; break ;
  123. case 'C': new->t_combine= YES ; break ;
  124. default :
  125. error("Unkown option %c in %s for %s",
  126. *ptr,new->t_name,inname) ;
  127. break ;
  128. }
  129. }
  130. } else
  131. if ( strcmp(ty_name,RUNT)==0 ) {
  132. if ( new->t_rts ) twice=YES ;
  133. new->t_rts= keeps(bol) ;
  134. } else
  135. if ( strcmp(ty_name,NEEDT)==0 ) {
  136. if ( new->t_needed ) twice=YES ;
  137. new->t_needed= keeps(bol) ;
  138. } else
  139. if ( strcmp(ty_name,END)==0 ) {
  140. break ;
  141. } else {
  142. fuerror("illegal keyword %s %s",ty_name,bol);
  143. }
  144. if ( twice ) {
  145. werror("%s: specified twice for %s",
  146. ty_name, new->t_name) ;
  147. }
  148. }
  149. if ( ! ( new->t_name && new->t_out && new->t_prog ) ) {
  150. fuerror("insufficient specification for %s in %s",
  151. new->t_name,inname) ;
  152. }
  153. if ( ! new->t_argd ) new->t_argd="" ;
  154. #ifdef DEBUG
  155. if ( debug>=3 ) {
  156. register list_elem *elem ;
  157. vprint("%s: from %s to %s '%s'\n",
  158. new->t_name,new->t_in,new->t_out,new->t_prog) ;
  159. vprint("\targs: ") ; prns(new->t_argd) ;
  160. scanlist( l_first(new->t_mapf), elem ) {
  161. vprint("\t%s\n",l_content(*elem)) ;
  162. }
  163. if ( new->t_rts ) vprint("\trts: %s\n",new->t_rts) ;
  164. if ( new->t_needed ) vprint("\tneeded: %s\n",new->t_needed) ;
  165. }
  166. #endif
  167. l_add(&tr_list,(char *)new) ;
  168. }
  169. /************************** IO from core or file *******************/
  170. static int incore ;
  171. static growstring rline ;
  172. static FILE *infile ;
  173. static char *inptr ;
  174. open_in(name) register char *name ; {
  175. register dmach *cmac ;
  176. gr_init(&rline) ;
  177. for ( cmac= massoc ; cmac->ma_index!= -1 ; cmac++ ) {
  178. if ( strcmp(name,cmac->ma_name)==0 ) {
  179. incore=YES ;
  180. inptr= &intable[cmac->ma_index] ;
  181. return ;
  182. }
  183. }
  184. /* Not in core */
  185. incore= NO ;
  186. #ifdef NEW
  187. gr_cat(&rline,EM_DIR) ;
  188. gr_cat(&rline,"/lib/n_ack/") ;
  189. #else
  190. gr_cat(&rline,ACK_DIR); gr_cat(&rline,"/") ;
  191. #endif
  192. gr_cat(&rline,name) ;
  193. infile= fopen(gr_start(rline),"r") ;
  194. #ifdef NEW
  195. if ( !infile ) {
  196. /* Try to read EM_DIR/lib/MACH/plan */
  197. gr_throw(&rline) ;
  198. gr_cat(&rline,EM_DIR) ;
  199. gr_cat(&rline,"/lib/") ; gr_cat(&rline,name) ;
  200. gr_cat(&rline,"/plan") ;
  201. infile= fopen(gr_start(rline),"r") ;
  202. }
  203. #endif
  204. if ( !infile ) {
  205. infile= fopen(name,"r") ;
  206. }
  207. if ( infile==NULL ) {
  208. fuerror("Cannot find description for %s",name) ;
  209. }
  210. }
  211. close_in() {
  212. if ( !incore ) fclose(infile) ;
  213. gr_throw(&rline) ;
  214. }
  215. char *readline() {
  216. /* Get a line from the input,
  217. return 0 if at end,
  218. The line is stored in a volatile buffer,
  219. a pointer to the line is returned.
  220. */
  221. register int nchar ;
  222. enum { BOL, ESCAPE, SKIPPING, MOL } state = BOL ;
  223. gr_throw(&rline) ;
  224. for (;;) {
  225. nchar= getinchar() ;
  226. if ( nchar==EOF ) {
  227. if ( state!=BOL ) {
  228. werror("incomplete line in %s", inname) ;
  229. }
  230. return 0 ;
  231. }
  232. if ( state==SKIPPING ) {
  233. if ( nchar=='\n' ) {
  234. state= MOL ;
  235. } else {
  236. continue ;
  237. }
  238. }
  239. if ( state==ESCAPE ) {
  240. switch( nchar ) {
  241. case '\n' :
  242. break ;
  243. default :
  244. gr_add(&rline,BSLASH) ;
  245. case COMMENT :
  246. case BSLASH :
  247. gr_add(&rline,nchar) ;
  248. break ;
  249. }
  250. state= MOL ;
  251. continue ;
  252. }
  253. switch ( nchar ) {
  254. case '\n' : gr_add(&rline,0) ;
  255. return gr_start(rline) ;
  256. case COMMENT : state= SKIPPING ;
  257. break ;
  258. case BSLASH : state= ESCAPE ;
  259. break ;
  260. default : gr_add(&rline,nchar) ;
  261. state= MOL ;
  262. }
  263. }
  264. }
  265. int getinchar() {
  266. if ( incore ) {
  267. if ( *inptr==0 ) return EOF ;
  268. return *inptr++ ;
  269. }
  270. return getc(infile) ;
  271. }
  272. int getline() {
  273. register char *c_ptr ;
  274. do {
  275. if ( (c_ptr=readline())==(char *)0 ) return 0 ;
  276. ty_name= skipblank(c_ptr) ;
  277. } while ( *ty_name==0 ) ;
  278. c_ptr= firstblank(ty_name) ;
  279. if ( *c_ptr ) {
  280. *c_ptr++ =0 ;
  281. c_ptr= skipblank(c_ptr) ;
  282. }
  283. bol= c_ptr ;
  284. return 1 ;
  285. }