]> git.sur5r.net Git - cc65/commitdiff
Added a more generic way to push sources that deliver a token stream
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 3 Jun 2000 11:15:11 +0000 (11:15 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 3 Jun 2000 11:15:11 +0000 (11:15 +0000)
independent of the actual input from the file. Change macro handling
to use the new input stack.
Fixed an error in FreeIf: If an unexpected .ENDIF was reached, the
assembler started an endless loop printing error messages.

git-svn-id: svn://svn.cc65.org/cc65/trunk@24 b7a2c559-68d2-44c3-8de9-860c34a00d81

23 files changed:
src/ca65/condasm.c
src/ca65/condasm.h
src/ca65/ea.c
src/ca65/error.c
src/ca65/error.h
src/ca65/expr.c
src/ca65/instr.c
src/ca65/istack.c [new file with mode: 0644]
src/ca65/istack.h [new file with mode: 0644]
src/ca65/macro.c
src/ca65/macro.h
src/ca65/main.c
src/ca65/make/gcc.mak
src/ca65/make/watcom.mak
src/ca65/nexttok.c [new file with mode: 0644]
src/ca65/nexttok.h [new file with mode: 0644]
src/ca65/pseudo.c
src/ca65/scanner.c
src/ca65/scanner.h
src/ca65/toklist.c [new file with mode: 0644]
src/ca65/toklist.h [new file with mode: 0644]
src/ca65/toknode.c [deleted file]
src/ca65/toknode.h [deleted file]

index 831802c377ba1343ab48a24ed4925209539f9ee8..5b699e574ccb5861773390fe906e5b2f4d8452e8 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "error.h"
 #include "expr.h"
-#include "scanner.h"
+#include "nexttok.h"
 #include "symtab.h"
 #include "condasm.h"
 
@@ -124,6 +124,7 @@ static void FreeIf (void)
                IfDesc* D = GetCurrentIf();
                if (D == 0) {
                    Error (ERR_UNEXPECTED, ".ENDIF");
+           Done = 1;
                } else {
                    Done = (D->Flags & ifNeedTerm) != 0;
             --IfCount;
@@ -402,7 +403,7 @@ void CheckOpenIfs (void)
            /* There are no open .IFs */
            break;
        }
-         
+
        if (D->Pos.Name != CurPos.Name) {
            /* The .if is from another file, bail out */
            break;
@@ -416,3 +417,21 @@ void CheckOpenIfs (void)
 
 
 
+unsigned GetIfStack (void)
+/* Get the current .IF stack pointer */
+{
+    return IfCount;
+}
+
+
+
+void CleanupIfStack (unsigned SP)
+/* Cleanup the .IF stack, remove anything above the given stack pointer */
+{
+    while (IfCount > SP) {
+       FreeIf ();
+    }
+}
+
+
+
index 3994b3929ca8089386a3e306a71e94ae9944cc04..84a2ac02603ea7c6e0ce5752fd7e1533345952c5 100644 (file)
@@ -52,6 +52,12 @@ void CheckOpenIfs (void);
  * open .ifs in this file.
  */
 
+unsigned GetIfStack (void);
+/* Get the current .IF stack pointer */
+
+void CleanupIfStack (unsigned SP);
+/* Cleanup the .IF stack, remove anything above the given stack pointer */
+
 
 
 /* End of condasm.h */
index 8bc8e810d9cf000c06f20cd8db7b758b02a52937..f715ec6d792287f6849af79e7121647ec93134a6 100644 (file)
@@ -36,7 +36,7 @@
 #include "error.h"
 #include "expr.h"
 #include "instr.h"
-#include "scanner.h"
+#include "nexttok.h"
 #include "ea.h"
 
 
index 5dea2d6e503d3e76deef4c633035124a8a6efe23..a81afc07c8f83a013fb1eb0f576a5b106876af82 100644 (file)
@@ -37,7 +37,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 
-#include "scanner.h"
+#include "nexttok.h"
 #include "error.h"
 
 
@@ -190,6 +190,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap)
        "CPU not supported",
        "Counter underflow",
        "Undefined label",
+       "Open `%s´",
     };
 
     fprintf (stderr, "%s(%lu): Error #%u: ",
@@ -257,7 +258,7 @@ void Fatal (unsigned FatNum, ...)
        "Cannot open listing file: %s",
        "Cannot write to listing file: %s",
        "Cannot read from listing file: %s",
-       "Macro nesting too deep",
+       "Too many nested constructs",
        "Too many symbols",
     };
     va_list ap;
index 7dba969241acd8ec5dde7664f5461b62f6750e00..ff365a99911ea45cd08465b59acc0d72002f13d1 100644 (file)
@@ -123,6 +123,7 @@ enum Errors {
     ERR_CPU_NOT_SUPPORTED,
     ERR_COUNTER_UNDERFLOW,
     ERR_UNDEFINED_LABEL,
+    ERR_OPEN_STMT,
     ERR_COUNT                                  /* Error count */
 };
 
@@ -140,7 +141,7 @@ enum Fatals {
     FAT_CANNOT_OPEN_LISTING,
     FAT_CANNOT_WRITE_LISTING,
     FAT_CANNOT_READ_LISTING,
-    FAT_MACRO_NESTING,
+    FAT_NESTING,
     FAT_TOO_MANY_SYMBOLS,
     FAT_COUNT                          /* Fatal error count */
 };
index 6131e39a0f6b01ec147b07707b019b1cf841f25e..509dc6ebacea6f4d060cc7de37e8889ffeded0ef 100644 (file)
 #include "global.h"
 #include "instr.h"
 #include "mem.h"
+#include "nexttok.h"
 #include "objcode.h"
 #include "objfile.h"
-#include "scanner.h"
 #include "symtab.h"
-#include "toknode.h"
+#include "toklist.h"
 #include "ulabel.h"
 #include "expr.h"
 
index 50c74923bf1e0b81c2662c8041b6638fde8470a3..6f8b3fea7c15b1496788d545f9b63ac423272bb5 100644 (file)
@@ -43,8 +43,8 @@
 #include "error.h"
 #include "expr.h"
 #include "global.h"
+#include "nexttok.h"
 #include "objcode.h"
-#include "scanner.h"
 #include "instr.h"
 
 
