]> git.sur5r.net Git - cc65/commitdiff
Added .REPEAT pseudo instruction
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 28 Jul 2000 12:15:40 +0000 (12:15 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Fri, 28 Jul 2000 12:15:40 +0000 (12:15 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@215 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/listing.c
src/ca65/main.c
src/ca65/make/gcc.mak
src/ca65/make/watcom.mak
src/ca65/pseudo.c
src/ca65/repeat.c [new file with mode: 0644]
src/ca65/repeat.h [new file with mode: 0644]
src/ca65/scanner.h
src/ca65/toklist.c
src/ca65/toklist.h

index 05dc6c4ecb0aead31acfaf5fb7202a363ffa314c..3f3fb3d79acb76b78875fa46f76f23463327a197 100644 (file)
 #include <string.h>
 #include <errno.h>
 
-#include "../common/fname.h"
-#include "../common/segdefs.h"
-#include "../common/version.h"
-#include "../common/xmalloc.h"
+/* common */
+#include "fname.h"
+#include "segdefs.h"
+#include "version.h"
+#include "xmalloc.h"
 
+/* ca65 */
 #include "error.h"
 #include "global.h"
 #include "objcode.h"
@@ -50,7 +52,7 @@
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                  Data                                    */
 /*****************************************************************************/
 
 
@@ -167,13 +169,28 @@ void InitListingLine (void)
 {
     if (Listing) {
        /* Make the last loaded line the current line */
-       LineCur = LineLast;
+       /* ###### This code is a hack! We really need to do it right
+        * as soon as we know, how:-(
+        */
+               if (LineCur && LineCur->Next && LineCur->Next != LineLast) {
+           ListLine* L = LineCur;
+           do {
+               L = L->Next;
+               /* Set the values for this line */
+               CHECK (L != 0);
+               L->PC            = GetPC ();
+               L->Reloc         = RelocMode;
+               L->Output        = (ListingEnabled > 0);
+               L->ListBytes = (unsigned char) ListBytes;
+           } while (L->Next != LineLast);
+       }
+       LineCur = LineLast;
 
-       /* Set the values for this line */
-       CHECK (LineCur != 0);
-       LineCur->PC         = GetPC ();
-       LineCur->Reloc      = RelocMode;
-       LineCur->Output     = (ListingEnabled > 0);
+       /* Set the values for this line */
+       CHECK (LineCur != 0);
+       LineCur->PC         = GetPC ();
+       LineCur->Reloc      = RelocMode;
+       LineCur->Output     = (ListingEnabled > 0);
                LineCur->ListBytes  = (unsigned char) ListBytes;
     }
 }
@@ -345,7 +362,7 @@ void CreateListing (void)
                    break;
 
                case FRAG_EXPR:
-               case FRAG_SEXPR:
+               case FRAG_SEXPR:
                    B = AddMult (B, 'r', Frag->Len*2);
                    break;
 
index f28224cb9b78b66fc4990ce94a84946a38550975..9f947f649119d05cec06b381c512253a95cb7178 100644 (file)
 #include <ctype.h>
 #include <time.h>
 
-#include "../common/cmdline.h"
-#include "../common/version.h"
-
+/* common */
+#include "cmdline.h"
+#include "version.h"
+         
+/* ca65 */
 #include "error.h"
 #include "expr.h"
 #include "global.h"
@@ -301,11 +303,11 @@ static void OneLine (void)
     int Done = 0;
 
     /* Initialize the new listing line if we are actually reading from file
-     * and not from internally pushed input.                               
+     * and not from internally pushed input.
      */
     if (!HavePushedInput ()) {
        InitListingLine ();
-    }
+    }    
 
     if (Tok == TOK_COLON) {
        /* An unnamed label */
index 90494d084ef85126fe79410025802345dc909224..8070998929e286d2cfd8a3cb061e58eccbf48e39 100644 (file)
@@ -1,8 +1,8 @@
 #
-# gcc Makefile for a65, link65 & libr65
+# gcc Makefile for ca65
 #
 
-CFLAGS         = -g -O2 -Wall
+CFLAGS         = -g -O2 -Wall -I../common
 CC     = gcc
 LDFLAGS        =
 
@@ -12,18 +12,19 @@ OBJS =  condasm.o   \
         expr.o         \
        fragment.o      \
         global.o               \
-       incpath.o       \
-        instr.o                \
-       istack.o        \
-       listing.o       \
-       macpack.o       \
-               macro.o         \
-        main.o                 \
-       nexttok.o       \
-        objcode.o      \
-        objfile.o      \
-               options.o       \
-        pseudo.o       \
+       incpath.o       \
+        instr.o                \
+       istack.o        \
+       listing.o       \
+       macpack.o       \
+               macro.o         \
+        main.o                 \
+       nexttok.o       \
+        objcode.o              \
+        objfile.o              \
+               options.o       \
+        pseudo.o               \
+       repeat.o        \
         scanner.o      \
         symtab.o       \
                toklist.o       \
index 430b964fb6bc141907f0a5121919ce5e9371447e..bc953996447e6cf285e502763f15cb3644700119 100644 (file)
@@ -81,6 +81,7 @@ OBJS =        condasm.obj     \
        objfile.obj     \
        options.obj     \
        pseudo.obj      \
+       repeat.obj      \
        scanner.obj     \
        symtab.obj      \
        toklist.obj     \
@@ -124,6 +125,7 @@ FILE objcode.obj
 FILE objfile.obj
 FILE options.obj
 FILE pseudo.obj
+FILE repeat.obj
 FILE scanner.obj
 FILE symtab.obj
 FILE toklist.obj
index fb2a6cee029eaea1c88f40b6cf44804e172a67ed..29befcea6d9d17045523f4ae15f5d46c3ab3c0f5 100644 (file)
 #include <ctype.h>
 #include <errno.h>
 
-#include "../common/bitops.h"
+/* common */
+#include "bitops.h"
 
+/* ca65 */
 #include "condasm.h"
 #include "error.h"
 #include "expr.h"
@@ -52,6 +54,7 @@
 #include "nexttok.h"
 #include "objcode.h"
 #include "options.h"
+#include "repeat.h"
 #include "symtab.h"
 #include "pseudo.h"
 
@@ -906,7 +909,7 @@ static void DoReloc (void)
 static void DoRepeat (void)
 /* Repeat some instruction block */
 {
-    ErrorSkip (ERR_NOT_IMPLEMENTED);
+    ParseRepeat ();
 }
 
 
@@ -1043,7 +1046,7 @@ static void DoWarning (void)
     if (Tok != TOK_STRCON) {
        ErrorSkip (ERR_STRCON_EXPECTED);
     } else {
-               Error (WARN_USER, SVal);
+               Warning (WARN_USER, SVal);
        SkipUntilSep ();
     }
 }
diff --git a/src/ca65/repeat.c b/src/ca65/repeat.c
new file mode 100644 (file)
index 0000000..b442c16
--- /dev/null
@@ -0,0 +1,179 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                repeat.c                                  */
+/*                                                                           */
+/*                  Handle the .REPEAT pseudo instruction                   */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2000     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* common */
+#include "xmalloc.h"
+
+/* ca65 */
+#include "error.h"
+#include "expr.h"
+#include "nexttok.h"
+#include "toklist.h"
+#include "repeat.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+static TokList* CollectRepeatTokens (void)
+/* Collect all tokens inside the .REPEAT body in a token list and return
+ * this list. In case of errors, NULL is returned.
+ */
+{
+    /* Create the token list */
+    TokList* List = NewTokList ();
+
+    /* Read the token list */
+    unsigned Repeats = 0;
+    while (Repeats != 0 || Tok != TOK_ENDREP) {
+
+       /* Check for end of input */
+               if (Tok == TOK_EOF) {
+           Error (ERR_UNEXPECTED_EOF);
+           FreeTokList (List);
+           return 0;
+       }
+
+       /* If we find a token that is equal to the repeat counter name,
+        * replace it by a REPCOUNTER token. This way we have to do strcmps
+        * only once for each identifier, and not for each expansion.
+        * Note: This will fail for nested repeats using the same repeat
+        * counter name, but
+        */
+
+
+
+               /* Collect all tokens in the list */
+       AddCurTok (List);
+
+       /* Check for and count nested .REPEATs */
+       if (Tok == TOK_REPEAT) {
+           ++Repeats;
+       } else if (Tok == TOK_ENDREP) {
+           --Repeats;
+       }
+
+               /* Get the next token */
+       NextTok ();
+    }
+
+    /* Eat the closing .ENDREP */
+    NextTok ();
+
+    /* Return the list of collected tokens */
+    return List;
+}
+
+
+
+static void RepeatTokenCheck (TokList* L)
+/* Called each time a token from a repeat token list is set. Is used to check
+ * for and replace identifiers that are the repeat counter.
+ */
+{                
+    if (Tok == TOK_IDENT && L->Data != 0 && strcmp (SVal, L->Data) == 0) {
+       /* Must replace by the repeat counter */
+       Tok  = TOK_INTCON;
+       IVal = L->RepCount;
+    }
+}
+
+
+
+void ParseRepeat (void)
+/* Parse and handle the .REPEAT statement */
+{
+    char* Name;
+    TokList* List;
+
+    /* Repeat count follows */
+    long RepCount = ConstExpression ();
+    if (RepCount < 0) {
+       Error (ERR_RANGE);
+       RepCount = 0;
+    }
+
+    /* Optional there is a comma and a counter variable */
+    Name = 0;
+    if (Tok == TOK_COMMA) {
+
+               /* Skip the comma */
+               NextTok ();
+
+               /* Check for an identifier */
+               if (Tok != TOK_IDENT) {
+                   ErrorSkip (ERR_IDENT_EXPECTED);
+               } else {
+                   /* Remember the name and skip it */
+                   Name = xstrdup (SVal);
+                   NextTok ();
+               }
+    }
+
+    /* Separator */
+    ConsumeSep ();
+
+    /* Read the token list */
+    List = CollectRepeatTokens ();
+
+    /* If we had an error, bail out */
+    if (List == 0) {
+       xfree (Name);
+               return;
+    }
+
+    /* Update the token list for replay */
+    List->RepMax = (unsigned) RepCount;
+    List->Data   = Name;
+    List->Check  = RepeatTokenCheck;
+
+    /* If the list is empty, or repeat count zero, there is nothing
+     * to repeat.
+     */
+    if (List->Count == 0 || RepCount == 0) {
+       FreeTokList (List);
+       return;
+    }
+
+    /* Read input from the repeat descriptor */
+    PushTokList (List, ".REPEAT");
+}
+
+
+
diff --git a/src/ca65/repeat.h b/src/ca65/repeat.h
new file mode 100644 (file)
index 0000000..8bb5d3e
--- /dev/null
@@ -0,0 +1,58 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                repeat.h                                  */
+/*                                                                           */
+/*                  Handle the .REPEAT pseudo instruction                   */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2000     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* This software is provided 'as-is', without any expressed or implied       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef REPEAT_H
+#define REPEAT_H
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void ParseRepeat (void);
+/* Parse and handle the .REPEAT statement */
+
+
+
+/* End of repeat.h */
+
+#endif
+
+
+
+
index 4c43b6c85e3a7b918521798b6752508c20602624..952c6bab0da5d9e6fa3dc5f2a93fca30dad58c4c 100644 (file)
@@ -38,7 +38,8 @@
 
 
 
-#include "../common/filepos.h"
+/* common */
+#include "filepos.h"
 
 
 
index ab93a6766a55e743e1349a8888c0694a333ae858..82137f720622d27a82a687795a37f5ff352305d8 100644 (file)
 
 
 #include <string.h>
-
-#include "../common/xmalloc.h"
-
+                     
+/* common */
+#include "xmalloc.h"
+         
+/* ca65 */
 #include "error.h"
 #include "istack.h"
 #include "scanner.h"
@@ -62,7 +64,7 @@ TokNode* NewTokNode (void)
     /* Initialize the token contents */
     T->Next    = 0;
     T->Tok     = Tok;
-    T->WS      = WS;
+    T->WS      = WS;
     T->IVal    = IVal;
     memcpy (T->SVal, SVal, Len);
     T->SVal [Len] = '\0';
@@ -125,8 +127,11 @@ void InitTokList (TokList* T)
     T->Next    = 0;
     T->Root    = 0;
     T->Last    = 0;
-    T->Repeat  = 1;
+    T->RepCount        = 0;
+    T->RepMax  = 1;
     T->Count   = 0;
+    T->Check   = 0;
+    T->Data    = 0;
 }
 
 
