next up previous
Next: Discussion Up: Class Definition Previous: Node * peel_do_loop (doNode

Node * peel_for_loop (forNode *);

// `For' is a little trickier since it has so many elements.  We'll first 
// transform it to a While stmt, i.e.:
//
// for (init; cond; next) stmt;
// =>
// init;
// while (cond) {
//      stmt;
//      next;
// }
//
// and then apply the loop peeling code for While.

Node * LoopPeelingChanger::peel_for_loop (forNode *p) {

        // Transform the For loop into a While loop.

        // Everything goes in a new block:
        //      { }

        blockNode *newblock = new blockNode (NULL, NULL);

        // First, insert the initialization of the For:
        //      { init; }

        newblock->stmts().push_back (new exprstmtNode (
                (exprNode *) clone_changer::clone(p->init())));

        // Now build the body of a new While loop...

        blockNode *whilebody = new blockNode (NULL, NULL);

        // ...from the body of the For:
        //      { stmt; }

        whilebody->stmts().push_back (
                (stmtNode *) clone_changer::clone(p->body()));

        // ...and the next from the For:
        //      { stmt; next; }

        whilebody->stmts().push_back (new exprstmtNode (
                (exprNode *) clone_changer::clone(p->next())));

        // Now we wrap this body up in a While using the For condition:
        //      while (expr) { stmt; next; }

        whileNode *newwhile = new whileNode (
                (exprNode *) clone_changer::clone(p->cond()),
                whilebody);

        // Do loop peeling on the while loop, inserting the result after the 
        // init in the block we made before.

        newblock->stmts().push_back (
                (stmtNode *) peel_while_loop (newwhile));
        return newblock;
}



Calvin Lin
2002-01-31