diff --git a/src/ca65/istack.c b/src/ca65/istack.c
new file mode 100644 (file)
index 0000000..6e2f9e2
--- /dev/null
@@ -0,0 +1,149 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                istack.c                                  */
+/*                                                                           */
+/*                       Input stack for the scanner                        */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include "error.h"
+#include "mem.h"
+#include "istack.h"
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* Size of the stack (== maximum nested macro or repeat count) */
+#define ISTACK_MAX     256
+
+/* Structure holding a stack element */
+typedef struct IElement IElement;
+struct IElement {
+    IElement*          Next;           /* Next stack element */
+    int                (*Func)(void*); /* Function called for input */
+    void*              Data;           /* User data given as argument */
+    const char* Desc;          /* Description */
+};
+
+/* The stack */
+static IElement* IStack = 0;   /* Input stack pointer */
+static unsigned  ICount        = 0;    /* Number of items on the stack */
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void PushInput (int (*Func) (void*), void* Data, const char* Desc)
+/* Push an input function onto the input stack */
+{
+    IElement* E;
+
+    /* Check for a stack overflow */
+    if (ICount > ISTACK_MAX) {
+       Fatal (FAT_NESTING);
+    }
+
+    /* Create a new stack element */
+    E = Xmalloc (sizeof (*E));
+
+    /* Initialize it */
+    E->Func = Func;
+    E->Data = Data;
+    E->Desc = Desc;
+
+    /* Push it */
+    E->Next = IStack;
+    IStack  = E;
+}
+
+
+
+void PopInput (void)
+/* Pop the current input function from the input stack */
+{
+    IElement* E;
+
+    /* We cannot pop from an empty stack */
+    PRECONDITION (IStack != 0);
+
+    /* Remember the last element */
+    E = IStack;
+
+    /* Pop it */
+    IStack = IStack->Next;
+
+    /* And delete it */
+    Xfree (E);
+}
+
+
+
+int InputFromStack (void)
+/* Try to get input from the input stack. Return true if we had such input,
+ * return false otherwise.
+ */
+{
+    /* Repeatedly call the TOS routine until we have a token or if run out of
+     * routines.
+     */
+    while (IStack) {
+       if (IStack->Func (IStack->Data) != 0) {
+           /* We have a token */
+           return 1;
+       }
+    }
+
+    /* Nothing is on the stack */
+    return 0;
+}
+
+
+
+void CheckInputStack (void)
+/* Called from the scanner before closing an input file. Will check for any
+ * stuff on the input stack.
+ */
+{
+    if (IStack) {
+       Error (ERR_OPEN_STMT, IStack->Desc);
+    }
+}
+
+
+
diff --git a/src/ca65/istack.h b/src/ca65/istack.h
new file mode 100644 (file)
index 0000000..0e8d893
--- /dev/null
@@ -0,0 +1,71 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                istack.h                                  */
+/*                                                                           */
+/*                       Input stack for the scanner                        */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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 ISTACK_H
+#define ISTACK_H
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void PushInput (int (*Func) (void*), void* Data, const char* Desc);
+/* Push an input function onto the input stack */
+
+void PopInput (void);
+/* Pop the current input function from the input stack */
+
+int InputFromStack (void);
+/* Try to get input from the input stack. Return true if we had such input,
+ * return false otherwise.
+ */                      
+
+void CheckInputStack (void);
+/* Called from the scanner before closing an input file. Will check for any
+ * stuff on the input stack.
+ */
+
+
+
+/* End of istack.h */
+
+#endif
+
+
+
+
index 73d8a0018c69dd569de437762da40645124d3d9c..a5eb78262b24c79874c85ea82ddd819e05e9691a 100644 (file)
 
 #include "../common/hashstr.h"
 
-#include "mem.h"
+#include "condasm.h"
 #include "error.h"
-#include "scanner.h"
-#include "toknode.h"
+#include "istack.h"
+#include "mem.h"
+#include "nexttok.h"
 #include "pseudo.h"
+#include "toklist.h"
 #include "macro.h"
 
 
@@ -90,6 +92,7 @@ typedef struct MacExp_ MacExp;
 struct MacExp_ {
     MacExp*    Next;           /* Pointer to next expansion */
     Macro*     M;              /* Which macro do we expand? */
+    unsigned   IfSP;           /* .IF stack pointer at start of expansion */
     TokNode*           Exp;            /* Pointer to current token */
     TokNode*   Final;          /* Pointer to final token */
     unsigned    LocalStart;    /* Start of counter for local symbol names */
@@ -98,11 +101,14 @@ struct MacExp_ {
     TokNode*   ParamExp;       /* Node for expanding parameters */
 };
 
-/* Data for macro expansions */
-#define        MAX_MACRO_EXPANSIONS    255
-static unsigned        MacroNesting    = 0;
-static MacExp*  CurMac         = 0;
-static unsigned LocalName      = 0;
+/* Number of active macro expansions */
+static unsigned MacExpansions = 0;
+
+/* Flag if a macro expansion should get aborted */
+static int DoMacAbort = 0;
+
+/* Counter to create local names for symbols */
+static unsigned LocalName = 0;
 
 
 
@@ -172,6 +178,7 @@ static MacExp* NewMacExp (Macro* M)
 
     /* Initialize the data */
     E->M                 = M;
+    E->IfSP      = GetIfStack ();
     E->Exp               = M->TokRoot;
     E->Final     = 0;
     E->LocalStart = LocalName;
@@ -183,44 +190,34 @@ static MacExp* NewMacExp (Macro* M)
        E->Params [I] = 0;
     }
 
-    /* And return it... */
-    return E;
-}
+    /* One macro expansion more */
+    ++MacExpansions;
 
-
-
-static void MacInsertExp (MacExp* E)
-/* Insert a macro expansion into the list */
-{
-    E->Next = CurMac;
-    CurMac  = E;
-    ++MacroNesting;
+    /* Return the new macro expansion */
+    return E;
 }
 
 
 
