home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
131_01
/
apar.c
< prev
next >
Wrap
Text File
|
1985-03-10
|
7KB
|
448 lines
/*
************************************************************
ACRL Parser
************************************************************
W. Lemiszki 9 Jan 1982
Filename: apar.c BDS C v1.50
*/
#include "acrl.h"
parse()
{
xrel = prepost = ltyp = specflag = FALSE; /* init for stmt */
codelen = 0;
errchar = ' ';
L1: scan(); /* scan 1st token */
if (class == EOL)
return; /* empty line */
if (class == IDENT) /* if identifier scanned... */
{
labsav(); /* save label params */
scan(); /* and scan next */
}
if (infunc && type == ':') /* label definition */
{
speclist(floc);
enter(LOCAL, idLAB+RELBIT, floc);
goto L1; /* go parse rest of line */
}
else if (class == PSEUDO)
pseudo_op();
else if (infunc && class == MACHINE)
instruction();
if (class != EOL) /* check last token */
error('Q'); /* extra garbage */
if (ltyp)
error('L'); /* label not used */
}
/*
* Process a pseudo op
* -------------------
*/
pseudo_op()
{
switch (type)
{
case psINCL:
include();
break;
case psEQU:
equset(idEQU);
break;
case psSET:
equset(idSET);
break;
case psFUNC:
function();
break;
case psFEND:
fend();
break;
case psEND:
endstmt();
break;
case psDB:
db();
break;
case psDW:
dw();
break;
case psDS:
ds();
break;
}
}
/*
* Process INCLUDE statement
* -------------------------
*/
include()
{
if (incflag) /* if already including... */
{
error('N'); /* nest error */
return;
}
scan(); /* scan filename string */
if (class == STRING)
{
if (fopen(tokbuf, incfile) == ERROR)
fatal("Can't include %s\n",tokbuf);
linesav = linecnt; /* save line # */
linecnt = 0;
incflag = TRUE;
scan();
}
else
error('Q'); /* no filename present */
}
/*
* Process EQU or SET statement
* ----------------------------
*/
equset(idtyp)
byte idtyp;
{
scan();
speclist(value = expression()); /* list the value */
enter(infunc ? LOCAL : GLOBAL, idtyp + (xrel ? RELBIT : 0), value);
}
/*
* Process FUNCTION definition
* ---------------------------
*/
function()
{
int xfn;
if (infunc) /* if already in a function */
{
error('N'); /* nest error */
return;
}
if (++numfunc > 64)
fatal("Too many functions (64 max)\n");
speclist(lc); /* list output file address */
enter(FUNCS, idFUNC, numfunc); /* add to function table */
infunc = TRUE;
scan();
xfn = 0; /* external funcs needed */
while (class == IDENT) /* for each ext function... */
{
labsav(); /* save identifier params */
enter(LOCAL, idFUNC, ++xfn); /* into local table */
nameout(lnam); /* output name to codebuf */
scan();
if (type == ',') /* eat the comma */
scan();
}
code(0); /* end of external funcs */
codew(flen[numfunc]); /* output body length */
floc = 0;
rellen = 0;
if (xfn) /* if any ext funcs */
{
code(0xC3); /* jmp around vectors */
codew(floc = 3*(xfn+1));
relbuf[rellen++] = 1; /* this jmp is reloc */
while (xfn--)
{
code(0xC3); /* output empty jmps */
codew(0);
}
}
faddr[numfunc] = lc; /* save crl file addr */
prepost = PRE;
}
/*
* Process FEND statement
* ----------------------
*/
fend()
{
int i;
if (!infunc) /* must be in a function */
{
error('N'); /* nest error */
return;
}
scan(); /* scan EOL */
speclist(flen[numfunc] = floc); /* save (and list) func len */
codew(rellen); /* output rellocation list */
for (i=0; i<rellen; )
codew(relbuf[i++]);
infunc = FALSE;
prepost = POST;
}
/*
* Process END statement
* ---------------------
*/
endstmt()
{
if (incflag) /* illegal in include files */
{
error('N'); /* nest error */
return;
}
endflag = TRUE;
if (infunc) /* illegal inside a function */
{
error('N'); /* nest error */
fend(); /* fake a FEND */
}
speclist(lc); /* list the output file addr */
scan(); /* scan the EOL */
}
/*
* Process DB statement
* --------------------
*/
db()
{
char *ptr;
if (!infunc)
return; /* Q error */
do
{
scan();
if (class == STRING && tokbuf[1]) /* if more than 1 char */
{
for (ptr = tokbuf; *ptr; ) /* copy to code buffer */
code(*ptr++);
scan();
}
else
code(expr8()); /* get 8 bit expression */
} while (type == ',');
}
/*
* Process DW statement
* --------------------
*/
dw()
{
if (!infunc)
return; /* Q error */
do
{
scan();
codew(expr16());
} while (type == ',');
}
/*
* Process DS statement
* --------------------
*/
ds()
{
int v;
if (!infunc)
return;
speclist(floc); /* list the address */
scan();
v = expression();
if (xrel)
{
error('T'); /* must not be reloc. */
xrel = FALSE;
v = 0;
}
floc += v; /* adjust */
lc += v; /* generate 0's */
}
/* SUPPORT ROUTINES */
/* Save label parameters */
labsav()
{
char *strsave();
if (type == idUND) /* if undefined */
lnam = strsave(tokbuf); /* save the name */
else
{
labid = id; /* else save entry ptr */
lnam = labid->nam;
}
ltyp = type + (reloc ? RELBIT : 0);
}
/* Define a user identifier */
enter(level, type, value)
int level;
byte type;
int value;
{
if (ltyp == 0) /* no label */
error('L');
else if (ltyp == idUND) /* undefined ? */
install(level, lnam, IDENT, type, value);
else if ((~RELBIT & type) == idSET && (~RELBIT & ltyp) == idSET)
{
labid->val = value; /* new 'set' value */
labid->typ = type; /* maybe new RELBIT */
}
else if (!pass || type != ltyp)
{
error('M'); /* multiply defined */
labid->typ = idMUL; /* flag in table */
}
else if (value != labid->val)
error('P'); /* phase error */
ltyp = 0; /* clear label flag */
}
/* Statement error handling */
error(c)
char c;
{
if (errchar != ' ') /* keep 1st error */
return;
errchar = c;
++errcnt; /* count it */
}
/* Set special value to list in address field */
speclist(v)
int v;
{
specflag = TRUE;
specval = v;
}
/* Byte to code buffer */
code(datum)
byte datum;
{
codebuf[codelen++] = datum;
}
/* Word to code buffer */
codew(word)
addr word;
{
code(word & 0xFF);
code(word >> 8);
}
/* Scan an 8 bit expression */
expr8()
{
int v;
v = expression();
if (xrel)
error('T'); /* must be absolute */
if (v >= -256 && v < 256)
return (v);
error('V'); /* out of range */
return (v & 0xFF);
}
/* Scan an address expression */
expr16()
{
int v;
if (class == IDENT && type == idFUNC) /* external function */
{
v = value * 3; /* its vector address */
scan();
xrel = TRUE;
if (class == OPERATOR) /* no expressions allowed */
error('X');
}
else
v = expression();
if (xrel) /* add to reloc list */
relbuf[rellen++] = floc + codelen;
return (v);
}
/*EOF*/