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);
|
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);
|
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);
|
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
|
|
|
|
|
1990-08-01 14:30:45 +00:00
|
|
|
/* getstring: read a string from the input
|
1987-01-06 11:05:35 +00:00
|
|
|
*/
|
|
|
|
/*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;
|
1990-08-01 14:30:45 +00:00
|
|
|
struct e_arg dummy;
|
1987-01-06 11:05:35 +00:00
|
|
|
|
1990-08-01 14:30:45 +00:00
|
|
|
getarg(cst_ptyp, &dummy);
|
1987-01-06 11:05:35 +00:00
|
|
|
/* Read length of string */
|
1990-08-01 14:30:45 +00:00
|
|
|
n = dummy.ema_cst;
|
1987-01-06 11:05:35 +00:00
|
|
|
#ifdef CHECKING
|
1990-08-01 14:30:45 +00:00
|
|
|
if (n < 0) {
|
|
|
|
xerror("Negative length in string");
|
|
|
|
s->length = 0;
|
|
|
|
return s;
|
1987-01-06 11:05:35 +00:00
|
|
|
}
|
1990-08-01 14:30:45 +00:00
|
|
|
#endif CHECKING
|
1987-01-06 11:05:35 +00:00
|
|
|
|
1990-08-01 14:30:45 +00:00
|
|
|
if (n > s->maxlen) {
|
|
|
|
if (! s->maxlen) {
|
|
|
|
s->str = Malloc(s->maxlen = 256);
|
|
|
|
}
|
|
|
|
else s->str = Realloc(s->str, (s->maxlen = (n+255)&~255));
|
1987-01-06 11:05:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
1987-07-03 10:35:55 +00:00
|
|
|
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;
|
1987-07-03 10:35:55 +00:00
|
|
|
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;
|
1987-07-03 10:35:55 +00:00
|
|
|
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;
|
1987-07-03 10:35:55 +00:00
|
|
|
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;
|
1987-07-03 10:35:55 +00:00
|
|
|
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;
|
1987-07-03 10:35:55 +00:00
|
|
|
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
|
|
|
}
|