home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_200
/
221_01
/
cc11.c
< prev
next >
Wrap
Text File
|
1979-12-31
|
10KB
|
411 lines
/* >>>>> start cc1 <<<<<< */
/* */
/* Compiler begins execution here */
/* */
#ifdef CMD_LINE
main(argc, argv) int argc, *argv[];
{
argcs=argc;
argvs=argv;
#else
main()
{
#endif
swend=(swnext=swq)+SWTABSZ+SWSIZ;
first_func=1; /* first function */
declared = -1;
glbptr=startglb; /* clear global symbols */
glbptr=startglb+symsiz*5;
statptr=startstat;
startcomp=endsearch=locptr=startloc; /* clear local symbols */
stagelast=stage+stagesize-1; /* set to end of stageing buffer */
wqptr=wq; /* clear while queue */
litptr= /* clear literal pool */
stkp = /* stack ptr (relative) */
errcnt= /* no errrpts */
eof= /* not eof yet */
input= /* no input file */
input2= /* or include file */
output= /* no open units */
ncmp= /* no open compound states */
lastst= /* no last statement yet */
iflevel= /* no ifdef yet */
skiplevel= /* also no skip of course */
stagenext=
quote[1]=
0; /* ...all set to zero.... */
quote[0]='"'; /* fake a quote literal */
cmode= /* enable preprocessing */
macptr= /* clear the macro pool */
1;
/* */
/* compiler body */
/* */
ask(); /* get user options */
#ifndef CMD_LINE
openout(); /* get an output file */
openin(); /* and initial input file */
#endif
header(); /* intro code */
parse(); /* process ALL input */
trailer(); /* follow-up code */
closeout(); /* close the output (if any) */
errrptsummary(); /* summarize errrpts */
return; /* then exit to system */
}
/* */
/* Process all input text */
/* */
/* At this level, only static declarations, */
/* defines, includes, and function */
/* definitions are legal... */
parse()
{
int storclass;
while (eof==0) /* do until no more input */
{
storclass = automatic;
if(amatch("extern",6)) storclass = EXTERNAL;
if(amatch("static",6)) storclass = statik;
if(amatch(_char,4)) {declglb(cchar, storclass);ns();}
else if(amatch(_int,3)){declglb(cint,storclass);ns();}
else if(match("#asm"))doasm();
else if(match("#include"))doinclude();
else if(match("#define"))addmac();
else newfunc(storclass);
blanks(); /* force eof if pending */
}
}
/* */
/* Dump the literal pool */
/* */
dumplits(siz) int siz;
{int j,k;
k=0; /* init an index... */
while (k<litptr) /* to loop with */
{defstorage(siz); /* pseudo-op to define byte */
j=10; /* max bytes per line */
while(j--)
{outdec(getint(litq+k, siz));
k=k+siz;
if ((j==0) | (k>=litptr))
{nl(); /* need <cr> */
break;
}
outbyte(','); /* separate bytes */
}
}
litptr=0;
}
/* */
/* Report errrpts for user */
/* */
errrptsummary()
{
/* see if anything left hanging... */
if (ncmp) errrpt("missing closing bracket");
/* open compound statement ... */
output=stdout;
cnl();
outdec(errcnt); /* total # errrpts */
outstr(" error(s) in compilation.");
}
/*
** get run options
*/
#ifdef CMD_LINE
ask() {
int i;
char *argptr;
i=nxtlab=0;
litlab=getlabel(); /* first label=literal pool */
kill(); /* erase line buffer */
output=stdout;
#ifdef OPTIMIZE
optimize=
#endif
#ifdef PHASE2
monitor=pause=DEFDEBUG=
#endif
ctext=NO;
if(argcs==1) {
sout("\nusage: cc <infile [>outfile] [-c]",stderr);
#ifdef OPTIMIZE
sout(" [-o]",stderr);
#endif
#ifdef PHASE2
sout(" [-m] [-p] [-t]",stderr);
#endif
sout("\n",stderr);
exit(0);
}
while(--argcs) { /* process all input */
argptr=argvs[++i];
if(*argptr=='<')
if((input=fopen(++argptr,"r"))==NULL) {
errrpt("input file error");
exit(0);
}
else continue;
else if(*argptr=='>')
if((output=fopen(++argptr,"w"))==NULL) {
errrpt("output file errrpt");
exit(0);
}
else continue;
else if(*argptr++ == '-')
if(upper(*argptr)=='C') ctext=YES;
#ifdef OPTIMIZE
else if(upper(*argptr)=='O') optimize=YES;
#endif
#ifdef PHASE2
else if(upper(*argptr)=='M') monitor=YES;
else if(upper(*argptr)=='P') pause=YES;
else if(upper(*argptr)=='T') DEFDEBUG=YES;
#endif
}
if(input==NULL) {
sout("\nno input file...\n",stderr);
exit(0);
}
}
#else
/* */
/* Get options from user */
/* */
ask()
{
int k,num[1];
output=stdout; /* init output to stdout */
kill(); /* clear input line */
#ifndef VMS
outbyte(CLS); /* clear the screen */
#endif
cnl();cnl();cnl(); /* print banner */
pl(" * * * small-c compiler * * *");
cnl();cnl();
/* see if user wants to interleave the c-text */
/* in form of comments (for clarity) */
pl("Do you wish the c-text to appear? ");
gets(line); /* get answer */
ctext=0; /* assume no */
if(upper(ch())=='Y')
ctext=1; /* user said yes */
litlab=getlabel(); /* first label=literal pool */
kill(); /* erase line */
}
/* */
/* Get output filename */
/* */
openout()
{
kill(); /* erase line */
output=0; /* start with none */
pl("Output filename? "); /* ask...*/
gets(line); /* get a filename */
if(ch()==0) {
output=stdout;
return; /* none given... */
}
#ifndef VMS
if((output=fopen(line,"w"))==NULL) /* Changed from UNIX to VMS */
#else
if((output=fdopen(creat(line,0,"rat=cr","rfm=var"),"w"))==NULL)
#endif
{output=0; /* can't open */
errrpt("Open failure");
}
kill(); /* erase line */
}
/* */
/* Get (next) input file */
/* */
openin()
{
input=0; /* none to start with */
while (input==0) /* any above 1 allowed */
{kill(); /* clear line */
if(eof)break; /* if user said none */
pl("Input filename? ");
gets(line); /* get a name */
if(ch()==0)
{eof=1;break;} /* none given... */
if((input=fopen(line,"r"))==NULL)
{input=0; /* can't open it */
pl("Open failure");
}
}
kill(); /* erase line */
}
#endif
/* */
/* Open an include file */
/* */
doinclude()
{
blanks(); /* skip over to name */
if((input2=fopen(line+lptr,"r"))==NULL)
{input2=0;
errrpt("Open failure on include file");
}
kill(); /* clear rest of line */
/* so next read will come from */
/* new file (if open */
}
/* */
/* Close the output file */
/* */
closeout()
{ if(output)fclose(output); /* if open, close it */
output=0; /* mark as closed */
}
/* */
/* Declare a static variable */
/* (i.e. define for use) */
/* */
/* makes an entry in the symbol table so subsequent */
/* references can call symbol by name */
declglb(typ,class) /* typ is cchar or cint */
int typ, class;
{ int k,j;char sname[namesize];
while(1)
{if(endst())return; /* do line */
if(match("*")) { /* pointer ? */
j=pointer; /* yes */
k=0;
}
else {
j=variable; /* no */
k=1;
}
if (symname(sname)==0) /* name ok? */
illname(); /* no... */
if(findglb(sname)) /* already there? */
multidef(sname);
if(match("()")) j=function;
else if (match("[")) /* array? */
{k=needsub(); /* get size */
j=array; /* !0=array */
}
if(class==EXTERNAL) declexternal(sname);
else {
entry(sname, class);
j=initials(typ>>2, j, k);
}
addglb(sname,j,typ,k,class); /* add symbol */
if(match(",")==0) return; /* more? */
}
}
/*
** declare local variables
** changed for static declaration
** dieter h. flunkert
** 29-oct-86
*/
declloc(typ, class) int typ, class; {
int k,j; char sname[namesize], numstring[namesize];
#ifdef STGOTO
if(noloc) errrpt("not allowed with goto");
#endif
if(declared < 0) errrpt("must declare first in block");
while(1) {
while(1) {
if(endst()) return;
if(match("*")) j=pointer;
else j=variable;
if (symname(sname)==0) illname();
endsearch=startcomp;
if(findloc(sname) != 0) multidef(sname);
endsearch=startloc;
k=2;
if (match("[")) {
k=needsub();
if(k || class == statik) {
j=array;
if(typ==cint)k=k+k;
}
else {j=pointer;
k=2;
}
}
else if(match("()")) j=function;
else if((typ==cchar)&&(j==variable)) k=1;
if(class == statik) { /* dhf 29-oct-86 */
convert(statlab++, numstring);
entry(numstring, class);
if(typ==cint) k = k>>1;
j=initials(typ>>2, j, k);
addstatic(sname, numstring, j, typ, k);
addloc(sname, j, typ, 0); /* making it known as local */
}
else {
declared = declared + k;
addloc(sname, j, typ, stkp - declared);
}
break;
}
if (match(",")==0) return;
}
}
convert(n,s) int n; char *s; {
char *c, ch;
c=s;
do {
*s++ = n % 10 + '0';
} while((n /= 10) > 0);
*s-- = '\0';
while(c < s) {
ch = *c;
*c++ = *s;
*s-- = ch;
}
}
/*
** initialize global objects
*/
initials(siz, id, dim) int siz, id, dim; {
int savedim;
if(dim==0) dim = -1;
savedim=dim;
if(match("=")) {
if(match("{")) {
while(dim) {
init(siz, id, &dim);
if(match(",")==0) break;
}
needbrack("}");
}
else init(siz, id, &dim);
}
if((dim == -1)&&(dim==savedim)) {
stowlit(0, siz=2);
id=pointer;
}
dumplits(siz);
dumpzero(siz*dim);
return id;
}
/*
** evaluate one initializer
*/
init(siz, id, dim) int siz, id, *dim; {
int value;
if(qstr(&value)) {
if((id==variable)||(siz!=1))
errrpt("must assign to char pointer or array");
*dim = - (litptr - value) + *dim;
if(id==pointer) point();
}
else if(constexpr(&value)) {
if(id==pointer) errrpt("cannot assign to pointer");
stowlit(value, siz);
*dim = -1 + *dim;
}
}