mirror of
https://github.com/cc65/cc65.git
synced 2024-09-08 16:54:52 +00:00
Added while loop inversion.
git-svn-id: svn://svn.cc65.org/cc65/trunk@4642 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
32be81510a
commit
48c647b6bd
@ -245,30 +245,49 @@ static void WhileStatement (void)
|
|||||||
/* Handle the 'while' statement */
|
/* 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 */
|
/* Get the loop control labels */
|
||||||
unsigned LoopLabel = GetLocalLabel ();
|
unsigned LoopLabel = GetLocalLabel ();
|
||||||
unsigned BreakLabel = GetLocalLabel ();
|
unsigned BreakLabel = GetLocalLabel ();
|
||||||
|
unsigned CondLabel = GetLocalLabel ();
|
||||||
|
|
||||||
/* Skip the while token */
|
/* Skip the while token */
|
||||||
NextToken ();
|
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.
|
* label is used for continue statements.
|
||||||
*/
|
*/
|
||||||
AddLoop (BreakLabel, LoopLabel);
|
AddLoop (BreakLabel, CondLabel);
|
||||||
|
|
||||||
|
/* 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 (LoopLabel, 1);
|
||||||
|
|
||||||
|
/* Remember the end of the condition evaluation code */
|
||||||
|
GetCodePos (&CondCodeEnd);
|
||||||
|
|
||||||
/* Define the head label */
|
/* Define the head label */
|
||||||
g_defcodelabel (LoopLabel);
|
g_defcodelabel (LoopLabel);
|
||||||
|
|
||||||
/* Test the loop condition */
|
|
||||||
TestInParens (BreakLabel, 0);
|
|
||||||
|
|
||||||
/* Loop body */
|
/* Loop body */
|
||||||
Statement (&PendingToken);
|
Statement (&PendingToken);
|
||||||
|
|
||||||
/* Jump back to loop top */
|
/* Move the test code here */
|
||||||
g_jump (LoopLabel);
|
GetCodePos (&Here);
|
||||||
|
MoveCode (&CondCodeStart, &CondCodeEnd, &Here);
|
||||||
|
|
||||||
/* Exit label */
|
/* Exit label */
|
||||||
g_defcodelabel (BreakLabel);
|
g_defcodelabel (BreakLabel);
|
||||||
|
Loading…
Reference in New Issue
Block a user