123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* This file must be included in the file "read_emk.c".
- It takes care of the reading of compact EM code.
- */
- #include <ctype.h>
- /* Since isascii is not standard, as c89 or C99, privide another method */
- #define IsAscii(_c) (((_c) & ~0x7f) == 0)
- /* get16, get32: read a signed constant
- */
- static int get16()
- {
- int l_byte, h_byte;
- l_byte = getbyte();
- h_byte = getbyte();
- if (h_byte >= 128) h_byte -= 256;
- return l_byte | (h_byte << 8);
- }
- static arith get32()
- {
- arith l;
- int h_byte;
- l = getbyte();
- l |= ((unsigned) getbyte() << 8);
- l |= ((arith) getbyte() << 16);
- h_byte = getbyte();
- if (h_byte >= 128) h_byte -= 256;
- return l | ((arith) h_byte << 24);
- }
- static struct string *getstring();
- /* getarg : read an argument of any type, and check it against "typset"
- if neccesary. Put result in "ap".
- */
- static void getarg(int typset, struct e_arg *ap)
- {
- int i = getbyte();
- #ifdef CHECKING
- int argtyp;
- #endif /* CHECKING */
- ap->ema_argtype = 0;
- switch(i) {
- default:
- if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) { /* A cst */
- ap->ema_cst = i - sp_zcst0;
- ap->ema_argtype = cst_ptyp;
- i = sp_cst2;
- }
- break;
- case sp_dlb1: /* Numeric data label encoded in one byte */
- ap->ema_dlb = getbyte();
- ap->ema_szoroff = 0;
- ap->ema_argtype = nof_ptyp;
- break;
- case sp_dlb2: /* Numeric data label encoded in two bytes */
- ap->ema_dlb = get16();
- ap->ema_szoroff = 0;
- ap->ema_argtype = nof_ptyp;
- #ifdef CHECKING
- if (ap->ema_dlb > 32767 && !EM_error) {
- EM_error = "Illegal data label";
- break;
- }
- #endif /* CHECKING */
- break;
- case sp_ilb1: /* Instruction label encoded in one byte */
- ap->ema_ilb = getbyte();
- ap->ema_argtype = ilb_ptyp;
- break;
- case sp_ilb2: /* Instruction label encoded in two bytes */
- ap->ema_ilb = get16();
- ap->ema_argtype = ilb_ptyp;
- #ifdef CHECKING
- if (ap->ema_ilb > 32767 && !EM_error) {
- EM_error = "Illegal instruction label";
- break;
- }
- #endif /* CHECKING */
- break;
- case sp_cst2: /* A cst encoded in two bytes */
- ap->ema_cst = get16();
- ap->ema_argtype = cst_ptyp;
- break;
- case sp_cst4: /* A cst encoded in four bytes */
- ap->ema_cst = get32();
- ap->ema_argtype = cst_ptyp;
- break;
- case sp_pnam: /* A procedure name */
- {
- struct string *p;
- p = getstring(1);
- ap->ema_pnam = p->str;
- ap->ema_argtype = pro_ptyp;
- break;
- }
- case sp_dnam: /* A Non-numeric data label */
- {
- struct string *p;
- p = getstring(1);
- ap->ema_dnam = p->str;
- ap->ema_szoroff = 0;
- ap->ema_argtype = sof_ptyp;
- break;
- }
- case sp_doff: /* A data label + offset */
- {
- struct e_arg dummy;
- getarg(lab_ptyp, ap);
- getarg(cst_ptyp, &dummy);
- ap->ema_szoroff = dummy.ema_cst;
- break;
- }
- case sp_icon: /* An integer constant */
- case sp_ucon: /* An unsigned constant */
- case sp_fcon: /* A floating constant */
- {
- struct string *p;
- getarg(cst_ptyp, ap);
- ap->ema_szoroff = ap->ema_cst;
- p = getstring(0);
- ap->ema_argtype = ptyp(i);
- ap->ema_string = p->str;
- break;
- }
- case sp_scon: /* A string constant */
- {
- struct string *p;
- p = getstring(0);
- ap->ema_argtype = str_ptyp;
- ap->ema_string = p->str;
- ap->ema_szoroff = p->length;
- break;
- }
- }
- #ifdef CHECKING
- argtyp = i;
- if (EM_error) return;
- if (i == EOF) {
- xfatal("Unexpected EOF");
- return;
- }
- if ((i -= sp_fspec) < 0 || i >= 16) {
- xerror("Illegal byte");
- return;
- }
- if ((typset & (1 << i)) == 0 && !EM_error) {
- EM_error = "Bad argument type";
- }
- if (argtyp == sp_cend) {
- ap->ema_argtype = 0;
- }
- #else /* not CHECKING */
- if (i == sp_cend) {
- ap->ema_argtype = 0;
- }
- #endif /* CHECKING */
- }
- #ifdef CHECKING
- /* checkident: check that a string indeed represents an identifier
- */
- static int checkident(struct string *s)
- {
- char *p;
- int n;
- p = s->str;
- if (!IsAscii(*p) || (!isalpha(*p) && *p != '_')) {
- return 0;
- }
- p++;
- for (n = s->length; --n > 0; p++) {
- if (!IsAscii(*p) || (!isalnum(*p) && *p != '_')) {
- return 0;
- }
- }
- return 1;
- }
- #endif /* CHECKING */
- /* getstring: read a string from the input
- */
- /*ARGSUSED*/
- static struct string *getstring(int isident)
- {
- char *p;
- int n;
- struct string *s = &string;
- struct e_arg dummy;
- getarg(cst_ptyp, &dummy);
- /* Read length of string */
- n = dummy.ema_cst;
- #ifdef CHECKING
- if (n < 0) {
- xerror("Negative length in string");
- s->length = 0;
- return s;
- }
- #endif /* CHECKING */
- if (n > s->maxlen) {
- if (! s->maxlen) {
- s->str = Malloc(s->maxlen = 256);
- }
- else s->str = Realloc(s->str, (s->maxlen = (n+255)&~255));
- }
- s->length = n;
- p = s->str;
- while (--n >= 0) {
- *p++ = getbyte();
- }
- *p++ = '\0';
- #ifdef CHECKING
- if (isident) {
- if (!checkident(s) && !EM_error) {
- EM_error = "Illegal identifier";
- }
- }
- #endif /* CHECKING */
- return s;
- }
- /* gethead: read the start of an EM-line
- */
- static void gethead(struct e_instr *p)
- {
- int i;
- EM_lineno++;
- if ((i = getbyte()) < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
- /* A mnemonic */
- p->em_type = EM_MNEM;
- p->em_opcode = i;
- return;
- }
- if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) { /* A pseudo */
- if (i == ps_mes) {
- p->em_type = EM_STARTMES;
- }
- else p->em_type = EM_PSEU;
- p->em_opcode = i;
- return;
- }
- if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) { /* Instruction label */
- p->em_type = EM_DEFILB;
- p->em_argtype = ilb_ptyp;
- p->em_ilb = i - sp_filb0;
- return;
- }
- switch(i) {
- case sp_ilb1: /* Instruction label */
- p->em_type = EM_DEFILB;
- p->em_argtype = ilb_ptyp;
- p->em_ilb = getbyte();
- break;
- case sp_ilb2: /* Instruction label */
- p->em_type = EM_DEFILB;
- p->em_argtype = ilb_ptyp;
- p->em_ilb = get16();
- #ifdef CHECKING
- if (p->em_ilb > 32767 && !EM_error) {
- EM_error = "Illegal instruction label definition";
- }
- #endif /* CHECKING */
- break;
- case sp_dlb1: /* Numeric data label */
- p->em_type = EM_DEFDLB;
- p->em_argtype = nof_ptyp;
- p->em_dlb = getbyte();
- break;
- case sp_dlb2: /* Numeric data label */
- p->em_type = EM_DEFDLB;
- p->em_argtype = nof_ptyp;
- p->em_dlb = get16();
- #ifdef CHECKING
- if (p->em_dlb > 32767 && !EM_error) {
- EM_error = "Illegal data label definition";
- }
- #endif /* CHECKING */
- break;
- case sp_dnam: /* Non-numeric data label */
- {
- struct string *s;
- p->em_type = EM_DEFDNAM;
- p->em_argtype = sof_ptyp;
- if (!(s = getstring(1))) {
- p->em_dnam = "";
- }
- else p->em_dnam = s->str;
- break;
- }
- case EOF: /* End of file */
- p->em_type = EM_EOF;
- return;
- default:
- xerror("Unknown opcode");
- break;
- }
- return;
- }
|