1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-26 05:29:30 +00:00

Move the increment code of a for loop after the loop body.

git-svn-id: svn://svn.cc65.org/cc65/trunk@799 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-07-17 12:50:38 +00:00
parent db707db0f1
commit 6c34eeb93d
5 changed files with 69 additions and 35 deletions

View File

@ -68,6 +68,16 @@ void RemoveCode (CodeMark M)
void MoveCode (CodeMark Start, CodeMark End, CodeMark Target)
/* Move the code between Start (inclusive) and End (exclusive) to
* (before) Target.
*/
{
CS_MoveEntries (CS->Code, Start, End - Start, Target);
}
void WriteOutput (FILE* F)
/* Write the final output to a file */
{

View File

@ -68,6 +68,11 @@ CodeMark GetCodePos (void);
void RemoveCode (CodeMark M);
/* Remove all code after the given code marker */
void MoveCode (CodeMark Start, CodeMark End, CodeMark Target);
/* Move the code between Start (inclusive) and End (exclusive) to
* (before) Target.
*/
void WriteOutput (FILE* F);
/* Write the final output to a file */

View File

@ -235,7 +235,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
L = ReadToken (L+1, ",)", Arg, sizeof (Arg));
/* Check for errors */
if (*L == '\0') {
if (*L == '\0') {
Error ("ASM code error: syntax error");
return 0;
}
@ -278,7 +278,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
AM = AM65_ZP_IND;
} else {
Error ("ASM code error: syntax error");
return 0;
return 0;
}
}
break;
@ -321,7 +321,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
AM = AM65_ABSX;
}
} else if (Reg == 'Y') {
AM = AM65_ABSY;
AM = AM65_ABSY;
} else {
Error ("ASM code error: syntax error");
return 0;
@ -545,43 +545,22 @@ void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count)
* memory moving.
*/
while (Count--) {
CS_DelEntry (S, Start + Count);
CS_DelEntry (S, Start + Count);
}
}
void CS_MoveEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos)
/* Move an entry from one position to another. OldPos is the current position
* of the entry, NewPos is the new position of the entry.
*/
{
/* Get the code entry and remove it from the collection */
CodeEntry* E = CS_GetEntry (S, OldPos);
CollDelete (&S->Entries, OldPos);
/* Correct NewPos if needed */
if (NewPos >= OldPos) {
/* Position has changed with removal */
--NewPos;
}
/* Now insert it at the new position */
CollInsert (&S->Entries, E, NewPos);
}
struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index)
/* Get the code entry following the one with the index Index. If there is no
* following code entry, return NULL.
*/
{
if (Index >= CollCount (&S->Entries)-1) {
/* This is the last entry */
return 0;
/* This is the last entry */
return 0;
} else {
/* Code entries left */
/* Code entries left */
return CollAtUnchecked (&S->Entries, Index+1);
}
}

View File

@ -116,10 +116,32 @@ void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count);
* labels attached to the entries and so on.
*/
void CS_MoveEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos);
#if defined(HAVE_INLINE)
INLINE void CS_MoveEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos)
/* Move an entry from one position to another. OldPos is the current position
* of the entry, NewPos is the new position of the entry.
*/
{
CollMove (&S->Entries, OldPos, NewPos);
}
#else
# define CS_MoveEntry(S, OldPos, NewPos) CollMove (&(S)->Entries, OldPos, NewPos)
#endif
#if defined(HAVE_INLINE)
INLINE void CS_MoveEntries (CodeSeg* S, unsigned Start, unsigned Count, unsigned NewPos)
/* Move a range of entries from one position to another. Start is the index
* of the first entry to move, Count is the number of entries and NewPos is
* the index of the target entry. The entry with the index Start will later
* have the index NewPos. All entries with indices NewPos and above are
* moved to higher indices.
*/
{
CollMoveMultiple (&S->Entries, Start, Count, NewPos);
}
#else
# define CS_MoveEntries(S, Start, Count, NewPos) CollMoveMultiple (&(S)->Entries, Start, Count, NewPos)
#endif
#if defined(HAVE_INLINE)
INLINE struct CodeEntry* CS_GetEntry (CodeSeg* S, unsigned Index)

View File

@ -81,7 +81,7 @@ static void CheckSemi (int* PendingToken)
static void SkipPending (int PendingToken)
/* Skip the pending token if we have one */
{
if (PendingToken) {
if (PendingToken) {
NextToken ();
}
}
@ -641,6 +641,9 @@ static void ForStatement (void)
struct expent lval1;
struct expent lval2;
struct expent lval3;
int HaveIncExpr;
CodeMark IncExprStart;
CodeMark IncExprEnd;
int PendingToken;
/* Get several local labels needed later */
@ -649,7 +652,7 @@ static void ForStatement (void)
unsigned IncLabel = GetLocalLabel ();
unsigned lstat = GetLocalLabel ();
/* Skip the FOR token */
/* Skip the FOR token */
NextToken ();
/* Add the loop to the loop stack */
@ -677,17 +680,24 @@ static void ForStatement (void)
}
ConsumeSemi ();
/* Remember the start of the increment expression */
IncExprStart = GetCodePos();
/* Label for the increment expression */
g_defcodelabel (IncLabel);
/* Parse the increment expression */
if (CurTok.Tok != TOK_RPAREN) {
HaveIncExpr = (CurTok.Tok != TOK_RPAREN);
if (HaveIncExpr) {
expression (&lval3);
}
/* Jump to the test */
g_jump (TestLabel);
/* Remember the end of the increment expression */
IncExprEnd = GetCodePos();
/* Skip the closing paren */
ConsumeRParen ();
@ -695,9 +705,17 @@ static void ForStatement (void)
g_defcodelabel (lstat);
Statement (&PendingToken);
/* Jump back to the increment expression */
g_jump (IncLabel);
/* If we had an increment expression, move the code to the bottom of
* the loop. In this case we don't need to jump there at the end of
* the loop body.
*/
if (HaveIncExpr) {
MoveCode (IncExprStart, IncExprEnd, GetCodePos());
} else {
/* Jump back to the increment expression */
g_jump (IncLabel);
}
/* Skip a pending token if we have one */
SkipPending (PendingToken);