/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstraße 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* common */
+#include "check.h"
#include "xmalloc.h"
/* cc65 */
-LoopDesc* AddLoop (unsigned sp, unsigned loop, unsigned label,
- unsigned linc, unsigned lstat)
-/* Create and add a new loop descriptor */
+LoopDesc* AddLoop (unsigned SP, unsigned BreakLabel, unsigned ContinueLabel)
+/* Create and add a new loop descriptor. */
{
/* Allocate a new struct */
- LoopDesc* L = (LoopDesc*) xmalloc (sizeof (LoopDesc));
+ LoopDesc* L = xmalloc (sizeof (LoopDesc));
/* Fill in the data */
- L->StackPtr = sp;
- L->Loop = loop;
- L->Label = label;
- L->linc = linc;
- L->lstat = lstat;
+ L->StackPtr = SP;
+ L->BreakLabel = BreakLabel;
+ L->ContinueLabel = ContinueLabel;
/* Insert it into the list */
L->Next = LoopStack;
/* Remove the current loop */
{
LoopDesc* L = LoopStack;
+ CHECK (L != 0);
LoopStack = LoopStack->Next;
xfree (L);
}
/* */
/* */
/* */
-/* (C) 1998-2000 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstraße 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/*****************************************************************************/
-/* data */
+/* data */
/*****************************************************************************/
struct LoopDesc {
LoopDesc* Next;
unsigned StackPtr;
- unsigned Loop;
- unsigned Label;
- unsigned linc;
- unsigned lstat;
+ unsigned BreakLabel;
+ unsigned ContinueLabel;
};
-LoopDesc* AddLoop (unsigned sp, unsigned loop, unsigned label,
- unsigned linc, unsigned lstat);
-/* Create and add a new loop descriptor */
+LoopDesc* AddLoop (unsigned SP, unsigned BreakLabel, unsigned ContinueLabel);
+/* Create and add a new loop descriptor. */
LoopDesc* CurrentLoop (void);
/* Return a pointer to the descriptor of the current loop */
/* */
/* */
/* (C) 1998-2003 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
+/* Römerstraße 52 */
+/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* Handle the 'do' statement */
{
/* Get the loop control labels */
- unsigned loop = GetLocalLabel ();
- unsigned lab = GetLocalLabel ();
+ unsigned LoopLabel = GetLocalLabel ();
+ unsigned BreakLabel = GetLocalLabel ();
+ unsigned ContinueLabel = GetLocalLabel ();
/* Skip the while token */
NextToken ();
/* Add the loop to the loop stack */
- AddLoop (oursp, loop, lab, 0, 0);
+ AddLoop (oursp, BreakLabel, ContinueLabel);
- /* Define the head label */
- g_defcodelabel (loop);
+ /* Define the loop label */
+ g_defcodelabel (LoopLabel);
/* Parse the loop body */
Statement (0);
+ /* Output the label for a continue */
+ g_defcodelabel (ContinueLabel);
+
/* Parse the end condition */
Consume (TOK_WHILE, "`while' expected");
- TestInParens (loop, 1);
+ TestInParens (LoopLabel, 1);
ConsumeSemi ();
/* Define the break label */
- g_defcodelabel (lab);
+ g_defcodelabel (BreakLabel);
/* Remove the loop from the loop stack */
DelLoop ();
int PendingToken;
/* Get the loop control labels */
- unsigned loop = GetLocalLabel ();
- unsigned lab = GetLocalLabel ();
+ unsigned LoopLabel = GetLocalLabel ();
+ unsigned BreakLabel = GetLocalLabel ();
/* Skip the while token */
NextToken ();
- /* Add the loop to the loop stack */
- AddLoop (oursp, loop, lab, 0, 0);
+ /* Add the loop to the loop stack. In case of a while loop, the loop head
+ * label is used for continue statements.
+ */
+ AddLoop (oursp, BreakLabel, LoopLabel);
/* Define the head label */
- g_defcodelabel (loop);
+ g_defcodelabel (LoopLabel);
/* Test the loop condition */
- TestInParens (lab, 0);
+ TestInParens (BreakLabel, 0);
/* Loop body */
Statement (&PendingToken);
/* Jump back to loop top */
- g_jump (loop);
+ g_jump (LoopLabel);
/* Exit label */
- g_defcodelabel (lab);
+ g_defcodelabel (BreakLabel);
/* Eat remaining tokens that were delayed because of line info
* correctness
g_space (oursp - L->StackPtr);
/* Jump to the exit label of the loop */
- g_jump (L->Label);
+ g_jump (L->BreakLabel);
}
/* Get the current loop descriptor */
L = CurrentLoop ();
if (L) {
- /* Search for the correct loop */
+ /* Search for a loop that has a continue label. */
do {
- if (L->Loop) {
- break;
+ if (L->ContinueLabel) {
+ break;
}
L = L->Next;
} while (L);
/* Correct the stackpointer if needed */
g_space (oursp - L->StackPtr);
- /* Output the loop code */
- if (L->linc) {
- g_jump (L->linc);
- } else {
- g_jump (L->Loop);
- }
+ /* Jump to next loop iteration */
+ g_jump (L->ContinueLabel);
}
int PendingToken;
/* Get several local labels needed later */
- unsigned TestLabel = GetLocalLabel ();
- unsigned lab = GetLocalLabel ();
- unsigned IncLabel = GetLocalLabel ();
- unsigned lstat = GetLocalLabel ();
+ unsigned TestLabel = GetLocalLabel ();
+ unsigned BreakLabel = GetLocalLabel ();
+ unsigned IncLabel = GetLocalLabel ();
+ unsigned BodyLabel = GetLocalLabel ();
/* Skip the FOR token */
NextToken ();
- /* Add the loop to the loop stack */
- AddLoop (oursp, TestLabel, lab, IncLabel, lstat);
+ /* Add the loop to the loop stack. A continue jumps to the start of the
+ * the increment condition.
+ */
+ AddLoop (oursp, BreakLabel, IncLabel);
/* Skip the opening paren */
ConsumeLParen ();
/* Parse the initializer expression */
if (CurTok.Tok != TOK_SEMI) {
- expression (&lval1);
+ expression (&lval1);
}
ConsumeSemi ();
/* Parse the test expression */
if (CurTok.Tok != TOK_SEMI) {
- Test (lstat, 1);
- g_jump (lab);
+ Test (BodyLabel, 1);
+ g_jump (BreakLabel);
} else {
- g_jump (lstat);
+ g_jump (BodyLabel);
}
ConsumeSemi ();
ConsumeRParen ();
/* Loop body */
- g_defcodelabel (lstat);
+ g_defcodelabel (BodyLabel);
Statement (&PendingToken);
/* If we had an increment expression, move the code to the bottom of
* the loop body.
*/
if (HaveIncExpr) {
- MoveCode (IncExprStart, IncExprEnd, GetCodePos());
+ MoveCode (IncExprStart, IncExprEnd, GetCodePos());
} else {
- /* Jump back to the increment expression */
- g_jump (IncLabel);
+ /* Jump back to the increment expression */
+ g_jump (IncLabel);
}
/* Skip a pending token if we have one */
SkipPending (PendingToken);
/* Declare the break label */
- g_defcodelabel (lab);
+ g_defcodelabel (BreakLabel);
/* Remove the loop from the loop stack */
DelLoop ();