X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fstmt.c;h=5078bfa11a1d32c4076e304247fd1b2d1bcde8cb;hb=112ae0e3db511ddd92e769c11328646ebe2a6240;hp=977971b01a98b1ad967f4cd56cd837323c991059;hpb=32e2eb3fad388453e48c38b5411d08f1af3a6ce8;p=cc65 diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 977971b01..5078bfa11 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -91,7 +91,7 @@ static void CheckTok (token_t Tok, const char* Msg, int* PendingToken) */ { if (CurTok.Tok != Tok) { - Error (Msg); + Error ("%s", Msg); } else if (PendingToken) { *PendingToken = 1; } else { @@ -244,31 +244,50 @@ static void DoStatement (void) static void WhileStatement (void) /* Handle the 'while' statement */ { - int PendingToken; + int PendingToken; + CodeMark CondCodeStart; /* Start of condition evaluation code */ + CodeMark CondCodeEnd; /* End of condition evaluation code */ + CodeMark Here; /* "Here" location of code */ /* Get the loop control labels */ unsigned LoopLabel = GetLocalLabel (); unsigned BreakLabel = GetLocalLabel (); + unsigned CondLabel = GetLocalLabel (); /* Skip the while token */ NextToken (); - /* Add the loop to the loop stack. In case of a while loop, the loop head + /* Add the loop to the loop stack. In case of a while loop, the condition * label is used for continue statements. */ - AddLoop (BreakLabel, LoopLabel); + AddLoop (BreakLabel, CondLabel); - /* Define the head label */ - g_defcodelabel (LoopLabel); + /* We will move the code that evaluates the while condition to the end of + * the loop, so generate a jump here. + */ + g_jump (CondLabel); + + /* Remember the current position */ + GetCodePos (&CondCodeStart); + + /* Emit the code position label */ + g_defcodelabel (CondLabel); /* Test the loop condition */ - TestInParens (BreakLabel, 0); + TestInParens (LoopLabel, 1); + + /* Remember the end of the condition evaluation code */ + GetCodePos (&CondCodeEnd); + + /* Define the head label */ + g_defcodelabel (LoopLabel); /* Loop body */ Statement (&PendingToken); - /* Jump back to loop top */ - g_jump (LoopLabel); + /* Move the test code here */ + GetCodePos (&Here); + MoveCode (&CondCodeStart, &CondCodeEnd, &Here); /* Exit label */ g_defcodelabel (BreakLabel);