-static void FreeMacExp (void)
+static void FreeMacExp (MacExp* E)
 /* Remove and free the current macro expansion */
 {
     unsigned I;
-    MacExp* E;
+
+    /* One macro expansion less */
+    --MacExpansions;
 
     /* Free the parameter list */
-    for (I = 0; I < CurMac->ParamCount; ++I) {
-       Xfree (CurMac->Params [I]);
+    for (I = 0; I < E->ParamCount; ++I) {
+       Xfree (E->Params [I]);
     }
-    Xfree (CurMac->Params);
+    Xfree (E->Params);
 
     /* Free the final token if we have one */
-    if (CurMac->Final) {
-       FreeTokNode (CurMac->Final);
+    if (E->Final) {
+       FreeTokNode (E->Final);
     }
 
-    /* Reset the list pointer */
-    E = CurMac;
-    CurMac = E->Next;
-    --MacroNesting;
-
     /* Free the structure itself */
     Xfree (E);
 }
@@ -390,7 +387,7 @@ void MacDef (unsigned Style)
 
                IdDesc* I;
 
-               /* Skip .local or comma */
+               /* Skip .local or comma */
                        NextTok ();
 
                /* Need an identifer */
@@ -461,6 +458,123 @@ void MacDef (unsigned Style)
 
 
 
+static int MacExpand (void* Data)
+/* If we're currently expanding a macro, set the the scanner token and
+ * attribute to the next value and return true. If we are not expanding
+ * a macro, return false.
+ */
+{
+    /* Cast the Data pointer to the actual data structure */
+    MacExp* Mac = (MacExp*) Data;
+
+    /* Check if we should abort this macro */
+    if (DoMacAbort) {
+
+       /* Reset the flag */
+       DoMacAbort = 0;
+
+       /* Abort any open .IF statements in this macro expansion */
+       CleanupIfStack (Mac->IfSP);
+
+       /* Terminate macro expansion */
+       goto MacEnd;
+    }
+
+    /* We're expanding a macro. Check if we are expanding one of the
+     * macro parameters.
+     */
+    if (Mac->ParamExp) {
+
+               /* Ok, use token from parameter list */
+               TokSet (Mac->ParamExp);
+
+               /* Set pointer to next token */
+               Mac->ParamExp = Mac->ParamExp->Next;
+
+               /* Done */
+               return 1;
+
+    }
+
+    /* We're not expanding macro parameters. Check if we have tokens left from
+     * the macro itself.
+     */
+    if (Mac->Exp) {
+
+               /* Use next macro token */
+               TokSet (Mac->Exp);
+
+               /* Set pointer to next token */
+               Mac->Exp = Mac->Exp->Next;
+
+               /* Is it a request for actual parameter count? */
+               if (Tok == TOK_PARAMCOUNT) {
+                   Tok  = TOK_INTCON;
+                   IVal = Mac->ParamCount;
+                   return 1;
+               }
+
+               /* Is it the name of a macro parameter? */
+               if (Tok == TOK_MACPARAM) {
+
+                   /* Start to expand the parameter token list */
+                   Mac->ParamExp = Mac->Params [IVal];
+
+                   /* Recursive call to expand the parameter */
+                   return MacExpand (Mac);
+               }
+
+               /* If it's an identifier, it may in fact be a local symbol */
+               if (Tok == TOK_IDENT && Mac->M->LocalCount) {
+                   /* Search for the local symbol in the list */
+                   unsigned Index = 0;
+                   IdDesc* I = Mac->M->Locals;
+                   while (I) {
+                       if (strcmp (SVal, I->Id) == 0) {
+                           /* This is in fact a local symbol, change the name */
+                           sprintf (SVal, "___%04X__", Mac->LocalStart + Index);
+                           break;
+                       }
+                       /* Next symbol */
+                       ++Index;
+                       I = I->Next;
+                   }
+
+                   /* Done */
+                   return 1;
+               }
+
+               /* The token was successfully set */
+               return 1;
+
+    }
+
+    /* No more macro tokens. Do we have a final token? */
+    if (Mac->Final) {
+
+       /* Set the final token and remove it */
+       TokSet (Mac->Final);
+       FreeTokNode (Mac->Final);
+       Mac->Final = 0;
+
+               /* The token was successfully set */
+               return 1;
+
+    }
+
+MacEnd:
+    /* End of macro expansion */
+    FreeMacExp (Mac);
+
+    /* Pop the input function */
+    PopInput ();
+
+    /* No token available */
+    return 0;
+}
+
+
+
 static void StartExpClassic (Macro* M)
 /* Start expanding the classic macro M */
 {
@@ -522,8 +636,8 @@ static void StartExpClassic (Macro* M)
        }
     }
 
-    /* Insert the newly created structure into the expansion list */
-    MacInsertExp (E);
+    /* Insert a new token input function */
+    PushInput (MacExpand, E, ".MACRO");
 }
 
 
@@ -596,8 +710,8 @@ static void StartExpDefine (Macro* M)
      */
     E->Final = NewTokNode ();
 
-    /* Insert the newly created structure into the expansion list */
-    MacInsertExp (E);
+    /* Insert a new token input function */
+    PushInput (MacExpand, E, ".DEFINE");
 }
 
 
