📄 stat.c
字号:
(void) asgnop1( r , p -> type );# endif PC return; } } (void) asgnop1(r, NLNIL);}/* * Asgnop1 handles all assignments. * If p is not nil then we are assigning * to a function variable, otherwise * we look the variable up ourselves. */struct nl *asgnop1(r, p) ASG_NODE *r; register struct nl *p;{ register struct nl *p1; int clas;#ifdef OBJ int w;#endif OBJ#ifdef OBJ if (p == NLNIL) { p = lvalue(r->lhs_var, MOD|ASGN|NOUSE , LREQ ); if ( p == NLNIL ) { (void) rvalue( r->rhs_expr , NLNIL , RREQ ); return NLNIL; } w = width(p); } else { /* * assigning to the return value, which is at least * of width two since it resides on the stack */ w = width(p); if (w < 2) w = 2; } clas = classify(p); if ((clas == TARY || clas == TSTR) && p->chain->class == CRANGE) { p1 = lvalue(r->rhs_expr, p , LREQ ); /* SHOULD THIS BE rvalue? */ } else { p1 = rvalue(r->rhs_expr, p , RREQ ); }# endif OBJ# ifdef PC if (p == NLNIL) { /* check for conformant array type */ codeoff(); p = rvalue(r->lhs_var, MOD|ASGN|NOUSE, LREQ); codeon(); if (p == NLNIL) { (void) rvalue(r->rhs_expr, NLNIL, RREQ); return NLNIL; } clas = classify(p); if ((clas == TARY || clas == TSTR) && p->chain->class == CRANGE) { return pcasgconf(r, p); } else { /* * since the second pass knows that it should reference * the lefthandside of asignments, what i need here is * an rvalue. */ p = lvalue( r->lhs_var , MOD|ASGN|NOUSE , RREQ ); } if ( p == NLNIL ) { (void) rvalue( r->rhs_expr , NLNIL , RREQ ); return NLNIL; } } /* * if this is a scalar assignment, * then i want to rvalue the righthandside. * if this is a structure assignment, * then i want an lvalue to the righthandside. * that's what the intermediate form sez. */ switch ( classify( p ) ) { case TINT: case TCHAR: case TBOOL: case TSCAL: precheck( p , "_RANG4" , "_RSNG4" ); /* and fall through */ case TDOUBLE: case TPTR: p1 = rvalue( r->rhs_expr , p , RREQ ); break; default: p1 = rvalue( r->rhs_expr , p , LREQ ); break; }# endif PC if (p1 == NLNIL) return (NLNIL); if (incompat(p1, p, r->rhs_expr)) { cerror("Type of expression clashed with type of variable in assignment"); return (NLNIL); }# ifdef OBJ switch (classify(p)) { case TINT: case TBOOL: case TCHAR: case TSCAL: rangechk(p, p1); (void) gen(O_AS2, O_AS2, w, width(p1)); break; case TDOUBLE: case TPTR: (void) gen(O_AS2, O_AS2, w, width(p1)); break; case TARY: case TSTR: if (p->chain->class == CRANGE) { /* conformant array assignment */ p1 = p->chain; w = width(p1->type); putcbnds(p1, 1); putcbnds(p1, 0); gen(NIL, T_SUB, w, w); put(2, w > 2? O_CON24: O_CON2, 1); gen(NIL, T_ADD, w, w); putcbnds(p1, 2); gen(NIL, T_MULT, w, w); put(1, O_VAS); break; } /* else fall through */ default: (void) put(2, O_AS, w); break; }# endif OBJ# ifdef PC switch (classify(p)) { case TINT: case TBOOL: case TCHAR: case TSCAL: postcheck(p, p1); sconv(p2type(p1), p2type(p)); putop( PCC_ASSIGN , p2type( p ) ); putdot( filename , line ); break; case TPTR: putop( PCC_ASSIGN , p2type( p ) ); putdot( filename , line ); break; case TDOUBLE: sconv(p2type(p1), p2type(p)); putop( PCC_ASSIGN , p2type( p ) ); putdot( filename , line ); break; default: putstrop(PCC_STASG, PCCM_ADDTYPE(p2type(p), PCCTM_PTR), (int) lwidth(p), align(p)); putdot( filename , line ); break; }# endif PC return (p); /* Used by for statement */}#ifdef PC/* * assignment to conformant arrays. Since these are variable length, * we use blkcpy() to perform the assignment. * blkcpy(rhs, lhs, (upper - lower + 1) * width) */struct nl *pcasgconf(r, p) register ASG_NODE *r; struct nl *p;{ struct nl *p1; if (r == (ASG_NODE *) TR_NIL || p == NLNIL) return NLNIL; putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR) , "_blkcpy" ); p1 = rvalue( r->rhs_expr , p , LREQ ); if (p1 == NLNIL) return NLNIL; p = lvalue( r->lhs_var , MOD|ASGN|NOUSE , LREQ ); if (p == NLNIL) return NLNIL; putop(PCC_CM, PCCT_INT); /* upper bound */ p1 = p->chain->nptr[1]; putRV(p1->symbol, (p1->nl_block & 037), p1->value[0], p1->extra_flags, p2type( p1 ) ); /* minus lower bound */ p1 = p->chain->nptr[0]; putRV(p1->symbol, (p1->nl_block & 037), p1->value[0], p1->extra_flags, p2type( p1 ) ); putop( PCC_MINUS, PCCT_INT ); /* add one */ putleaf(PCC_ICON, 1, 0, PCCT_INT, 0); putop( PCC_PLUS, PCCT_INT ); /* and multiply by the width */ p1 = p->chain->nptr[2]; putRV(p1->symbol, (p1->nl_block & 037), p1->value[0], p1->extra_flags, p2type( p1 ) ); putop( PCC_MUL , PCCT_INT ); putop(PCC_CM, PCCT_INT); putop(PCC_CALL, PCCT_INT); putdot( filename , line); return p;}#endif PC/* * if expr then stat [ else stat ] */ifop(if_n) IF_NODE *if_n;{ register struct nl *p; register l1, l2; /* l1 is start of else, l2 is end of else */ int goc; bool nr; goc = gocnt; putline(); p = rvalue(if_n->cond_expr, NLNIL , RREQ ); if (p == NIL) { statement(if_n->then_stmnt); noreach = FALSE; statement(if_n->else_stmnt); noreach = FALSE; return; } if (isnta(p, "b")) { error("Type of expression in if statement must be Boolean, not %s", nameof(p)); statement(if_n->then_stmnt); noreach = FALSE; statement(if_n->else_stmnt); noreach = FALSE; return; }# ifdef OBJ l1 = put(2, O_IF, getlab());# endif OBJ# ifdef PC l1 = (int) getlab(); putleaf( PCC_ICON , l1 , 0 , PCCT_INT , (char *) 0 ); putop( PCC_CBRANCH , PCCT_INT ); putdot( filename , line );# endif PC putcnt(); statement(if_n->then_stmnt); nr = noreach; if (if_n->else_stmnt != TR_NIL) { /* * else stat */ --level; ungoto(); ++level;# ifdef OBJ l2 = put(2, O_TRA, getlab());# endif OBJ# ifdef PC l2 = (int) getlab(); putjbr( (long) l2 );# endif PC patch((PTR_DCL)l1); noreach = FALSE; statement(if_n->else_stmnt); noreach = (noreach && nr)?TRUE:FALSE; l1 = l2; } else noreach = FALSE; patch((PTR_DCL)l1); if (goc != gocnt) putcnt();}/* * while expr do stat */whilop(w_node) WHI_CAS *w_node;{ register struct nl *p; register char *l1, *l2; int goc; goc = gocnt; l1 = getlab(); (void) putlab(l1); putline(); p = rvalue(w_node->expr, NLNIL , RREQ ); if (p == NLNIL) { statement(w_node->stmnt_list); noreach = FALSE; return; } if (isnta(p, "b")) { error("Type of expression in while statement must be Boolean, not %s", nameof(p)); statement(w_node->stmnt_list); noreach = FALSE; return; } l2 = getlab();# ifdef OBJ (void) put(2, O_IF, l2);# endif OBJ# ifdef PC putleaf( PCC_ICON , (int) l2 , 0 , PCCT_INT , (char *) 0 ); putop( PCC_CBRANCH , PCCT_INT ); putdot( filename , line );# endif PC putcnt(); statement(w_node->stmnt_list);# ifdef OBJ (void) put(2, O_TRA, l1);# endif OBJ# ifdef PC putjbr( (long) l1 );# endif PC patch((PTR_DCL) l2); if (goc != gocnt) putcnt();}/* * repeat stat* until expr */repop(r) REPEAT *r;{ register struct nl *p; register l; int goc; goc = gocnt; l = (int) putlab(getlab()); putcnt(); statlist(r->stmnt_list); line = r->line_no; p = rvalue(r->term_expr, NLNIL , RREQ ); if (p == NLNIL) return; if (isnta(p,"b")) { error("Until expression type must be Boolean, not %s, in repeat statement", nameof(p)); return; }# ifdef OBJ (void) put(2, O_IF, l);# endif OBJ# ifdef PC putleaf( PCC_ICON , l , 0 , PCCT_INT , (char *) 0 ); putop( PCC_CBRANCH , PCCT_INT ); putdot( filename , line );# endif PC if (goc != gocnt) putcnt();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -