Research V7 development
[unix-history] / usr / src / cmd / mip / common
# ifndef EXIT
# define EXIT exit
# endif
int nerrors = 0; /* number of errors */
NODE *NIL; /* pointer which always has 0 in it */
NODE *lastfree; /* pointer to last free node; (for allocator) */
/* 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 */
++nerrors;
where('u');
fprintf( stderr, s, a );
fprintf( stderr, "\n" );
if( nerrors > 30 ) cerror( "too many errors");
}
/* VARARGS1 */
cerror( s, a, b, c ) char *s; { /* compiler error: die */
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" );
}
EXIT(1);
}
/* VARARGS1 */
werror( s, a, b ) char *s; { /* warning */
where('w');
fprintf( stderr, "warning: " );
fprintf( stderr, s, a, b );
fprintf( stderr, "\n" );
}
tinit(){ /* initialize expression tree search */
NODE *p;
for( p=node; p<= &node[TREESZ-1]; ++p ) p->op = FREE;
lastfree = node;
}
# define TNEXT(p) (p== &node[TREESZ-1]?node:p+1)
NODE *
talloc(){
NODE *p, *q;
q = lastfree;
for( p = TNEXT(q); p!=q; p= TNEXT(p))
if( p->op ==FREE ) return(lastfree=p);
cerror( "out of tree space; simplify expression");
/* NOTREACHED */
}
tcheck(){ /* ensure that all nodes have been freed */
NODE *p;
if( !nerrors )
for( p=node; p<= &node[TREESZ-1]; ++p )
if( p->op != FREE ) cerror( "wasted space: %o", p );
tinit();
}
tfree( p ) NODE *p; {
/* free the tree p */
extern tfree1();
if( p->op != FREE ) walkf( p, tfree1 );
}
tfree1(p) NODE *p; {
if( p == 0 ) cerror( "freeing blank tree!");
else p->op = FREE;
}
fwalk( t, f, down ) register NODE *t; int (*f)(); {
int down1, down2;
more:
down1 = down2 = 0;
(*f)( t, down, &down1, &down2 );
switch( optype( t->op ) ){
case BITYPE:
fwalk( t->left, f, down1 );
t = t->right;
down = down2;
goto more;
case UTYPE:
t = t->left;
down = down1;
goto more;
}
}
walkf( t, f ) register NODE *t; int (*f)(); {
register opty;
opty = optype(t->op);
if( opty != LTYPE ) walkf( t->left, f );
if( opty == BITYPE ) walkf( t->right, f );
(*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,
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,
ER, "^", BITYPE|COMMFLG|SIMPFLG,
ASG ER, "^=", BITYPE|COMMFLG|SIMPFLG|ASGFLG|ASGOPFLG,
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,
-1, 0
};
mkdope(){
register struct dopest *q;
for( q = indope; q->dopeop >= 0; ++q ){
dope[q->dopeop] = q->dopeval;
opst[q->dopeop] = q->opst;
}
}
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;
}
}
}