@@ -605,123 +719,15 @@ static void StartExpDefine (Macro* M)
 void MacExpandStart (void)
 /* Start expanding the macro in SVal */
 {
-    Macro* M;
-
-    /* Beware of runoff macros */
-    if (MacroNesting ==        MAX_MACRO_EXPANSIONS) {
-       Fatal (FAT_MACRO_NESTING);
-    }
-
     /* Search for the macro */
-    M = MacFind (SVal, HashStr (SVal) % HASHTAB_SIZE);
+    Macro* M = MacFind (SVal, HashStr (SVal) % HASHTAB_SIZE);
     CHECK (M != 0);
 
     /* Call the apropriate subroutine */
     switch (M->Style) {
        case MAC_STYLE_CLASSIC: StartExpClassic (M);    break;
        case MAC_STYLE_DEFINE:  StartExpDefine (M);     break;
-       default:                Internal ("Invalid macro style: %d", M->Style);
-    }
-}
-
-
-
-int MacExpand (void)
-/* If we're currently expanding a macro, set the the scanner token and
- * attribute to the next value and return true. If we are not expanding
- * a macro, return false.
- */
-{
-    if (MacroNesting == 0) {
-               /* Not expanding a macro */
-        return 0;
-    }
-
-    /* We're expanding a macro. Check if we are expanding one of the
-     * macro parameters.
-     */
-    if (CurMac->ParamExp) {
-
-               /* Ok, use token from parameter list */
-               TokSet (CurMac->ParamExp);
-
-               /* Set pointer to next token */
-               CurMac->ParamExp = CurMac->ParamExp->Next;
-
-               /* Done */
-               return 1;
-
-    } else if (CurMac->Exp) {
-
-               /* We're not expanding a parameter, use next macro token */
-               TokSet (CurMac->Exp);
-
-               /* Set pointer to next token */
-               CurMac->Exp = CurMac->Exp->Next;
-
-               /* Is it a request for actual parameter count? */
-               if (Tok == TOK_PARAMCOUNT) {
-                   Tok  = TOK_INTCON;
-                   IVal = CurMac->ParamCount;
-                   return 1;
-               }
-
-               /* Is it an .exitmacro command? */
-               if (Tok == TOK_EXITMACRO) {
-                   /* Forced exit from macro expansion */
-                   FreeMacExp ();
-                   return MacExpand ();
-               }
-
-               /* Is it the name of a macro parameter? */
-               if (Tok == TOK_MACPARAM) {
-
-                   /* Start to expand the parameter token list */
-                   CurMac->ParamExp = CurMac->Params [IVal];
-
-                   /* Recursive call to expand the parameter */
-                   return MacExpand ();
-               }
-
-               /* If it's an identifier, it may in fact be a local symbol */
-               if (Tok == TOK_IDENT && CurMac->M->LocalCount) {
-                   /* Search for the local symbol in the list */
-                   unsigned Index = 0;
-                   IdDesc* I = CurMac->M->Locals;
-                   while (I) {
-                       if (strcmp (SVal, I->Id) == 0) {
-                           /* This is in fact a local symbol, change the name */
-                           sprintf (SVal, "___%04X__", CurMac->LocalStart + Index);
-                           break;
-                       }
-                       /* Next symbol */
-                       ++Index;
-                       I = I->Next;
-                   }
-
-                   /* Done */
-                   return 1;
-               }
-
-               /* The token was successfully set */
-               return 1;
-
-    } else if (CurMac->Final) {
-
-       /* Set the final token and remove it */
-       TokSet (CurMac->Final);
-       FreeTokNode (CurMac->Final);
-       CurMac->Final = 0;
-
-               /* The token was successfully set */
-               return 1;
-
-    } else {
-
-               /* End of macro expansion */
-               FreeMacExp ();
-               return MacExpand ();
-
+       default:                Internal ("Invalid macro style: %d", M->Style);
     }
 }
 
@@ -731,10 +737,10 @@ void MacAbort (void)
 /* Abort the current macro expansion */
 {
     /* Must have an expansion */
-    CHECK (CurMac != 0);
+    CHECK (MacExpansions > 0);
 
-    /* Free current structure */
-    FreeMacExp ();
+    /* Set a flag so macro expansion will terminate on the next call */
+    DoMacAbort = 1;
 }
 
 
@@ -759,7 +765,7 @@ int IsDefine (const char* Name)
 int InMacExpansion (void)
 /* Return true if we're currently expanding a macro */
 {
-    return MacroNesting != 0;
+    return (MacExpansions > 0);
 }
 
 
index defcd9ad8e6af3cee2ff488c7c135b971d854775..d889f1aa01b30c8d365f6a4422a9cf572c8e6615 100644 (file)
@@ -62,12 +62,6 @@ void MacDef (unsigned Style);
 void MacExpandStart (void);
 /* Start expanding the macro in SVal */
 
-int MacExpand (void);
-/* If we're currently expanding a macro, set the the scanner token and
- * attribute to the next value and return true. If we are not expanding
- * a macro, return false.
- */
-
 void MacAbort (void);
 /* Abort the current macro expansion */
 
@@ -77,7 +71,7 @@ int IsMacro (const char* Name);
 int IsDefine (const char* Name);
 /* Return true if the given name is the name of a define style macro */
 
-int InMacExpansion (void); 
+int InMacExpansion (void);
 /* Return true if we're currently expanding a macro */
 
 
index ec5dac13d91d05781a6c09f1c9c08acc663ac400..063f467af1ebdf9bb2ed1929fef91b1908a0606d 100644 (file)
@@ -49,6 +49,7 @@
 #include "listing.h"
 #include "macro.h"
 #include "mem.h"
+#include "nexttok.h"
 #include "objcode.h"
 #include "objfile.h"
 #include "options.h"
@@ -543,7 +544,7 @@ int main (int argc, char* argv [])
                            OptIgnoreCase (Arg);
                            break;
 
-                       case 'l':     
+                       case 'l':
                    OptListing (Arg);
                            break;
 
index 97d58b76a0c6260094e72b66b51f6bcba4fa742c..7476985a00a54b7baa7e21e625e9db8f6f41499f 100644 (file)
@@ -15,11 +15,13 @@ OBJS =  condasm.o   \
         global.o               \
        incpath.o       \
         instr.o                \
+       istack.o        \
        listing.o       \
        macpack.o       \
                macro.o         \
-        main.o         \
-        mem.o          \
+        main.o                 \
+        mem.o                  \
+       nexttok.o       \
         objcode.o      \
         objfile.o      \
                options.o       \
@@ -27,7 +29,7 @@ OBJS =  condasm.o     \
         scanner.o      \
        strexpr.o       \
         symtab.o       \
-               toknode.o       \
+               toklist.o       \
        ulabel.o
 
 LIBS = ../common/common.a
@@ -62,3 +64,4 @@ depend dep:   $(OBJS:.o=.c)
        @echo "Creating dependency information"
        $(CC) -MM $^ > .depend
 
+
index 0e3c287345a86259da7400d203aaa5ef870d21c7..92e34ce435370b0fa42e09873b5ba058458ba4d3 100644 (file)
@@ -72,11 +72,13 @@ OBJS =      condasm.obj     \
        global.obj      \
        incpath.obj     \
                instr.obj       \
+       istack.obj      \
        listing.obj     \
        macpack.obj     \
        macro.obj       \
        main.obj        \
        mem.obj         \
+       nexttok.obj     \
        objcode.obj     \
        objfile.obj     \
        options.obj     \
@@ -84,7 +86,7 @@ OBJS =        condasm.obj     \
        scanner.obj     \
        strexpr.obj     \
        symtab.obj      \
-       toknode.obj     \
+       toklist.obj     \
        ulabel.obj
 
 LIBS = ..\common\common.lib
