mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
Use FileStackNode constructor to avoid std::monostate possibility
This commit is contained in:
@@ -16,21 +16,22 @@
|
|||||||
#include "asm/lexer.hpp"
|
#include "asm/lexer.hpp"
|
||||||
|
|
||||||
struct FileStackNode {
|
struct FileStackNode {
|
||||||
FileStackNode *parent; // Pointer to parent node, for error reporting
|
|
||||||
// Line at which the parent context was exited; meaningless for the root level
|
|
||||||
uint32_t lineNo;
|
|
||||||
|
|
||||||
bool referenced; // If referenced by a Symbol, Section, or Patch's `src`, don't `delete`!
|
|
||||||
uint32_t ID; // Set only if referenced: ID within the object file, -1 if not output yet
|
|
||||||
|
|
||||||
enum FileStackNodeType type;
|
enum FileStackNodeType type;
|
||||||
std::variant<
|
std::variant<
|
||||||
std::monostate, // Default constructed; `.type` and `.data` must be set manually
|
|
||||||
std::vector<uint32_t>, // NODE_REPT
|
std::vector<uint32_t>, // NODE_REPT
|
||||||
std::string // NODE_FILE, NODE_MACRO
|
std::string // NODE_FILE, NODE_MACRO
|
||||||
>
|
>
|
||||||
data;
|
data;
|
||||||
|
|
||||||
|
FileStackNode *parent; // Pointer to parent node, for error reporting
|
||||||
|
// Line at which the parent context was exited; meaningless for the root level
|
||||||
|
uint32_t lineNo;
|
||||||
|
|
||||||
|
// If referenced by a Symbol, Section, or Patch's `src`, don't `delete`!
|
||||||
|
bool referenced = false;
|
||||||
|
// Set only if referenced: ID within the object file, -1 if not output yet
|
||||||
|
uint32_t ID = -1;
|
||||||
|
|
||||||
// REPT iteration counts since last named node, in reverse depth order
|
// REPT iteration counts since last named node, in reverse depth order
|
||||||
std::vector<uint32_t> &iters();
|
std::vector<uint32_t> &iters();
|
||||||
std::vector<uint32_t> const &iters() const;
|
std::vector<uint32_t> const &iters() const;
|
||||||
@@ -38,6 +39,11 @@ struct FileStackNode {
|
|||||||
std::string &name();
|
std::string &name();
|
||||||
std::string const &name() const;
|
std::string const &name() const;
|
||||||
|
|
||||||
|
FileStackNode(
|
||||||
|
enum FileStackNodeType type_, std::variant<std::vector<uint32_t>, std::string> data_
|
||||||
|
)
|
||||||
|
: type(type_), data(data_) {};
|
||||||
|
|
||||||
void dump(uint32_t curLineNo) const;
|
void dump(uint32_t curLineNo) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,6 @@ extern bool disablePadding;
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
struct FileStackNode {
|
struct FileStackNode {
|
||||||
FileStackNode *parent;
|
|
||||||
// Line at which the parent context was exited; meaningless for the root level
|
|
||||||
uint32_t lineNo;
|
|
||||||
|
|
||||||
enum FileStackNodeType type;
|
enum FileStackNodeType type;
|
||||||
std::variant<
|
std::variant<
|
||||||
std::monostate, // Default constructed; `.type` and `.data` must be set manually
|
std::monostate, // Default constructed; `.type` and `.data` must be set manually
|
||||||
@@ -50,6 +46,10 @@ struct FileStackNode {
|
|||||||
>
|
>
|
||||||
data;
|
data;
|
||||||
|
|
||||||
|
FileStackNode *parent;
|
||||||
|
// Line at which the parent context was exited; meaningless for the root level
|
||||||
|
uint32_t lineNo;
|
||||||
|
|
||||||
// REPT iteration counts since last named node, in reverse depth order
|
// REPT iteration counts since last named node, in reverse depth order
|
||||||
std::vector<uint32_t> &iters();
|
std::vector<uint32_t> &iters();
|
||||||
std::vector<uint32_t> const &iters() const;
|
std::vector<uint32_t> const &iters() const;
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ struct Context {
|
|||||||
LexerState lexerState;
|
LexerState lexerState;
|
||||||
uint32_t uniqueID;
|
uint32_t uniqueID;
|
||||||
MacroArgs *macroArgs; // Macro args are *saved* here
|
MacroArgs *macroArgs; // Macro args are *saved* here
|
||||||
uint32_t nbReptIters;
|
uint32_t nbReptIters = 0;
|
||||||
bool isForLoop;
|
bool isForLoop = false;
|
||||||
int32_t forValue;
|
int32_t forValue = 0;
|
||||||
int32_t forStep;
|
int32_t forStep = 0;
|
||||||
std::string forName;
|
std::string forName;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -108,8 +108,8 @@ FileStackNode *fstk_GetFileStack() {
|
|||||||
|
|
||||||
// Mark node and all of its parents as referenced if not already so they don't get freed
|
// Mark node and all of its parents as referenced if not already so they don't get freed
|
||||||
for (FileStackNode *node = topNode; node && !node->referenced; node = node->parent) {
|
for (FileStackNode *node = topNode; node && !node->referenced; node = node->parent) {
|
||||||
node->ID = -1;
|
|
||||||
node->referenced = true;
|
node->referenced = true;
|
||||||
|
node->ID = -1;
|
||||||
}
|
}
|
||||||
return topNode;
|
return topNode;
|
||||||
}
|
}
|
||||||
@@ -200,6 +200,7 @@ bool yywrap() {
|
|||||||
fatalerror("Failed to duplicate REPT file node: %s\n", strerror(errno));
|
fatalerror("Failed to duplicate REPT file node: %s\n", strerror(errno));
|
||||||
// Copy all info but the referencing
|
// Copy all info but the referencing
|
||||||
context.fileInfo->referenced = false;
|
context.fileInfo->referenced = false;
|
||||||
|
context.fileInfo->ID = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32_t> &fileInfoIters = context.fileInfo->iters();
|
std::vector<uint32_t> &fileInfoIters = context.fileInfo->iters();
|
||||||
@@ -255,17 +256,11 @@ static Context &newContext(FileStackNode &fileInfo) {
|
|||||||
// Save the current `\@` value, to be restored when this context ends
|
// Save the current `\@` value, to be restored when this context ends
|
||||||
contextStack.top().uniqueID = macro_GetUniqueID();
|
contextStack.top().uniqueID = macro_GetUniqueID();
|
||||||
|
|
||||||
FileStackNode *parent = contextStack.top().fileInfo;
|
fileInfo.parent = contextStack.top().fileInfo;
|
||||||
|
|
||||||
fileInfo.parent = parent;
|
|
||||||
fileInfo.lineNo = lexer_GetLineNo();
|
fileInfo.lineNo = lexer_GetLineNo();
|
||||||
fileInfo.referenced = false;
|
|
||||||
|
|
||||||
Context &context = contextStack.emplace();
|
Context &context = contextStack.emplace();
|
||||||
|
|
||||||
context.fileInfo = &fileInfo;
|
context.fileInfo = &fileInfo;
|
||||||
context.isForLoop = false;
|
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,19 +278,16 @@ void fstk_RunInclude(char const *path) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStackNode *fileInfo = new (std::nothrow) FileStackNode();
|
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_FILE, *fullPath);
|
||||||
|
delete fullPath;
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
error("Failed to alloc file info for INCLUDE: %s\n", strerror(errno));
|
error("Failed to alloc file info for INCLUDE: %s\n", strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fileInfo->type = NODE_FILE;
|
|
||||||
fileInfo->data = *fullPath;
|
|
||||||
delete fullPath;
|
|
||||||
|
|
||||||
uint32_t uniqueID = contextStack.top().uniqueID;
|
uint32_t uniqueID = contextStack.top().uniqueID;
|
||||||
Context &context = newContext(*fileInfo);
|
|
||||||
|
|
||||||
|
Context &context = newContext(*fileInfo);
|
||||||
if (!lexer_OpenFile(context.lexerState, fileInfo->name().c_str()))
|
if (!lexer_OpenFile(context.lexerState, fileInfo->name().c_str()))
|
||||||
fatalerror("Failed to set up lexer for file include\n");
|
fatalerror("Failed to set up lexer for file include\n");
|
||||||
lexer_SetStateAtEOL(&context.lexerState);
|
lexer_SetStateAtEOL(&context.lexerState);
|
||||||
@@ -318,18 +310,14 @@ static void runPreIncludeFile() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileStackNode *fileInfo = new (std::nothrow) FileStackNode();
|
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_FILE, *fullPath);
|
||||||
|
delete fullPath;
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
error("Failed to alloc file info for pre-include: %s\n", strerror(errno));
|
error("Failed to alloc file info for pre-include: %s\n", strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fileInfo->type = NODE_FILE;
|
|
||||||
fileInfo->data = *fullPath;
|
|
||||||
delete fullPath;
|
|
||||||
|
|
||||||
Context &context = newContext(*fileInfo);
|
Context &context = newContext(*fileInfo);
|
||||||
|
|
||||||
if (!lexer_OpenFile(context.lexerState, fileInfo->name().c_str()))
|
if (!lexer_OpenFile(context.lexerState, fileInfo->name().c_str()))
|
||||||
fatalerror("Failed to set up lexer for file include\n");
|
fatalerror("Failed to set up lexer for file include\n");
|
||||||
lexer_SetState(&context.lexerState);
|
lexer_SetState(&context.lexerState);
|
||||||
@@ -350,18 +338,14 @@ void fstk_RunMacro(char const *macroName, MacroArgs &args) {
|
|||||||
}
|
}
|
||||||
contextStack.top().macroArgs = macro_GetCurrentArgs();
|
contextStack.top().macroArgs = macro_GetCurrentArgs();
|
||||||
|
|
||||||
FileStackNode *fileInfo = new (std::nothrow) FileStackNode();
|
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_MACRO, "");
|
||||||
|
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
error("Failed to alloc file info for \"%s\": %s\n", macro->name, strerror(errno));
|
error("Failed to alloc file info for \"%s\": %s\n", macro->name, strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fileInfo->type = NODE_MACRO;
|
|
||||||
fileInfo->data = "";
|
|
||||||
|
|
||||||
// Print the name...
|
// Print the name...
|
||||||
std::string &fileInfoName = fileInfo->name();
|
std::string &fileInfoName = fileInfo->name();
|
||||||
|
|
||||||
for (FileStackNode const *node = macro->src; node; node = node->parent) {
|
for (FileStackNode const *node = macro->src; node; node = node->parent) {
|
||||||
if (node->type != NODE_REPT) {
|
if (node->type != NODE_REPT) {
|
||||||
fileInfoName.append(node->name());
|
fileInfoName.append(node->name());
|
||||||
@@ -384,7 +368,6 @@ void fstk_RunMacro(char const *macroName, MacroArgs &args) {
|
|||||||
|
|
||||||
Context &context = newContext(*fileInfo);
|
Context &context = newContext(*fileInfo);
|
||||||
std::string_view *macroView = macro->getMacro();
|
std::string_view *macroView = macro->getMacro();
|
||||||
|
|
||||||
lexer_OpenFileView(
|
lexer_OpenFileView(
|
||||||
context.lexerState, "MACRO", macroView->data(), macroView->size(), macro->fileLine
|
context.lexerState, "MACRO", macroView->data(), macroView->size(), macro->fileLine
|
||||||
);
|
);
|
||||||
@@ -394,18 +377,14 @@ void fstk_RunMacro(char const *macroName, MacroArgs &args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool newReptContext(int32_t reptLineNo, char const *body, size_t size) {
|
static bool newReptContext(int32_t reptLineNo, char const *body, size_t size) {
|
||||||
uint32_t reptDepth = contextStack.top().fileInfo->type == NODE_REPT
|
FileStackNode *fileInfo = new (std::nothrow) FileStackNode(NODE_REPT, std::vector<uint32_t>{1});
|
||||||
? contextStack.top().fileInfo->iters().size()
|
|
||||||
: 0;
|
|
||||||
FileStackNode *fileInfo = new (std::nothrow) FileStackNode();
|
|
||||||
|
|
||||||
if (!fileInfo) {
|
if (!fileInfo) {
|
||||||
error("Failed to alloc file info for REPT: %s\n", strerror(errno));
|
error("Failed to alloc file info for REPT: %s\n", strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fileInfo->type = NODE_REPT;
|
|
||||||
fileInfo->data = std::vector<uint32_t>{1};
|
if (contextStack.top().fileInfo->type == NODE_REPT
|
||||||
if (reptDepth) {
|
&& !contextStack.top().fileInfo->iters().empty()) {
|
||||||
// Append all parent iter counts
|
// Append all parent iter counts
|
||||||
fileInfo->iters().insert(
|
fileInfo->iters().insert(
|
||||||
fileInfo->iters().end(), RANGE(contextStack.top().fileInfo->iters())
|
fileInfo->iters().end(), RANGE(contextStack.top().fileInfo->iters())
|
||||||
@@ -413,13 +392,12 @@ static bool newReptContext(int32_t reptLineNo, char const *body, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Context &context = newContext(*fileInfo);
|
Context &context = newContext(*fileInfo);
|
||||||
|
|
||||||
// Correct our line number, which currently points to the `ENDR` line
|
// Correct our line number, which currently points to the `ENDR` line
|
||||||
context.fileInfo->lineNo = reptLineNo;
|
context.fileInfo->lineNo = reptLineNo;
|
||||||
|
|
||||||
lexer_OpenFileView(context.lexerState, "REPT", body, size, reptLineNo);
|
lexer_OpenFileView(context.lexerState, "REPT", body, size, reptLineNo);
|
||||||
lexer_SetStateAtEOL(&context.lexerState);
|
lexer_SetStateAtEOL(&context.lexerState);
|
||||||
context.uniqueID = macro_UseNewUniqueID();
|
context.uniqueID = macro_UseNewUniqueID();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,28 +475,18 @@ void fstk_NewRecursionDepth(size_t newDepth) {
|
|||||||
|
|
||||||
void fstk_Init(char const *mainPath, size_t maxDepth) {
|
void fstk_Init(char const *mainPath, size_t maxDepth) {
|
||||||
Context &context = contextStack.emplace();
|
Context &context = contextStack.emplace();
|
||||||
|
|
||||||
if (!lexer_OpenFile(context.lexerState, mainPath))
|
if (!lexer_OpenFile(context.lexerState, mainPath))
|
||||||
fatalerror("Failed to open main file\n");
|
fatalerror("Failed to open main file\n");
|
||||||
lexer_SetState(&context.lexerState);
|
lexer_SetState(&context.lexerState);
|
||||||
|
|
||||||
FileStackNode *fileInfo = new (std::nothrow) FileStackNode();
|
context.fileInfo = new (std::nothrow) FileStackNode(NODE_FILE, lexer_GetFileName());
|
||||||
|
if (!context.fileInfo)
|
||||||
if (!fileInfo)
|
|
||||||
fatalerror("Failed to allocate memory for main file info: %s\n", strerror(errno));
|
fatalerror("Failed to allocate memory for main file info: %s\n", strerror(errno));
|
||||||
fileInfo->type = NODE_FILE;
|
|
||||||
fileInfo->data = lexer_GetFileName();
|
|
||||||
// lineNo and nbReptIters are unused on the top-level context
|
// lineNo and nbReptIters are unused on the top-level context
|
||||||
fileInfo->parent = nullptr;
|
context.fileInfo->parent = nullptr;
|
||||||
fileInfo->lineNo = 0; // This still gets written to the object file, so init it
|
context.fileInfo->lineNo = 0; // This still gets written to the object file, so init it
|
||||||
fileInfo->referenced = false;
|
|
||||||
|
|
||||||
context.fileInfo = fileInfo;
|
|
||||||
context.uniqueID = macro_UndefUniqueID();
|
context.uniqueID = macro_UndefUniqueID();
|
||||||
context.nbReptIters = 0;
|
|
||||||
context.forValue = 0;
|
|
||||||
context.forStep = 0;
|
|
||||||
context.isForLoop = false;
|
|
||||||
|
|
||||||
maxRecursionDepth = maxDepth;
|
maxRecursionDepth = maxDepth;
|
||||||
|
|
||||||
|
|||||||
@@ -503,10 +503,10 @@ void obj_ReadFile(char const *fileName, unsigned int fileID) {
|
|||||||
// Since SDCC does not provide line info, everything will be reported as coming from the
|
// Since SDCC does not provide line info, everything will be reported as coming from the
|
||||||
// object file. It's better than nothing.
|
// object file. It's better than nothing.
|
||||||
nodes[fileID].push_back({
|
nodes[fileID].push_back({
|
||||||
.parent = nullptr,
|
|
||||||
.lineNo = 0,
|
|
||||||
.type = NODE_FILE,
|
.type = NODE_FILE,
|
||||||
.data = fileName,
|
.data = fileName,
|
||||||
|
.parent = nullptr,
|
||||||
|
.lineNo = 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
std::vector<Symbol> &fileSymbols = symbolLists.emplace_front();
|
std::vector<Symbol> &fileSymbols = symbolLists.emplace_front();
|
||||||
|
|||||||
Reference in New Issue
Block a user