1 /* $Id: reade.c,v 1.14 1994/06/24 11:21:31 ceriel Exp $ */
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".
6 /* This file is ment to be included in the file read_em.c.
7 It contains the part that takes care of the reading of human readable
13 /* #define XXX_YYY /* only for early debugging */
16 #define out(str) (sys_write(STDOUT, str, strlen(str)))
21 #define fit16i(x) ((x) >= -32768L && (x) <= 32767L)
23 #define HSIZE 256 /* Size of hashtable for mnemonics */
25 static int hashtab[HSIZE]; /* The hashtable for mnemonics */
27 static int argnum; /* Number of arguments */
29 #define COMMENTSTARTER ';'
31 /* inithash, pre_hash, hash: Simple hashtable mechanism
57 if (h >= HSIZE) h %= HSIZE;
58 if (hashtab[h] == 0) {
66 extern char em_mnem[][4];
67 extern char em_pseu[][4];
74 /* Enter instructions ... */
75 for (i = sp_fmnem; i <= sp_lmnem; i++) {
76 pre_hash(i, em_mnem[i - sp_fmnem]);
80 for (i = sp_fpseu; i <= sp_lpseu; i++) {
81 pre_hash(i, em_pseu[i - sp_fpseu]);
85 /* nospace: skip until we find a non-space character. Also skip
94 while (isspace(c) && c != '\n');
96 if (c == COMMENTSTARTER) {
98 while (c != '\n' && c != EOF);
104 /* syntax: Put an error message in EM_error and skip to the end of the line
114 while ((c = getbyte()) != '\n' && c != EOF) /* nothing */ ;
118 /* checkeol: check that we have a complete line (except maybe for spaces)
124 if (nospace() != '\n') {
125 syntax("end of line expected");
130 /* getescape: read a '\' escape sequence
135 register int c, j, r;
137 if ((c = getbyte()) >= '0' && c <= '7') { /* numeric escape */
140 for (j = 0; j < 2; j++) {
141 if ((c = getbyte()) < '0' || c > '7') {
153 case 'b': return '\b';
154 case 'f': return '\f';
155 case 'n': return '\n';
156 case 'r': return '\r';
157 case 't': return '\t';
163 /* getname: Read a string of characters representing an identifier
165 PRIVATE struct string *
169 register struct string *s;
176 s->str = p = Malloc(256);
180 if (!(isalpha(c) || c == '_')) {
182 syntax("Letter expected");
186 while (isalnum(c) || c == '_') {
187 if (p >= &(s->str[s->maxlen])) {
189 s->str = Realloc(s->str, (s->maxlen += 256));
198 s->length = p - s->str;
202 /* getstring: read a string of characters between quotes
204 PRIVATE struct string *
216 s->str = p = Malloc(256);
220 /* assert(termc == '"' || termc == '\''); */
221 /* This assertion does not work. Compiler error messages.
222 The trouble lies in the ", it terminates the string
223 created in the assertion macro
227 if ((c = getbyte()) == '\n' || c == EOF) {
229 syntax("non-terminated string");
234 if (termc == '"') *p++ = '\0';
238 if (c == '\\') c = getescape();
240 if (p >= &(s->str[s->maxlen])) {
242 s->str = Realloc(s->str, (s->maxlen += 256));
250 s->length = p - s->str;
254 PRIVATE void gettyp();
257 offsetted(argtyp, ap)
262 if ((c = nospace()) == '+' || c == '-') {
265 gettyp(cst_ptyp, &dummy);
266 if (c == '-') *ap = -(dummy.ema_cst);
267 else *ap = dummy.ema_cst;
279 register struct e_arg *ap;
282 register char *p = str;
287 ap->ema_argtype = cst_ptyp;
290 if (c == '+' || c == '-') {
291 if (c == '-') *p++ = c;
297 syntax("digit expected");
304 if (p >= &(str[256])) {
305 syntax("number too long");
311 if ((c = getbyte()) == '.' || c == 'e' || c == 'E') {
319 if (c == '+' || c == '-') continue;
322 if (! isdigit(c)) break;
329 if (n == sp_fcon && c != 'F') {
331 syntax("'F' expected");
335 if (c == 'I' || c == 'U' || c == 'F') {
338 strcpy(string.str, str);
339 ap->ema_string = string.str;
340 gettyp(cst_ptyp, &dummy);
341 ap->ema_szoroff = dummy.ema_cst;
345 ap->ema_argtype = ico_ptyp;
348 ap->ema_argtype = uco_ptyp;
351 ap->ema_argtype = fco_ptyp;
358 ap->ema_cst = (arith) str2long(str, 10);
362 PRIVATE int getexpr();
367 register struct e_arg *ap;
370 if (getexpr(nospace(), ap) != sp_cst4) {
371 syntax("expression expected");
373 else if ((c = nospace()) != ')') {
375 syntax("')' expected");
379 return getnumber(c, ap);
385 register struct e_arg *ap;
389 if ((c = getfactor(c, ap)) != sp_cst4) return c;
392 if ((c = nospace()) != '*' && c != '/' && c != '%') {
398 if (getfactor(nospace(), ap) != sp_cst4) {
399 syntax("factor expected");
403 if (c == '*') ap->ema_cst *= left;
404 else if (c == '/') ap->ema_cst = left / ap->ema_cst;
405 else ap->ema_cst = left % ap->ema_cst;
413 register struct e_arg *ap;
417 if ((c = getterm(c, ap)) != sp_cst4) return c;
420 if ((c = nospace()) != '+' && c != '-') {
426 if (getterm(nospace(), ap) != sp_cst4) {
427 syntax("term expected");
431 if (c == '+') ap->ema_cst += left;
432 else ap->ema_cst = left - ap->ema_cst;
442 if (getnumber(getbyte(), &dummy) != sp_cst4) {
443 syntax("integer expected");
445 else check((dummy.ema_cst & ~077777) == 0);
446 return (int) (dummy.ema_cst);
451 register struct e_arg *ap;
456 if ((c = nospace()) == '\n') {
461 else if (isdigit(c) || c == '+' || c == '-' || c == '(') {
463 argtyp = getexpr(c, ap);
464 if (argtyp == sp_cst4 && fit16i(ap->ema_cst)) argtyp = sp_cst2;
466 else if (isalpha(c) || c == '_') {
469 ap->ema_dnam = getname()->str;
470 ap->ema_argtype = sof_ptyp;
471 argtyp = offsetted(sp_dnam, &(ap->ema_szoroff));
475 ap->ema_dlb = get15u();
476 ap->ema_argtype = nof_ptyp;
477 argtyp = offsetted(sp_dlb2, &(ap->ema_szoroff));
481 ap->ema_ilb = get15u();
482 ap->ema_argtype = ilb_ptyp;
487 ap->ema_pnam = getname()->str;
488 ap->ema_argtype = pro_ptyp;
491 else if (c == '"' || c == '\'') {
492 register struct string *s;
497 ap->ema_string = s->str;
498 ap->ema_szoroff = s->length;
499 ap->ema_argtype = str_ptyp;
508 /* c != '\n', so "ungetbyte" not neccesary */
509 syntax("operand expected");
513 t = argtyp - sp_fspec;
514 assert(t >= 0 && t < 16);
515 if ((typset & (1 << t)) == 0) {
516 syntax("Bad argument type");
520 if (argtyp == sp_cend) {
532 if ((c = nospace()) != ',') {
534 syntax("comma expected");
544 /* getmnem: We found the start of either an instruction or a pseudo.
549 register struct e_instr *p;
553 register struct string *s;
561 if (h >= HSIZE) h %= HSIZE;
562 if ((i = hashtab[h]) == 0) {
563 syntax("bad mnemonic");
566 else if (i <= sp_lmnem) {
567 assert(i >= sp_fmnem);
568 if (strcmp(s->str, em_mnem[i - sp_fmnem]) != 0) {
571 p->em_type = EM_MNEM;
575 assert(i <= sp_lpseu && i >= sp_fpseu);
576 if (strcmp(s->str, em_pseu[i - sp_fpseu]) != 0) {
580 p->em_type = EM_STARTMES;
584 p->em_type = EM_PSEU;
592 static char filebuf[256 + 1];
596 gettyp(ptyp(sp_cst2), &dummy);
597 EM_lineno = dummy.ema_cst;
598 gettyp(str_ptyp, &dummy);
599 btscpy(filebuf, dummy.ema_string, (int) dummy.ema_szoroff);
600 EM_filename = filebuf;
605 register struct e_instr *p;
609 gettyp(lab_ptyp|ptyp(sp_cst2), &(p->em_arg));
610 switch(p->em_argtype) {
612 p->em_type = EM_DEFILB;
613 p->em_argtype = ilb_ptyp;
614 p->em_ilb = p->em_cst;
617 p->em_type = EM_DEFDNAM;
620 p->em_type = EM_DEFDLB;
628 register struct e_instr *p;
636 if (c == COMMENTSTARTER) {
638 while (c != '\n' && c != EOF);
644 if (c == '\n') continue;
647 if (isalpha(c) || c == '_') {
653 else if (c == '#') line_line();
659 if (p->em_type == EM_ERROR || p->em_type == EM_FATAL) return;