@@ -116,11 +118,13 @@ FILE fragment.obj
 FILE global.obj
 FILE incpath.obj
 FILE instr.obj
+FILE istack.obj
 FILE listing.obj
 FILE macpack.obj
 FILE macro.obj
 FILE main.obj
 FILE mem.obj
+FILE nexttok.obj
 FILE objcode.obj
 FILE objfile.obj
 FILE options.obj
@@ -128,7 +132,7 @@ FILE pseudo.obj
 FILE scanner.obj
 FILE strexpr.obj
 FILE symtab.obj
-FILE toknode.obj
+FILE toklist.obj
 FILE ulabel.obj
 LIBRARY ..\common\common.lib
 |
diff --git a/src/ca65/nexttok.c b/src/ca65/nexttok.c
new file mode 100644 (file)
index 0000000..3934126
--- /dev/null
@@ -0,0 +1,219 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                nexttok.c                                 */
+/*                                                                           */
+/*             Get next token and handle token level functions              */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include "error.h"
+#include "expr.h"
+#include "scanner.h"
+#include "toklist.h"
+#include "nexttok.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+static TokList* CollectTokens (unsigned Start, unsigned Count)
+/* Read a list of tokens that is terminated by a right paren. For all tokens
+ * starting at the one with index Start, and ending at (Start+Count-1), place
+ * them into a token list, and return this token list.
+ */
+{
+    /* Create the token list */
+    TokList* List = NewTokList ();
+
+    /* Read the token list */
+    unsigned Current = 0;
+    unsigned Parens  = 0;
+    while (Parens != 0 && Tok != TOK_RPAREN) {
+
+       /* Check for end of line or end of input */
+       if (Tok == TOK_SEP || Tok == TOK_EOF) {
+           Error (ERR_UNEXPECTED_EOL);
+           return List;
+       }
+
+       /* Collect tokens in the given range */
+       if (Current >= Start && Current < Start+Count) {
+           /* Add the current token to the list */
+           AddCurTok (List);
+       }
+
+       /* Check for and count parenthesii */
+       if (Tok == TOK_LPAREN) {
+           ++Parens;
+       } else if (Tok == TOK_RPAREN) {
+           --Parens;
+       }
+
+       /* Get the next token */
+       NextTok ();
+    }
+
+    /* Eat the closing paren */
+    ConsumeRParen ();
+
+    /* Return the list of collected tokens */
+    return List;
+}
+
+
+
+static void FuncMid (void)
+/* Handle the .MID function */
+{
+    long       Start;
+    long               Count;
+    TokList*   List;
+
+    /* Skip it */
+    NextTok ();
+
+    /* Left paren expected */
+    ConsumeRParen ();
+
+    /* Start argument */
+    Start = ConstExpression ();
+    if (Start < 0 || Start > 100) {
+       Error (ERR_RANGE);
+       Start = 0;
+    }
+    ConsumeComma ();
+
+    /* Count argument */
+    Count = ConstExpression ();
+    if (Count > 100) {
+       Error (ERR_RANGE);
+       Count = 1;
+    }
+    ConsumeComma ();
+
+    /* Read the token list */
+    List = CollectTokens ((unsigned) Start, (unsigned) Count);
+
+    /* Insert it into the scanner feed */
+
+
+
+}
+
+
+
+void NextTok (void)
+/* Get next token and handle token level functions */
+{
+    /* Get the next raw token */
+    NextRawTok ();
+
+    /* Check for token handling functions */
+    switch (Tok) {
+
+       case TOK_MID:
+           FuncMid ();
+           break;
+
+       default:
+           /* Quiet down gcc */
+           break;
+
+    }
+}
+
+
+
+void Consume (enum Token Expected, unsigned ErrMsg)
+/* Consume Expected, print an error if we don't find it */
+{
+    if (Tok == Expected) {
+       NextTok ();
+    } else {
+       Error (ErrMsg);
+    }
+}
+
+
+
+void ConsumeSep (void)
+/* Consume a separator token */
+{
+    /* Accept an EOF as separator */
+    if (Tok != TOK_EOF) {
+       if (Tok != TOK_SEP) {
+           Error (ERR_TOO_MANY_CHARS);
+           SkipUntilSep ();
+       } else {
+           NextTok ();
+       }
+    }
+}
+
+
+
+void ConsumeLParen (void)
+/* Consume a left paren */
+{
+    Consume (TOK_LPAREN, ERR_LPAREN_EXPECTED);
+}
+
+
+
+void ConsumeRParen (void)
+/* Consume a right paren */
+{
+    Consume (TOK_RPAREN, ERR_RPAREN_EXPECTED);
+}
+
+
+
+void ConsumeComma (void)
+/* Consume a comma */
+{
+    Consume (TOK_COMMA, ERR_COMMA_EXPECTED);
+}
+
+
+
+void SkipUntilSep (void)
+/* Skip tokens until we reach a line separator */
+{
+    while (Tok != TOK_SEP && Tok != TOK_EOF) {
+       NextTok ();
+    }
+}
+
+
+
diff --git a/src/ca65/nexttok.h b/src/ca65/nexttok.h
new file mode 100644 (file)
index 0000000..bc63b69
--- /dev/null
@@ -0,0 +1,80 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                nexttok.h                                 */
+/*                                                                           */
+/*             Get next token and handle token level functions              */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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 NEXTTOK_H
+#define NEXTTOK_H
+
+
+
+#include "scanner.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void NextTok (void);
+/* Get next token and handle token level functions */
+
+void Consume (enum Token Expected, unsigned ErrMsg);
+/* Consume Token, print an error if we don't find it */
+
+void ConsumeSep (void);
+/* Consume a separator token */
+
+void ConsumeLParen (void);
+/* Consume a left paren */
+
+void ConsumeRParen (void);
+/* Consume a right paren */
+
+void ConsumeComma (void);
+/* Consume a comma */
+
+void SkipUntilSep (void);
+/* Skip tokens until we reach a line separator */
+
+
+
+/* End of nexttok.h */
+
+#endif
+
+
+
+
index f2ad9b350cdcc35cec5bcd2ad99685126d2077e0..2edf19ec837c498adc90017998bdfb81ae632c13 100644 (file)
@@ -49,9 +49,9 @@
 #include "listing.h"
 #include "macpack.h"
 #include "macro.h"
