]> git.sur5r.net Git - cc65/commitdiff
First implementation of .UNDEF for deleting a macro.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 11 Jun 2011 22:18:48 +0000 (22:18 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 11 Jun 2011 22:18:48 +0000 (22:18 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@5049 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/macro.c
src/ca65/macro.h
src/ca65/pseudo.c
src/ca65/scanner.c
src/ca65/token.h

index 868b03f19cffedcf724b6a97232a3c6f4ae633ce..21db6e81ff4f5c73d8fdb8d9c42b93eafb08fb28 100644 (file)
@@ -106,9 +106,10 @@ struct Macro {
     unsigned       TokCount;   /* Number of tokens for this macro */
     TokNode*       TokRoot;    /* Root of token list */
     TokNode*       TokLast;    /* Pointer to last token in list */
+    StrBuf          Name;      /* Macro name, dynamically allocated */
+    unsigned        Expansions; /* Number of active macro expansions */
     unsigned char   Style;     /* Macro style */
     unsigned char   Incomplete; /* Macro is currently built */
-    StrBuf          Name;      /* Macro name, dynamically allocated */
 };
 
 /* Hash table functions */
@@ -122,9 +123,6 @@ static const HashFunctions HashFunc = {
 /* Macro hash table */
 static HashTable MacroTab = STATIC_HASHTABLE_INITIALIZER (117, &HashFunc);
 
-/* Global macro data */
-static Macro*          MacroRoot = 0;  /* List of all macros */
-
 /* Structs that holds data for a macro expansion */
 typedef struct MacExp MacExp;
 struct MacExp {
@@ -152,6 +150,9 @@ static int DoMacAbort = 0;
 /* Counter to create local names for symbols */
 static unsigned LocalName = 0;
 
+/* Define style macros disabled if != 0 */
+static unsigned DisableDefines = 0;
+
 
 
 /*****************************************************************************/
@@ -233,14 +234,11 @@ static Macro* NewMacro (const StrBuf* Name, unsigned char Style)
     M->TokCount          = 0;
     M->TokRoot    = 0;
     M->TokLast    = 0;
-    M->Style     = Style;
-    M->Incomplete = 1;
     SB_Init (&M->Name);
     SB_Copy (&M->Name, Name);
-
-    /* Insert the macro into the global macro list */
-    M->List = MacroRoot;
-    MacroRoot = M;
+    M->Expansions = 0;
+    M->Style     = Style;
+    M->Incomplete = 1;
 
     /* Insert the macro into the hash table */
     HT_Insert (&MacroTab, &M->Node);
@@ -268,12 +266,15 @@ static MacExp* NewMacExp (Macro* M)
     LocalName    += M->LocalCount;
     E->ParamCount = 0;
     E->Params     = xmalloc (M->ParamCount * sizeof (TokNode*));
-    E->ParamExp          = 0;
     for (I = 0; I < M->ParamCount; ++I) {
        E->Params[I] = 0;
     }
+    E->ParamExp          = 0;
     E->LISlot     = AllocLineInfoSlot (LI_TYPE_MACRO, MacExpansions);
 
+    /* Mark the macro as expanding */
+    ++M->Expansions;
+
     /* One macro expansion more */
     ++MacExpansions;
 
@@ -291,6 +292,9 @@ static void FreeMacExp (MacExp* E)
     /* One macro expansion less */
     --MacExpansions;
 
+    /* No longer expanding this macro */
+    --E->M->Expansions;
+
     /* Free the parameter lists */
     for (I = 0; I < E->ParamCount; ++I) {
         /* Free one parameter list */
@@ -321,18 +325,18 @@ static void MacSkipDef (unsigned Style)
 /* Skip a macro definition */
 {
     if (Style == MAC_STYLE_CLASSIC) {
-       /* Skip tokens until we reach the final .endmacro */
-       while (CurTok.Tok != TOK_ENDMACRO && CurTok.Tok != TOK_EOF) {
-           NextTok ();
-       }
-       if (CurTok.Tok != TOK_EOF) {
-           SkipUntilSep ();
-       } else {
-           Error ("`.ENDMACRO' expected");
-       }
+               /* Skip tokens until we reach the final .endmacro */
+               while (CurTok.Tok != TOK_ENDMACRO && CurTok.Tok != TOK_EOF) {
+                   NextTok ();
+               }
+               if (CurTok.Tok != TOK_EOF) {
+                   SkipUntilSep ();
+               } else {
+                   Error ("`.ENDMACRO' expected");
+               }
     } else {
-       /* Skip until end of line */
-       SkipUntilSep ();
+               /* Skip until end of line */
+               SkipUntilSep ();
     }
 }
 
@@ -451,7 +455,7 @@ void MacDef (unsigned Style)
                /* Done */
                break;
            }
-           /* May not have end of file in a macro definition */
+           /* May not have end of file in a macro definition */
            if (CurTok.Tok == TOK_EOF) {
                Error ("`.ENDMACRO' expected");
                goto Done;
@@ -485,7 +489,7 @@ void MacDef (unsigned Style)
                I->Next = M->Locals;
                M->Locals = I;
                ++M->LocalCount;
-               NextTok ();
+                       NextTok ();
 
                /* Check for end of list */
                if (CurTok.Tok != TOK_COMMA) {
@@ -548,6 +552,28 @@ Done:
 
 
 
+void MacUndef (const StrBuf* Name)
+/* Undefine the macro with the given name. */
+{
+    /* Search for the macro */
+    Macro* M = HT_FindEntry (&MacroTab, Name);
+
+    /* Don't let the user kid with us */
+    if (M == 0) {
+        Error ("No such macro: %m%p", Name);
+        return;
+    }
+    if (M->Expansions > 0) {
+        Error ("Cannot delete a macro that is currently expanded");
+        return;
+    }
+
+    /* Remove the macro from the macro table */
+    HT_RemoveEntry (&MacroTab, M);
+}
+
+
+
 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
@@ -678,19 +704,11 @@ MacEnd:
 
 
 
-static void StartExpClassic (Macro* M)
-/* Start expanding the classic macro M */
+static void StartExpClassic (MacExp* E)
+/* Start expanding a classic macro */
 {
-    MacExp*     E;
     token_t     Term;
 
-
-    /* Create a structure holding expansion data. This must be done before
-     * skipping the macro name, because the call to NextTok may cause a new
-     * expansion if the next token is actually a .define style macro.
-     */
-    E = NewMacExp (M);
-
     /* Skip the macro name */
     NextTok ();
 
@@ -700,10 +718,10 @@ static void StartExpClassic (Macro* M)
        TokNode* Last;
 
                /* Check for maximum parameter count */
-       if (E->ParamCount >= M->ParamCount) {
+       if (E->ParamCount >= E->M->ParamCount) {
                    ErrorSkip ("Too many macro parameters");
            break;
-       }
+       }
 
         /* The macro may optionally be enclosed in curly braces */
         Term = GetTokListTerm (TOK_COMMA);
@@ -730,7 +748,7 @@ static void StartExpClassic (Macro* M)
            } else {
                Last->Next = T;
            }
-           Last = T;
+                   Last = T;
 
            /* And skip it... */
            NextTok ();
@@ -752,8 +770,8 @@ static void StartExpClassic (Macro* M)
 
        /* Check for a comma */
        if (CurTok.Tok == TOK_COMMA) {
-           NextTok ();
-       } else {
+           NextTok ();
+       } else {
            break;
        }
     }
@@ -767,16 +785,13 @@ static void StartExpClassic (Macro* M)
 
 
 
-static void StartExpDefine (Macro* M)
+static void StartExpDefine (MacExp* E)
 /* Start expanding a DEFINE style macro */
 {
-    /* Create a structure holding expansion data */
-    MacExp* E = NewMacExp (M);
-
     /* A define style macro must be called with as many actual parameters
      * as there are formal ones. Get the parameter count.
      */
-    unsigned Count = M->ParamCount;
+    unsigned Count = E->M->ParamCount;
 
     /* Skip the current token */
     NextTok ();
@@ -813,13 +828,13 @@ static void StartExpDefine (Macro* M)
                    }
                    Last = T;
 
-           /* And skip it... */
-           NextTok ();
+           /* And skip it... */
+           NextTok ();
 
                } while (CurTok.Tok != Term && !TokIsSep (CurTok.Tok));
 
-       /* One parameter more */
-       ++E->ParamCount;
+       /* One parameter more */
+       ++E->ParamCount;
 
         /* If the macro argument was enclosed in curly braces, end-of-line
          * is an error. Skip the closing curly brace.
@@ -858,9 +873,11 @@ static void StartExpDefine (Macro* M)
 void MacExpandStart (void)
 /* Start expanding the macro in SVal */
 {
+    MacExp* E;
+
     /* Search for the macro */
     Macro* M = HT_FindEntry (&MacroTab, &CurTok.SVal);
-    CHECK (M != 0);
+    CHECK (M != 0 && (M->Style != MAC_STYLE_DEFINE || DisableDefines == 0));
 
     /* We cannot expand an incomplete macro */
     if (M->Incomplete) {
@@ -876,11 +893,14 @@ void MacExpandStart (void)
         return;
     }
 
+    /* Create a structure holding expansion data */
+    E = NewMacExp (M);
+
     /* 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);
+       case MAC_STYLE_CLASSIC: StartExpClassic (E);    break;
+       case MAC_STYLE_DEFINE:  StartExpDefine (E);     break;
+       default:                Internal ("Invalid macro style: %d", M->Style);
     }
 }
 
@@ -908,8 +928,16 @@ int IsMacro (const StrBuf* Name)
 
 int IsDefine (const StrBuf* Name)
 /* Return true if the given name is the name of a define style macro */
-{
-    Macro* M = HT_FindEntry (&MacroTab, Name);
+{   
+    Macro* M;
+
+    /* Never if disabled */
+    if (DisableDefines) {             
+        return 0;
+    }
+
+    /* Check if we have such a macro */
+    M = HT_FindEntry (&MacroTab, Name);
     return (M != 0 && M->Style == MAC_STYLE_DEFINE);
 }
 
@@ -923,4 +951,22 @@ int InMacExpansion (void)
 
 
 
+void DisableDefineStyleMacros (void)
+/* Disable define style macros until EnableDefineStyleMacros is called */
+{
+    ++DisableDefines;
+}
+
+
+
+void EnableDefineStyleMacros (void)
+/* Re-enable define style macros previously disabled with
+ * DisableDefineStyleMacros.
+ */
+{
+    PRECONDITION (DisableDefines > 0);
+    --DisableDefines;
+}
+
+
 
index 045204a6e4feebe9581bb9dfea199ecd1f3aa93d..921b601dbd6c85cd0c540cb6434a381178c212a9 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2008 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                 Forwards                                  */
+/*****************************************************************************/
+
+
+
+struct StrBuf;
+
+
+
+/*****************************************************************************/
+/*                                  Data                                    */
 /*****************************************************************************/
 
 
 
 /* Macro styles */
-#define MAC_STYLE_CLASSIC      0
-#define MAC_STYLE_DEFINE       1
+#define MAC_STYLE_CLASSIC      0
+#define MAC_STYLE_DEFINE       1
 
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                          Code                                    */
 /*****************************************************************************/
 
 
@@ -59,6 +69,9 @@
 void MacDef (unsigned Style);
 /* Parse a macro definition */
 
+void MacUndef (const struct StrBuf* Name);
+/* Undefine the macro with the given name. */
+
 void MacExpandStart (void);
 /* Start expanding the macro in SVal */
 
@@ -74,6 +87,14 @@ int IsDefine (const StrBuf* Name);
 int InMacExpansion (void);
 /* Return true if we're currently expanding a macro */
 
+void DisableDefineStyleMacros (void);
+/* Disable define style macros until EnableDefineStyleMacros is called */
+
+void EnableDefineStyleMacros (void);
+/* Re-enable define style macros previously disabled with
+ * DisableDefineStyleMacros.
+ */
+
 
 
 /* End of macro.h */
index 4b81e7c627955de01f1c58bf6873384f018bd3b5..85891e471426cfdb291cf32b72e125723bf93fb8 100644 (file)
@@ -1778,6 +1778,29 @@ static void DoTag (void)
 
 
 
+static void DoUnDef (void)
+/* Undefine a macro */
+{                              
+    /* The function is called with the .UNDEF token in place, because we need
+     * to disable .define macro expansions before reading the next token. 
+     * Otherwise the name of the macro would be expanded, so we would never 
+     * see it.
+     */
+    DisableDefineStyleMacros ();
+    NextTok ();
+    EnableDefineStyleMacros ();
+
+    /* We expect an identifier */
+    if (CurTok.Tok != TOK_IDENT) {
+       ErrorSkip ("Identifier expected");
+    } else {
+        MacUndef (&CurTok.SVal);
+        NextTok ();
+    }
+}
+
+
+
 static void DoUnexpected (void)
 /* Got an unexpected keyword */
 {
@@ -1824,7 +1847,7 @@ static void DoZeropage (void)
 
 
 /*****************************************************************************/
-/*                               Table data                                 */
+/*                               Table data                                 */
 /*****************************************************************************/
 
 
@@ -1914,7 +1937,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccKeepToken,     DoConditionals  },      /* .IFP816 */
     { ccKeepToken,     DoConditionals  },      /* .IFPC02 */
     { ccKeepToken,     DoConditionals  },      /* .IFPSC02 */
-    { ccKeepToken,     DoConditionals  },      /* .IFREF */
+    { ccKeepToken,     DoConditionals  },      /* .IFREF */
     { ccNone,          DoImport        },
     { ccNone,          DoImportZP      },
     { ccNone,          DoIncBin        },
@@ -1936,7 +1959,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,                  DoInvalid       },      /* .MID */
     { ccNone,                  DoUnexpected    },      /* .MIN */
     { ccNone,          DoNull          },
-    { ccNone,          DoOrg           },
+    { ccNone,          DoOrg           },
     { ccNone,          DoOut           },
     { ccNone,          DoP02           },
     { ccNone,          DoP816          },
@@ -1970,10 +1993,11 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,           DoTag           },
     { ccNone,          DoUnexpected    },      /* .TCOUNT */
     { ccNone,                  DoUnexpected    },      /* .TIME */
+    { ccKeepToken,      DoUnDef         },
     { ccNone,           DoUnion         },
     { ccNone,           DoUnexpected    },      /* .VERSION */
     { ccNone,          DoWarning       },
-    { ccNone,          DoWord          },
+    { ccNone,          DoWord          },
     { ccNone,                  DoUnexpected    },      /* .XMATCH */
     { ccNone,          DoZeropage      },
 };
@@ -1981,7 +2005,7 @@ static CtrlDesc CtrlCmdTab [] = {
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                          Code                                    */
 /*****************************************************************************/
 
 
index a9fd7c2d9d8adb0ce05cfb8425f393163616b855..a49c8a2224ddd61147615060cc8fac96930d47db 100644 (file)
@@ -265,8 +265,8 @@ struct DotKeyword {
     { ".SEGMENT",      TOK_SEGMENT     },
     { ".SET",           TOK_SET         },
     { ".SETCPU",       TOK_SETCPU      },
-    { ".SHL",          TOK_SHL         },
-    { ".SHR",          TOK_SHR         },
+    { ".SHL",                  TOK_SHL         },
+    { ".SHR",                  TOK_SHR         },
     { ".SIZEOF",        TOK_SIZEOF      },
     { ".SMART",                TOK_SMART       },
     { ".SPRINTF",       TOK_SPRINTF     },
@@ -278,6 +278,8 @@ struct DotKeyword {
     { ".TAG",           TOK_TAG         },
     { ".TCOUNT",       TOK_TCOUNT      },
     { ".TIME",                 TOK_TIME        },
+    { ".UNDEF",         TOK_UNDEF       },
+    { ".UNDEFINE",      TOK_UNDEF       },
     { ".UNION",         TOK_UNION       },
     { ".VERSION",       TOK_VERSION     },
     { ".WARNING",      TOK_WARNING     },
index cbff651d891d3ec30be3f9741b593e44465fe512..a95edfb5257c155be87a89ae2b11d7316695e3d5 100644 (file)
@@ -247,6 +247,7 @@ typedef enum token_t {
     TOK_TAG,
     TOK_TCOUNT,
     TOK_TIME,
+    TOK_UNDEF,
     TOK_UNION,
     TOK_VERSION,
     TOK_WARNING,