mirror of
https://github.com/cc65/cc65.git
synced 2025-02-27 14:29:52 +00:00
Use the new generic hash tables
git-svn-id: svn://svn.cc65.org/cc65/trunk@2561 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
ff2dca420b
commit
966dbc53d8
@ -55,17 +55,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned GenHash (const void* Index);
|
static unsigned HT_GenHash (const void* Key);
|
||||||
/* Generate the hash over an index. */
|
/* Generate the hash over a key. */
|
||||||
|
|
||||||
static const void* GetIndex (void* Entry);
|
static const void* HT_GetKey (void* Entry);
|
||||||
/* Given a pointer to the user entry data, return a pointer to the index */
|
/* Given a pointer to the user entry data, return a pointer to the key. */
|
||||||
|
|
||||||
static HashNode* GetHashNode (void* Entry);
|
static HashNode* HT_GetHashNode (void* Entry);
|
||||||
/* Given a pointer to the user entry data, return a pointer to the hash node */
|
/* Given a pointer to the user entry data, return a pointer to the hash node */
|
||||||
|
|
||||||
static int Compare (const void* Index1, const void* Index2);
|
static int HT_Compare (const void* Key1, const void* Key2);
|
||||||
/* Compare two indices for equality */
|
/* Compare two keys for equality */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ typedef struct FileEntry FileEntry;
|
|||||||
struct FileEntry {
|
struct FileEntry {
|
||||||
HashNode Node;
|
HashNode Node;
|
||||||
unsigned Name; /* File name */
|
unsigned Name; /* File name */
|
||||||
unsigned Index; /* Index of entry */
|
unsigned Index; /* Index of entry */
|
||||||
unsigned long Size; /* Size of file */
|
unsigned long Size; /* Size of file */
|
||||||
unsigned long MTime; /* Time of last modification */
|
unsigned long MTime; /* Time of last modification */
|
||||||
};
|
};
|
||||||
@ -94,10 +94,10 @@ static Collection FileTab = STATIC_COLLECTION_INITIALIZER;
|
|||||||
|
|
||||||
/* Hash table functions */
|
/* Hash table functions */
|
||||||
static const HashFunctions HashFunc = {
|
static const HashFunctions HashFunc = {
|
||||||
GenHash,
|
HT_GenHash,
|
||||||
GetIndex,
|
HT_GetKey,
|
||||||
GetHashNode,
|
HT_GetHashNode,
|
||||||
Compare
|
HT_Compare
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Hash table, hashed by name */
|
/* Hash table, hashed by name */
|
||||||
@ -111,15 +111,15 @@ static HashTable HashTab = STATIC_HASHTABLE_INITIALIZER (HASHTAB_COUNT, &HashFun
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static unsigned GenHash (const void* Index)
|
static unsigned HT_GenHash (const void* Key)
|
||||||
/* Generate the hash over an index. */
|
/* Generate the hash over a key. */
|
||||||
{
|
{
|
||||||
return (*(const unsigned*)Index & HASHTAB_MASK);
|
return (*(const unsigned*)Key & HASHTAB_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const void* GetIndex (void* Entry)
|
static const void* HT_GetKey (void* Entry)
|
||||||
/* Given a pointer to the user entry data, return a pointer to the index */
|
/* Given a pointer to the user entry data, return a pointer to the index */
|
||||||
{
|
{
|
||||||
return &((FileEntry*) Entry)->Name;
|
return &((FileEntry*) Entry)->Name;
|
||||||
@ -127,7 +127,7 @@ static const void* GetIndex (void* Entry)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static HashNode* GetHashNode (void* Entry)
|
static HashNode* HT_GetHashNode (void* Entry)
|
||||||
/* Given a pointer to the user entry data, return a pointer to the hash node */
|
/* Given a pointer to the user entry data, return a pointer to the hash node */
|
||||||
{
|
{
|
||||||
return &((FileEntry*) Entry)->Node;
|
return &((FileEntry*) Entry)->Node;
|
||||||
@ -135,10 +135,10 @@ static HashNode* GetHashNode (void* Entry)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int Compare (const void* Index1, const void* Index2)
|
static int HT_Compare (const void* Key1, const void* Key2)
|
||||||
/* Compare two indices for equality */
|
/* Compare two keys for equality */
|
||||||
{
|
{
|
||||||
return (*(const unsigned*)Index1 == *(const unsigned*)Index2);
|
return (*(const unsigned*)Key1 == *(const unsigned*)Key2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
143
src/ca65/macro.c
143
src/ca65/macro.c
@ -7,9 +7,9 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2003 Ullrich von Bassewitz */
|
/* (C) 1998-2003 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Römerstrasse 52 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@cc65.org */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@ -39,6 +39,7 @@
|
|||||||
/* common */
|
/* common */
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "hashstr.h"
|
#include "hashstr.h"
|
||||||
|
#include "hashtab.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
@ -53,6 +54,26 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* 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 for equality */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Data */
|
/* Data */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -60,18 +81,18 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Struct that describes an identifer (macro param, local list) */
|
/* Struct that describes an identifer (macro param, local list) */
|
||||||
typedef struct IdDesc_ IdDesc;
|
typedef struct IdDesc IdDesc;
|
||||||
struct IdDesc_ {
|
struct IdDesc {
|
||||||
IdDesc* Next; /* Linked list */
|
IdDesc* Next; /* Linked list */
|
||||||
char Id [1]; /* Identifier, dynamically allocated */
|
char Id [1]; /* Identifier, dynamically allocated */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Struct that describes a macro definition */
|
/* Struct that describes a macro definition */
|
||||||
typedef struct Macro_ Macro;
|
typedef struct Macro Macro;
|
||||||
struct Macro_ {
|
struct Macro {
|
||||||
Macro* Next; /* Next macro with same hash */
|
HashNode Node; /* Hash list node */
|
||||||
Macro* List; /* List of all macros */
|
Macro* List; /* List of all macros */
|
||||||
unsigned LocalCount; /* Count of local symbols */
|
unsigned LocalCount; /* Count of local symbols */
|
||||||
IdDesc* Locals; /* List of local symbols */
|
IdDesc* Locals; /* List of local symbols */
|
||||||
@ -84,25 +105,32 @@ struct Macro_ {
|
|||||||
char Name [1]; /* Macro name, dynamically allocated */
|
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 */
|
/* Macro hash table */
|
||||||
#define HASHTAB_SIZE 117
|
static HashTable MacroTab = STATIC_HASHTABLE_INITIALIZER (117, &HashFunc);
|
||||||
static Macro* MacroTab [HASHTAB_SIZE];
|
|
||||||
|
|
||||||
/* Global macro data */
|
/* Global macro data */
|
||||||
static Macro* MacroRoot = 0; /* List of all macros */
|
static Macro* MacroRoot = 0; /* List of all macros */
|
||||||
|
|
||||||
/* Structs that holds data for a macro expansion */
|
/* Structs that holds data for a macro expansion */
|
||||||
typedef struct MacExp_ MacExp;
|
typedef struct MacExp MacExp;
|
||||||
struct MacExp_ {
|
struct MacExp {
|
||||||
MacExp* Next; /* Pointer to next expansion */
|
MacExp* Next; /* Pointer to next expansion */
|
||||||
Macro* M; /* Which macro do we expand? */
|
Macro* M; /* Which macro do we expand? */
|
||||||
unsigned IfSP; /* .IF stack pointer at start of expansion */
|
unsigned IfSP; /* .IF stack pointer at start of expansion */
|
||||||
TokNode* Exp; /* Pointer to current token */
|
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 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** Params; /* List of actual parameters */
|
||||||
TokNode* ParamExp; /* Node for expanding parameters */
|
TokNode* ParamExp; /* Node for expanding parameters */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Number of active macro expansions */
|
/* Number of active macro expansions */
|
||||||
@ -116,6 +144,44 @@ 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 for equality */
|
||||||
|
{
|
||||||
|
return (strcmp (Key1, Key2) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* Code */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -140,7 +206,7 @@ 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 */
|
/* Generate a new macro entry, initialize and return it */
|
||||||
{
|
{
|
||||||
/* Allocate memory */
|
/* Allocate memory */
|
||||||
@ -148,6 +214,7 @@ static Macro* NewMacro (const char* Name, unsigned HashVal, unsigned char Style)
|
|||||||
Macro* M = xmalloc (sizeof (Macro) + Len);
|
Macro* M = xmalloc (sizeof (Macro) + Len);
|
||||||
|
|
||||||
/* Initialize the macro struct */
|
/* Initialize the macro struct */
|
||||||
|
InitHashNode (&M->Node, M);
|
||||||
M->LocalCount = 0;
|
M->LocalCount = 0;
|
||||||
M->Locals = 0;
|
M->Locals = 0;
|
||||||
M->ParamCount = 0;
|
M->ParamCount = 0;
|
||||||
@ -156,16 +223,14 @@ static Macro* NewMacro (const char* Name, unsigned HashVal, unsigned char Style)
|
|||||||
M->TokRoot = 0;
|
M->TokRoot = 0;
|
||||||
M->TokLast = 0;
|
M->TokLast = 0;
|
||||||
M->Style = Style;
|
M->Style = Style;
|
||||||
memcpy (M->Name, Name, Len);
|
memcpy (M->Name, Name, Len+1);
|
||||||
M->Name [Len] = '\0';
|
|
||||||
|
|
||||||
/* Insert the macro into the global macro list */
|
/* Insert the macro into the global macro list */
|
||||||
M->List = MacroRoot;
|
M->List = MacroRoot;
|
||||||
MacroRoot = M;
|
MacroRoot = M;
|
||||||
|
|
||||||
/* Insert the macro into the hash table */
|
/* Insert the macro into the hash table */
|
||||||
M->Next = MacroTab [HashVal];
|
HT_Insert (&MacroTab, &M->Node);
|
||||||
MacroTab [HashVal] = M;
|
|
||||||
|
|
||||||
/* Return the new macro struct */
|
/* Return the new macro struct */
|
||||||
return M;
|
return M;
|
||||||
@ -250,28 +315,11 @@ 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)
|
void MacDef (unsigned Style)
|
||||||
/* Parse a macro definition */
|
/* Parse a macro definition */
|
||||||
{
|
{
|
||||||
Macro* M;
|
Macro* M;
|
||||||
TokNode* T;
|
TokNode* T;
|
||||||
unsigned HashVal;
|
|
||||||
int HaveParams;
|
int HaveParams;
|
||||||
|
|
||||||
/* We expect a macro name here */
|
/* We expect a macro name here */
|
||||||
@ -281,11 +329,8 @@ void MacDef (unsigned Style)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate the hash value */
|
|
||||||
HashVal = HashStr (SVal) % HASHTAB_SIZE;
|
|
||||||
|
|
||||||
/* Did we already define that macro? */
|
/* Did we already define that macro? */
|
||||||
if (MacFind (SVal, HashVal) != 0) {
|
if (HT_Find (&MacroTab, SVal) != 0) {
|
||||||
/* Macro is already defined */
|
/* Macro is already defined */
|
||||||
Error (ERR_SYM_ALREADY_DEFINED, SVal);
|
Error (ERR_SYM_ALREADY_DEFINED, SVal);
|
||||||
/* Skip tokens until we reach the final .endmacro */
|
/* Skip tokens until we reach the final .endmacro */
|
||||||
@ -294,7 +339,7 @@ void MacDef (unsigned Style)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Define the macro */
|
/* Define the macro */
|
||||||
M = NewMacro (SVal, HashVal, Style);
|
M = NewMacro (SVal, Style);
|
||||||
|
|
||||||
/* Switch to raw token mode and skip the macro name */
|
/* Switch to raw token mode and skip the macro name */
|
||||||
EnterRawTokenMode ();
|
EnterRawTokenMode ();
|
||||||
@ -738,7 +783,7 @@ void MacExpandStart (void)
|
|||||||
/* Start expanding the macro in SVal */
|
/* Start expanding the macro in SVal */
|
||||||
{
|
{
|
||||||
/* Search for the macro */
|
/* Search for the macro */
|
||||||
Macro* M = MacFind (SVal, HashStr (SVal) % HASHTAB_SIZE);
|
Macro* M = HT_FindEntry (&MacroTab, SVal);
|
||||||
CHECK (M != 0);
|
CHECK (M != 0);
|
||||||
|
|
||||||
/* Call the apropriate subroutine */
|
/* Call the apropriate subroutine */
|
||||||
@ -766,7 +811,7 @@ void MacAbort (void)
|
|||||||
int IsMacro (const char* Name)
|
int IsMacro (const char* Name)
|
||||||
/* Return true if the given name is the name of a macro */
|
/* Return true if the given name is the name of a macro */
|
||||||
{
|
{
|
||||||
return MacFind (Name, HashStr (Name) % HASHTAB_SIZE) != 0;
|
return (HT_Find (&MacroTab, Name) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -774,7 +819,7 @@ int IsMacro (const char* Name)
|
|||||||
int IsDefine (const char* Name)
|
int IsDefine (const char* Name)
|
||||||
/* Return true if the given name is the name of a define style macro */
|
/* Return true if the given name is the name of a define style macro */
|
||||||
{
|
{
|
||||||
Macro* M = MacFind (Name, HashStr (Name) % HASHTAB_SIZE);
|
Macro* M = HT_FindEntry (&MacroTab, Name);
|
||||||
return (M != 0 && M->Style == MAC_STYLE_DEFINE);
|
return (M != 0 && M->Style == MAC_STYLE_DEFINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user