private void ifStatement_rest() throws Exception
    {
        // parse relation before anything else since it is part of the current block
        Cmp comp = relation();
        if(scan.sym != Token.then) {
            throw new Exception("Misformed if statement, no 'then' keyword");
        }
        // sym == "then"
        scan.next();

        // make basic blocks preemptivly
        BasicBlock oldCurrent = currentBB;
        BasicBlock oldJoin = currentJoinBlock;
        BasicBlock ifStartBB = new BasicBlock(oldCurrent);
        BasicBlock elseStartBB = new BasicBlock(oldCurrent);
        BasicBlock nextBB = new BasicBlock(oldCurrent);

        // if branch must exist
        oldCurrent.setFallThrough(ifStartBB);

	// set currentBB to be the start of the 'if' body
        currentBB = ifStartBB;
	// set the join block to be the BB that will follow the 'if'
	// statement
        currentJoinBlock = nextBB;

	// generate code for the 'if' body
        currentJoinBlock.setCurrentBranch(1);
        env.enter();
        statSequence();
        env.exit();
        currentJoinBlock.setIncomingBranch(currentBB);

        currentJoinBlock.setCurrentBranch(2);


        // even if there is no 'else' clause in this if statement, we
        // will still insert the empty basic block for the else
        // branch, other wise we will introduce critical edges.
        // Critical edges are edges that connect a block with multiple
        // successors in the CFG to a block with multiple
        // predecessors. By always inserting the else block we avoid
        // this and always have a safe place to put the moves needed
        // resolve phi instructions.

        // the else block will be the target of the branch
        oldCurrent.addInstruction(makeProperBranch(comp, elseStartBB));
        // also add unconditional branch from the end of the 'if'
        // statSequence over the else block
        currentBB.addInstruction(new Bra(nextBB));
        // the start of the else will be placed after the if condition
        currentBB.setNext(elseStartBB);

        if(scan.sym == Token.else_t) {
	    scan.next();


	    // set the new current, this must be done AFTER the
	    // branches are emited
            currentBB = elseStartBB;

	    // generate code for the 'else' body
            env.enter();
            statSequence();
            env.exit();
            currentBB.setFallThrough(nextBB);
            currentJoinBlock.setIncomingBranch(currentBB);
        } else {
            // otherwise, no else statement, still use the else block as the target
            currentJoinBlock.setIncomingBranch(elseStartBB);
            elseStartBB.setFallThrough(nextBB);
        }
        if(scan.sym == Token.fi) {
            scan.next();
	    currentBB = nextBB;
            currentJoinBlock = oldJoin; // restore the join block
	    // propogate the phis from this join block to the enclosing join block
	    currentBB.propagatePhis(env, currentJoinBlock);
        } else {
            throw new Exception("Misformed if statement, no 'fi' keyword");
        }
    }