In c.y: 1. Add the non-terminal do to %type at top of c.y. 2. Add the following productions: stmt: | do stmt while '(' cond ')' { ($5)[0] = $1; /* fixup conditional branch */ fprintf(ap,"%s %d","fixup location ",(&$5[0] - progbase)); fprintf(ap,"%s %d\n"," with ",($1 - progbase)); } do DO { $$ = progp; } ; In init.c: Add do to reserved words (Note that it should already be there because I forgot to delete it from last time. t1.c is the following program and the results after running it: $ compile < t1.c CHICO STATE MINI C COMPILER................EXPERIMENTAL VERSION 6 - Feb 98 main() { a = 0; do { a = a + 1; printf(a); } while(a < 10); } PROGRAM OUTPUT 1 $ In t2.c below the operator in the conditional expression is changed from < to >=. i.e., a >=10: $ compile < t2.c CHICO STATE MINI C COMPILER................EXPERIMENTAL VERSION 6 - Feb 98 main() { a = 0; do { a = a + 1; printf(a); } while(a >= 10); } PROGRAM OUTPUT 1 2 3 4 5 6 7 8 9 10 $ PROBLEM The do-while program works fine if the universal complement of the intended operator is used instead of the intended one. The reason for this is that the contitional branch emitted by the cond non-terminal expects to branch if the condition is false and not branch (go to the next sequential instruction) if the condition is true. That is good logic for the while, because the next sequential instruction in the true case is the first instruction in the loop and the branch on false is to the first instruction after the loop. It is poor logic for the do-while because in the true case it sends the program out of the loop and in the false case it keeps the program in the loop (backwards). SOLUTION Add an unconditional branch at the end of the do-while that branches to the top of the do-while loop. That way, in the true case you will always branch to the top of the loop. Place the conditional branch fixup after this unconditional branch and make the fixup address progp instead of the top of the loop. That will make the conditional branch take the program out of the loop in the false case instead of keeping it in the loop.