ack/modules/src/read_em/readk.c

376 lines
7 KiB
C
Raw Normal View History

1987-03-10 09:24:02 +00:00
/* $Header$ */
1987-03-09 15:15:03 +00:00
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
1987-01-06 11:05:35 +00:00
/* This file must be included in the file "read_emk.c".
It takes care of the reading of compact EM code.
*/
#include <ctype.h>
/* get16, get32: read a signed constant
*/
PRIVATE int
get16()
{
register int l_byte, h_byte;
l_byte = getbyte();
h_byte = getbyte();
if (h_byte >= 128) h_byte -= 256;
return l_byte | (h_byte << 8);
}
PRIVATE arith
get32()
{
register arith l;
register 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);
}
PRIVATE struct string *getstring();
/* getarg : read an argument of any type, and check it against "typset"
1987-06-30 12:55:30 +00:00
if neccesary. Put result in "ap".
1987-01-06 11:05:35 +00:00
*/
1987-06-30 12:55:30 +00:00
PRIVATE
getarg(typset, ap)
register struct e_arg *ap;
1987-01-06 11:05:35 +00:00
{
register int i = getbyte();
#ifdef CHECKING
int argtyp;
#endif CHECKING
1987-08-06 14:21:01 +00:00
ap->ema_argtype = 0;
1987-01-06 11:05:35 +00:00
switch(i) {
default:
if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) { /* A cst */
1987-06-30 12:55:30 +00:00
ap->ema_cst = i - sp_zcst0;
1987-06-30 18:59:51 +00:00
ap->ema_argtype = cst_ptyp;
1987-01-06 11:05:35 +00:00
i = sp_cst2;
}
break;
case sp_dlb1: /* Numeric data label encoded in one byte */
1987-06-30 12:55:30 +00:00
ap->ema_dlb = getbyte();
1987-06-30 18:59:51 +00:00
ap->ema_szoroff = 0;
ap->ema_argtype = nof_ptyp;
1987-01-06 11:05:35 +00:00
break;
case sp_dlb2: /* Numeric data label encoded in two bytes */
1987-06-30 12:55:30 +00:00
ap->ema_dlb = get16();
1987-06-30 18:59:51 +00:00
ap->ema_szoroff = 0;
ap->ema_argtype = nof_ptyp;
1987-01-06 11:05:35 +00:00
#ifdef CHECKING
1987-06-30 12:55:30 +00:00
if (ap->ema_dlb > 32767 && !EM_error) {
1987-03-31 08:16:41 +00:00
EM_error = "Illegal data label";
1987-01-06 11:05:35 +00:00
break;
}
#endif CHECKING
break;
case sp_ilb1: /* Instruction label encoded in one byte */
1987-06-30 12:55:30 +00:00
ap->ema_ilb = getbyte();
1987-06-30 18:59:51 +00:00
ap->ema_argtype = ilb_ptyp;
1987-01-06 11:05:35 +00:00
break;
case sp_ilb2: /* Instruction label encoded in two bytes */
1987-06-30 12:55:30 +00:00
ap->ema_ilb = get16();
1987-06-30 18:59:51 +00:00
ap->ema_argtype = ilb_ptyp;
1987-01-06 11:05:35 +00:00
#ifdef CHECKING
1987-06-30 12:55:30 +00:00
if (ap->ema_ilb > 32767 && !EM_error) {
1987-03-31 08:16:41 +00:00
EM_error = "Illegal instruction label";
1987-01-06 11:05:35 +00:00
break;
}
#endif CHECKING
break;
case sp_cst2: /* A cst encoded in two bytes */
1987-06-30 12:55:30 +00:00
ap->ema_cst = get16();
1987-06-30 18:59:51 +00:00
ap->ema_argtype = cst_ptyp;
1987-01-06 11:05:35 +00:00
break;
case sp_cst4: /* A cst encoded in four bytes */
1987-06-30 12:55:30 +00:00
ap->ema_cst = get32();
1987-06-30 18:59:51 +00:00
ap->ema_argtype = cst_ptyp;
1987-01-06 11:05:35 +00:00
break;
case sp_pnam: /* A procedure name */
{
register struct string *p;
p = getstring(1);
#ifdef CHECKING
if (state & INSTRING) {
xerror("Procedure name too long");
}
#endif CHECKING
1987-06-30 12:55:30 +00:00
ap->ema_pnam = p->str;
1987-06-30 18:59:51 +00:00
ap->ema_argtype = pro_ptyp;
1987-01-06 11:05:35 +00:00
break;
}
case sp_dnam: /* A Non-numeric data label */
{
register struct string *p;
p = getstring(1);
#ifdef CHECKING
if (state & INSTRING) {
xerror("Data label too long");
}
#endif CHECKING
1987-06-30 12:55:30 +00:00
ap->ema_dnam = p->str;
1987-06-30 18:59:51 +00:00
ap->ema_szoroff = 0;
ap->ema_argtype = sof_ptyp;
1987-01-06 11:05:35 +00:00
break;
}
case sp_doff: /* A data label + offset */
{
1987-06-30 12:55:30 +00:00
struct e_arg dummy;
getarg(lab_ptyp, ap);
getarg(cst_ptyp, &dummy);
1987-06-30 18:59:51 +00:00
ap->ema_szoroff = dummy.ema_cst;
1987-01-06 11:05:35 +00:00
break;
}
case sp_icon: /* An integer constant */
case sp_ucon: /* An unsigned constant */
case sp_fcon: /* A floating constant */
{
register struct string *p;
1987-06-30 12:55:30 +00:00
getarg(cst_ptyp, ap);
1987-06-30 18:59:51 +00:00
ap->ema_szoroff = ap->ema_cst;
1987-01-06 11:05:35 +00:00
p = getstring(0);
#ifdef CHECKING
if (state & INSTRING) {
xerror("Numeric constant too long");
}
#endif CHECKING
1987-06-30 18:59:51 +00:00
ap->ema_argtype = ptyp(i);
1987-06-30 12:55:30 +00:00
ap->ema_string = p->str;
1987-01-06 11:05:35 +00:00
break;
}
case sp_scon: /* A string constant */
{
register struct string *p;
p = getstring(0);
1987-06-30 18:59:51 +00:00
ap->ema_argtype = str_ptyp;
1987-06-30 12:55:30 +00:00
ap->ema_string = p->str;
1987-06-30 18:59:51 +00:00
ap->ema_szoroff = p->length;
1987-01-06 11:05:35 +00:00
break;
}
}
#ifdef CHECKING
argtyp = i;
1987-06-30 12:55:30 +00:00
if (EM_error) return;
1987-01-06 11:05:35 +00:00
if (i == EOF) {
xfatal("Unexpected EOF");
1987-06-30 12:55:30 +00:00
return;
1987-01-06 11:05:35 +00:00
}
if ((i -= sp_fspec) < 0 || i >= 16) {
xerror("Illegal byte");
1987-06-30 12:55:30 +00:00
return;
1987-01-06 11:05:35 +00:00
}
1987-03-31 08:16:41 +00:00
if ((typset & (1 << i)) == 0 && !EM_error) {
EM_error = "Bad argument type";
1987-01-06 11:05:35 +00:00
}
1987-06-30 12:55:30 +00:00
if (argtyp == sp_cend) {
1987-06-30 18:59:51 +00:00
ap->ema_argtype = 0;
1987-06-30 12:55:30 +00:00
}
1987-01-06 11:05:35 +00:00
#else not CHECKING
1987-06-30 12:55:30 +00:00
if (i == sp_cend) {
1987-06-30 18:59:51 +00:00
ap->ema_argtype = 0;
1987-06-30 12:55:30 +00:00
}
1987-01-06 11:05:35 +00:00
#endif CHECKING
}
#ifdef CHECKING
/* checkident: check that a string indeed represents an identifier
*/
PRIVATE int
checkident(s)
register struct string *s;
{
register char *p;
register 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, but at most STRSIZ characters
of it. The next characters will be read another time around
*/
/*ARGSUSED*/
PRIVATE struct string *
getstring(isident)
{
register char *p;
register int n;
1987-06-30 12:55:30 +00:00
register struct string *s = &string;
1987-01-06 11:05:35 +00:00
if (!(state & INSTRING)) { /* Not reading a string yet */
1987-06-30 12:55:30 +00:00
struct e_arg dummy;
getarg(cst_ptyp, &dummy);
1987-01-06 11:05:35 +00:00
/* Read length of string */
1987-06-30 12:55:30 +00:00
strleft = dummy.ema_cst;
1987-01-06 11:05:35 +00:00
#ifdef CHECKING
if (strleft < 0) {
xerror("Negative length in string");
1989-06-19 11:09:44 +00:00
s->length = 0;
return s;
1987-01-06 11:05:35 +00:00
}
#endif CHECKING
}
if (strleft <= STRSIZ) { /* Handle the whole string */
n = strleft;
state &= ~INSTRING;
}
else { /* Handle STRSIZ characters of it, and
indicate that there is more
*/
n = STRSIZ;
strleft -= STRSIZ;
state |= INSTRING;
}
s->length = n;
p = s->str;
while (--n >= 0) {
*p++ = getbyte();
}
*p++ = '\0';
#ifdef CHECKING
if (isident) {
1987-03-31 08:16:41 +00:00
if (!checkident(s) && !EM_error) {
EM_error = "Illegal identifier";
1987-01-06 11:05:35 +00:00
}
}
#endif CHECKING
return s;
}
/* gethead: read the start of an EM-line
*/
1987-06-30 12:55:30 +00:00
PRIVATE
gethead(p)
register struct e_instr *p;
1987-01-06 11:05:35 +00:00
{
register 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;
1987-06-30 12:55:30 +00:00
return;
1987-01-06 11:05:35 +00:00
}
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;
1987-06-30 12:55:30 +00:00
return;
1987-01-06 11:05:35 +00:00
}
if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) { /* Instruction label */
p->em_type = EM_DEFILB;
p->em_argtype = ilb_ptyp;
1987-06-30 12:55:30 +00:00
p->em_ilb = i - sp_filb0;
return;
1987-01-06 11:05:35 +00:00
}
switch(i) {
case sp_ilb1: /* Instruction label */
p->em_type = EM_DEFILB;
p->em_argtype = ilb_ptyp;
1987-06-30 12:55:30 +00:00
p->em_ilb = getbyte();
1987-01-06 11:05:35 +00:00
break;
case sp_ilb2: /* Instruction label */
p->em_type = EM_DEFILB;
p->em_argtype = ilb_ptyp;
1987-06-30 12:55:30 +00:00
p->em_ilb = get16();
1987-01-06 11:05:35 +00:00
#ifdef CHECKING
1987-06-30 12:55:30 +00:00
if (p->em_ilb > 32767 && !EM_error) {
1987-03-31 08:16:41 +00:00
EM_error = "Illegal instruction label definition";
1987-01-06 11:05:35 +00:00
}
#endif CHECKING
break;
case sp_dlb1: /* Numeric data label */
p->em_type = EM_DEFDLB;
p->em_argtype = nof_ptyp;
1987-06-30 12:55:30 +00:00
p->em_dlb = getbyte();
1987-01-06 11:05:35 +00:00
break;
case sp_dlb2: /* Numeric data label */
p->em_type = EM_DEFDLB;
p->em_argtype = nof_ptyp;
1987-06-30 12:55:30 +00:00
p->em_dlb = get16();
1987-01-06 11:05:35 +00:00
#ifdef CHECKING
1987-06-30 12:55:30 +00:00
if (p->em_dlb > 32767 && !EM_error) {
1987-03-31 08:16:41 +00:00
EM_error = "Illegal data label definition";
1987-01-06 11:05:35 +00:00
}
#endif CHECKING
break;
case sp_dnam: /* Non-numeric data label */
{
struct string *s;
p->em_type = EM_DEFDNAM;
p->em_argtype = sof_ptyp;
1987-01-06 11:05:35 +00:00
if (!(s = getstring(1))) {
1987-06-30 12:55:30 +00:00
p->em_dnam = "";
1987-01-06 11:05:35 +00:00
}
1987-06-30 12:55:30 +00:00
else p->em_dnam = s->str;
1987-01-06 11:05:35 +00:00
break;
}
case EOF: /* End of file */
1987-06-30 12:55:30 +00:00
p->em_type = EM_EOF;
return;
1987-01-06 11:05:35 +00:00
default:
xerror("Unknown opcode");
break;
}
1987-06-30 12:55:30 +00:00
return;
1987-01-06 11:05:35 +00:00
}