trees.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,611 行 · 第 1/3 页
C
1,611 行
#ifndef lintstatic char *sccsid ="@(#)trees.c 1.1 (decvax!reilly) 4/27/84";#endif/************************************************************************ * * Modification History * * Stephen Reilly, 13-Feb-84 * 002- Fix a coding bug from ( 001 ). The problem was I thought asgop * only was true for assign type operations. Not true the RETURN * CAST are considered assign typea which causes conversion problems. * * Stephen Reilly, 20-Jan-84 * 001- Fix the problem with ( int op= real ). The bug was that the * real was converted to the int rather than the int being * converted to real. * ***********************************************************************//************************************************************************ * * * Copyright (c) 1984 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************/# include "mfile1" /* corrections when in violation of lint *//* some special actions, used in finding the type of nodes */# define NCVT 01# define PUN 02# define TYPL 04# define TYPR 010# define TYMATCH 040# define LVAL 0100# define CVTO 0200# define CVTL 0400# define CVTR 01000# define PTMATCH 02000# define OTHER 04000# define NCVTR 010000/* node conventions: NAME: rval>0 is stab index for external rval<0 is -inlabel number lval is offset in bits ICON: lval has the value rval has the STAB index, or - label number, if a name whose address is in the constant rval = NONAME means no name REG: rval is reg. identification cookie */int bdebug = 0;extern ddebug;NODE *buildtree( o, l, r ) register NODE *l, *r; { register NODE *p, *q; register actions; register opty; register struct symtab *sp; register NODE *lr, *ll; int i; extern int eprint();# ifndef BUG1 if( bdebug ) printf( "buildtree( %s, %o, %o )\n", opst[o], l, r );# endif opty = optype(o); /* check for constants */ if( opty == UTYPE && l->in.op == ICON ){ switch( o ){ case NOT: if( hflag ) werror( "constant argument to NOT" ); case UNARY MINUS: case COMPL: if( conval( l, o, l ) ) return(l); break; } } else if( o==UNARY MINUS && l->in.op==FCON ){ l->fpn.dval = -l->fpn.dval; return(l); } else if( o==QUEST && l->in.op==ICON ) { l->in.op = FREE; r->in.op = FREE; if( l->tn.lval ){ tfree( r->in.right ); return( r->in.left ); } else { tfree( r->in.left ); return( r->in.right ); } } else if( (o==ANDAND || o==OROR) && (l->in.op==ICON||r->in.op==ICON) ) goto ccwarn; else if( opty == BITYPE && l->in.op == ICON && r->in.op == ICON ){ switch( o ){ case ULT: case UGT: case ULE: case UGE: case LT: case GT: case LE: case GE: case EQ: case NE: case ANDAND: case OROR: case CBRANCH: ccwarn: if( hflag ) werror( "constant in conditional context" ); case PLUS: case MINUS: case MUL: case DIV: case MOD: case AND: case OR: case ER: case LS: case RS: if( conval( l, o, r ) ) { r->in.op = FREE; return(l); } break; } } else if( opty == BITYPE && (l->in.op==FCON||l->in.op==ICON) && (r->in.op==FCON||r->in.op==ICON) ){ switch(o){ case PLUS: case MINUS: case MUL: case DIV: if( l->in.op == ICON ){ l->fpn.dval = l->tn.lval; } if( r->in.op == ICON ){ r->fpn.dval = r->tn.lval; } l->in.op = FCON; l->in.type = l->fn.csiz = DOUBLE; r->in.op = FREE; switch(o){ case PLUS: l->fpn.dval += r->fpn.dval; return(l); case MINUS: l->fpn.dval -= r->fpn.dval; return(l); case MUL: l->fpn.dval *= r->fpn.dval; return(l); case DIV: if( r->fpn.dval == 0 ) uerror( "division by 0." ); else l->fpn.dval /= r->fpn.dval; return(l); } } } /* its real; we must make a new node */ p = block( o, l, r, INT, 0, INT ); actions = opact(p); if( actions&LVAL ){ /* check left descendent */ if( notlval(p->in.left) ) { uerror( "illegal lhs of assignment operator" ); } } if( actions & NCVTR ){ p->in.left = pconvert( p->in.left ); } else if( !(actions & NCVT ) ){ switch( opty ){ case BITYPE: p->in.right = pconvert( p->in.right ); case UTYPE: p->in.left = pconvert( p->in.left ); } } if( (actions&PUN) && (o!=CAST||cflag) ){ chkpun(p); } if( actions & (TYPL|TYPR) ){ q = (actions&TYPL) ? p->in.left : p->in.right; p->in.type = q->in.type; p->fn.cdim = q->fn.cdim; p->fn.csiz = q->fn.csiz; } if( actions & CVTL ) p = convert( p, CVTL ); if( actions & CVTR ) p = convert( p, CVTR ); if( actions & TYMATCH ) p = tymatch(p); if( actions & PTMATCH ) p = ptmatch(p); if( actions & OTHER ){ l = p->in.left; r = p->in.right; switch(o){ case NAME: sp = &stab[idname]; if( sp->stype == UNDEF ){#ifndef FLEXNAMES uerror( "%.8s undefined", sp->sname );#else uerror( "%s undefined", sp->sname );#endif /* make p look reasonable */ p->in.type = p->fn.cdim = p->fn.csiz = INT; p->tn.rval = idname; p->tn.lval = 0; defid( p, SNULL ); break; } p->in.type = sp->stype; p->fn.cdim = sp->dimoff; p->fn.csiz = sp->sizoff; p->tn.lval = 0; p->tn.rval = idname; /* special case: MOETY is really an ICON... */ if( p->in.type == MOETY ){ p->tn.rval = NONAME; p->tn.lval = sp->offset; p->fn.cdim = 0; p->in.type = ENUMTY; p->in.op = ICON; } break; case ICON: p->in.type = INT; p->fn.cdim = 0; p->fn.csiz = INT; break; case STRING: p->in.op = NAME; p->in.type = CHAR+ARY; p->tn.lval = 0; p->tn.rval = NOLAB; p->fn.cdim = curdim; p->fn.csiz = CHAR; break; case FCON: p->tn.lval = 0; p->tn.rval = 0; p->in.type = DOUBLE; p->fn.cdim = 0; p->fn.csiz = DOUBLE; break; case STREF: /* p->x turned into *(p+offset) */ /* rhs must be a name; check correctness */ i = r->tn.rval; if( i<0 || ((sp= &stab[i])->sclass != MOS && sp->sclass != MOU && !(sp->sclass&FIELD)) ){ uerror( "member of structure or union required" ); }else /* if this name is non-unique, find right one */ if( stab[i].sflags & SNONUNIQ && (l->in.type==PTR+STRTY || l->in.type == PTR+UNIONTY) && (l->fn.csiz +1) >= 0 ){ /* nonunique name && structure defined */ char * memnam, * tabnam; register k; int j; int memi; j=dimtab[l->fn.csiz+1]; for( ; (memi=dimtab[j]) >= 0; ++j ){ tabnam = stab[memi].sname; memnam = stab[i].sname;# ifndef BUG1 if( ddebug>1 ){#ifndef FLEXNAMES printf("member %.8s==%.8s?\n",#else printf("member %s==%s?\n",#endif memnam, tabnam); }# endif if( stab[memi].sflags & SNONUNIQ ){#ifndef FLEXNAMES for( k=0; k<NCHNAM; ++k ){ if(*memnam++!=*tabnam) goto next; if(!*tabnam++) break; }#else if (memnam != tabnam) goto next;#endif r->tn.rval = i = memi; break; } next: continue; } if( memi < 0 )#ifndef FLEXNAMES uerror("illegal member use: %.8s",#else uerror("illegal member use: %s",#endif stab[i].sname); } else { register j; if( l->in.type != PTR+STRTY && l->in.type != PTR+UNIONTY ){ if( stab[i].sflags & SNONUNIQ ){ uerror( "nonunique name demands struct/union or struct/union pointer" ); } else werror( "struct/union or struct/union pointer required" ); } else if( (j=l->fn.csiz+1)<0 ) cerror( "undefined structure or union" ); else if( !chkstr( i, dimtab[j], DECREF(l->in.type) ) ){#ifndef FLEXNAMES werror( "illegal member use: %.8s", stab[i].sname );#else werror( "illegal member use: %s", stab[i].sname );#endif } } p = stref( p ); break; case UNARY MUL: if( l->in.op == UNARY AND ){ p->in.op = l->in.op = FREE; p = l->in.left; } if( !ISPTR(l->in.type))uerror("illegal indirection"); p->in.type = DECREF(l->in.type); p->fn.cdim = l->fn.cdim; p->fn.csiz = l->fn.csiz; break; case UNARY AND: switch( l->in.op ){ case UNARY MUL: p->in.op = l->in.op = FREE; p = l->in.left; case NAME: p->in.type = INCREF( l->in.type ); p->fn.cdim = l->fn.cdim; p->fn.csiz = l->fn.csiz; break; case COMOP: lr = buildtree( UNARY AND, l->in.right, NIL ); p->in.op = l->in.op = FREE; p = buildtree( COMOP, l->in.left, lr ); break; case QUEST: lr = buildtree( UNARY AND, l->in.right->in.right, NIL ); ll = buildtree( UNARY AND, l->in.right->in.left, NIL ); p->in.op = l->in.op = l->in.right->in.op = FREE; p = buildtree( QUEST, l->in.left, buildtree( COLON, ll, lr ) ); break;# ifdef ADDROREG case OREG: /* OREG was built in clocal() * for an auto or formal parameter * now its address is being taken * local code must unwind it * back to PLUS/MINUS REG ICON * according to local conventions */ { extern NODE * addroreg(); p->in.op = FREE; p = addroreg( l ); } break;# endif default: uerror( "unacceptable operand of &" ); break; } break; case LS: case RS: case ASG LS: case ASG RS: if(tsize(p->in.right->in.type, p->in.right->fn.cdim, p->in.right->fn.csiz) > SZINT) p->in.right = makety(p->in.right, INT, 0, INT ); break; case RETURN: case ASSIGN: case CAST: /* structure assignment */ /* take the addresses of the two sides; then make an /* operator using STASG and /* the addresses of left and right */ { register TWORD t; register d, s; if( l->fn.csiz != r->fn.csiz ) uerror( "assignment of different structures" ); r = buildtree( UNARY AND, r, NIL ); t = r->in.type; d = r->fn.cdim; s = r->fn.csiz; l = block( STASG, l, r, t, d, s ); if( o == RETURN ){ p->in.op = FREE; p = l; break; } p->in.op = UNARY MUL; p->in.left = l; p->in.right = NIL; break; } case COLON: /* structure colon */ if( l->fn.csiz != r->fn.csiz ) uerror( "type clash in conditional" ); break; case CALL: p->in.right = r = strargs( p->in.right ); case UNARY CALL: if( !ISPTR(l->in.type)) uerror("illegal function"); p->in.type = DECREF(l->in.type); if( !ISFTN(p->in.type)) uerror("illegal function"); p->in.type = DECREF( p->in.type ); p->fn.cdim = l->fn.cdim; p->fn.csiz = l->fn.csiz; if( l->in.op == UNARY AND && l->in.left->in.op == NAME && l->in.left->tn.rval >= 0 && l->in.left->tn.rval != NONAME && ( (i=stab[l->in.left->tn.rval].sclass) == FORTRAN || i==UFORTRAN ) ){ p->in.op += (FORTCALL-CALL); } if( p->in.type == STRTY || p->in.type == UNIONTY ){ /* function returning structure */ /* make function really return ptr to str., with * */ p->in.op += STCALL-CALL; p->in.type = INCREF( p->in.type ); p = buildtree( UNARY MUL, p, NIL ); } break; default: cerror( "other code %d", o ); } } if( actions & CVTO ) p = oconvert(p); p = clocal(p);# ifndef BUG1 if( bdebug ) fwalk( p, eprint, 0 );# endif return(p); }NODE *strargs( p ) register NODE *p; { /* rewrite structure flavored arguments */ if( p->in.op == CM ){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?