]> git.sur5r.net Git - cc65/blobdiff - src/ca65/macro.c
New module strstack
[cc65] / src / ca65 / macro.c
index 73d8a0018c69dd569de437762da40645124d3d9c..3b60297d09175250035155613819878474434a2e 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2000 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstraße 52                                              */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 #include <stdio.h>
 #include <string.h>
 
-#include "../common/hashstr.h"
+/* common */
+#include "check.h"
+#include "hashstr.h"
+#include "hashtab.h"
+#include "xmalloc.h"
 
-#include "mem.h"
+/* ca65 */
+#include "condasm.h"
 #include "error.h"
-#include "scanner.h"
-#include "toknode.h"
+#include "global.h"
+#include "istack.h"
+#include "nexttok.h"
 #include "pseudo.h"
+#include "toklist.h"
 #include "macro.h"
 
 
 
+/*****************************************************************************/
+/*                                 Forwards                                  */
+/*****************************************************************************/
+
+
+
+static unsigned HT_GenHash (const void* Key);
+/* Generate the hash over a key. */
+
+static const void* HT_GetKey (void* Entry);
+/* Given a pointer to the user entry data, return a pointer to the key */
+
+static HashNode* HT_GetHashNode (void* Entry);
+/* Given a pointer to the user entry data, return a pointer to the hash node */
+
+static int HT_Compare (const void* Key1, const void* Key2);
+/* Compare two keys. The function must return a value less than zero if
+ * Key1 is smaller than Key2, zero if both are equal, and a value greater
+ * than zero if Key1 is greater then Key2.
+ */
+
+
+
 /*****************************************************************************/
 /*                                          Data                                    */
 /*****************************************************************************/
 
 
 /* Struct that describes an identifer (macro param, local list) */
