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:
parent
db707db0f1
commit
6c34eeb93d
5 changed files with 69 additions and 35 deletions
|
@ -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)
|
void WriteOutput (FILE* F)
|
||||||
/* Write the final output to a file */
|
/* Write the final output to a file */
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,6 +68,11 @@ CodeMark GetCodePos (void);
|
||||||
void RemoveCode (CodeMark M);
|
void RemoveCode (CodeMark M);
|
||||||
/* Remove all code after the given code marker */
|
/* 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);
|
void WriteOutput (FILE* F);
|
||||||
/* Write the final output to a file */
|
/* Write the final output to a file */
|
||||||
|
|
||||||
|
|
|
@ -235,7 +235,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||||
L = ReadToken (L+1, ",)", Arg, sizeof (Arg));
|
L = ReadToken (L+1, ",)", Arg, sizeof (Arg));
|
||||||
|
|
||||||
/* Check for errors */
|
/* Check for errors */
|
||||||
if (*L == '\0') {
|
if (*L == '\0') {
|
||||||
Error ("ASM code error: syntax error");
|
Error ("ASM code error: syntax error");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -278,7 +278,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||||
AM = AM65_ZP_IND;
|
AM = AM65_ZP_IND;
|
||||||
} else {
|
} else {
|
||||||
Error ("ASM code error: syntax error");
|
Error ("ASM code error: syntax error");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -321,7 +321,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
|
||||||
AM = AM65_ABSX;
|
AM = AM65_ABSX;
|
||||||
}
|
}
|
||||||
} else if (Reg == 'Y') {
|
} else if (Reg == 'Y') {
|
||||||
AM = AM65_ABSY;
|
AM = AM65_ABSY;
|
||||||
} else {
|
} else {
|
||||||
Error ("ASM code error: syntax error");
|
Error ("ASM code error: syntax error");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -545,43 +545,22 @@ void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count)
|
||||||
* memory moving.
|
* memory moving.
|
||||||
*/
|
*/
|
||||||
while (Count--) {
|
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)
|
struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index)
|
||||||
/* Get the code entry following the one with the index Index. If there is no
|
/* Get the code entry following the one with the index Index. If there is no
|
||||||
* following code entry, return NULL.
|
* following code entry, return NULL.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (Index >= CollCount (&S->Entries)-1) {
|
if (Index >= CollCount (&S->Entries)-1) {
|
||||||
/* This is the last entry */
|
/* This is the last entry */
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
/* Code entries left */
|
/* Code entries left */
|
||||||
return CollAtUnchecked (&S->Entries, Index+1);
|
return CollAtUnchecked (&S->Entries, Index+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,10 +116,32 @@ void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count);
|
||||||
* labels attached to the entries and so on.
|
* 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
|
/* Move an entry from one position to another. OldPos is the current position
|
||||||
* of the entry, NewPos is the new position of the entry.
|
* 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)
|
#if defined(HAVE_INLINE)
|
||||||
INLINE struct CodeEntry* CS_GetEntry (CodeSeg* S, unsigned Index)
|
INLINE struct CodeEntry* CS_GetEntry (CodeSeg* S, unsigned Index)
|
||||||
|
|
|
@ -641,6 +641,9 @@ static void ForStatement (void)
|
||||||
struct expent lval1;
|
struct expent lval1;
|
||||||
struct expent lval2;
|
struct expent lval2;
|
||||||
struct expent lval3;
|
struct expent lval3;
|
||||||
|
int HaveIncExpr;
|
||||||
|
CodeMark IncExprStart;
|
||||||
|
CodeMark IncExprEnd;
|
||||||
int PendingToken;
|
int PendingToken;
|
||||||
|
|
||||||
/* Get several local labels needed later */
|
/* Get several local labels needed later */
|
||||||
|
@ -677,17 +680,24 @@ static void ForStatement (void)
|
||||||
}
|
}
|
||||||
ConsumeSemi ();
|
ConsumeSemi ();
|
||||||
|
|
||||||
|
/* Remember the start of the increment expression */
|
||||||
|
IncExprStart = GetCodePos();
|
||||||
|
|
||||||
/* Label for the increment expression */
|
/* Label for the increment expression */
|
||||||
g_defcodelabel (IncLabel);
|
g_defcodelabel (IncLabel);
|
||||||
|
|
||||||
/* Parse the increment expression */
|
/* Parse the increment expression */
|
||||||
if (CurTok.Tok != TOK_RPAREN) {
|
HaveIncExpr = (CurTok.Tok != TOK_RPAREN);
|
||||||
|
if (HaveIncExpr) {
|
||||||
expression (&lval3);
|
expression (&lval3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Jump to the test */
|
/* Jump to the test */
|
||||||
g_jump (TestLabel);
|
g_jump (TestLabel);
|
||||||
|
|
||||||
|
/* Remember the end of the increment expression */
|
||||||
|
IncExprEnd = GetCodePos();
|
||||||
|
|
||||||
/* Skip the closing paren */
|
/* Skip the closing paren */
|
||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
|
|
||||||
|
@ -695,8 +705,16 @@ static void ForStatement (void)
|
||||||
g_defcodelabel (lstat);
|
g_defcodelabel (lstat);
|
||||||
Statement (&PendingToken);
|
Statement (&PendingToken);
|
||||||
|
|
||||||
/* Jump back to the increment expression */
|
/* If we had an increment expression, move the code to the bottom of
|
||||||
g_jump (IncLabel);
|
* 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 */
|
/* Skip a pending token if we have one */
|
||||||
SkipPending (PendingToken);
|
SkipPending (PendingToken);
|
||||||
|
|
Loading…
Add table
Reference in a new issue