@@ -157,6 +162,11 @@ void FreeTokList (TokList* List)
        FreeTokNode (Tmp);
     }
 
+    /* If we have associated data, free it */
+    if (List->Data) {
+       xfree (List->Data);
+    }
+
     /* Free the list structure itself */
     xfree (List);
 }
@@ -198,6 +208,13 @@ static int ReplayTokList (void* List)
     /* Set the next token from the list */
     TokSet (L->Last);
 
+    /* If a check function is defined, call it, so it may look at the token
+     * just set and changed it as apropriate.
+     */
+    if (L->Check) {
+       L->Check (L);
+    }
+
     /* Set the pointer to the next token */
     L->Last = L->Last->Next;
 
@@ -205,7 +222,7 @@ static int ReplayTokList (void* List)
      * zero, delete the list and remove the function from the stack.
      */
     if (L->Last == 0) {
-       if (--L->Repeat == 0) {
+       if (++L->RepCount >= L->RepMax) {
            /* Done with this list */
            FreeTokList (L);
            PopInput ();
index 498631d830b2f661f593e9f37b3aa9c98fc4b1a3..9826724d4d475a0c7879e9086f444d52cc423728 100644 (file)
 /* Struct holding a token */
 typedef struct TokNode TokNode;
 struct TokNode {
-    TokNode*                   Next;           /* For single linked list */
-    enum Token         Tok;            /* Token value */
-    int                        WS;             /* Whitespace before token? */
-    long                       IVal;           /* Integer token attribute */
-    char                       SVal [1];       /* String attribute, dyn. allocated */
+    TokNode*   Next;                   /* For single linked list */
+    enum Token Tok;                    /* Token value */
+    int                WS;                     /* Whitespace before token? */
+    long               IVal;                   /* Integer token attribute */
+    char               SVal [1];               /* String attribute, dyn. allocated */
 };
 
 /* Struct holding a token list */
 typedef struct TokList TokList;
 struct TokList {
-    TokList*           Next;           /* Single linked list (for replay) */
-    TokNode*           Root;           /* First node in list */
-    TokNode*           Last;           /* Last node in list or replay */
-    unsigned           Repeat;         /* Repeat counter (used for replay) */
-    unsigned           Count;          /* Token count */
+    TokList*   Next;                   /* Single linked list (for replay) */
+    TokNode*   Root;                   /* First node in list */
+    TokNode*   Last;                   /* Last node in list or replay */
+    unsigned           RepCount;               /* Repeat counter (used for replay) */
+    unsigned   RepMax;                 /* Maximum repeat count for replay */
+    unsigned   Count;                  /* Token count */
+    void       (*Check)(TokList*);     /* Token check function */
+    void*              Data;                   /* Additional data for check */
 };