+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 */
{
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 */
L = ReadToken (L+1, ",)", Arg, sizeof (Arg));
/* Check for errors */
- if (*L == '\0') {
+ if (*L == '\0') {
Error ("ASM code error: syntax error");
return 0;
}
AM = AM65_ZP_IND;
} else {
Error ("ASM code error: syntax error");
- return 0;
+ return 0;
}
}
break;
AM = AM65_ABSX;
}
} else if (Reg == 'Y') {
- AM = AM65_ABSY;
+ AM = AM65_ABSY;
} else {
Error ("ASM code error: syntax error");
return 0;
* memory moving.
*/
while (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;
+ CS_DelEntry (S, Start + Count);
}
-
- /* Now insert it at the new position */
- CollInsert (&S->Entries, E, NewPos);
}
*/
{
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);
}
}
* 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)
static void SkipPending (int PendingToken)
/* Skip the pending token if we have one */
{
- if (PendingToken) {
+ if (PendingToken) {
NextToken ();
}
}
struct expent lval1;
struct expent lval2;
struct expent lval3;
+ int HaveIncExpr;
+ CodeMark IncExprStart;
+ CodeMark IncExprEnd;
int PendingToken;
/* Get several local labels needed later */
unsigned IncLabel = GetLocalLabel ();
unsigned lstat = GetLocalLabel ();
- /* Skip the FOR token */
+ /* Skip the FOR token */
NextToken ();
/* Add the loop to the loop stack */
}
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 ();
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);