mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Use hashmap system for charmap
This commit is contained in:
1
Makefile
1
Makefile
@@ -69,6 +69,7 @@ rgbasm_obj := \
|
|||||||
src/extern/err.o \
|
src/extern/err.o \
|
||||||
src/extern/getopt.o \
|
src/extern/getopt.o \
|
||||||
src/extern/utf8decoder.o \
|
src/extern/utf8decoder.o \
|
||||||
|
src/hashmap.o \
|
||||||
src/linkdefs.o
|
src/linkdefs.o
|
||||||
|
|
||||||
src/asm/globlex.o src/asm/lexer.o src/asm/constexpr.o: src/asm/asmy.h
|
src/asm/globlex.o src/asm/lexer.o src/asm/constexpr.o: src/asm/asmy.h
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ struct Charmap {
|
|||||||
struct Charnode nodes[MAXCHARNODES]; /* first node is reserved for the
|
struct Charnode nodes[MAXCHARNODES]; /* first node is reserved for the
|
||||||
* root node in charmap.
|
* root node in charmap.
|
||||||
*/
|
*/
|
||||||
struct Charmap *next; /* next charmap in hash table bucket */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void charmap_InitMain(void);
|
void charmap_InitMain(void);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -19,6 +20,8 @@
|
|||||||
#include "asm/util.h"
|
#include "asm/util.h"
|
||||||
#include "asm/warning.h"
|
#include "asm/warning.h"
|
||||||
|
|
||||||
|
#include "hashmap.h"
|
||||||
|
|
||||||
#define CHARMAP_HASH_SIZE (1 << 9)
|
#define CHARMAP_HASH_SIZE (1 << 9)
|
||||||
|
|
||||||
struct CharmapStackEntry {
|
struct CharmapStackEntry {
|
||||||
@@ -26,26 +29,16 @@ struct CharmapStackEntry {
|
|||||||
struct CharmapStackEntry *next;
|
struct CharmapStackEntry *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct Charmap *tHashedCharmaps[CHARMAP_HASH_SIZE];
|
static HashMap charmaps;
|
||||||
|
|
||||||
static struct Charmap *mainCharmap;
|
static struct Charmap *mainCharmap;
|
||||||
static struct Charmap *currentCharmap;
|
static struct Charmap *currentCharmap;
|
||||||
|
|
||||||
struct CharmapStackEntry *charmapStack;
|
struct CharmapStackEntry *charmapStack;
|
||||||
|
|
||||||
static uint32_t charmap_CalcHash(const char *s)
|
static inline struct Charmap *charmap_Get(const char *name)
|
||||||
{
|
{
|
||||||
return calchash(s) % CHARMAP_HASH_SIZE;
|
return hash_GetElement(charmaps, name);
|
||||||
}
|
|
||||||
|
|
||||||
static struct Charmap **charmap_Get(const char *name)
|
|
||||||
{
|
|
||||||
struct Charmap **ppCharmap = &tHashedCharmaps[charmap_CalcHash(name)];
|
|
||||||
|
|
||||||
while (*ppCharmap != NULL && strcmp((*ppCharmap)->name, name))
|
|
||||||
ppCharmap = &(*ppCharmap)->next;
|
|
||||||
|
|
||||||
return ppCharmap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CopyNode(struct Charmap *dest,
|
static void CopyNode(struct Charmap *dest,
|
||||||
@@ -62,56 +55,54 @@ static void CopyNode(struct Charmap *dest,
|
|||||||
|
|
||||||
struct Charmap *charmap_New(const char *name, const char *baseName)
|
struct Charmap *charmap_New(const char *name, const char *baseName)
|
||||||
{
|
{
|
||||||
struct Charmap *pBase = NULL;
|
struct Charmap *base = NULL;
|
||||||
|
|
||||||
if (baseName != NULL) {
|
if (baseName != NULL) {
|
||||||
struct Charmap **ppBase = charmap_Get(baseName);
|
base = charmap_Get(baseName);
|
||||||
|
|
||||||
if (*ppBase == NULL)
|
if (base == NULL)
|
||||||
yyerror("Base charmap '%s' doesn't exist", baseName);
|
yyerror("Base charmap '%s' doesn't exist", baseName);
|
||||||
else
|
|
||||||
pBase = *ppBase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Charmap **ppCharmap = charmap_Get(name);
|
struct Charmap *charmap = charmap_Get(name);
|
||||||
|
|
||||||
if (*ppCharmap != NULL) {
|
if (charmap != NULL) {
|
||||||
yyerror("Charmap '%s' already exists", name);
|
yyerror("Charmap '%s' already exists", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ppCharmap = calloc(1, sizeof(struct Charmap));
|
charmap = malloc(sizeof(*charmap));
|
||||||
|
if (charmap == NULL)
|
||||||
|
fatalerror("Failed to create charmap: %s", strerror(errno));
|
||||||
|
|
||||||
if (*ppCharmap == NULL)
|
/* Init the new charmap's fields */
|
||||||
fatalerror("Not enough memory for charmap");
|
snprintf(charmap->name, sizeof(charmap->name), "%s", name);
|
||||||
|
if (base != NULL) {
|
||||||
struct Charmap *pCharmap = *ppCharmap;
|
charmap->charCount = base->charCount;
|
||||||
|
charmap->nodeCount = base->nodeCount;
|
||||||
snprintf(pCharmap->name, sizeof(pCharmap->name), "%s", name);
|
|
||||||
|
|
||||||
if (pBase != NULL) {
|
|
||||||
pCharmap->charCount = pBase->charCount;
|
|
||||||
pCharmap->nodeCount = pBase->nodeCount;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAXCHARNODES; i++)
|
for (int i = 0; i < MAXCHARNODES; i++)
|
||||||
CopyNode(pCharmap, pBase, i);
|
CopyNode(charmap, base, i);
|
||||||
|
} else {
|
||||||
|
charmap->charCount = 0;
|
||||||
|
charmap->nodeCount = 0;
|
||||||
|
memset(charmap->nodes, 0, sizeof(charmap->nodes));
|
||||||
}
|
}
|
||||||
|
|
||||||
currentCharmap = pCharmap;
|
hash_AddElement(charmaps, charmap->name, charmap);
|
||||||
|
currentCharmap = charmap;
|
||||||
|
|
||||||
return pCharmap;
|
return charmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void charmap_Set(const char *name)
|
void charmap_Set(const char *name)
|
||||||
{
|
{
|
||||||
struct Charmap **ppCharmap = charmap_Get(name);
|
struct Charmap *charmap = charmap_Get(name);
|
||||||
|
|
||||||
if (*ppCharmap == NULL) {
|
if (charmap == NULL)
|
||||||
yyerror("Charmap '%s' doesn't exist", name);
|
yyerror("Charmap '%s' doesn't exist", name);
|
||||||
return;
|
else
|
||||||
}
|
currentCharmap = charmap;
|
||||||
|
|
||||||
currentCharmap = *ppCharmap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void charmap_Push(void)
|
void charmap_Push(void)
|
||||||
|
|||||||
Reference in New Issue
Block a user