+#include "nexttok.h"
 #include "objcode.h"
 #include "options.h"
-#include "scanner.h"
 #include "strexpr.h"
 #include "symtab.h"
 #include "pseudo.h"
@@ -789,6 +789,16 @@ static void DoMacro (void)
 
 
 
+static void DoMid (void)
+/* Handle .MID - this should never happen, since the keyword is actually
+ * handled on a much lower level of the expression hierarchy.
+ */
+{
+    Internal ("Unexpected token: .MID");
+}
+
+
+
 static void DoNull (void)
 /* Switch to the NULL segment */
 {
@@ -1119,6 +1129,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoMacPack       },
     { ccNone,          DoMacro         },
     { ccNone,                  DoUnexpected    },      /* .MATCH */
+    { ccNone,                  DoMid           },
     { ccNone,          DoNull          },
     { ccNone,          DoOrg           },
     { ccNone,          DoOut           },
index 8a2a376addbca768a213ad0e7f0d806171f4de9c..30ba6db7c914d5850b2b0987d7254bae7396afe2 100644 (file)
 #include "global.h"
 #include "incpath.h"
 #include "instr.h"
+#include "istack.h"
 #include "listing.h"
 #include "macro.h"
 #include "mem.h"
 #include "objfile.h"
+#include "toklist.h"
 #include "scanner.h"
 
 
