⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rval.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * Copyright (c) 1980, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)rval.c	8.1 (Berkeley) 6/6/93";#endif /* not lint */#include "whoami.h"#include "0.h"#include "tree.h"#include "opcode.h"#include "objfmt.h"#ifdef PC#   include	"pc.h"#   include <pcc.h>#endif PC#include "tmps.h"#include "tree_ty.h"extern	char *opnames[];    /* line number of the last record comparison warning */short reccompline = 0;    /* line number of the last non-standard set comparison */short nssetline = 0;#ifdef PC    char	*relts[] =  {				"_RELEQ" , "_RELNE" ,				"_RELTLT" , "_RELTGT" ,				"_RELTLE" , "_RELTGE"			    };    char	*relss[] =  {				"_RELEQ" , "_RELNE" ,				"_RELSLT" , "_RELSGT" ,				"_RELSLE" , "_RELSGE"			    };    long	relops[] =  {					PCC_EQ , PCC_NE ,				PCC_LT , PCC_GT ,				PCC_LE , PCC_GE 			    };    long	mathop[] =  {	PCC_MUL , PCC_PLUS , PCC_MINUS };    char	*setop[] =  {	"_MULT" , "_ADDT" , "_SUBT" };#endif PC/* * Rvalue - an expression. * * Contype is the type that the caller would prefer, nand is important * if constant strings are involved, because of string padding. * required is a flag whether an lvalue or an rvalue is required. * only VARs and structured things can have gt their lvalue this way. *//*ARGSUSED*/struct nl *rvalue(r, contype , required )	struct tnode *r;	struct nl *contype;	int	required;{	register struct nl *p, *p1;	register struct nl *q;	int c, c1, w;#ifdef OBJ	int g;#endif	struct tnode *rt;	char *cp, *cp1, *opname;	long l;	union	{	    long plong[2];	    double pdouble;	}f;	extern int	flagwas;	struct csetstr	csetd;#	ifdef PC	    struct nl	*rettype;	    long	ctype;	    struct nl	*tempnlp;#	endif PC	if (r == TR_NIL)		return (NLNIL);	if (nowexp(r))		return (NLNIL);	/*	 * Pick up the name of the operation	 * for future error messages.	 */	if (r->tag <= T_IN)		opname = opnames[r->tag];	/*	 * The root of the tree tells us what sort of expression we have.	 */	switch (r->tag) {	/*	 * The constant nil	 */	case T_NIL:#		ifdef OBJ		    (void) put(2, O_CON2, 0);#		endif OBJ#		ifdef PC		    putleaf( PCC_ICON , 0 , 0 , PCCTM_PTR|PCCT_UNDEF , (char *) 0 );#		endif PC		return (nl+TNIL);	/*	 * Function call with arguments.	 */	case T_FCALL:#	    ifdef OBJ		return (funccod(r));#	    endif OBJ#	    ifdef PC		return (pcfunccod( r ));#	    endif PC	case T_VAR:		p = lookup(r->var_node.cptr);		if (p == NLNIL || p->class == BADUSE)			return (NLNIL);		switch (p->class) {		    case VAR:			    /*			     * If a variable is			     * qualified then get			     * the rvalue by a			     * lvalue and an ind.			     */			    if (r->var_node.qual != TR_NIL)				    goto ind;			    q = p->type;			    if (q == NIL)				    return (NLNIL);#			    ifdef OBJ				w = width(q);				switch (w) {				    case 8:					(void) put(2, O_RV8 | bn << 8+INDX,						(int)p->value[0]);					break;				    case 4:					(void) put(2, O_RV4 | bn << 8+INDX,						(int)p->value[0]);					break;				    case 2:					(void) put(2, O_RV2 | bn << 8+INDX,						(int)p->value[0]);					break;				    case 1:					(void) put(2, O_RV1 | bn << 8+INDX,						(int)p->value[0]);					break;				    default:					(void) put(3, O_RV | bn << 8+INDX,						(int)p->value[0], w);				}#			   endif OBJ#			   ifdef PC				if ( required == RREQ ) {				    putRV( p -> symbol , bn , p -> value[0] ,					    p -> extra_flags , p2type( q ) );				} else {				    putLV( p -> symbol , bn , p -> value[0] ,					    p -> extra_flags , p2type( q ) );				}#			   endif PC			   return (q);		    case WITHPTR:		    case REF:			    /*			     * A lvalue for these			     * is actually what one			     * might consider a rvalue.			     */ind:			    q = lvalue(r, NOFLAGS , LREQ );			    if (q == NIL)				    return (NLNIL);#			    ifdef OBJ				w = width(q);				switch (w) {				    case 8:					    (void) put(1, O_IND8);					    break;				    case 4:					    (void) put(1, O_IND4);					    break;				    case 2:					    (void) put(1, O_IND2);					    break;				    case 1:					    (void) put(1, O_IND1);					    break;				    default:					    (void) put(2, O_IND, w);				}#			    endif OBJ#			    ifdef PC				if ( required == RREQ ) {				    putop( PCCOM_UNARY PCC_MUL , p2type( q ) );				}#			    endif PC			    return (q);		    case CONST:			    if (r->var_node.qual != TR_NIL) {				error("%s is a constant and cannot be qualified", r->var_node.cptr);				return (NLNIL);			    }			    q = p->type;			    if (q == NLNIL)				    return (NLNIL);			    if (q == nl+TSTR) {				    /*				     * Find the size of the string				     * constant if needed.				     */				    cp = (char *) p->ptr[0];cstrng:				    cp1 = cp;				    for (c = 0; *cp++; c++)					    continue;				    w = c;				    if (contype != NIL && !opt('s')) {					    if (width(contype) < c && classify(contype) == TSTR) {						    error("Constant string too long");						    return (NLNIL);					    }					    w = width(contype);				    }#				    ifdef OBJ					(void) put(2, O_CONG, w);					putstr(cp1, w - c);#				    endif OBJ#				    ifdef PC					putCONG( cp1 , w , required );#				    endif PC				    /*				     * Define the string temporarily				     * so later people can know its				     * width.				     * cleaned out by stat.				     */				    q = defnl((char *) 0, STR, NLNIL, w);				    q->type = q;				    return (q);			    }			    if (q == nl+T1CHAR) {#				    ifdef OBJ					(void) put(2, O_CONC, (int)p->value[0]);#				    endif OBJ#				    ifdef PC					putleaf( PCC_ICON , p -> value[0] , 0						, PCCT_CHAR , (char *) 0 );#				    endif PC				    return (q);			    }			    /*			     * Every other kind of constant here			     */			    switch (width(q)) {			    case 8:#ifndef DEBUG#				    ifdef OBJ					(void) put(2, O_CON8, p->real);#				    endif OBJ#				    ifdef PC					putCON8( p -> real );#				    endif PC#else				    if (hp21mx) {					    f.pdouble = p->real;					    conv((int *) (&f.pdouble));					    l = f.plong[1];					    (void) put(2, O_CON4, l);				    } else#					    ifdef OBJ						(void) put(2, O_CON8, p->real);#					    endif OBJ#					    ifdef PC						putCON8( p -> real );#					    endif PC#endif				    break;			    case 4:#				    ifdef OBJ					(void) put(2, O_CON4, p->range[0]);#				    endif OBJ#				    ifdef PC					putleaf( PCC_ICON , (int) p->range[0] , 0						, PCCT_INT , (char *) 0 );#				    endif PC				    break;			    case 2:#				    ifdef OBJ					(void) put(2, O_CON2, (short)p->range[0]);#				    endif OBJ#				    ifdef PC					putleaf( PCC_ICON , (short) p -> range[0]						, 0 , PCCT_SHORT , (char *) 0 );#				    endif PC				    break;			    case 1:#				    ifdef OBJ					(void) put(2, O_CON1, p->value[0]);#				    endif OBJ#				    ifdef PC					putleaf( PCC_ICON , p -> value[0] , 0						, PCCT_CHAR , (char *) 0 );#				    endif PC				    break;			    default:				    panic("rval");			    }			    return (q);		    case FUNC:		    case FFUNC:			    /*			     * Function call with no arguments.			     */			    if (r->var_node.qual != TR_NIL) {				    error("Can't qualify a function result value");				    return (NLNIL);			    }#			    ifdef OBJ				return (funccod(r));#			    endif OBJ#			    ifdef PC				return (pcfunccod( r ));#			    endif PC		    case TYPE:			    error("Type names (e.g. %s) allowed only in declarations", p->symbol);			    return (NLNIL);		    case PROC:		    case FPROC:			    error("Procedure %s found where expression required", p->symbol);			    return (NLNIL);		    default:			    panic("rvid");		}	/*	 * Constant sets	 */	case T_CSET:#		ifdef OBJ		    if ( precset( r , contype , &csetd ) ) {			if ( csetd.csettype == NIL ) {			    return (NLNIL);			}			postcset( r , &csetd );		    } else {			(void) put( 2, O_PUSH, -lwidth(csetd.csettype));			postcset( r , &csetd );			setran( ( csetd.csettype ) -> type );			(void) put( 2, O_CON24, set.uprbp);			(void) put( 2, O_CON24, set.lwrb);			(void) put( 2, O_CTTOT,				(int)(4 + csetd.singcnt + 2 * csetd.paircnt));		    }		    return csetd.csettype;#		endif OBJ#		ifdef PC		    if ( precset( r , contype , &csetd ) ) {			if ( csetd.csettype == NIL ) {			    return (NLNIL);			}			postcset( r , &csetd );		    } else {			putleaf( PCC_ICON , 0 , 0				, PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )				, "_CTTOT" );			/*			 *	allocate a temporary and use it			 */			tempnlp = tmpalloc(lwidth(csetd.csettype),				csetd.csettype, NOREG);			putLV( (char *) 0 , cbn , tempnlp -> value[ NL_OFFS ] ,				tempnlp -> extra_flags , PCCTM_PTR|PCCT_STRTY );			setran( ( csetd.csettype ) -> type );			putleaf( PCC_ICON , set.lwrb , 0 , PCCT_INT , (char *) 0 );			putop( PCC_CM , PCCT_INT );			putleaf( PCC_ICON , set.uprbp , 0 , PCCT_INT , (char *) 0 );			putop( PCC_CM , PCCT_INT );			postcset( r , &csetd );			putop( PCC_CALL , PCCT_INT );		    }		    return csetd.csettype;

⌨️ 快捷键说明

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