readk.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* This file must be included in the file "read_emk.c".
  7. It takes care of the reading of compact EM code.
  8. */
  9. #include <ctype.h>
  10. /* Since isascii is not standard, as c89 or C99, privide another method */
  11. #define IsAscii(_c) (((_c) & ~0x7f) == 0)
  12. /* get16, get32: read a signed constant
  13. */
  14. static int get16()
  15. {
  16. int l_byte, h_byte;
  17. l_byte = getbyte();
  18. h_byte = getbyte();
  19. if (h_byte >= 128) h_byte -= 256;
  20. return l_byte | (h_byte << 8);
  21. }
  22. static arith get32()
  23. {
  24. arith l;
  25. int h_byte;
  26. l = getbyte();
  27. l |= ((unsigned) getbyte() << 8);
  28. l |= ((arith) getbyte() << 16);
  29. h_byte = getbyte();
  30. if (h_byte >= 128) h_byte -= 256;
  31. return l | ((arith) h_byte << 24);
  32. }
  33. static struct string *getstring();
  34. /* getarg : read an argument of any type, and check it against "typset"
  35. if neccesary. Put result in "ap".
  36. */
  37. static void getarg(int typset, struct e_arg *ap)
  38. {
  39. int i = getbyte();
  40. #ifdef CHECKING
  41. int argtyp;
  42. #endif /* CHECKING */
  43. ap->ema_argtype = 0;
  44. switch(i) {
  45. default:
  46. if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) { /* A cst */
  47. ap->ema_cst = i - sp_zcst0;
  48. ap->ema_argtype = cst_ptyp;
  49. i = sp_cst2;
  50. }
  51. break;
  52. case sp_dlb1: /* Numeric data label encoded in one byte */
  53. ap->ema_dlb = getbyte();
  54. ap->ema_szoroff = 0;
  55. ap->ema_argtype = nof_ptyp;
  56. break;
  57. case sp_dlb2: /* Numeric data label encoded in two bytes */
  58. ap->ema_dlb = get16();
  59. ap->ema_szoroff = 0;
  60. ap->ema_argtype = nof_ptyp;
  61. #ifdef CHECKING
  62. if (ap->ema_dlb > 32767 && !EM_error) {
  63. EM_error = "Illegal data label";
  64. break;
  65. }
  66. #endif /* CHECKING */
  67. break;
  68. case sp_ilb1: /* Instruction label encoded in one byte */
  69. ap->ema_ilb = getbyte();
  70. ap->ema_argtype = ilb_ptyp;
  71. break;
  72. case sp_ilb2: /* Instruction label encoded in two bytes */
  73. ap->ema_ilb = get16();
  74. ap->ema_argtype = ilb_ptyp;
  75. #ifdef CHECKING
  76. if (ap->ema_ilb > 32767 && !EM_error) {
  77. EM_error = "Illegal instruction label";
  78. break;
  79. }
  80. #endif /* CHECKING */
  81. break;
  82. case sp_cst2: /* A cst encoded in two bytes */
  83. ap->ema_cst = get16();
  84. ap->ema_argtype = cst_ptyp;
  85. break;
  86. case sp_cst4: /* A cst encoded in four bytes */
  87. ap->ema_cst = get32();
  88. ap->ema_argtype = cst_ptyp;
  89. break;
  90. case sp_pnam: /* A procedure name */
  91. {
  92. struct string *p;
  93. p = getstring(1);
  94. ap->ema_pnam = p->str;
  95. ap->ema_argtype = pro_ptyp;
  96. break;
  97. }
  98. case sp_dnam: /* A Non-numeric data label */
  99. {
  100. struct string *p;
  101. p = getstring(1);
  102. ap->ema_dnam = p->str;
  103. ap->ema_szoroff = 0;
  104. ap->ema_argtype = sof_ptyp;
  105. break;
  106. }
  107. case sp_doff: /* A data label + offset */
  108. {
  109. struct e_arg dummy;
  110. getarg(lab_ptyp, ap);
  111. getarg(cst_ptyp, &dummy);
  112. ap->ema_szoroff = dummy.ema_cst;
  113. break;
  114. }
  115. case sp_icon: /* An integer constant */
  116. case sp_ucon: /* An unsigned constant */
  117. case sp_fcon: /* A floating constant */
  118. {
  119. struct string *p;
  120. getarg(cst_ptyp, ap);
  121. ap->ema_szoroff = ap->ema_cst;
  122. p = getstring(0);
  123. ap->ema_argtype = ptyp(i);
  124. ap->ema_string = p->str;
  125. break;
  126. }
  127. case sp_scon: /* A string constant */
  128. {
  129. struct string *p;
  130. p = getstring(0);
  131. ap->ema_argtype = str_ptyp;
  132. ap->ema_string = p->str;
  133. ap->ema_szoroff = p->length;
  134. break;
  135. }
  136. }
  137. #ifdef CHECKING
  138. argtyp = i;
  139. if (EM_error) return;
  140. if (i == EOF) {
  141. xfatal("Unexpected EOF");
  142. return;
  143. }
  144. if ((i -= sp_fspec) < 0 || i >= 16) {
  145. xerror("Illegal byte");
  146. return;
  147. }
  148. if ((typset & (1 << i)) == 0 && !EM_error) {
  149. EM_error = "Bad argument type";
  150. }
  151. if (argtyp == sp_cend) {
  152. ap->ema_argtype = 0;
  153. }
  154. #else /* not CHECKING */
  155. if (i == sp_cend) {
  156. ap->ema_argtype = 0;
  157. }
  158. #endif /* CHECKING */
  159. }
  160. #ifdef CHECKING
  161. /* checkident: check that a string indeed represents an identifier
  162. */
  163. static int checkident(struct string *s)
  164. {
  165. char *p;
  166. int n;
  167. p = s->str;
  168. if (!IsAscii(*p) || (!isalpha(*p) && *p != '_')) {
  169. return 0;
  170. }
  171. p++;
  172. for (n = s->length; --n > 0; p++) {
  173. if (!IsAscii(*p) || (!isalnum(*p) && *p != '_')) {
  174. return 0;
  175. }
  176. }
  177. return 1;
  178. }
  179. #endif /* CHECKING */
  180. /* getstring: read a string from the input
  181. */
  182. /*ARGSUSED*/
  183. static struct string *getstring(int isident)
  184. {
  185. char *p;
  186. int n;
  187. struct string *s = &string;
  188. struct e_arg dummy;
  189. getarg(cst_ptyp, &dummy);
  190. /* Read length of string */
  191. n = dummy.ema_cst;
  192. #ifdef CHECKING
  193. if (n < 0) {
  194. xerror("Negative length in string");
  195. s->length = 0;
  196. return s;
  197. }
  198. #endif /* CHECKING */
  199. if (n > s->maxlen) {
  200. if (! s->maxlen) {
  201. s->str = Malloc(s->maxlen = 256);
  202. }
  203. else s->str = Realloc(s->str, (s->maxlen = (n+255)&~255));
  204. }
  205. s->length = n;
  206. p = s->str;
  207. while (--n >= 0) {
  208. *p++ = getbyte();
  209. }
  210. *p++ = '\0';
  211. #ifdef CHECKING
  212. if (isident) {
  213. if (!checkident(s) && !EM_error) {
  214. EM_error = "Illegal identifier";
  215. }
  216. }
  217. #endif /* CHECKING */
  218. return s;
  219. }
  220. /* gethead: read the start of an EM-line
  221. */
  222. static void gethead(struct e_instr *p)
  223. {
  224. int i;
  225. EM_lineno++;
  226. if ((i = getbyte()) < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
  227. /* A mnemonic */
  228. p->em_type = EM_MNEM;
  229. p->em_opcode = i;
  230. return;
  231. }
  232. if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) { /* A pseudo */
  233. if (i == ps_mes) {
  234. p->em_type = EM_STARTMES;
  235. }
  236. else p->em_type = EM_PSEU;
  237. p->em_opcode = i;
  238. return;
  239. }
  240. if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) { /* Instruction label */
  241. p->em_type = EM_DEFILB;
  242. p->em_argtype = ilb_ptyp;
  243. p->em_ilb = i - sp_filb0;
  244. return;
  245. }
  246. switch(i) {
  247. case sp_ilb1: /* Instruction label */
  248. p->em_type = EM_DEFILB;
  249. p->em_argtype = ilb_ptyp;
  250. p->em_ilb = getbyte();
  251. break;
  252. case sp_ilb2: /* Instruction label */
  253. p->em_type = EM_DEFILB;
  254. p->em_argtype = ilb_ptyp;
  255. p->em_ilb = get16();
  256. #ifdef CHECKING
  257. if (p->em_ilb > 32767 && !EM_error) {
  258. EM_error = "Illegal instruction label definition";
  259. }
  260. #endif /* CHECKING */
  261. break;
  262. case sp_dlb1: /* Numeric data label */
  263. p->em_type = EM_DEFDLB;
  264. p->em_argtype = nof_ptyp;
  265. p->em_dlb = getbyte();
  266. break;
  267. case sp_dlb2: /* Numeric data label */
  268. p->em_type = EM_DEFDLB;
  269. p->em_argtype = nof_ptyp;
  270. p->em_dlb = get16();
  271. #ifdef CHECKING
  272. if (p->em_dlb > 32767 && !EM_error) {
  273. EM_error = "Illegal data label definition";
  274. }
  275. #endif /* CHECKING */
  276. break;
  277. case sp_dnam: /* Non-numeric data label */
  278. {
  279. struct string *s;
  280. p->em_type = EM_DEFDNAM;
  281. p->em_argtype = sof_ptyp;
  282. if (!(s = getstring(1))) {
  283. p->em_dnam = "";
  284. }
  285. else p->em_dnam = s->str;
  286. break;
  287. }
  288. case EOF: /* End of file */
  289. p->em_type = EM_EOF;
  290. return;
  291. default:
  292. xerror("Unknown opcode");
  293. break;
  294. }
  295. return;
  296. }