intr.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 723 行 · 第 1/2 页

C
723
字号
} ;char callbyvalue[ ][XL] =	{	"sqrt",	"exp",	"log",	"sin",	"cos",	"tan",	"asin",	"acos",	"atan",	"atan2",	"sinh",	"cosh",	"tanh",	"log10"	};expptr intrcall(np, argsp, nargs)Namep np;struct Listblock *argsp;int nargs;{int i, rettype;Addrp ap;register struct Specblock *sp;register struct Chain *cp;expptr inline(), mkcxcon(), mkrealcon();expptr q, ep;int mtype;int op;int f1field, f2field, f3field;packed.ijunk = np->vardesc.varno;f1field = packed.bits.f1;f2field = packed.bits.f2;f3field = packed.bits.f3;if(nargs == 0)	goto badnargs;mtype = 0;for(cp = argsp->listp ; cp ; cp = cp->nextp)	{/* TEMPORARY */ ep = (expptr) (cp->datap);/* TEMPORARY */	if( ISCONST(ep) && ep->headblock.vtype==TYSHORT )/* TEMPORARY */		cp->datap = (tagptr) mkconv(tyint, ep);	mtype = maxtype(mtype, ep->headblock.vtype);	}switch(f1field)	{	case INTRBOOL:		op = f3field;		if( ! ONEOF(mtype, MSKINT|MSKLOGICAL) )			goto badtype;		if(op == OPBITNOT)			{			if(nargs != 1)				goto badnargs;			q = mkexpr(OPBITNOT, argsp->listp->datap, ENULL);			}		else			{			if(nargs != 2)				goto badnargs;			q = mkexpr(op, argsp->listp->datap,				argsp->listp->nextp->datap);			}		frchain( &(argsp->listp) );		free( (charptr) argsp);		return(q);	case INTRCONV:		if (nargs == 1)			{			if(argsp->listp->datap->headblock.vtype == TYERROR)				{				free( (charptr) argsp->listp->datap);				frchain( &(argsp->listp) );				free( (charptr) argsp);				return( errnode() );				}			}		else if (nargs == 2)			{			if(argsp->listp->nextp->datap->headblock.vtype == 				TYERROR ||				argsp->listp->datap->headblock.vtype == TYERROR)				{				free( (charptr) argsp->listp->nextp->datap);				free( (charptr) argsp->listp->datap);				frchain( &(argsp->listp) );				free( (charptr) argsp);				return( errnode() );				}			}		rettype = f2field;		if( ISCOMPLEX(rettype) && nargs==2)			{			expptr qr, qi;			if(dblflag) rettype = TYDCOMPLEX;			qr = (expptr) (argsp->listp->datap);			qi = (expptr) (argsp->listp->nextp->datap);			if(ISCONST(qr) && ISCONST(qi))				q = mkcxcon(qr,qi);			else	q = mkexpr(OPCONV,intrconv(rettype-2,qr),					intrconv(rettype-2,qi));			}		else if(nargs == 1)			{			if(rettype == TYLONG) rettype = tyint;			else if( dblflag )				{				if ( rettype == TYREAL )					rettype = TYDREAL;				else if( rettype == TYCOMPLEX )					rettype = TYDCOMPLEX;				}			q = intrconv(rettype, argsp->listp->datap);			}		else goto badnargs;		q->headblock.vtype = rettype;		frchain(&(argsp->listp));		free( (charptr) argsp);		return(q);	case INTRGEN:		sp = spectab + f3field;#ifdef ONLY66		if(no66flag)			if(sp->atype == mtype)				goto specfunct;			else err66("generic function");#endif		for(i=0; i<f2field ; ++i)			if(sp->atype == mtype)				goto specfunct;			else				++sp;		goto badtype;	case INTRSPEC:		sp = spectab + f3field;		if( dblflag )			{			/* convert specific complex functions to double complex:			 *	 cabs,csqrt,cexp,clog,csin,ccos, aimag			 * and convert real specifics to double:			 *	 amod,alog,alog10			 * (sqrt,cos,sin,... o.k. since go through INTRGEN)			 */			if( (sp->atype==TYCOMPLEX && (sp+1)->atype==TYDCOMPLEX)				||(sp->atype==TYREAL && (sp+1)->atype==TYDREAL))					sp++;			}	specfunct:		if(tyint==TYLONG && ONEOF(sp->rtype,M(TYSHORT)|M(TYLOGICAL))			&& (sp+1)->atype==sp->atype)				++sp;		if(nargs != sp->nargs)			goto badnargs;		if(mtype != sp->atype			&& (!dblflag || f3field != 26 || mtype != TYDREAL ) )				goto badtype;		fixargs(YES, argsp);		if(q = inline(sp-spectab, mtype, argsp->listp))			{			frchain( &(argsp->listp) );			free( (charptr) argsp);			}		else if(sp->othername)			{			ap = builtin(TYDREAL,				varstr(XL, callbyvalue[sp->othername-1]) );			ap->vstg = STGINTR;			q = fixexpr( mkexpr(OPCCALL, ap, argsp) );			if( sp->rtype != TYDREAL )				q = mkconv( sp->rtype, q );			}		else			{			ap = builtin(sp->rtype, varstr(XL, sp->spxname) );			ap->vstg = STGINTR;			q = fixexpr( mkexpr(OPCALL, ap, argsp) );			}		return(q);	case INTRMIN:	case INTRMAX:		if(nargs < 2)			goto badnargs;		if( ! ONEOF(mtype, MSKINT|MSKREAL) )			goto badtype;		argsp->vtype = mtype;		q = mkexpr( (f1field==INTRMIN ? OPMIN : OPMAX), argsp, ENULL);		q->headblock.vtype = mtype;		rettype = f2field;		if(rettype == TYLONG)			rettype = tyint;		else if(rettype == TYUNKNOWN)			rettype = mtype;		else if( dblflag && rettype == TYREAL )			rettype = TYDREAL;		return( intrconv(rettype, q) );	default:		fatali("intrcall: bad intrgroup %d", f1field);	}badnargs:	errstr("bad number of arguments to intrinsic %s",		varstr(VL,np->varname) );	goto bad;badtype:	errstr("bad argument type to intrinsic %s", varstr(VL, np->varname) );bad:	return( errnode() );}intrfunct(s)char s[VL];{register struct Intrblock *p;char nm[VL];register int i;for(i = 0 ; i<VL ; ++s)	nm[i++] = (*s==' ' ? '\0' : *s);for(p = intrtab; p->intrval.intrgroup!=INTREND ; ++p)	{	if( eqn(VL, nm, p->intrfname) )		{		packed.bits.f1 = p->intrval.intrgroup;		packed.bits.f2 = p->intrval.intrstuff;		packed.bits.f3 = p->intrval.intrno;		return(packed.ijunk);		}	}return(0);}Addrp intraddr(np)Namep np;{Addrp q;register struct Specblock *sp;int f3field;if(np->vclass!=CLPROC || np->vprocclass!=PINTRINSIC)	fatalstr("intraddr: %s is not intrinsic", varstr(VL,np->varname));packed.ijunk = np->vardesc.varno;f3field = packed.bits.f3;switch(packed.bits.f1)	{	case INTRGEN:		/* imag, log, and log10 arent specific functions */		if(f3field==31 || f3field==43 || f3field==47)			goto bad;	case INTRSPEC:		sp = spectab + f3field;		if( dblflag )			{			if((sp->atype==TYCOMPLEX && (sp+1)->atype==TYDCOMPLEX)				||(sp->atype==TYREAL && (sp+1)->atype==TYDREAL))					sp++;			else if( f3field==4 )					sp += 2;  /* h_nint -> h_dnnt */			else if( f3field==8 || f3field==18 || f3field==22)					sp += 3;  /* r_{abs,sign,dim} ->d_... */			else if( f3field==26 )					sp = spectab + 81; /* dprod */			}		if(tyint==TYLONG && sp->rtype==TYSHORT)			++sp;		q = builtin(sp->rtype, varstr(XL,sp->spxname) );		q->vstg = STGINTR;		return(q);	case INTRCONV:	case INTRMIN:	case INTRMAX:	case INTRBOOL:	bad:		errstr("cannot pass %s as actual",			varstr(VL,np->varname));		return( (Addrp) errnode() );	}fatali("intraddr: impossible f1=%d\n", (int) packed.bits.f1);/* NOTREACHED */}expptr inline(fno, type, args)int fno;int type;struct Chain *args;{register expptr q, t, t1;switch(fno)	{	case 8:	/* real abs */	case 9:	/* short int abs */	case 10:	/* long int abs */	case 11:	/* double precision abs */		if( addressable(q = (expptr) (args->datap)) )			{			t = q;			q = NULL;			}		else			t = (expptr) mktemp(type,PNULL);		t1 = mkexpr(OPQUEST,			mkexpr(OPLE, intrconv(type,ICON(0)), cpexpr(t)),			mkexpr(OPCOLON, cpexpr(t),				mkexpr(OPNEG, cpexpr(t), ENULL) ));		if(q)			t1 = mkexpr(OPCOMMA, mkexpr(OPASSIGN, cpexpr(t),q), t1);		frexpr(t);		return(t1);	case 26:	/* dprod */		q = mkexpr(OPSTAR, intrconv(TYDREAL,args->datap), args->nextp->datap);		return(q);	case 27:	/* len of character string */	case 28:		q = (expptr) cpexpr(args->datap->headblock.vleng);		frexpr(args->datap);		return(q);	case 14:	/* half-integer mod */	case 15:	/* mod */		return( mkexpr(OPMOD, (expptr) (args->datap),			(expptr) (args->nextp->datap) ));	}return(NULL);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?