help.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. #if __STDC__
  2. #include <stdarg.h>
  3. extern out(char *, ...);
  4. extern error(char *, ...);
  5. #else
  6. #include <varargs.h>
  7. #endif
  8. #include "decl.h"
  9. /* All the functions in this file will be called by the parser.
  10. */
  11. extern char *strindex();
  12. static struct Op_info { char *name, *type; }
  13. op_info[ MAX_OPERANDS] = { { 0, 0}};
  14. static int n_ops = 0; /* Number of opertands of current
  15. * assembly instruction.
  16. */
  17. static char *assem_instr = 0; /* Name of the current assembly instr */
  18. static Bool restriction = FALSE; /* Is there a restriction on the
  19. * current operand?
  20. */
  21. File *outfile;
  22. save_instr( instr, len)
  23. char *instr;
  24. int len;
  25. {
  26. assem_instr = Salloc( instr, len + 1);
  27. }
  28. save_name( name, len)
  29. char *name;
  30. int len;
  31. {
  32. op_info[ n_ops].name = Salloc( name, len + 1);
  33. }
  34. save_type( type, len)
  35. char *type;
  36. int len;
  37. {
  38. op_info[ n_ops].type = Salloc( type, len + 1);
  39. restriction = TRUE;
  40. }
  41. pr_header()
  42. {
  43. out( "%s_instr", assem_instr);
  44. param_list();
  45. out( "{\n");
  46. save_mnem( assem_instr);
  47. }
  48. param_list()
  49. {
  50. int i;
  51. out( "(");
  52. if ( n_ops > 0) {
  53. out( " %s", op_info[0].name);
  54. for ( i = 1; i < n_ops; i++)
  55. out( ", %s", op_info[i].name);
  56. }
  57. out( ")\n");
  58. if ( n_ops > 0) {
  59. out( "struct t_operand *%s", op_info[0].name);
  60. for ( i = 1; i < n_ops; i++)
  61. out( ", *%s", op_info[i].name);
  62. out( ";\n");
  63. }
  64. }
  65. pr_restriction()
  66. {
  67. int i;
  68. Bool more = FALSE;
  69. if ( !restriction)
  70. return;
  71. out( "if ( ");
  72. for ( i = 0; i < n_ops; i++)
  73. if ( op_info[i].type != 0) {
  74. if ( more)
  75. out( " &&");
  76. out( " %s( %s)", op_info[i].type, op_info[i].name);
  77. more = TRUE;
  78. }
  79. out( ") ");
  80. }
  81. pr_warning()
  82. {
  83. if ( restriction)
  84. out( "else\nerror( \"No match for %s\");\n", assem_instr);
  85. restriction = FALSE;
  86. }
  87. clear_restriction()
  88. {
  89. restriction = FALSE;
  90. }
  91. char *skip_string( str)
  92. char *str;
  93. /* returns position after the first '"'-charcter, look out for '\' escape
  94. * sequence
  95. */
  96. {
  97. for ( str++; *str != '"' || *(str-1) == '\\'; str++);
  98. return( str + 1);
  99. }
  100. pr_subroutine( str)
  101. char *str;
  102. {
  103. out( "%s;\n", str);
  104. }
  105. #include <ctype.h>
  106. pr_call( str)
  107. char *str;
  108. /* Ouput 'str', but keep track of the number of bytes and take care of
  109. * conversions like %$.
  110. */
  111. {
  112. if ( strncmp( "text", str, 4) == 0 && isdigit( *(str+4)))
  113. out( "cur_pos += %d;\n", *(str+4) - '0');
  114. else if ( strncmp( "reloc", str, 5) == 0 && isdigit( *(str+5)))
  115. out( "cur_pos += %d;\n", *(str+5) - '0');
  116. pr_text_with_conversions( str);
  117. out( "fprint( outfile, \";\");");
  118. }
  119. pr_end()
  120. {
  121. out( "fprint( outfile, \"}\\n\");");
  122. }
  123. pr_els()
  124. {
  125. out( "fprint( outfile, \"else\\n\");");
  126. }
  127. pr_else()
  128. {
  129. out( "fprint( outfile, \"else {\\n\");");
  130. }
  131. pr_question( quest)
  132. char *quest;
  133. {
  134. out( "fprint( outfile, \"if\");");
  135. pr_text_with_conversions( quest);
  136. out( "fprint( outfile, \"{\\n\");");
  137. }
  138. init_table()
  139. {
  140. outfile = STDOUT;
  141. out( "#include \"as.h\"\n");
  142. out( "#include \"as_parser.h\"\n");
  143. }
  144. clean()
  145. /* Free space, allocated during the parsing of an entry in 'as_table'.
  146. */
  147. {
  148. int i;
  149. if ( assem_instr != 0) {
  150. free( assem_instr);
  151. assem_instr = 0;
  152. }
  153. for ( i = 0; i < n_ops; i++) {
  154. free( op_info[i].name);
  155. op_info[i].name = 0;
  156. if ( op_info[i].type != 0) {
  157. free( op_info[i].type);
  158. op_info[i].type = 0;
  159. }
  160. }
  161. n_ops = 0;
  162. }
  163. operand_clean()
  164. /* Free space for the operands */
  165. {
  166. int i;
  167. for ( i = 0; i < n_ops; i++) {
  168. free( op_info[i].name);
  169. op_info[i].name = 0;
  170. if ( op_info[i].type != 0) {
  171. free( op_info[i].type);
  172. op_info[i].type = 0;
  173. }
  174. }
  175. n_ops = 0;
  176. }
  177. #if __STDC__
  178. /*VARARGS*/
  179. out(char *fmt, ...)
  180. {
  181. va_list pvar;
  182. va_start(pvar, fmt);
  183. doprnt( outfile, fmt, pvar);
  184. va_end(pvar);
  185. }
  186. extern int nerrors;
  187. /*VARARGS*/
  188. error(char *fmt, ...)
  189. {
  190. va_list pvar;
  191. nerrors++;
  192. va_start(pvar, fmt);
  193. fprint( STDERR, "!! ERROR : ");
  194. doprnt( STDERR, fmt, pvar);
  195. fprint( STDERR, " !!\n");
  196. va_end(pvar);
  197. }
  198. #else
  199. /*VARARGS*/
  200. out(va_alist)
  201. va_dcl
  202. {
  203. va_list pvar;
  204. char *fmt;
  205. va_start(pvar);
  206. fmt = va_arg(pvar, char *);
  207. doprnt( outfile, fmt, pvar);
  208. va_end(pvar);
  209. }
  210. extern int nerrors;
  211. /*VARARGS*/
  212. error(va_alist)
  213. va_dcl
  214. {
  215. char *fmt;
  216. va_list pvar;
  217. nerrors++;
  218. va_start(pvar);
  219. fmt = va_arg(pvar, char *);
  220. fprint( STDERR, "!! ERROR : ");
  221. doprnt( STDERR, fmt, pvar);
  222. fprint( STDERR, " !!\n");
  223. va_end(pvar);
  224. }
  225. #endif
  226. inc_ops()
  227. {
  228. n_ops++;
  229. }
  230. /**********************************/
  231. char *mnemonic[ MAX_MNEMONICS];
  232. int n_mnems = 0;
  233. save_mnem( mnem)
  234. char *mnem;
  235. {
  236. if ( n_mnems == MAX_MNEMONICS)
  237. error( "too many assembler instructions!! MAX_MNEMONICS = %d",
  238. MAX_MNEMONICS);
  239. else
  240. mnemonic[ n_mnems++] = Salloc( mnem, strlen( mnem) + 1);
  241. }
  242. end_table()
  243. /* Flush information in the array 'mnemonic'
  244. */
  245. {
  246. int i;
  247. quicksort( 0, n_mnems - 1);
  248. out( "char *mnemonic[] = {\n");
  249. for ( i = 0; i < n_mnems - 1; i++)
  250. out( "\t\"%s\",\n", mnemonic[i]);
  251. out( "\t\"%s\"};\n\n", mnemonic[ n_mnems-1]);
  252. out( "int (*instruction[])() = {\n");
  253. for ( i = 0; i < n_mnems - 1; i++)
  254. out( "\t%s_instr,\n", mnemonic[i]);
  255. out( "\t%s_instr};\n\n", mnemonic[ n_mnems-1]);
  256. out( "int n_mnems = %d;\n", n_mnems);
  257. }
  258. quicksort( lower, upper)
  259. int lower, upper;
  260. /* Sort the array 'mnemonic'.
  261. */
  262. {
  263. char *key, *tmp;
  264. int index1, index2;
  265. if ( lower >= upper)
  266. return;
  267. key = mnemonic[lower];
  268. index1 = lower;
  269. index2 = upper+1;
  270. while ( index1 < index2) {
  271. do
  272. index1++;
  273. while (index1 <= upper && strcmp( mnemonic[index1], key) < 0 );
  274. do
  275. index2--;
  276. while ( strcmp( mnemonic[index2], key) > 0);
  277. if ( index1 < index2) {
  278. tmp = mnemonic[index2];
  279. mnemonic[index2] = mnemonic[index1];
  280. mnemonic[index1] = tmp;
  281. }
  282. }
  283. mnemonic[lower] = mnemonic[index2];
  284. mnemonic[index2] = key;
  285. quicksort( lower, index2-1);
  286. quicksort( index2+1, upper);
  287. }