|
|
researchv9-SUN3(old)
/* @(#)common 1.1 86/02/03 SMI */
#ifdef FORT
#undef BUFSTDERR
#endif
#ifndef ONEPASS
#undef BUFSTDERR
#endif
# ifndef EXIT
# define EXIT exit
# endif
int nerrors = 0; /* number of errors */
int errline = -1; /* where last error took place */
extern unsigned int offsz;
unsigned caloff(){
register i;
unsigned int temp;
unsigned int off;
temp = 1;
i = 0;
do {
temp <<= 1;
++i;
} while( temp > 0 );
off = 1 << (i-1);
return (off);
}
/* VARARGS1 */
uerror( s, a ) char *s; { /* nonfatal error message */
/* the routine where is different for pass 1 and pass 2;
/* it tells where the error took place */
fflush( stdout );
++nerrors;
errline = lineno;
where('u');
fprintf( stderr, s, a );
fprintf( stderr, "\n" );
#ifdef BUFSTDERR
fflush(stderr);
#endif
if( nerrors > 30 ) fatal( "too many errors");
}
/* VARARGS1 */
cerror( s, a, b, c ) char *s; { /* compiler error: die */
fflush( stdout );
where('c');
if( nerrors && nerrors <= 30 ){ /* give the compiler the benefit of the doubt */
fprintf( stderr, "cannot recover from earlier errors: goodbye!\n" );
}
else {
fprintf( stderr, "compiler error: " );
fprintf( stderr, s, a, b, c );
fprintf( stderr, "\n" );
}
#ifdef BUFSTDERR
fflush(stderr);
#endif
EXIT(1);
}
fatal( s, a, b, c ) char *s; { /* non-compiler but fatal error: die */
fflush( stdout );
where('f');
fprintf( stderr, "fatal error: " );
fprintf( stderr, s, a, b, c );
fprintf( stderr, "\n" );
#ifdef BUFSTDERR
fflush(stderr);
#endif
EXIT(1);
}
int Wflag = 0; /* Non-zero means do not print warnings */
/* VARARGS1 */
werror( s, a, b ) char *s; { /* warning */
if(Wflag) return;
fflush( stdout );
where('w');
fprintf( stderr, "warning: " );
fprintf( stderr, s, a, b );
fprintf( stderr, "\n" );
#ifdef BUFSTDERR
fflush(stderr);
#endif
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifdef TESTALLOC
/*
* this enables us to test
* tree allocation without having
* to construct bizarre test programs
*/
#undef TREESZ
#define TREESZ 16
#endif TESTALLOC
#define MAXTSEG 64 /* max # of tree segments */
static NODE treespace[TREESZ]; /* initial tree space */
static NODE *treeseg[MAXTSEG] = {treespace};/* table of seg pointers */
static NODE **activeseg = &treeseg[0]; /* ptr to active seg slot */
static NODE *node = treespace; /* ptr to active segment */
static NODE *nextfree = treespace; /* ptr to next free node */
static int nsegs = 1; /* # of allocated segments */
static int recycling = 0; /* =1 if using old nodes */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static NODE *
tsegalloc()
{
NODE *newseg;
if ( activeseg == &treeseg[nsegs-1] ) {
/*
* no unused segments; allocate a new one
*/
if (nsegs == MAXTSEG) {
cerror("out of tree space; try simplifying");
/*NOTREACHED*/
}
newseg = (NODE *)malloc(TREESZ*sizeof(NODE));
*++activeseg = newseg;
nsegs++;
} else {
/*
* segment already allocated; use it
*/
newseg = *++activeseg;
if (newseg == NIL) {
cerror("tree space allocation");
/*NOTREACHED*/
}
}
return newseg;
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
tinit()
{
/* initialize tree space allocation */
activeseg = &treeseg[0]; /* ptr to active seg slot */
node = *activeseg; /* ptr to active segment */
nextfree = node; /* ptr to next free node */
recycling = 0;
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define TNEXT(p) (p == &node[TREESZ]? node : p+1)
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
NODE *
talloc()
{
register NODE *p, *q;
static NODE *lastfrag;
if ( nextfree < &node[TREESZ] )
return nextfree++;
if ( !recycling ) {
recycling = 1;
lastfrag = node;
}
q = lastfrag;
for( p = TNEXT(q); p != q; p = TNEXT(p) ) {
if (p->tn.op == FREE) {
return lastfrag = p;
}
}
/*
* current tree space segment is full;
* get a new one.
*/
nextfree = node = tsegalloc();
recycling = 0;
return nextfree++;
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
tcheck()
{
/*
* ensure that all nodes have been freed. Note that in the
* C compiler, some nodes remain active until the end of the
* current function, so this should not be called until then.
* In the backend-only configuration (fort) this is called
* on a statement-by-statement basis.
*/
register NODE *p;
register NODE *limit;
NODE **seg;
if( !nerrors ) {
/*
* all segments below the top one must be scanned
* from beginning to end. The top one need only
* be scanned up to the high-water mark (nextfree)
*/
for( seg = &treeseg[0]; seg < activeseg; seg++ ) {
limit = *seg + TREESZ;
for (p = *seg; p < limit; p++ ) {
if( p->in.op != FREE ) {
cerror( "wasted space: %#x", p );
}
}
}
limit = nextfree;
for( p=node; p < limit; ++p ) {
if( p->in.op != FREE ) {
cerror( "wasted space: %#x", p );
}
}
}
tinit();
#ifdef FLEXNAMES
freetstr();
#endif
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
tfree(p)
register NODE *p;
{
if (p == NIL)
return;
again:
switch(optype(p->in.op)) {
case UTYPE:
tfree(p->in.left);
/*fall through*/
case LTYPE:
p->in.op = FREE;
return;
case BITYPE:
tfree(p->in.left);
p->in.op = FREE;
p = p->in.right;
goto again;
}
}
fwalk( t, f, down ) register NODE *t; int (*f)(); {
int down1, down2;
more:
down1 = down2 = 0;
(*f)( t, down, &down1, &down2 );
switch( optype( t->in.op ) ){
case BITYPE:
fwalk( t->in.left, f, down1 );
t = t->in.right;
down = down2;
goto more;
case UTYPE:
t = t->in.left;
down = down1;
goto more;
}
}
walkf( t, f )
register NODE *t;
int (*f)();
{
switch(optype(t->in.op)) {
case LTYPE:
break;
case UTYPE:
walkf(t->in.left, f);
break;
default:
walkf(t->in.left, f);
walkf(t->in.right, f);
break;
}
(*f)( t );
}
int dope[ DSIZE ];
char *opst[DSIZE];
struct dopest { int dopeop; char opst[8]; int dopeval; } indope[] = {
NAME, "NAME", LTYPE,
STRING, "STRING", LTYPE,
REG, "REG", LTYPE,
OREG, "OREG", LTYPE,
ICON, "ICON", LTYPE,
FCON, "FCON", LTYPE,
FCCODES, "FCCODES", LTYPE,
CCODES, "CCODES", LTYPE,
UNARY MINUS, "U-", UTYPE,
UNARY MUL, "U*", UTYPE,
UNARY AND, "U&", UTYPE,
UNARY CALL, "UCALL", UTYPE|CALLFLG,
UNARY FORTCALL, "UFCALL", UTYPE|CALLFLG,
NOT, "!", UTYPE|LOGFLG,
COMPL, "~", UTYPE,
FORCE, "FORCE", UTYPE,
INIT, "INIT", UTYPE,
SCONV, "SCONV", UTYPE,
PCONV, "PCONV", UTYPE,
PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG,
ASG PLUS, "+=", BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG,
MINUS, "-", BITYPE|FLOFLG|SIMPFLG,
ASG MINUS, "-=", BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG,
MUL, "*", BITYPE|FLOFLG|MULFLG,
ASG MUL, "*=", BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG,
AND, "&", BITYPE|SIMPFLG|COMMFLG,
ASG AND, "&=", BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG,
QUEST, "?", BITYPE,
COLON, ":", BITYPE,
ANDAND, "&&", BITYPE|LOGFLG,
OROR, "||", BITYPE|LOGFLG,
CM, ",", BITYPE,
COMOP, ",OP", BITYPE,
ASSIGN, "=", BITYPE|ASGFLG,
DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG,
ASG DIV, "/=", BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG,
MOD, "%", BITYPE|DIVFLG,
ASG MOD, "%=", BITYPE|DIVFLG|ASGFLG|ASGOPFLG,
LS, "<<", BITYPE|SHFFLG,
ASG LS, "<<=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
RS, ">>", BITYPE|SHFFLG,
ASG RS, ">>=", BITYPE|SHFFLG|ASGFLG|ASGOPFLG,
OR, "|", BITYPE|COMMFLG|SIMPFLG,
ASG OR, "|=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
#ifdef VAX
ER, "^", BITYPE|COMMFLG|SIMPFLG,
ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
#else
ER, "^", BITYPE|COMMFLG,
ASG ER, "^=", BITYPE|COMMFLG|ASGFLG|ASGOPFLG,
#endif
INCR, "++", BITYPE|ASGFLG,
DECR, "--", BITYPE|ASGFLG,
STREF, "->", BITYPE,
CALL, "CALL", BITYPE|CALLFLG,
FORTCALL, "FCALL", BITYPE|CALLFLG,
EQ, "==", BITYPE|LOGFLG,
NE, "!=", BITYPE|LOGFLG,
LE, "<=", BITYPE|LOGFLG,
LT, "<", BITYPE|LOGFLG,
GE, ">", BITYPE|LOGFLG,
GT, ">", BITYPE|LOGFLG,
UGT, "UGT", BITYPE|LOGFLG,
UGE, "UGE", BITYPE|LOGFLG,
ULT, "ULT", BITYPE|LOGFLG,
ULE, "ULE", BITYPE|LOGFLG,
ARS, "A>>", BITYPE,
TYPE, "TYPE", LTYPE,
LB, "[", BITYPE,
CBRANCH, "CBRANCH", BITYPE,
FLD, "FLD", UTYPE,
PMCONV, "PMCONV", BITYPE,
PVCONV, "PVCONV", BITYPE,
RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG,
CAST, "CAST", BITYPE|ASGFLG|ASGOPFLG,
GOTO, "GOTO", UTYPE,
STASG, "STASG", BITYPE|ASGFLG,
STARG, "STARG", UTYPE,
STCALL, "STCALL", BITYPE|CALLFLG,
UNARY STCALL, "USTCALL", UTYPE|CALLFLG,
CHK, "CHK", BITYPE,
FABS, "FABS", UTYPE|INTRFLG,
FCOS, "FCOS", UTYPE|INTRFLG,
FSIN, "FSIN", UTYPE|INTRFLG,
FTAN, "FTAN", UTYPE|INTRFLG,
FACOS, "FACOS", UTYPE|INTRFLG,
FASIN, "FASIN", UTYPE|INTRFLG,
FATAN, "FATAN", UTYPE|INTRFLG,
FCOSH, "FCOSH", UTYPE|INTRFLG,
FSINH, "FSINH", UTYPE|INTRFLG,
FTANH, "FTANH", UTYPE|INTRFLG,
FEXP, "FEXP", UTYPE|INTRFLG,
F10TOX, "F10TOX", UTYPE|INTRFLG,
F2TOX, "F2TOX", UTYPE|INTRFLG,
FLOGN, "FLOGN", UTYPE|INTRFLG,
FLOG10, "FLOG10", UTYPE|INTRFLG,
FLOG2, "FLOG2", UTYPE|INTRFLG,
FSQR, "FSQR", UTYPE|INTRFLG,
FSQRT, "FSQRT", UTYPE|INTRFLG,
FAINT, "FAINT", UTYPE|INTRFLG,
FANINT, "FANINT", UTYPE|INTRFLG,
FNINT, "FNINT", UTYPE,
-1, "", 0
};
mkdope(){
register struct dopest *q;
for( q = indope; q->dopeop >= 0; ++q ){
dope[q->dopeop] = q->dopeval;
opst[q->dopeop] = q->opst;
}
}
# ifndef BUG4
tprint( t ) TWORD t; { /* output a nice description of the type of t */
static char * tnames[] = {
"undef",
"farg",
"char",
"short",
"int",
"long",
"float",
"double",
"strty",
"unionty",
"enumty",
"moety",
"uchar",
"ushort",
"unsigned",
"ulong",
"?", "?"
};
for(;; t = DECREF(t) ){
if( ISPTR(t) ) printf( "PTR " );
else if( ISFTN(t) ) printf( "FTN " );
else if( ISARY(t) ) printf( "ARY " );
else {
printf( "%s", tnames[t] );
return;
}
}
}
# endif
#ifdef FLEXNAMES
#define NTSTRBUF 40
#define TSTRSZ 2048
char itstrbuf[TSTRSZ];
char *tstrbuf[NTSTRBUF] = { itstrbuf };
char **curtstr = tstrbuf;
int tstrused;
char *
tstr(cp)
register char *cp;
{
register int i = strlen(cp);
register char *dp;
if (tstrused + i >= TSTRSZ) {
if (++curtstr >= &tstrbuf[NTSTRBUF])
cerror("out of temporary string space");
tstrused = 0;
if (*curtstr == 0) {
dp = (char *)malloc(TSTRSZ);
*curtstr = dp;
}
}
strcpy(dp = *curtstr+tstrused, cp);
tstrused += i + 1;
return (dp);
}
#endif
#ifdef malloc
#undef malloc
#endif malloc
/*
* NOTE: malloc is defined as malloc_with_care everywhere but here.
*/
char *
malloc_with_care(nbytes)
{
char *p;
p = (char*)malloc(nbytes);
if (p == NULL) {
fatal("memory allocation exceeded");
exit(1);
}
return(p);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.