📄 stat.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[] = "@(#)stat.c 8.1 (Berkeley) 6/6/93";#endif /* not lint */#include "whoami.h"#include "0.h"#include "tree.h"#include "objfmt.h"#ifdef PC# include <pcc.h># include "pc.h"#endif PC#include "tmps.h"int cntstat;short cnts = 3;#include "opcode.h"#include "tree_ty.h"/* * Statement list */statlist(r) struct tnode *r;{ register struct tnode *sl; for (sl=r; sl != TR_NIL; sl=sl->list_node.next) statement(sl->list_node.list);}/* * Statement */statement(r) struct tnode *r;{ register struct tnode *tree_node; register struct nl *snlp; struct tmps soffset; tree_node = r; snlp = nlp; soffset = sizes[cbn].curtmps;top: if (cntstat) { cntstat = 0; putcnt(); } if (tree_node == TR_NIL) return; line = tree_node->lined.line_no; if (tree_node->tag == T_LABEL) { labeled(tree_node->label_node.lbl_ptr); tree_node = tree_node->label_node.stmnt; noreach = FALSE; cntstat = 1; goto top; } if (noreach) { noreach = FALSE; warning(); error("Unreachable statement"); } switch (tree_node->tag) { case T_PCALL: putline();# ifdef OBJ proc(tree_node);# endif OBJ# ifdef PC pcproc( tree_node );# endif PC break; case T_ASGN: putline(); asgnop(&(tree_node->asg_node)); break; case T_GOTO: putline(); gotoop(tree_node->goto_node.lbl_ptr); noreach = TRUE; cntstat = 1; break; default: level++; switch (tree_node->tag) { default: panic("stat"); case T_IF: case T_IFEL: ifop(&(tree_node->if_node)); break; case T_WHILE: whilop(&(tree_node->whi_cas)); noreach = FALSE; break; case T_REPEAT: repop(&(tree_node->repeat)); break; case T_FORU: case T_FORD: forop(tree_node); noreach = FALSE; break; case T_BLOCK: statlist(tree_node->stmnt_blck.stmnt_list); break; case T_CASE: putline();# ifdef OBJ caseop(&(tree_node->whi_cas));# endif OBJ# ifdef PC pccaseop(&(tree_node->whi_cas));# endif PC break; case T_WITH: withop(&(tree_node->with_node)); break; } --level; if (gotos[cbn]) ungoto(); break; } /* * Free the temporary name list entries defined in * expressions, e.g. STRs, and WITHPTRs from withs. */ nlfree(snlp); /* * free any temporaries allocated for this statement * these come from strings and sets. */ tmpfree(&soffset);}ungoto(){ register struct nl *p; for (p = gotos[cbn]; p != NLNIL; p = p->chain) if ((p->nl_flags & NFORWD) != 0) { if (p->value[NL_GOLEV] != NOTYET) if (p->value[NL_GOLEV] > level) p->value[NL_GOLEV] = level; } else if (p->value[NL_GOLEV] != DEAD) if (p->value[NL_GOLEV] > level) p->value[NL_GOLEV] = DEAD;}putcnt(){ if (monflg == FALSE) { return; } inccnt( getcnt() );}intgetcnt() { return ++cnts; }inccnt( counter ) int counter; {# ifdef OBJ (void) put(2, O_COUNT, counter );# endif OBJ# ifdef PC putRV( PCPCOUNT , 0 , counter * sizeof (long) , NGLOBAL , PCCT_INT ); putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 ); putop( PCCOM_ASG PCC_PLUS , PCCT_INT ); putdot( filename , line );# endif PC }putline(){# ifdef OBJ if (opt('p') != 0) (void) put(2, O_LINO, line); /* * put out line number information for pdx */ lineno(line);# endif OBJ# ifdef PC static lastline; if ( line != lastline ) { stabline( line ); lastline = line; } if ( opt( 'p' ) ) { if ( opt('t') ) { putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_LINO" ); putop( PCCOM_UNARY PCC_CALL , PCCT_INT ); putdot( filename , line ); } else { putRV( STMTCOUNT , 0 , 0 , NGLOBAL , PCCT_INT ); putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 ); putop( PCCOM_ASG PCC_PLUS , PCCT_INT ); putdot( filename , line ); } }# endif PC}/* * With varlist do stat * * With statement requires an extra word * in automatic storage for each level of withing. * These indirect pointers are initialized here, and * the scoping effect of the with statement occurs * because lookup examines the field names of the records * associated with the WITHPTRs on the withlist. */withop(s) WITH_NODE *s;{ register struct tnode *p; register struct nl *r; struct nl *tempnlp; struct nl *swl; putline(); swl = withlist; for (p = s->var_list; p != TR_NIL; p = p->list_node.next) { tempnlp = tmpalloc((long) (sizeof(int *)), nl+TPTR, REGOK); /* * no one uses the allocated temporary namelist entry, * since we have to use it before we know its type; * but we use its runtime location for the with pointer. */# ifdef OBJ (void) put(2, O_LV | cbn <<8+INDX, tempnlp -> value[ NL_OFFS ] );# endif OBJ# ifdef PC putRV( (char *) 0 , cbn , tempnlp -> value[ NL_OFFS ] , tempnlp -> extra_flags , PCCTM_PTR|PCCT_STRTY );# endif PC r = lvalue(p->list_node.list, MOD , LREQ ); if (r == NLNIL) continue; if (r->class != RECORD) { error("Variable in with statement refers to %s, not to a record", nameof(r)); continue; } r = defnl((char *) 0, WITHPTR, r, tempnlp -> value[ NL_OFFS ] );# ifdef PC r -> extra_flags |= tempnlp -> extra_flags;# endif PC r->nl_next = withlist; withlist = r;# ifdef OBJ (void) put(1, PTR_AS);# endif OBJ# ifdef PC putop( PCC_ASSIGN , PCCTM_PTR|PCCT_STRTY ); putdot( filename , line );# endif PC } statement(s->stmnt); withlist = swl;}extern flagwas;/* * var := expr */asgnop(r) ASG_NODE *r;{ register struct nl *p; register struct tnode *av; /* * Asgnop's only function is * to handle function variable * assignments. All other assignment * stuff is handled by asgnop1. * the if below checks for unqualified lefthandside: * necessary for fvars. */ av = r->lhs_var; if (av != TR_NIL && av->tag == T_VAR && av->var_node.qual == TR_NIL) { p = lookup1(av->var_node.cptr); if (p != NLNIL) p->nl_flags = flagwas; if (p != NLNIL && p->class == FVAR) { /* * Give asgnop1 the func * which is the chain of * the FVAR. */ p->nl_flags |= NUSED|NMOD; p = p->chain; if (p == NLNIL) { p = rvalue(r->rhs_expr, NLNIL , RREQ ); return; }# ifdef OBJ (void) put(2, O_LV | bn << 8+INDX, (int)p->value[NL_OFFS]); if (isa(p->type, "i") && width(p->type) == 1) (void) asgnop1(r, nl+T2INT); else (void) asgnop1(r, p->type);# endif OBJ# ifdef PC /* * this should be the lvalue of the fvar, * but since the second pass knows to use * the address of the left operand of an * assignment, what i want here is an rvalue. * see note in funchdr about fvar allocation. */ p = p -> ptr[ NL_FVAR ]; putRV( p -> symbol , bn , p -> value[ NL_OFFS ] , p -> extra_flags , p2type( p -> type ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -