📄 rval.c
字号:
/*- * 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 + -