readk.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /* $Header$ */
  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. /* get16, get32: read a signed constant
  11. */
  12. PRIVATE int
  13. get16()
  14. {
  15. register int l_byte, h_byte;
  16. l_byte = getbyte();
  17. h_byte = getbyte();
  18. if (h_byte >= 128) h_byte -= 256;
  19. return l_byte | (h_byte << 8);
  20. }
  21. PRIVATE arith
  22. get32()
  23. {
  24. register arith l;
  25. register 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. PRIVATE struct string *getstring();
  34. /* getarg : read an argument of any type, and check it against "typset"
  35. if neccesary. Return a pointer to the argument.
  36. */
  37. PRIVATE struct e_args *
  38. getarg(typset)
  39. {
  40. register struct e_args *ap = argentry();
  41. register int i = getbyte();
  42. #ifdef CHECKING
  43. int argtyp;
  44. #endif CHECKING
  45. ap->em_next = 0;
  46. switch(i) {
  47. default:
  48. if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) { /* A cst */
  49. ap->em_cst = i - sp_zcst0;
  50. ap->em_argtype = cst_ptyp;
  51. i = sp_cst2;
  52. }
  53. break;
  54. case sp_dlb1: /* Numeric data label encoded in one byte */
  55. ap->em_dlb = getbyte();
  56. ap->em_noff = 0;
  57. ap->em_argtype = nof_ptyp;
  58. break;
  59. case sp_dlb2: /* Numeric data label encoded in two bytes */
  60. ap->em_dlb = get16();
  61. ap->em_noff = 0;
  62. ap->em_argtype = nof_ptyp;
  63. #ifdef CHECKING
  64. if (ap->em_dlb < 0) {
  65. xerror("Illegal data label");
  66. break;
  67. }
  68. #endif CHECKING
  69. break;
  70. case sp_ilb1: /* Instruction label encoded in one byte */
  71. ap->em_ilb = getbyte();
  72. ap->em_argtype = ilb_ptyp;
  73. break;
  74. case sp_ilb2: /* Instruction label encoded in two bytes */
  75. ap->em_ilb = get16();
  76. ap->em_argtype = ilb_ptyp;
  77. #ifdef CHECKING
  78. if (ap->em_ilb < 0) {
  79. xerror("Illegal instruction label");
  80. break;
  81. }
  82. #endif CHECKING
  83. break;
  84. case sp_cst2: /* A cst encoded in two bytes */
  85. ap->em_cst = get16();
  86. ap->em_argtype = cst_ptyp;
  87. break;
  88. case sp_cst4: /* A cst encoded in four bytes */
  89. ap->em_cst = get32();
  90. ap->em_argtype = cst_ptyp;
  91. break;
  92. case sp_pnam: /* A procedure name */
  93. {
  94. register struct string *p;
  95. p = getstring(1);
  96. #ifdef CHECKING
  97. if (state & INSTRING) {
  98. xerror("Procedure name too long");
  99. }
  100. #endif CHECKING
  101. ap->em_pnam = p->str;
  102. ap->em_argtype = pro_ptyp;
  103. break;
  104. }
  105. case sp_dnam: /* A Non-numeric data label */
  106. {
  107. register struct string *p;
  108. p = getstring(1);
  109. #ifdef CHECKING
  110. if (state & INSTRING) {
  111. xerror("Data label too long");
  112. }
  113. #endif CHECKING
  114. ap->em_dnam = p->str;
  115. ap->em_soff = 0;
  116. ap->em_argtype = sof_ptyp;
  117. break;
  118. }
  119. case sp_doff: /* A data label + offset */
  120. {
  121. register struct e_args *ap1;
  122. ap1 = getarg(lab_ptyp);
  123. *ap = *ap1;
  124. i_emargs--;
  125. ap1 = getarg(cst_ptyp);
  126. if (ap->em_argtype == sof_ptyp) { /* non-numeric label */
  127. ap->em_soff = ap1->em_cst;
  128. }
  129. else ap->em_noff = ap1->em_cst;
  130. i_emargs--;
  131. break;
  132. }
  133. case sp_icon: /* An integer constant */
  134. case sp_ucon: /* An unsigned constant */
  135. case sp_fcon: /* A floating constant */
  136. {
  137. register struct string *p;
  138. ap->em_size = getarg(cst_ptyp)->em_cst;
  139. i_emargs--;
  140. p = getstring(0);
  141. #ifdef CHECKING
  142. if (state & INSTRING) {
  143. xerror("Numeric constant too long");
  144. }
  145. #endif CHECKING
  146. ap->em_argtype = ptyp(i);
  147. ap->em_str = p->str;
  148. break;
  149. }
  150. case sp_scon: /* A string constant */
  151. {
  152. register struct string *p;
  153. p = getstring(0);
  154. ap->em_argtype = str_ptyp;
  155. ap->em_str = p->str;
  156. ap->em_size = p->length;
  157. break;
  158. }
  159. }
  160. #ifdef CHECKING
  161. argtyp = i;
  162. if (EM_error) return 0;
  163. if (i == EOF) {
  164. xfatal("Unexpected EOF");
  165. return 0;
  166. }
  167. if ((i -= sp_fspec) < 0 || i >= 16) {
  168. xerror("Illegal byte");
  169. return 0;
  170. }
  171. if ((typset & (1 << i)) == 0) {
  172. xerror("Bad argument type");
  173. }
  174. if (argtyp == sp_cend) return 0;
  175. #else not CHECKING
  176. if (i == sp_cend) return 0;
  177. #endif CHECKING
  178. return ap;
  179. }
  180. #ifdef CHECKING
  181. /* checkident: check that a string indeed represents an identifier
  182. */
  183. PRIVATE int
  184. checkident(s)
  185. register struct string *s;
  186. {
  187. register char *p;
  188. register int n;
  189. p = s->str;
  190. if (!isascii(*p) || (!isalpha(*p) && *p != '_')) {
  191. return 0;
  192. }
  193. p++;
  194. for (n = s->length; --n > 0; p++) {
  195. if (!isascii(*p) || (!isalnum(*p) && *p != '_')) {
  196. return 0;
  197. }
  198. }
  199. return 1;
  200. }
  201. #endif CHECKING
  202. /* getstring: read a string from the input, but at most STRSIZ characters
  203. of it. The next characters will be read another time around
  204. */
  205. /*ARGSUSED*/
  206. PRIVATE struct string *
  207. getstring(isident)
  208. {
  209. register char *p;
  210. register int n;
  211. register struct string *s;
  212. if (!(state & INSTRING)) { /* Not reading a string yet */
  213. struct e_args *ap = getarg(cst_ptyp);
  214. /* Read length of string */
  215. i_emargs--;
  216. strleft = ap->em_cst;
  217. #ifdef CHECKING
  218. if (strleft < 0) {
  219. xerror("Negative length in string");
  220. return 0;
  221. }
  222. #endif CHECKING
  223. }
  224. s = stringentry();
  225. if (strleft <= STRSIZ) { /* Handle the whole string */
  226. n = strleft;
  227. state &= ~INSTRING;
  228. }
  229. else { /* Handle STRSIZ characters of it, and
  230. indicate that there is more
  231. */
  232. n = STRSIZ;
  233. strleft -= STRSIZ;
  234. state |= INSTRING;
  235. }
  236. s->length = n;
  237. p = s->str;
  238. while (--n >= 0) {
  239. *p++ = getbyte();
  240. }
  241. *p++ = '\0';
  242. #ifdef CHECKING
  243. if (isident) {
  244. if (!checkident(s)) {
  245. xerror("Illegal identifier");
  246. }
  247. }
  248. #endif CHECKING
  249. return s;
  250. }
  251. /* gethead: read the start of an EM-line
  252. */
  253. PRIVATE struct e_instr *
  254. gethead()
  255. {
  256. register int i;
  257. register struct e_instr *p = &emhead;
  258. EM_lineno++;
  259. if ((i = getbyte()) < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
  260. /* A mnemonic */
  261. p->em_type = EM_MNEM;
  262. p->em_opcode = i;
  263. return p;
  264. }
  265. if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) { /* A pseudo */
  266. if (i == ps_mes) {
  267. p->em_type = EM_STARTMES;
  268. }
  269. else p->em_type = EM_PSEU;
  270. p->em_opcode = i;
  271. return p;
  272. }
  273. if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) { /* Instruction label */
  274. p->em_type = EM_DEFILB;
  275. p->em_deflb = i - sp_filb0;
  276. return p;
  277. }
  278. switch(i) {
  279. case sp_ilb1: /* Instruction label */
  280. p->em_type = EM_DEFILB;
  281. p->em_deflb = getbyte();
  282. break;
  283. case sp_ilb2: /* Instruction label */
  284. p->em_type = EM_DEFILB;
  285. p->em_deflb = get16();
  286. #ifdef CHECKING
  287. if (p->em_deflb < 0) {
  288. xerror("Illegal instruction label definition");
  289. }
  290. #endif CHECKING
  291. break;
  292. case sp_dlb1: /* Numeric data label */
  293. p->em_type = EM_DEFDLB;
  294. p->em_deflb = getbyte();
  295. break;
  296. case sp_dlb2: /* Numeric data label */
  297. p->em_type = EM_DEFDLB;
  298. p->em_deflb = get16();
  299. #ifdef CHECKING
  300. if (p->em_deflb < 0) {
  301. xerror("Illegal data label definition");
  302. }
  303. #endif CHECKING
  304. break;
  305. case sp_dnam: /* Non-numeric data label */
  306. {
  307. struct string *s;
  308. p->em_type = EM_DEFDNAM;
  309. if (!(s = getstring(1))) {
  310. p->em_type = EM_ERROR;
  311. }
  312. else p->em_defdnam = s->str;
  313. break;
  314. }
  315. case EOF: /* End of file */
  316. return 0;
  317. default:
  318. xerror("Unknown opcode");
  319. break;
  320. }
  321. return p;
  322. }