@@ -104,10 +106,10 @@ static struct {
 static unsigned    FileCount = 0;
 
 /* Current input variables */
-static InputFile* IFile = 0;
-static InputData* IData = 0;
-static unsigned          ICount = 0;           /* Count of input files */
-static int       C = 0;
+static InputFile* IFile                = 0;    /* Current input file */
+static InputData* IData                = 0;    /* Current input memory data */
+static unsigned          ICount        = 0;    /* Count of input files */
+static int       C             = 0;    /* Current input character */
 
 /* Force end of assembly */
 int              ForcedEnd = 0;
@@ -121,7 +123,7 @@ struct DotKeyword {
     { "A8",            TOK_A8          },
     { "ADDR",          TOK_ADDR        },
     { "ALIGN",         TOK_ALIGN       },
-    { "AND",           TOK_BAND        },
+    { "AND",           TOK_BAND        },
     { "ASCIIZ",                TOK_ASCIIZ      },
     { "AUTOIMPORT",    TOK_AUTOIMPORT  },
     { "BITAND",                TOK_AND         },
@@ -131,15 +133,15 @@ struct DotKeyword {
     { "BLANK",         TOK_BLANK       },
     { "BSS",           TOK_BSS         },
     { "BYTE",          TOK_BYTE        },
-    { "CASE",          TOK_CASE        },
+    { "CASE",                  TOK_CASE        },
     { "CODE",          TOK_CODE        },
     { "CONST",                 TOK_CONST       },
-    { "CPU",           TOK_CPU         },
+    { "CPU",           TOK_CPU         },
     { "DATA",                  TOK_DATA        },
     { "DBYT",                  TOK_DBYT        },
     { "DEBUGINFO",     TOK_DEBUGINFO   },
     { "DEF",                   TOK_DEFINED     },
-    { "DEFINE",                TOK_DEFINE      },
+    { "DEFINE",                TOK_DEFINE      },
     { "DEFINED",       TOK_DEFINED     },
     { "DWORD",                 TOK_DWORD       },
     { "ELSE",                  TOK_ELSE        },
@@ -189,10 +191,11 @@ struct DotKeyword {
     { "MACPACK",       TOK_MACPACK     },
     { "MACRO",         TOK_MACRO       },
     { "MATCH",         TOK_MATCH       },
-    { "MOD",           TOK_MOD         },
-    { "NOT",           TOK_BNOT        },
+    { "MID",                   TOK_MID         },
+    { "MOD",           TOK_MOD         },
+    { "NOT",           TOK_BNOT        },
     { "NULL",          TOK_NULL        },
-    { "OR",            TOK_BOR         },
+    { "OR",            TOK_BOR         },
     { "ORG",           TOK_ORG         },
     { "OUT",           TOK_OUT         },
     { "P02",           TOK_P02         },
@@ -202,15 +205,15 @@ struct DotKeyword {
     { "PARAMCOUNT",    TOK_PARAMCOUNT  },
     { "PC02",          TOK_PC02        },
     { "PROC",          TOK_PROC        },
-    { "REF",           TOK_REFERENCED  },
+    { "REF",           TOK_REFERENCED  },
     { "REFERENCED",    TOK_REFERENCED  },
     { "RELOC",         TOK_RELOC       },
     { "REPEAT",                TOK_REPEAT      },
     { "RES",           TOK_RES         },
     { "RODATA",                TOK_RODATA      },
     { "SEGMENT",       TOK_SEGMENT     },
-    { "SHL",           TOK_SHL         },
-    { "SHR",           TOK_SHR         },
+    { "SHL",           TOK_SHL         },
+    { "SHR",           TOK_SHR         },
     { "SMART",         TOK_SMART       },
     { "STRING",                TOK_STRING      },
     { "SUNPLUS",       TOK_SUNPLUS     },
@@ -489,7 +492,7 @@ static void NextChar (void)
                /* End of file. Add an empty line to the listing. This is a
                 * small hack needed to keep the PC output in sync.
                 */
-               NewListingLine ("", IFile->Pos.Name, ICount);
+               NewListingLine ("", IFile->Pos.Name, ICount);
                C = EOF;
                return;
            }
@@ -627,7 +630,7 @@ static unsigned ReadStringConst (int StringTerm)
 
 
 
-void NextTok (void)
+void NextRawTok (void)
 /* Read the next raw token from the input stream */
 {
     /* If we've a forced end of assembly, don't read further */
@@ -636,8 +639,9 @@ void NextTok (void)
        return;
     }
 
-    /* If we're expanding a macro, the tokens come from the macro expansion */
-    if (MacExpand ()) {
+Restart:
+    /* Check if we have tokens from another input source */
+    if (InputFromStack ()) {
        return;
     }
 
@@ -813,9 +817,7 @@ Again:
                } else if (IsDefine (SVal)) {
            /* This is a define style macro - expand it */
            MacExpandStart ();
-           if (!MacExpand ()) {
-               goto Again;
-           }
+           goto Restart;
        } else {
            /* An identifier */
            Tok = TOK_IDENT;
@@ -894,8 +896,8 @@ CharAgain:
                    IVal = 0;
                    do {
                        ++IVal;
-                       NextChar ();
-                   } while (C == '+');
+                       NextChar ();
+                   } while (C == '+');
                    Tok = TOK_ULABEL;
                    break;
 
@@ -1029,8 +1031,8 @@ CharAgain:
                    /* Handle as white space */
                    NextChar ();
                    C = ' ';
-                   goto Again;
-               }
+                   goto Again;
+               }
            }
            break;
 
@@ -1042,6 +1044,8 @@ CharAgain:
         case EOF:
            /* Check if we have any open .IFs in this file */
            CheckOpenIfs ();
+           /* Check if we have any open token lists in this file */
+           CheckInputStack ();
 
            /* If this was an include file, then close it and handle like a
             * separator. Do not close the main file, but return EOF.
@@ -1065,68 +1069,6 @@ CharAgain:
 
 
 
-void Consume (enum Token Expected, unsigned ErrMsg)
-/* Consume Expected, print an error if we don't find it */
-{
-    if (Tok == Expected) {
-       NextTok ();
-    } else {
-       Error (ErrMsg);
-    }
-}
-
-
-
-void ConsumeSep (void)
-/* Consume a separator token */
-{
-    /* Accept an EOF as separator */
-    if (Tok != TOK_EOF) {
-       if (Tok != TOK_SEP) {
-           Error (ERR_TOO_MANY_CHARS);
-           SkipUntilSep ();
-       } else {
-           NextTok ();
-       }
-    }
-}
-
-
-
-void ConsumeLParen (void)
-/* Consume a left paren */
-{
-    Consume (TOK_LPAREN, ERR_LPAREN_EXPECTED);
-}
-
-
-
-void ConsumeRParen (void)
-/* Consume a right paren */
-{
-    Consume (TOK_RPAREN, ERR_RPAREN_EXPECTED);
-}
-
-
-
-void ConsumeComma (void)
-/* Consume a comma */
-{
-    Consume (TOK_COMMA, ERR_COMMA_EXPECTED);
-}
-
-
-
-void SkipUntilSep (void)
-/* Skip tokens until we reach a line separator */
-{
-    while (Tok != TOK_SEP && Tok != TOK_EOF) {
-       NextTok ();
-    }
-}
-
-
-
 int TokHasSVal (enum Token Tok)
 /* Return true if the given token has an attached SVal */
 {
index 813a54f767f0ef5320a46597c05daddaa36bbf88..7c1a424c2a0c13ff9e89fb990d2cc60e22eb38f0 100644 (file)
@@ -168,6 +168,7 @@ enum Token {
     TOK_MACPACK,
     TOK_MACRO,
     TOK_MATCH,
+    TOK_MID,
     TOK_NULL,
     TOK_ORG,
     TOK_OUT,
@@ -230,26 +231,8 @@ void NewInputData (const char* Data, int Malloced);
 void UpcaseSVal (void);
 /* Make SVal upper case */
 
-void NextTok (void);
-/* Read the next token from the input stream */
-
-void Consume (enum Token Expected, unsigned ErrMsg);
-/* Consume Token, print an error if we don't find it */
-
-void ConsumeSep (void);
-/* Consume a separator token */
-
-void ConsumeLParen (void);
-/* Consume a left paren */
-
-void ConsumeRParen (void);
-/* Consume a right paren */
-
-void ConsumeComma (void);
-/* Consume a comma */
-
-void SkipUntilSep (void);
-/* Skip tokens until we reach a line separator */
+void NextRawTok (void);
+/* Read the next raw token from the input stream */
 
 int TokHasSVal (enum Token Tok);
 /* Return true if the given token has an attached SVal */
diff --git a/src/ca65/toklist.c b/src/ca65/toklist.c
new file mode 100644 (file)
index 0000000..dc2712d
--- /dev/null
@@ -0,0 +1,185 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                toklist.c                                 */
+/*                                                                           */
+/*                 Token list for the ca65 macroassembler                   */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 1998     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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <string.h>
+
+#include "mem.h"
+#include "scanner.h"
+#include "toklist.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+TokNode* NewTokNode (void)
+/* Create and return a token node with the current token value */
+{
+    TokNode* T;
+
+    /* Allocate memory */
+    unsigned Len = TokHasSVal (Tok)? strlen (SVal) : 0;
+    T = Xmalloc (sizeof (TokNode) + Len);
+
+    /* Initialize the token contents */
+    T->Next    = 0;
+    T->Tok     = Tok;
+    T->WS      = WS;
+    T->IVal    = IVal;
+    memcpy (T->SVal, SVal, Len);
+    T->SVal [Len] = '\0';
+
+    /* Return the node */
+    return T;
+}
+
+
+
+void FreeTokNode (TokNode* T)
+/* Free the given token node */
+{
+    Xfree (T);
+}
+
+
+
+void TokSet (TokNode* T)
+/* Set the scanner token from the given token node */
+{
+    /* Set the values */
+    Tok  = T->Tok;
+    WS   = T->WS;
+    IVal = T->IVal;
+    strcpy (SVal, T->SVal);
+}
+
+
+
+enum TC TokCmp (const TokNode* T)
+/* Compare the token given as parameter against the current token */
+{
+    if (T->Tok != Tok) {
+       /* Different token */
+       return tcDifferent;
+    }
+
+    /* If the token has string attribute, check it */
+    if (TokHasSVal (T->Tok)) {
+       if (strcmp  (T->SVal, SVal) != 0) {
+           return tcSameToken;
+       }
+    } else if (TokHasIVal (T->Tok)) {
+       if (T->IVal != IVal) {
+           return tcSameToken;
+       }
+    }
+
+    /* Tokens are identical */
+    return tcIdentical;
+}
+
+
+
+void InitTokList (TokList* T)
+/* Initialize a token list structure for later use */
+{
+    /* Initialize the fields */
+    T->Next    = 0;
+    T->Root    = 0;
+    T->Last    = 0;
+    T->Repeat  = 1;
+    T->Count   = 0;
+}
+
+
+
+TokList* NewTokList (void)
+/* Create a new, empty token list */
+{
+    /* Allocate memory for the list structure */
+    TokList* T = Xmalloc (sizeof (TokList));
+
+    /* Initialize the fields */
+    InitTokList (T);
+
+    /* Return the new list */
+    return T;
+}
+
+
+
+void FreeTokList (TokList* List)
+/* Delete the token list including all token nodes */
+{
+    /* Free the token list */
+    TokNode* T = List->Root;
+    while (T) {
+       TokNode* Tmp = T;
+       T = T->Next;
+       FreeTokNode (Tmp);
+    }
+
+    /* Free the list structure itself */
+    Xfree (List);
+}
+
+
+
+void AddCurTok (TokList* List)
+/* Add the current token to the token list */
+{
+    /* Create a token node with the current token value */
+    TokNode* T = NewTokNode ();
+
+    /* Insert the node into the list */
+    if (List->Root == 0) {
+       List->Root = T;
+    } else {
+       List->Last->Next = T;
+    }
+    List->Last = T;
+
+    /* Count nodes */
+    List->Count++;
+}
+
+
+
+
+
+
diff --git a/src/ca65/toklist.h b/src/ca65/toklist.h
new file mode 100644 (file)
index 0000000..fb03513
--- /dev/null
@@ -0,0 +1,116 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                toklist.h                                 */
+/*                                                                           */
+/*                 Token list for the ca65 macroassembler                   */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (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 TOKLIST_H
+#define TOKLIST_H
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* 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 */
+};
+
+/* 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 */
+};
+
+
+
+/* Return codes for TokCmp - higher numeric code means better match */
+enum TC {
+    tcDifferent,                       /* Different tokents */
+    tcSameToken,                       /* Same token, different attribute */
+    tcIdentical                                /* Identical (token + attribute) */
+};
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+TokNode* NewTokNode (void);
+/* Create and return a token node with the current token value */
+
+void FreeTokNode (TokNode* T);
+/* Free the given token node */
+
+void TokSet (TokNode* T);
+/* Set the scanner token from the given token node */
+
+enum TC TokCmp (const TokNode* T);
+/* Compare the token given as parameter against the current token */
+
+void InitTokList (TokList* T);
+/* Initialize a token list structure for later use */
+
+TokList* NewTokList (void);
+/* Create a new, empty token list */
+
+void FreeTokList (TokList* T);
+/* Delete the token list including all token nodes */
+
+void AddCurTok (TokList* T);
+/* Add the current token to the token list */
+
+
+
+/* End of toklist.h */
+
+#endif
+
+
+
+
diff --git a/src/ca65/toknode.c b/src/ca65/toknode.c
deleted file mode 100644 (file)
index b1eeb8b..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*****************************************************************************/
-/*                                                                           */
-/*                                toknode.c                                 */
-/*                                                                           */
-/*               Token list node for the ca65 macroassembler                */
-/*                                                                           */
-/*                                                                           */
-/*                                                                           */
-/* (C) 1998     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.                                                          */
-/*                                                                           */
-/*****************************************************************************/
-
-
-
-#include <string.h>
-
-#include "mem.h"
-#include "scanner.h"
-#include "toknode.h"
-
-
-
-/*****************************************************************************/
-/*                                          Code                                    */
-/*****************************************************************************/
-
-
-
-TokNode* NewTokNode (void)
-/* Create and return a token node with the current token value */
-{
-    TokNode* T;
-
-    /* Allocate memory */
-    unsigned Len = TokHasSVal (Tok)? strlen (SVal) : 0;
-    T = Xmalloc (sizeof (TokNode) + Len);
-
-    /* Initialize the token contents */
-    T->Next    = 0;
-    T->Tok     = Tok;
-    T->WS      = WS;
-    T->IVal    = IVal;
-    memcpy (T->SVal, SVal, Len);
-    T->SVal [Len] = '\0';
-
-    /* Return the node */
-    return T;
-}
-
-
-
-void FreeTokNode (TokNode* T)
-/* Free the given token node */
-{
-    Xfree (T);
-}
-
-
-
-void TokSet (TokNode* T)
-/* Set the scanner token from the given token node */
-{
-    /* Set the values */
-    Tok  = T->Tok;
-    WS   = T->WS;
-    IVal = T->IVal;
-    strcpy (SVal, T->SVal);
-}
-
-
-
-enum TC TokCmp (const TokNode* T)
-/* Compare the token given as parameter against the current token */
-{
-    if (T->Tok != Tok) {
-       /* Different token */
-       return tcDifferent;
-    }
-     
-    /* If the token has string attribute, check it */
-    if (TokHasSVal (T->Tok)) {
-       if (strcmp  (T->SVal, SVal) != 0) {
-           return tcSameToken;
-       }
-    } else if (TokHasIVal (T->Tok)) {
-       if (T->IVal != IVal) {
-           return tcSameToken;
-       }
-    }
-        
-    /* Tokens are identical */
-    return tcIdentical;
-}
-
-
-
diff --git a/src/ca65/toknode.h b/src/ca65/toknode.h
deleted file mode 100644 (file)
index e3580e2..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*****************************************************************************/
-/*                                                                           */
-/*                                toknode.h                                 */
-/*                                                                           */
-/*               Token list node for the ca65 macroassembler                */
-/*                                                                           */
-/*                                                                           */
-/*                                                                           */
-/* (C) 1998     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 TOKNODE_H
-#define TOKNODE_H
-
-
-
-/*****************************************************************************/
-/*                                          Data                                    */
-/*****************************************************************************/
-
-
-
-/* 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 */
-};
-
-
-
-/* Return codes for TokCmp - higher numeric code means better match */
-enum TC {
-    tcDifferent,                       /* Different tokents */
-    tcSameToken,                       /* Same token, different attribute */
-    tcIdentical                                /* Identical (token + attribute) */
-};
-
-
-
-/*****************************************************************************/
-/*                                          Code                                    */
-/*****************************************************************************/
-
-
-
-TokNode* NewTokNode (void);
-/* Create and return a token node with the current token value */
-
-void FreeTokNode (TokNode* T);
-/* Free the given token node */
-
-void TokSet (TokNode* T);
-/* Set the scanner token from the given token node */
-
-enum TC TokCmp (const TokNode* T);
-/* Compare the token given as parameter against the current token */
-
-
-
-/* End of toknode.h */
-
-#endif
-
-
-
-