rmach.c 6.9 KB

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