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

📄 forop.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * 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[] = "@(#)forop.c	8.1 (Berkeley) 6/6/93";#endif /* not lint */#include	"whoami.h"#include	"0.h"#include	"opcode.h"#include	"tree.h"#include	"objfmt.h"#ifdef PC#    include	"pc.h"#    include	<pcc.h>#endif PC#include	"tmps.h"#include	"tree_ty.h"    /*     *	for-statements.     *     *	the relevant quote from the standard:  6.8.3.9:     *	``The control-variable shall be an entire-variable whose identifier     *	is declared in the variable-declaration-part of the block closest-     *	containing the for-statement.  The control-variable shall possess     *	an ordinal-type, and the initial-value and the final-value shall be     *	of a type compatible with this type.  The statement of a for-statement     *	shall not contain an assigning-reference to the control-variable     *	of the for-statement.  The value of the final-value shall be      *	assignment-compatible with the control-variable when the initial-value     *	is assigned to the control-variable.  After a for-statement is     *	executed (other than being left by a goto-statement leading out of it)     *	the control-variable shall be undefined.  Apart from the restrictions     *	imposed by these requirements, the for-statement     *		for v := e1 to e2 do body     *	shall be equivalent to     *		begin     *		    temp1 := e1;     *		    temp2 := e2;     *		    if temp1 <= temp2 then begin     *			v := temp1;     *			body;     *			while v <> temp2 do begin     *			    v := succ(v);     *			    body;     *			end     *		    end     *		end     *	where temp1 and temp2 denote auxiliary variables that the program     *	does not otherwise contain, and that possess the type possessed by     *	the variable v if that type is not a subrange-type;  otherwise the     *	host type possessed by the variable v.''     *     *	The Berkeley Pascal systems try to do all that without duplicating     *	the body, and shadowing the control-variable in (possibly) a     *	register variable.     *     *	arg here looks like:     *	arg[0]	T_FORU or T_FORD     *	   [1]	lineof "for"     *	   [2]	[0]	T_ASGN     *		[1]	lineof ":="     *		[2]	[0]	T_VAR     *			[1]	lineof id     *			[2]	char * to id     *			[3]	qualifications     *		[3]	initial expression     *	  [3]	termination expression     *	  [4]	statement     */forop( tree_node)    struct tnode	*tree_node;    {	struct tnode	*lhs;	VAR_NODE	*lhs_node;	FOR_NODE	*f_node;	struct nl	*forvar;	struct nl	*fortype;#ifdef PC	int		forp2type;#endif PC	int		forwidth;	struct tnode	*init_node;	struct nl	*inittype;	struct nl	*initnlp;	/* initial value namelist entry */	struct tnode	*term_node;	struct nl	*termtype;	struct nl	*termnlp;	/* termination value namelist entry */	struct nl	*shadownlp;	/* namelist entry for the shadow */	struct tnode	*stat_node;	int		goc;		/* saved gocnt */	int		again;		/* label at the top of the loop */	int		after;		/* label after the end of the loop */	struct nl	saved_nl;	/* saved namelist entry for loop var */	goc = gocnt;	forvar = NLNIL;	if ( tree_node == TR_NIL ) { 	    goto byebye;	}	f_node = &(tree_node->for_node);	if ( f_node->init_asg == TR_NIL ) {	    goto byebye;	}	line = f_node->line_no;	putline();	lhs = f_node->init_asg->asg_node.lhs_var;	init_node = f_node->init_asg->asg_node.rhs_expr;	term_node = f_node->term_expr;	stat_node = f_node->for_stmnt;	if (lhs == TR_NIL) {nogood:	    if (forvar != NIL) {		forvar->value[ NL_FORV ] = FORVAR;	    }	    (void) rvalue( init_node , NLNIL , RREQ ); 	    (void) rvalue( term_node , NLNIL , RREQ );	    statement( stat_node );	    goto byebye;	}	else lhs_node = &(lhs->var_node);	    /*	     * and this marks the variable as used!!!	     */	forvar = lookup( lhs_node->cptr );	if ( forvar == NIL ) {	    goto nogood;	}	saved_nl = *forvar;	if ( lhs_node->qual != TR_NIL ) {	    error("For variable %s must be unqualified", forvar->symbol);	    goto nogood;	}	if (forvar->class == WITHPTR) {	    error("For variable %s cannot be an element of a record", 			lhs_node->cptr);	    goto nogood;	}	if ( opt('s') &&	    ( ( bn != cbn ) ||#ifdef OBJ		(whereis(forvar->value[NL_OFFS], 0) == PARAMVAR)#endif OBJ#ifdef PC		(whereis(forvar->value[NL_OFFS], forvar->extra_flags)		    == PARAMVAR )#endif PC	    ) ) {	    standard();	    error("For variable %s must be declared in the block in which it is used", forvar->symbol);	}	    /*	     * find out the type of the loop variable	     */	codeoff();	fortype = lvalue( lhs , MOD , RREQ );	codeon();	if ( fortype == NLNIL ) {	    goto nogood;	}	if ( isnta( fortype , "bcis" ) ) {	    error("For variable %s cannot be %ss", forvar->symbol, nameof( fortype ) );	    goto nogood;	}	if ( forvar->value[ NL_FORV ] & FORVAR ) {	    error("Can't modify the for variable %s in the range of the loop", forvar->symbol);	    forvar = NLNIL;	    goto nogood;	}	forwidth = lwidth(fortype);#	ifdef PC	    forp2type = p2type(fortype);#	endif PC	    /*	     *	allocate temporaries for the initial and final expressions	     *	and maybe a register to shadow the for variable.	     */	initnlp = tmpalloc((long) sizeof(long), nl+T4INT, NOREG);	termnlp = tmpalloc((long) sizeof(long), nl+T4INT, NOREG);	shadownlp = tmpalloc((long) forwidth, fortype, REGOK);#	ifdef PC		/*		 * compute and save the initial expression		 */	    putRV((char *) 0 , cbn , initnlp -> value[ NL_OFFS ] ,		    initnlp -> extra_flags , PCCT_INT );#	endif PC#	ifdef OBJ	    (void) put(2, O_LV | cbn<<8+INDX, initnlp -> value[ NL_OFFS ] );#	endif OBJ	inittype = rvalue( init_node , fortype , RREQ );	if ( incompat( inittype , fortype , init_node ) ) {	    cerror("Type of initial expression clashed with index type in 'for' statement");	    if (forvar != NLNIL) {		forvar->value[ NL_FORV ] = FORVAR;	    }	    (void) rvalue( term_node , NLNIL , RREQ );	    statement( stat_node );	    goto byebye;	}#	ifdef PC	    sconv(p2type(inittype), PCCT_INT);	    putop( PCC_ASSIGN , PCCT_INT );

⌨️ 快捷键说明

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