-typedef struct IdDesc_ IdDesc;
-struct IdDesc_ {
-    IdDesc*        Next;       /* Linked list */
+typedef struct IdDesc IdDesc;
+struct IdDesc {
+    IdDesc*        Next;       /* Linked list */
     char                   Id [1];     /* Identifier, dynamically allocated */
 };
 
 
 
 /* Struct that describes a macro definition */
-typedef struct Macro_ Macro;
-struct Macro_ {
-    Macro*                 Next;       /* Next macro with same hash */
+typedef struct Macro Macro;
+struct Macro {
+    HashNode        Node;       /* Hash list node */
     Macro*         List;       /* List of all macros */
     unsigned       LocalCount; /* Count of local symbols */
     IdDesc*        Locals;     /* List of local symbols */
@@ -78,31 +108,83 @@ struct Macro_ {
     char                   Name [1];   /* Macro name, dynamically allocated */
 };
 
+/* Hash table functions */
+static const HashFunctions HashFunc = {
+    HT_GenHash,
+    HT_GetKey,
+    HT_GetHashNode,
+    HT_Compare
+};
+
 /* Macro hash table */
-#define HASHTAB_SIZE           117
-static Macro*          MacroTab [HASHTAB_SIZE];
+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_ {
-    MacExp*    Next;           /* Pointer to next expansion */
-    Macro*     M;              /* Which macro do we expand? */
+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 */
+    TokNode*   Final;          /* Pointer to final token */
     unsigned    LocalStart;    /* Start of counter for local symbol names */
-    unsigned   ParamCount;     /* Number of actual parameters */
+    unsigned   ParamCount;     /* Number of actual parameters */
     TokNode**  Params;         /* List of actual parameters */
-    TokNode*   ParamExp;       /* Node for expanding parameters */
+    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;
+
+
+
+/*****************************************************************************/
+/*                           Hash table functions                            */
+/*****************************************************************************/
+
+
+
+static unsigned HT_GenHash (const void* Key)
+/* Generate the hash over a key. */
+{
+    return HashStr (Key);
+}
+
+
+
+static const void* HT_GetKey (void* Entry)
+/* Given a pointer to the user entry data, return a pointer to the index */
+{
+    return ((Macro*) Entry)->Name;
+}
+
+
+
+static HashNode* HT_GetHashNode (void* Entry)
+/* Given a pointer to the user entry data, return a pointer to the hash node */
+{
+    return &((Macro*) Entry)->Node;
+}
+
+
+
+static int HT_Compare (const void* Key1, const void* Key2)
+/* Compare two keys. The function must return a value less than zero if
+ * Key1 is smaller than Key2, zero if both are equal, and a value greater
+ * than zero if Key1 is greater then Key2.
+ */
+{
+    return strcmp (Key1, Key2);
+}
 
 
 
@@ -117,7 +199,7 @@ static IdDesc* NewIdDesc (const char* Id)
 {
     /* Allocate memory */
     unsigned Len = strlen (Id);
-    IdDesc* I = Xmalloc (sizeof (IdDesc) + Len);
+    IdDesc* I = xmalloc (sizeof (IdDesc) + Len);
 
     /* Initialize the struct */
     I->Next = 0;
@@ -130,31 +212,31 @@ static IdDesc* NewIdDesc (const char* Id)
 
 
 
-static Macro* NewMacro (const char* Name, unsigned HashVal, unsigned char Style)
+static Macro* NewMacro (const char* Name, unsigned char Style)
 /* Generate a new macro entry, initialize and return it */
 {
     /* Allocate memory */
     unsigned Len = strlen (Name);
-    Macro* M = Xmalloc (sizeof (Macro) + Len);
+    Macro* M = xmalloc (sizeof (Macro) + Len);
 
     /* Initialize the macro struct */
+    InitHashNode (&M->Node, M);
     M->LocalCount = 0;
+    M->Locals     = 0;
     M->ParamCount = 0;
     M->Params     = 0;
     M->TokCount          = 0;
     M->TokRoot    = 0;
     M->TokLast    = 0;
     M->Style     = Style;
-    memcpy (M->Name, Name, Len);
-    M->Name [Len] = '\0';
+    memcpy (M->Name, Name, Len+1);
 
     /* Insert the macro into the global macro list */
     M->List = MacroRoot;
     MacroRoot = M;
 
     /* Insert the macro into the hash table */
-    M->Next = MacroTab [HashVal];
-    MacroTab [HashVal] = M;
+    HT_Insert (&MacroTab, &M->Node);
 
     /* Return the new macro struct */
     return M;
@@ -168,61 +250,52 @@ static MacExp* NewMacExp (Macro* M)
     unsigned I;
 
     /* Allocate memory */
-    MacExp* E = Xmalloc (sizeof (MacExp));
+    MacExp* E = xmalloc (sizeof (MacExp));
 
     /* Initialize the data */
     E->M                 = M;
+    E->IfSP      = GetIfStack ();
     E->Exp               = M->TokRoot;
     E->Final     = 0;
     E->LocalStart = LocalName;
     LocalName    += M->LocalCount;
     E->ParamCount = 0;
-    E->Params     = Xmalloc (M->ParamCount * sizeof (TokNode*));
+    E->Params     = xmalloc (M->ParamCount * sizeof (TokNode*));
     E->ParamExp          = 0;
     for (I = 0; I < M->ParamCount; ++I) {
        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);
+    xfree (E);
 }
 
 
@@ -238,7 +311,7 @@ static void MacSkipDef (unsigned Style)
        if (Tok != TOK_EOF) {
            SkipUntilSep ();
        } else {
-           Error (ERR_ENDMACRO_EXPECTED);
+           Error ("`.ENDMACRO' expected");
        }
     } else {
        /* Skip until end of line */
@@ -248,51 +321,34 @@ static void MacSkipDef (unsigned Style)
 
 
 
-static Macro* MacFind (const char* Name, unsigned HashVal)
-/* Search for a macro in the hash table */
-{
-    /* Search for the identifier */
-    Macro* M = MacroTab [HashVal];
-    while (M) {
-       if (strcmp (Name, M->Name) == 0) {
-           return M;
-       }
-       M = M->Next;
-    }
-    return 0;
-}
-
-
-
 void MacDef (unsigned Style)
 /* Parse a macro definition */
 {
     Macro* M;
     TokNode* T;
-    unsigned HashVal;
     int HaveParams;
 
     /* We expect a macro name here */
     if (Tok != TOK_IDENT) {
-       Error (ERR_IDENT_EXPECTED);
+       Error ("Identifier expected");
        MacSkipDef (Style);
        return;
     }
 
-    /* Generate the hash value */
-    HashVal = HashStr (SVal) % HASHTAB_SIZE;
-
     /* Did we already define that macro? */
-    if (MacFind (SVal, HashVal) != 0) {
+    if (HT_Find (&MacroTab, SVal) != 0) {
                /* Macro is already defined */
-       Error (ERR_SYM_ALREADY_DEFINED, SVal);
+       Error ("A macro named `%s' is already defined", SVal);
        /* Skip tokens until we reach the final .endmacro */
        MacSkipDef (Style);
                return;
     }
 
     /* Define the macro */
-    M = NewMacro (SVal, HashVal, Style);
+    M = NewMacro (SVal, Style);
+
+    /* Switch to raw token mode and skip the macro name */
+    EnterRawTokenMode ();
     NextTok ();
 
     /* If we have a DEFINE style macro, we may have parameters in braces,
@@ -324,8 +380,8 @@ void MacDef (unsigned Style)
                IdDesc* List = M->Params;
                while (1) {
                    if (strcmp (List->Id, SVal) == 0) {
-                       Error (ERR_SYM_ALREADY_DEFINED, SVal);
-                   }
+                       Error ("Duplicate symbol `%s'", SVal);
+                   }                                 
                    if (List->Next == 0) {
                        break;
                    } else {
@@ -373,12 +429,12 @@ void MacDef (unsigned Style)
            }
            /* May not have end of file in a macro definition */
            if (Tok == TOK_EOF) {
-               Error (ERR_ENDMACRO_EXPECTED);
-               return;
+               Error ("`.ENDMACRO' expected");
+               goto Done;
            }
        } else {
            /* Accept a newline or end of file for new style macros */
-           if (Tok == TOK_SEP || Tok == TOK_EOF) {
+           if (TokIsSep (Tok)) {
                break;
            }
        }
@@ -390,12 +446,12 @@ void MacDef (unsigned Style)
 
                IdDesc* I;
 
-               /* Skip .local or comma */
+               /* Skip .local or comma */
                        NextTok ();
 
                /* Need an identifer */
                if (Tok != TOK_IDENT) {
-                   Error (ERR_IDENT_EXPECTED);
+                   Error ("Identifier expected");
                    SkipUntilSep ();
                    break;
                }
@@ -457,6 +513,133 @@ void MacDef (unsigned Style)
     if (Style == MAC_STYLE_CLASSIC) {
        NextTok ();
     }
+
+Done:
+    /* Switch out of raw token mode */
+    LeaveRawTokenMode ();
+}
+
+
+
+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. Be sure
+                     * to generate a local label name if the original name was
+                     * a local label, and also generate a name that cannot be
+                     * generated by a user.
+                     */
+                    unsigned PrefixLen = (I->Id[0] == LocalStart);
+                           sprintf (SVal, "%.*sLOCAL-MACRO-SYMBOL-%04X", PrefixLen,
+                             I->Id, 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;
 }
 
 
@@ -473,14 +656,14 @@ static void StartExpClassic (Macro* M)
     E = NewMacExp (M);
 
     /* Read the actual parameters */
-    while (Tok != TOK_SEP && Tok != TOK_EOF) {
+    while (!TokIsSep (Tok)) {
 
        TokNode* Last;
 
                /* Check for maximum parameter count */
        if (E->ParamCount >= M->ParamCount) {
-           Error (ERR_TOO_MANY_PARAMS);
-           SkipUntilSep ();
+           Error ("Too many macro parameters");
+           SkipUntilSep ();                    
            break;
        }
 
@@ -492,7 +675,7 @@ static void StartExpClassic (Macro* M)
 
            /* Check for end of file */
            if (Tok == TOK_EOF) {
-               Error (ERR_SYNTAX);
+               Error ("Unexpected end of file");
                return;
            }
 
@@ -522,8 +705,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");
 }
 
 
@@ -548,8 +731,8 @@ static void StartExpDefine (Macro* M)
                TokNode* Last;
 
                /* Check if there is really a parameter */
-               if (Tok == TOK_SEP || Tok == TOK_EOF || Tok == TOK_COMMA) {
-                   Error (ERR_MACRO_PARAM_EXPECTED);
+               if (TokIsSep (Tok) || Tok == TOK_COMMA) {
+                   Error ("Macro parameter expected");
                    SkipUntilSep ();
                    return;
                }
@@ -565,16 +748,16 @@ static void StartExpDefine (Macro* M)
 
                    /* Insert it into the list */
                    if (Last == 0) {
-                       E->Params [E->ParamCount] = T;
+                       E->Params [E->ParamCount] = T;
                    } else {
-                       Last->Next = T;
+                       Last->Next = T;
                    }
                    Last = T;
 
            /* And skip it... */
            NextTok ();
 
-       } while (Tok != TOK_COMMA && Tok != TOK_SEP && Tok != TOK_EOF);
+       } while (Tok != TOK_COMMA && !TokIsSep (Tok));
 
        /* One parameter more */
        ++E->ParamCount;
@@ -584,7 +767,7 @@ static void StartExpDefine (Macro* M)
                    if (Tok == TOK_COMMA) {
                        NextTok ();
                    } else {
-                       Error (ERR_COMMA_EXPECTED);
+                       Error ("`,' expected");
                    }
                }
     }
@@ -596,8 +779,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 +788,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 = HT_FindEntry (&MacroTab, SVal);
     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 +806,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;
 }
 
 
@@ -742,7 +817,7 @@ void MacAbort (void)
 int IsMacro (const char* Name)
 /* Return true if the given name is the name of a macro */
 {
-    return MacFind (SVal, HashStr (SVal) % HASHTAB_SIZE) != 0;
+    return (HT_Find (&MacroTab, Name) != 0);
 }
 
 
@@ -750,7 +825,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 */
 {
-    Macro* M = MacFind (SVal, HashStr (SVal) % HASHTAB_SIZE);
+    Macro* M = HT_FindEntry (&MacroTab, Name);
     return (M != 0 && M->Style == MAC_STYLE_DEFINE);
 }
 
@@ -759,7 +834,7 @@ int IsDefine (const char* Name)
 int InMacExpansion (void)
 /* Return true if we're currently expanding a macro */
 {
-    return MacroNesting != 0;
+    return (MacExpansions > 0);
 }