📄 forop.c
字号:
putdot( filename , line ); /* * compute and save the termination expression */ putRV((char *) 0 , cbn , termnlp -> value[ NL_OFFS ] , termnlp -> extra_flags , PCCT_INT );# endif PC# ifdef OBJ (void) gen(O_AS2, O_AS2, sizeof(long), width(inittype)); /* * compute and save the termination expression */ (void) put(2, O_LV | cbn<<8+INDX, termnlp -> value[ NL_OFFS ] );# endif OBJ termtype = rvalue( term_node , fortype , RREQ ); if ( incompat( termtype , fortype , term_node ) ) { cerror("Type of limit expression clashed with index type in 'for' statement"); if (forvar != NLNIL) { forvar->value[ NL_FORV ] = FORVAR; } statement( stat_node ); goto byebye; }# ifdef PC sconv(p2type(termtype), PCCT_INT); putop( PCC_ASSIGN , PCCT_INT ); putdot( filename , line ); /* * we can skip the loop altogether if !( init <= term ) */ after = (int) getlab(); putRV((char *) 0 , cbn , initnlp -> value[ NL_OFFS ] , initnlp -> extra_flags , PCCT_INT ); putRV((char *) 0 , cbn , termnlp -> value[ NL_OFFS ] , termnlp -> extra_flags , PCCT_INT ); putop( ( tree_node->tag == T_FORU ? PCC_LE : PCC_GE ) , PCCT_INT ); putleaf( PCC_ICON , after , 0 , PCCT_INT, (char *) 0 ); putop( PCC_CBRANCH , PCCT_INT ); putdot( filename , line ); /* * okay, so we have to execute the loop body, * but first, if checking is on, * check that the termination expression * is assignment compatible with the control-variable. */ if (opt('t')) { precheck(fortype, "_RANG4", "_RSNG4"); putRV((char *) 0, cbn, termnlp -> value[NL_OFFS], termnlp -> extra_flags, PCCT_INT); postcheck(fortype, nl+T4INT); putdot(filename, line); } /* * assign the initial expression to the shadow * checking the assignment if necessary. */ putRV((char *) 0, cbn, shadownlp -> value[NL_OFFS], shadownlp -> extra_flags, forp2type); if (opt('t')) { precheck(fortype, "_RANG4", "_RSNG4"); putRV((char *) 0, cbn, initnlp -> value[NL_OFFS], initnlp -> extra_flags, PCCT_INT); postcheck(fortype, nl+T4INT); } else { putRV((char *) 0, cbn, initnlp -> value[NL_OFFS], initnlp -> extra_flags, PCCT_INT); } sconv(PCCT_INT, forp2type); putop(PCC_ASSIGN, forp2type); putdot(filename, line); /* * put down the label at the top of the loop */ again = (int) getlab(); (void) putlab((char *) again ); /* * each time through the loop * assign the shadow to the for variable. */ (void) lvalue(lhs, NOUSE, RREQ); putRV((char *) 0, cbn, shadownlp -> value[NL_OFFS], shadownlp -> extra_flags, forp2type); putop(PCC_ASSIGN, forp2type); putdot(filename, line);# endif PC# ifdef OBJ (void) gen(O_AS2, O_AS2, sizeof(long), width(termtype)); /* * we can skip the loop altogether if !( init <= term ) */ (void) put(2, O_RV4 | cbn<<8+INDX, initnlp -> value[ NL_OFFS ] ); (void) put(2, O_RV4 | cbn<<8+INDX, termnlp -> value[ NL_OFFS ] ); (void) gen(NIL, tree_node->tag == T_FORU ? T_LE : T_GE, sizeof(long), sizeof(long)); after = (int) getlab(); (void) put(2, O_IF, after); /* * okay, so we have to execute the loop body, * but first, if checking is on, * check that the termination expression * is assignment compatible with the control-variable. */ if (opt('t')) { (void) put(2, O_LV | cbn<<8+INDX, shadownlp -> value[ NL_OFFS ] ); (void) put(2, O_RV4 | cbn<<8+INDX, termnlp -> value[ NL_OFFS ] ); rangechk(fortype, nl+T4INT); (void) gen(O_AS2, O_AS2, forwidth, sizeof(long)); } /* * assign the initial expression to the shadow * checking the assignment if necessary. */ (void) put(2, O_LV | cbn<<8+INDX, shadownlp -> value[ NL_OFFS ] ); (void) put(2, O_RV4 | cbn<<8+INDX, initnlp -> value[ NL_OFFS ] ); rangechk(fortype, nl+T4INT); (void) gen(O_AS2, O_AS2, forwidth, sizeof(long)); /* * put down the label at the top of the loop */ again = (int) getlab(); (void) putlab( (char *) again ); /* * each time through the loop * assign the shadow to the for variable. */ (void) lvalue(lhs, NOUSE, RREQ); (void) stackRV(shadownlp); (void) gen(O_AS2, O_AS2, forwidth, sizeof(long));# endif OBJ /* * shadowing the real for variable * with the shadow temporary: * save the real for variable flags (including nl_block). * replace them with the shadow's offset, * and mark the for variable as being a for variable. */ shadownlp -> nl_flags |= NLFLAGS(forvar -> nl_flags); *forvar = *shadownlp; forvar -> symbol = saved_nl.symbol; forvar -> nl_next = saved_nl.nl_next; forvar -> type = saved_nl.type; forvar -> value[ NL_FORV ] = FORVAR; /* * and don't forget ... */ putcnt(); statement( stat_node ); /* * wasn't that fun? do we get to do it again? * we don't do it again if ( !( forvar < limit ) ) * pretend we were doing this at the top of the loop */ line = f_node->line_no;# ifdef PC 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 ); } } /*rvalue( lhs_node , NIL , RREQ );*/ putRV( (char *) 0 , cbn , shadownlp -> value[ NL_OFFS ] , shadownlp -> extra_flags , forp2type ); sconv(forp2type, PCCT_INT); putRV( (char *) 0 , cbn , termnlp -> value[ NL_OFFS ] , termnlp -> extra_flags , PCCT_INT ); putop( ( tree_node->tag == T_FORU ? PCC_LT : PCC_GT ) , PCCT_INT ); putleaf( PCC_ICON , after , 0 , PCCT_INT , (char *) 0 ); putop( PCC_CBRANCH , PCCT_INT ); putdot( filename , line ); /* * okay, so we have to do it again, * but first, increment the for variable. * no need to rangecheck it, since we checked the * termination value before we started. */ /*lvalue( lhs , MOD , RREQ );*/ putRV( (char *) 0 , cbn , shadownlp -> value[ NL_OFFS ] , shadownlp -> extra_flags , forp2type ); /*rvalue( lhs_node , NIL , RREQ );*/ putRV( (char *) 0 , cbn , shadownlp -> value[ NL_OFFS ] , shadownlp -> extra_flags , forp2type ); sconv(forp2type, PCCT_INT); putleaf( PCC_ICON , 1 , 0 , PCCT_INT , (char *) 0 ); putop( ( tree_node->tag == T_FORU ? PCC_PLUS : PCC_MINUS ) , PCCT_INT ); sconv(PCCT_INT, forp2type); putop( PCC_ASSIGN , forp2type ); putdot( filename , line ); /* * and do it all again */ putjbr( (long) again ); /* * and here we are */ (void) putlab( (char *) after );# endif PC# ifdef OBJ /* * okay, so we have to do it again. * Luckily we have a magic opcode which increments the * index variable, checks the limit falling through if * it has been reached, else updating the index variable, * and returning to the top of the loop. */ putline(); (void) put(2, O_RV4 | cbn<<8+INDX, termnlp -> value[ NL_OFFS ] ); (void) put(2, O_LV | cbn<<8+INDX, shadownlp -> value[ NL_OFFS ] ); (void) put(2, (tree_node->tag == T_FORU ? O_FOR1U : O_FOR1D) + (forwidth >> 1), again); /* * and here we are */ patch( (PTR_DCL) after );# endif OBJbyebye: noreach = FALSE; if (forvar != NLNIL) { saved_nl.nl_flags |= NLFLAGS(forvar -> nl_flags) & (NUSED|NMOD); *forvar = saved_nl; } if ( goc != gocnt ) { putcnt(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -