mirror of
https://github.com/cc65/cc65.git
synced 2025-01-25 11:30:06 +00:00
A continue statement within a do loop did not work. Cleaned up the loop
code a little bit. git-svn-id: svn://svn.cc65.org/cc65/trunk@2722 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
855fdbfcb0
commit
cb8c3746f5
@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstraße 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "check.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
@ -59,19 +60,16 @@ static LoopDesc* LoopStack = 0;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
LoopDesc* AddLoop (unsigned sp, unsigned loop, unsigned label,
|
LoopDesc* AddLoop (unsigned SP, unsigned BreakLabel, unsigned ContinueLabel)
|
||||||
unsigned linc, unsigned lstat)
|
/* Create and add a new loop descriptor. */
|
||||||
/* Create and add a new loop descriptor */
|
|
||||||
{
|
{
|
||||||
/* Allocate a new struct */
|
/* Allocate a new struct */
|
||||||
LoopDesc* L = (LoopDesc*) xmalloc (sizeof (LoopDesc));
|
LoopDesc* L = xmalloc (sizeof (LoopDesc));
|
||||||
|
|
||||||
/* Fill in the data */
|
/* Fill in the data */
|
||||||
L->StackPtr = sp;
|
L->StackPtr = SP;
|
||||||
L->Loop = loop;
|
L->BreakLabel = BreakLabel;
|
||||||
L->Label = label;
|
L->ContinueLabel = ContinueLabel;
|
||||||
L->linc = linc;
|
|
||||||
L->lstat = lstat;
|
|
||||||
|
|
||||||
/* Insert it into the list */
|
/* Insert it into the list */
|
||||||
L->Next = LoopStack;
|
L->Next = LoopStack;
|
||||||
@ -95,6 +93,7 @@ void DelLoop (void)
|
|||||||
/* Remove the current loop */
|
/* Remove the current loop */
|
||||||
{
|
{
|
||||||
LoopDesc* L = LoopStack;
|
LoopDesc* L = LoopStack;
|
||||||
|
CHECK (L != 0);
|
||||||
LoopStack = LoopStack->Next;
|
LoopStack = LoopStack->Next;
|
||||||
xfree (L);
|
xfree (L);
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstraße 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* data */
|
/* data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@ -48,10 +48,8 @@ typedef struct LoopDesc LoopDesc;
|
|||||||
struct LoopDesc {
|
struct LoopDesc {
|
||||||
LoopDesc* Next;
|
LoopDesc* Next;
|
||||||
unsigned StackPtr;
|
unsigned StackPtr;
|
||||||
unsigned Loop;
|
unsigned BreakLabel;
|
||||||
unsigned Label;
|
unsigned ContinueLabel;
|
||||||
unsigned linc;
|
|
||||||
unsigned lstat;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -62,9 +60,8 @@ struct LoopDesc {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
LoopDesc* AddLoop (unsigned sp, unsigned loop, unsigned label,
|
LoopDesc* AddLoop (unsigned SP, unsigned BreakLabel, unsigned ContinueLabel);
|
||||||
unsigned linc, unsigned lstat);
|
/* Create and add a new loop descriptor. */
|
||||||
/* Create and add a new loop descriptor */
|
|
||||||
|
|
||||||
LoopDesc* CurrentLoop (void);
|
LoopDesc* CurrentLoop (void);
|
||||||
/* Return a pointer to the descriptor of the current loop */
|
/* Return a pointer to the descriptor of the current loop */
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstraße 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
@ -184,28 +184,32 @@ static void DoStatement (void)
|
|||||||
/* Handle the 'do' statement */
|
/* Handle the 'do' statement */
|
||||||
{
|
{
|
||||||
/* Get the loop control labels */
|
/* Get the loop control labels */
|
||||||
unsigned loop = GetLocalLabel ();
|
unsigned LoopLabel = GetLocalLabel ();
|
||||||
unsigned lab = GetLocalLabel ();
|
unsigned BreakLabel = GetLocalLabel ();
|
||||||
|
unsigned ContinueLabel = GetLocalLabel ();
|
||||||
|
|
||||||
/* Skip the while token */
|
/* Skip the while token */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Add the loop to the loop stack */
|
/* Add the loop to the loop stack */
|
||||||
AddLoop (oursp, loop, lab, 0, 0);
|
AddLoop (oursp, BreakLabel, ContinueLabel);
|
||||||
|
|
||||||
/* Define the head label */
|
/* Define the loop label */
|
||||||
g_defcodelabel (loop);
|
g_defcodelabel (LoopLabel);
|
||||||
|
|
||||||
/* Parse the loop body */
|
/* Parse the loop body */
|
||||||
Statement (0);
|
Statement (0);
|
||||||
|
|
||||||
|
/* Output the label for a continue */
|
||||||
|
g_defcodelabel (ContinueLabel);
|
||||||
|
|
||||||
/* Parse the end condition */
|
/* Parse the end condition */
|
||||||
Consume (TOK_WHILE, "`while' expected");
|
Consume (TOK_WHILE, "`while' expected");
|
||||||
TestInParens (loop, 1);
|
TestInParens (LoopLabel, 1);
|
||||||
ConsumeSemi ();
|
ConsumeSemi ();
|
||||||
|
|
||||||
/* Define the break label */
|
/* Define the break label */
|
||||||
g_defcodelabel (lab);
|
g_defcodelabel (BreakLabel);
|
||||||
|
|
||||||
/* Remove the loop from the loop stack */
|
/* Remove the loop from the loop stack */
|
||||||
DelLoop ();
|
DelLoop ();
|
||||||
@ -219,29 +223,31 @@ static void WhileStatement (void)
|
|||||||
int PendingToken;
|
int PendingToken;
|
||||||
|
|
||||||
/* Get the loop control labels */
|
/* Get the loop control labels */
|
||||||
unsigned loop = GetLocalLabel ();
|
unsigned LoopLabel = GetLocalLabel ();
|
||||||
unsigned lab = GetLocalLabel ();
|
unsigned BreakLabel = GetLocalLabel ();
|
||||||
|
|
||||||
/* Skip the while token */
|
/* Skip the while token */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Add the loop to the loop stack */
|
/* Add the loop to the loop stack. In case of a while loop, the loop head
|
||||||
AddLoop (oursp, loop, lab, 0, 0);
|
* label is used for continue statements.
|
||||||
|
*/
|
||||||
|
AddLoop (oursp, BreakLabel, LoopLabel);
|
||||||
|
|
||||||
/* Define the head label */
|
/* Define the head label */
|
||||||
g_defcodelabel (loop);
|
g_defcodelabel (LoopLabel);
|
||||||
|
|
||||||
/* Test the loop condition */
|
/* Test the loop condition */
|
||||||
TestInParens (lab, 0);
|
TestInParens (BreakLabel, 0);
|
||||||
|
|
||||||
/* Loop body */
|
/* Loop body */
|
||||||
Statement (&PendingToken);
|
Statement (&PendingToken);
|
||||||
|
|
||||||
/* Jump back to loop top */
|
/* Jump back to loop top */
|
||||||
g_jump (loop);
|
g_jump (LoopLabel);
|
||||||
|
|
||||||
/* Exit label */
|
/* Exit label */
|
||||||
g_defcodelabel (lab);
|
g_defcodelabel (BreakLabel);
|
||||||
|
|
||||||
/* Eat remaining tokens that were delayed because of line info
|
/* Eat remaining tokens that were delayed because of line info
|
||||||
* correctness
|
* correctness
|
||||||
@ -316,7 +322,7 @@ static void BreakStatement (void)
|
|||||||
g_space (oursp - L->StackPtr);
|
g_space (oursp - L->StackPtr);
|
||||||
|
|
||||||
/* Jump to the exit label of the loop */
|
/* Jump to the exit label of the loop */
|
||||||
g_jump (L->Label);
|
g_jump (L->BreakLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -332,10 +338,10 @@ static void ContinueStatement (void)
|
|||||||
/* Get the current loop descriptor */
|
/* Get the current loop descriptor */
|
||||||
L = CurrentLoop ();
|
L = CurrentLoop ();
|
||||||
if (L) {
|
if (L) {
|
||||||
/* Search for the correct loop */
|
/* Search for a loop that has a continue label. */
|
||||||
do {
|
do {
|
||||||
if (L->Loop) {
|
if (L->ContinueLabel) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
L = L->Next;
|
L = L->Next;
|
||||||
} while (L);
|
} while (L);
|
||||||
@ -350,12 +356,8 @@ static void ContinueStatement (void)
|
|||||||
/* Correct the stackpointer if needed */
|
/* Correct the stackpointer if needed */
|
||||||
g_space (oursp - L->StackPtr);
|
g_space (oursp - L->StackPtr);
|
||||||
|
|
||||||
/* Output the loop code */
|
/* Jump to next loop iteration */
|
||||||
if (L->linc) {
|
g_jump (L->ContinueLabel);
|
||||||
g_jump (L->linc);
|
|
||||||
} else {
|
|
||||||
g_jump (L->Loop);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -371,23 +373,25 @@ static void ForStatement (void)
|
|||||||
int PendingToken;
|
int PendingToken;
|
||||||
|
|
||||||
/* Get several local labels needed later */
|
/* Get several local labels needed later */
|
||||||
unsigned TestLabel = GetLocalLabel ();
|
unsigned TestLabel = GetLocalLabel ();
|
||||||
unsigned lab = GetLocalLabel ();
|
unsigned BreakLabel = GetLocalLabel ();
|
||||||
unsigned IncLabel = GetLocalLabel ();
|
unsigned IncLabel = GetLocalLabel ();
|
||||||
unsigned lstat = GetLocalLabel ();
|
unsigned BodyLabel = GetLocalLabel ();
|
||||||
|
|
||||||
/* Skip the FOR token */
|
/* Skip the FOR token */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
/* Add the loop to the loop stack */
|
/* Add the loop to the loop stack. A continue jumps to the start of the
|
||||||
AddLoop (oursp, TestLabel, lab, IncLabel, lstat);
|
* the increment condition.
|
||||||
|
*/
|
||||||
|
AddLoop (oursp, BreakLabel, IncLabel);
|
||||||
|
|
||||||
/* Skip the opening paren */
|
/* Skip the opening paren */
|
||||||
ConsumeLParen ();
|
ConsumeLParen ();
|
||||||
|
|
||||||
/* Parse the initializer expression */
|
/* Parse the initializer expression */
|
||||||
if (CurTok.Tok != TOK_SEMI) {
|
if (CurTok.Tok != TOK_SEMI) {
|
||||||
expression (&lval1);
|
expression (&lval1);
|
||||||
}
|
}
|
||||||
ConsumeSemi ();
|
ConsumeSemi ();
|
||||||
|
|
||||||
@ -396,10 +400,10 @@ static void ForStatement (void)
|
|||||||
|
|
||||||
/* Parse the test expression */
|
/* Parse the test expression */
|
||||||
if (CurTok.Tok != TOK_SEMI) {
|
if (CurTok.Tok != TOK_SEMI) {
|
||||||
Test (lstat, 1);
|
Test (BodyLabel, 1);
|
||||||
g_jump (lab);
|
g_jump (BreakLabel);
|
||||||
} else {
|
} else {
|
||||||
g_jump (lstat);
|
g_jump (BodyLabel);
|
||||||
}
|
}
|
||||||
ConsumeSemi ();
|
ConsumeSemi ();
|
||||||
|
|
||||||
@ -425,7 +429,7 @@ static void ForStatement (void)
|
|||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
|
|
||||||
/* Loop body */
|
/* Loop body */
|
||||||
g_defcodelabel (lstat);
|
g_defcodelabel (BodyLabel);
|
||||||
Statement (&PendingToken);
|
Statement (&PendingToken);
|
||||||
|
|
||||||
/* If we had an increment expression, move the code to the bottom of
|
/* If we had an increment expression, move the code to the bottom of
|
||||||
@ -433,17 +437,17 @@ static void ForStatement (void)
|
|||||||
* the loop body.
|
* the loop body.
|
||||||
*/
|
*/
|
||||||
if (HaveIncExpr) {
|
if (HaveIncExpr) {
|
||||||
MoveCode (IncExprStart, IncExprEnd, GetCodePos());
|
MoveCode (IncExprStart, IncExprEnd, GetCodePos());
|
||||||
} else {
|
} else {
|
||||||
/* Jump back to the increment expression */
|
/* Jump back to the increment expression */
|
||||||
g_jump (IncLabel);
|
g_jump (IncLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip a pending token if we have one */
|
/* Skip a pending token if we have one */
|
||||||
SkipPending (PendingToken);
|
SkipPending (PendingToken);
|
||||||
|
|
||||||
/* Declare the break label */
|
/* Declare the break label */
|
||||||
g_defcodelabel (lab);
|
g_defcodelabel (BreakLabel);
|
||||||
|
|
||||||
/* Remove the loop from the loop stack */
|
/* Remove the loop from the loop stack */
|
||||||
DelLoop ();
|
DelLoop ();
|
||||||
|
@ -117,7 +117,7 @@ void SwitchStatement (void)
|
|||||||
ExitLabel = GetLocalLabel ();
|
ExitLabel = GetLocalLabel ();
|
||||||
|
|
||||||
/* Create a loop so we may use break. */
|
/* Create a loop so we may use break. */
|
||||||
AddLoop (oursp, 0, ExitLabel, 0, 0);
|
AddLoop (oursp, ExitLabel, 0);
|
||||||
|
|
||||||
/* Create the collection for the case node tree */
|
/* Create the collection for the case node tree */
|
||||||
Nodes = NewCollection ();
|
Nodes = NewCollection ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user