help.c 5.6 KB

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