mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use std::stack for unions
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
#include <stack>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -28,8 +29,7 @@ uint8_t fillByte;
|
|||||||
struct UnionStackEntry {
|
struct UnionStackEntry {
|
||||||
uint32_t start;
|
uint32_t start;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
struct UnionStackEntry *next;
|
};
|
||||||
} *unionStack = NULL;
|
|
||||||
|
|
||||||
struct SectionStackEntry {
|
struct SectionStackEntry {
|
||||||
struct Section *section;
|
struct Section *section;
|
||||||
@@ -37,10 +37,11 @@ struct SectionStackEntry {
|
|||||||
char const *scope; // Section's symbol scope
|
char const *scope; // Section's symbol scope
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
int32_t loadOffset;
|
int32_t loadOffset;
|
||||||
struct UnionStackEntry *unionStack;
|
std::stack<struct UnionStackEntry> *unionStack;
|
||||||
struct SectionStackEntry *next;
|
struct SectionStackEntry *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::stack<struct UnionStackEntry> *currentUnionStack = NULL;
|
||||||
struct SectionStackEntry *sectionStack;
|
struct SectionStackEntry *sectionStack;
|
||||||
uint32_t curOffset; // Offset into the current section (see sect_GetSymbolOffset)
|
uint32_t curOffset; // Offset into the current section (see sect_GetSymbolOffset)
|
||||||
struct Section *currentSection = NULL;
|
struct Section *currentSection = NULL;
|
||||||
@@ -381,7 +382,7 @@ static struct Section *getSection(char const *name, enum SectionType type, uint3
|
|||||||
// Set the current section
|
// Set the current section
|
||||||
static void changeSection(void)
|
static void changeSection(void)
|
||||||
{
|
{
|
||||||
if (unionStack)
|
if (currentUnionStack && !currentUnionStack->empty())
|
||||||
fatalerror("Cannot change the section within a UNION\n");
|
fatalerror("Cannot change the section within a UNION\n");
|
||||||
|
|
||||||
sym_SetCurrentSymbolScope(NULL);
|
sym_SetCurrentSymbolScope(NULL);
|
||||||
@@ -574,28 +575,28 @@ void sect_StartUnion(void)
|
|||||||
error("Cannot use UNION inside of ROM0 or ROMX sections\n");
|
error("Cannot use UNION inside of ROM0 or ROMX sections\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct UnionStackEntry *entry = (struct UnionStackEntry *)malloc(sizeof(*entry));
|
|
||||||
|
|
||||||
if (!entry)
|
if (!currentUnionStack)
|
||||||
fatalerror("Failed to allocate new union stack entry: %s\n", strerror(errno));
|
currentUnionStack = new(std::nothrow) std::stack<struct UnionStackEntry>();
|
||||||
entry->start = curOffset;
|
if (!currentUnionStack)
|
||||||
entry->size = 0;
|
fatalerror("No memory for union stack: %s\n", strerror(errno));
|
||||||
entry->next = unionStack;
|
|
||||||
unionStack = entry;
|
currentUnionStack->push({ .start = curOffset, .size = 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
static void endUnionMember(void)
|
static void endUnionMember(void)
|
||||||
{
|
{
|
||||||
uint32_t memberSize = curOffset - unionStack->start;
|
struct UnionStackEntry &member = currentUnionStack->top();
|
||||||
|
uint32_t memberSize = curOffset - member.start;
|
||||||
|
|
||||||
if (memberSize > unionStack->size)
|
if (memberSize > member.size)
|
||||||
unionStack->size = memberSize;
|
member.size = memberSize;
|
||||||
curOffset = unionStack->start;
|
curOffset = member.start;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sect_NextUnionMember(void)
|
void sect_NextUnionMember(void)
|
||||||
{
|
{
|
||||||
if (!unionStack) {
|
if (!currentUnionStack || currentUnionStack->empty()) {
|
||||||
error("Found NEXTU outside of a UNION construct\n");
|
error("Found NEXTU outside of a UNION construct\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -604,22 +605,21 @@ void sect_NextUnionMember(void)
|
|||||||
|
|
||||||
void sect_EndUnion(void)
|
void sect_EndUnion(void)
|
||||||
{
|
{
|
||||||
if (!unionStack) {
|
if (!currentUnionStack || currentUnionStack->empty()) {
|
||||||
error("Found ENDU outside of a UNION construct\n");
|
error("Found ENDU outside of a UNION construct\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
endUnionMember();
|
endUnionMember();
|
||||||
curOffset += unionStack->size;
|
curOffset += currentUnionStack->top().size;
|
||||||
struct UnionStackEntry *next = unionStack->next;
|
currentUnionStack->pop();
|
||||||
|
|
||||||
free(unionStack);
|
|
||||||
unionStack = next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sect_CheckUnionClosed(void)
|
void sect_CheckUnionClosed(void)
|
||||||
{
|
{
|
||||||
if (unionStack)
|
if (currentUnionStack && !currentUnionStack->empty())
|
||||||
error("Unterminated UNION construct\n");
|
error("Unterminated UNION construct\n");
|
||||||
|
if (currentUnionStack)
|
||||||
|
delete currentUnionStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output an absolute byte
|
// Output an absolute byte
|
||||||
@@ -945,13 +945,13 @@ void sect_PushSection(void)
|
|||||||
struct SectionStackEntry *entry = (struct SectionStackEntry *)malloc(sizeof(*entry));
|
struct SectionStackEntry *entry = (struct SectionStackEntry *)malloc(sizeof(*entry));
|
||||||
|
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
fatalerror("No memory for section stack: %s\n", strerror(errno));
|
fatalerror("No memory for section stack: %s\n", strerror(errno));
|
||||||
entry->section = currentSection;
|
entry->section = currentSection;
|
||||||
entry->loadSection = currentLoadSection;
|
entry->loadSection = currentLoadSection;
|
||||||
entry->scope = sym_GetCurrentSymbolScope();
|
entry->scope = sym_GetCurrentSymbolScope();
|
||||||
entry->offset = curOffset;
|
entry->offset = curOffset;
|
||||||
entry->loadOffset = loadOffset;
|
entry->loadOffset = loadOffset;
|
||||||
entry->unionStack = unionStack;
|
entry->unionStack = currentUnionStack;
|
||||||
entry->next = sectionStack;
|
entry->next = sectionStack;
|
||||||
sectionStack = entry;
|
sectionStack = entry;
|
||||||
|
|
||||||
@@ -959,7 +959,7 @@ void sect_PushSection(void)
|
|||||||
currentSection = NULL;
|
currentSection = NULL;
|
||||||
currentLoadSection = NULL;
|
currentLoadSection = NULL;
|
||||||
sym_SetCurrentSymbolScope(NULL);
|
sym_SetCurrentSymbolScope(NULL);
|
||||||
unionStack = NULL;
|
currentUnionStack = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sect_PopSection(void)
|
void sect_PopSection(void)
|
||||||
@@ -978,7 +978,8 @@ void sect_PopSection(void)
|
|||||||
sym_SetCurrentSymbolScope(entry->scope);
|
sym_SetCurrentSymbolScope(entry->scope);
|
||||||
curOffset = entry->offset;
|
curOffset = entry->offset;
|
||||||
loadOffset = entry->loadOffset;
|
loadOffset = entry->loadOffset;
|
||||||
unionStack = entry->unionStack;
|
delete currentUnionStack;
|
||||||
|
currentUnionStack = entry->unionStack;
|
||||||
|
|
||||||
sectionStack = entry->next;
|
sectionStack = entry->next;
|
||||||
free(entry);
|
free(entry);
|
||||||
@@ -992,7 +993,7 @@ void sect_EndSection(void)
|
|||||||
if (currentLoadSection)
|
if (currentLoadSection)
|
||||||
fatalerror("Cannot end the section within a `LOAD` block\n");
|
fatalerror("Cannot end the section within a `LOAD` block\n");
|
||||||
|
|
||||||
if (unionStack)
|
if (currentUnionStack && !currentUnionStack->empty())
|
||||||
fatalerror("Cannot end the section within a UNION\n");
|
fatalerror("Cannot end the section within a UNION\n");
|
||||||
|
|
||||||
// Reset the section scope
|
// Reset the section scope
|
||||||
|
|||||||
Reference in New Issue
Block a user