mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Use std::stack for fstack contexts
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 <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -23,7 +24,6 @@
|
|||||||
#define MAXINCPATHS 128
|
#define MAXINCPATHS 128
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
struct Context *parent;
|
|
||||||
struct FileStackNode *fileInfo;
|
struct FileStackNode *fileInfo;
|
||||||
struct LexerState *lexerState;
|
struct LexerState *lexerState;
|
||||||
uint32_t uniqueID;
|
uint32_t uniqueID;
|
||||||
@@ -34,8 +34,7 @@ struct Context {
|
|||||||
char *forName;
|
char *forName;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct Context *contextStack;
|
static std::stack<struct Context> contextStack;
|
||||||
static size_t contextDepth = 0;
|
|
||||||
size_t maxRecursionDepth;
|
size_t maxRecursionDepth;
|
||||||
|
|
||||||
static unsigned int nbIncPaths = 0;
|
static unsigned int nbIncPaths = 0;
|
||||||
@@ -75,33 +74,32 @@ void fstk_Dump(struct FileStackNode const *node, uint32_t lineNo)
|
|||||||
|
|
||||||
void fstk_DumpCurrent(void)
|
void fstk_DumpCurrent(void)
|
||||||
{
|
{
|
||||||
if (!contextStack) {
|
if (contextStack.empty()) {
|
||||||
fputs("at top level", stderr);
|
fputs("at top level", stderr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fstk_Dump(contextStack->fileInfo, lexer_GetLineNo());
|
fstk_Dump(contextStack.top().fileInfo, lexer_GetLineNo());
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FileStackNode *fstk_GetFileStack(void)
|
struct FileStackNode *fstk_GetFileStack(void)
|
||||||
{
|
{
|
||||||
if (!contextStack)
|
if (contextStack.empty())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
struct FileStackNode *node = contextStack->fileInfo;
|
struct FileStackNode *topNode = contextStack.top().fileInfo;
|
||||||
|
|
||||||
// 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
|
||||||
while (node && !node->referenced) {
|
for (struct FileStackNode *node = topNode; node && !node->referenced; node = node->parent) {
|
||||||
node->ID = -1;
|
node->ID = -1;
|
||||||
node->referenced = true;
|
node->referenced = true;
|
||||||
node = node->parent;
|
|
||||||
}
|
}
|
||||||
return contextStack->fileInfo;
|
return topNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
char const *fstk_GetFileName(void)
|
char const *fstk_GetFileName(void)
|
||||||
{
|
{
|
||||||
// Iterating via the nodes themselves skips nested REPTs
|
// Iterating via the nodes themselves skips nested REPTs
|
||||||
struct FileStackNode const *node = contextStack->fileInfo;
|
struct FileStackNode const *node = contextStack.top().fileInfo;
|
||||||
|
|
||||||
while (node->type != NODE_FILE)
|
while (node->type != NODE_FILE)
|
||||||
node = node->parent;
|
node = node->parent;
|
||||||
@@ -195,12 +193,12 @@ bool yywrap(void)
|
|||||||
fatalerror("Ended block with %" PRIu32 " unterminated IF construct%s\n",
|
fatalerror("Ended block with %" PRIu32 " unterminated IF construct%s\n",
|
||||||
ifDepth, ifDepth == 1 ? "" : "s");
|
ifDepth, ifDepth == 1 ? "" : "s");
|
||||||
|
|
||||||
if (contextStack->fileInfo->type == NODE_REPT) {
|
if (struct Context &context = contextStack.top(); context.fileInfo->type == NODE_REPT) {
|
||||||
// The context is a REPT or FOR block, which may loop
|
// The context is a REPT or FOR block, which may loop
|
||||||
struct FileStackReptNode *fileInfo = (struct FileStackReptNode *)contextStack->fileInfo;
|
struct FileStackReptNode *fileInfo = (struct FileStackReptNode *)context.fileInfo;
|
||||||
|
|
||||||
// If the node is referenced, we can't edit it; duplicate it
|
// If the node is referenced, we can't edit it; duplicate it
|
||||||
if (contextStack->fileInfo->referenced) {
|
if (context.fileInfo->referenced) {
|
||||||
struct FileStackReptNode *copy = (struct FileStackReptNode *)malloc(sizeof(*copy));
|
struct FileStackReptNode *copy = (struct FileStackReptNode *)malloc(sizeof(*copy));
|
||||||
|
|
||||||
// Copy all info but the referencing
|
// Copy all info but the referencing
|
||||||
@@ -214,18 +212,15 @@ bool yywrap(void)
|
|||||||
copy->node.referenced = false;
|
copy->node.referenced = false;
|
||||||
|
|
||||||
fileInfo = copy;
|
fileInfo = copy;
|
||||||
contextStack->fileInfo = (struct FileStackNode *)fileInfo;
|
context.fileInfo = (struct FileStackNode *)fileInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a FOR, update the symbol value
|
// If this is a FOR, update the symbol value
|
||||||
if (contextStack->forName && fileInfo->iters->front() <= contextStack->nbReptIters) {
|
if (context.forName && fileInfo->iters->front() <= context.nbReptIters) {
|
||||||
// Avoid arithmetic overflow runtime error
|
// Avoid arithmetic overflow runtime error
|
||||||
uint32_t forValue = (uint32_t)contextStack->forValue +
|
uint32_t forValue = (uint32_t)context.forValue + (uint32_t)context.forStep;
|
||||||
(uint32_t)contextStack->forStep;
|
context.forValue = forValue <= INT32_MAX ? forValue : -(int32_t)~forValue - 1;
|
||||||
contextStack->forValue = forValue <= INT32_MAX ? forValue
|
struct Symbol *sym = sym_AddVar(context.forName, context.forValue);
|
||||||
: -(int32_t)~forValue - 1;
|
|
||||||
struct Symbol *sym = sym_AddVar(contextStack->forName,
|
|
||||||
contextStack->forValue);
|
|
||||||
|
|
||||||
// This error message will refer to the current iteration
|
// This error message will refer to the current iteration
|
||||||
if (sym->type != SYM_VAR)
|
if (sym->type != SYM_VAR)
|
||||||
@@ -234,72 +229,66 @@ bool yywrap(void)
|
|||||||
// Advance to the next iteration
|
// Advance to the next iteration
|
||||||
fileInfo->iters->front()++;
|
fileInfo->iters->front()++;
|
||||||
// If this wasn't the last iteration, wrap instead of popping
|
// If this wasn't the last iteration, wrap instead of popping
|
||||||
if (fileInfo->iters->front() <= contextStack->nbReptIters) {
|
if (fileInfo->iters->front() <= context.nbReptIters) {
|
||||||
lexer_RestartRept(contextStack->fileInfo->lineNo);
|
lexer_RestartRept(context.fileInfo->lineNo);
|
||||||
contextStack->uniqueID = macro_UseNewUniqueID();
|
context.uniqueID = macro_UseNewUniqueID();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!contextStack->parent) {
|
} else if (contextStack.size() == 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Context *context = contextStack;
|
struct Context oldContext = contextStack.top();
|
||||||
|
|
||||||
contextStack = contextStack->parent;
|
contextStack.pop();
|
||||||
assert(contextDepth != 0); // This is never supposed to underflow
|
|
||||||
contextDepth--;
|
|
||||||
|
|
||||||
lexer_DeleteState(context->lexerState);
|
lexer_DeleteState(oldContext.lexerState);
|
||||||
// Restore args if a macro (not REPT) saved them
|
// Restore args if a macro (not REPT) saved them
|
||||||
if (context->fileInfo->type == NODE_MACRO) {
|
if (oldContext.fileInfo->type == NODE_MACRO) {
|
||||||
macro_FreeArgs(macro_GetCurrentArgs());
|
macro_FreeArgs(macro_GetCurrentArgs());
|
||||||
macro_UseNewArgs(contextStack->macroArgs);
|
macro_UseNewArgs(contextStack.top().macroArgs);
|
||||||
}
|
}
|
||||||
// Free the file stack node
|
// Free the file stack node
|
||||||
if (!context->fileInfo->referenced) {
|
if (!oldContext.fileInfo->referenced) {
|
||||||
if (context->fileInfo->type == NODE_REPT)
|
if (oldContext.fileInfo->type == NODE_REPT)
|
||||||
delete ((struct FileStackReptNode *)context->fileInfo)->iters;
|
delete ((struct FileStackReptNode *)oldContext.fileInfo)->iters;
|
||||||
else
|
else
|
||||||
delete ((struct FileStackNamedNode *)context->fileInfo)->name;
|
delete ((struct FileStackNamedNode *)oldContext.fileInfo)->name;
|
||||||
free(context->fileInfo);
|
free(oldContext.fileInfo);
|
||||||
}
|
}
|
||||||
// Free the FOR symbol name
|
// Free the FOR symbol name
|
||||||
free(context->forName);
|
free(oldContext.forName);
|
||||||
// Free the entry and make its parent the current entry
|
|
||||||
free(context);
|
|
||||||
|
|
||||||
lexer_SetState(contextStack->lexerState);
|
lexer_SetState(contextStack.top().lexerState);
|
||||||
macro_SetUniqueID(contextStack->uniqueID);
|
macro_SetUniqueID(contextStack.top().uniqueID);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure not to switch the lexer state before calling this, so the saved line no is correct.
|
// Make sure not to switch the lexer state before calling this, so the saved line no is correct.
|
||||||
// BE CAREFUL! This modifies the file stack directly, you should have set up the file info first.
|
// BE CAREFUL! This modifies the file stack directly, you should have set up the file info first.
|
||||||
// Callers should set contextStack->lexerState after this so it is not NULL.
|
// Callers should set `contextStack.top().lexerState` after this so it is not NULL.
|
||||||
static void newContext(struct FileStackNode *fileInfo)
|
static struct Context &newContext(struct FileStackNode *fileInfo)
|
||||||
{
|
{
|
||||||
++contextDepth;
|
if (contextStack.size() > maxRecursionDepth)
|
||||||
fstk_NewRecursionDepth(maxRecursionDepth); // Only checks if the max depth was exceeded
|
fatalerror("Recursion limit (%zu) exceeded\n", maxRecursionDepth);
|
||||||
|
|
||||||
// Save the current `\@` value, to be restored when this context ends
|
// Save the current `\@` value, to be restored when this context ends
|
||||||
contextStack->uniqueID = macro_GetUniqueID();
|
contextStack.top().uniqueID = macro_GetUniqueID();
|
||||||
|
|
||||||
struct Context *context = (struct Context *)malloc(sizeof(*context));
|
struct FileStackNode *parent = contextStack.top().fileInfo;
|
||||||
|
|
||||||
if (!context)
|
fileInfo->parent = parent;
|
||||||
fatalerror("Failed to allocate memory for new context: %s\n", strerror(errno));
|
|
||||||
fileInfo->parent = contextStack->fileInfo;
|
|
||||||
fileInfo->lineNo = 0; // Init to a default value, see struct definition for info
|
fileInfo->lineNo = 0; // Init to a default value, see struct definition for info
|
||||||
fileInfo->referenced = false;
|
fileInfo->referenced = false;
|
||||||
fileInfo->lineNo = lexer_GetLineNo();
|
fileInfo->lineNo = lexer_GetLineNo();
|
||||||
context->fileInfo = fileInfo;
|
|
||||||
context->forName = NULL;
|
|
||||||
|
|
||||||
// Link new entry to its parent so it's reachable later
|
struct Context &context = contextStack.emplace();
|
||||||
// ERRORS SHOULD NOT OCCUR AFTER THIS!
|
|
||||||
context->parent = contextStack;
|
context.fileInfo = fileInfo;
|
||||||
contextStack = context;
|
context.forName = NULL;
|
||||||
|
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fstk_RunInclude(char const *path)
|
void fstk_RunInclude(char const *path)
|
||||||
@@ -327,15 +316,17 @@ void fstk_RunInclude(char const *path)
|
|||||||
fileInfo->node.type = NODE_FILE;
|
fileInfo->node.type = NODE_FILE;
|
||||||
fileInfo->name = fullPath; // `fullPath` is already `new`-allocated, so just point to it
|
fileInfo->name = fullPath; // `fullPath` is already `new`-allocated, so just point to it
|
||||||
|
|
||||||
newContext((struct FileStackNode *)fileInfo);
|
uint32_t uniqueID = contextStack.top().uniqueID;
|
||||||
contextStack->lexerState = lexer_OpenFile(fileInfo->name->c_str());
|
struct Context &context = newContext((struct FileStackNode *)fileInfo);
|
||||||
if (!contextStack->lexerState)
|
|
||||||
|
context.lexerState = lexer_OpenFile(fileInfo->name->c_str());
|
||||||
|
if (!context.lexerState)
|
||||||
fatalerror("Failed to set up lexer for file include\n");
|
fatalerror("Failed to set up lexer for file include\n");
|
||||||
lexer_SetStateAtEOL(contextStack->lexerState);
|
lexer_SetStateAtEOL(context.lexerState);
|
||||||
// We're back at top-level, so most things are reset,
|
// We're back at top-level, so most things are reset,
|
||||||
// but not the unique ID, since INCLUDE may be inside a
|
// but not the unique ID, since INCLUDE may be inside a
|
||||||
// MACRO or REPT/FOR loop
|
// MACRO or REPT/FOR loop
|
||||||
contextStack->uniqueID = contextStack->parent->uniqueID;
|
context.uniqueID = uniqueID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similar to `fstk_RunInclude`, but not subject to `-MG`, and
|
// Similar to `fstk_RunInclude`, but not subject to `-MG`, and
|
||||||
@@ -361,13 +352,14 @@ static void runPreIncludeFile(void)
|
|||||||
fileInfo->node.type = NODE_FILE;
|
fileInfo->node.type = NODE_FILE;
|
||||||
fileInfo->name = fullPath; // `fullPath` is already `new`-allocated, so just point to it
|
fileInfo->name = fullPath; // `fullPath` is already `new`-allocated, so just point to it
|
||||||
|
|
||||||
newContext((struct FileStackNode *)fileInfo);
|
struct Context &context = newContext((struct FileStackNode *)fileInfo);
|
||||||
contextStack->lexerState = lexer_OpenFile(fileInfo->name->c_str());
|
|
||||||
if (!contextStack->lexerState)
|
context.lexerState = lexer_OpenFile(fileInfo->name->c_str());
|
||||||
|
if (!context.lexerState)
|
||||||
fatalerror("Failed to set up lexer for file include\n");
|
fatalerror("Failed to set up lexer for file include\n");
|
||||||
lexer_SetState(contextStack->lexerState);
|
lexer_SetState(context.lexerState);
|
||||||
// We're back at top-level, so most things are reset
|
// We're back at top-level, so most things are reset
|
||||||
contextStack->uniqueID = macro_UndefUniqueID();
|
context.uniqueID = macro_UndefUniqueID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void fstk_RunMacro(char const *macroName, struct MacroArgs *args)
|
void fstk_RunMacro(char const *macroName, struct MacroArgs *args)
|
||||||
@@ -382,7 +374,7 @@ void fstk_RunMacro(char const *macroName, struct MacroArgs *args)
|
|||||||
error("\"%s\" is not a macro\n", macroName);
|
error("\"%s\" is not a macro\n", macroName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
contextStack->macroArgs = macro_GetCurrentArgs();
|
contextStack.top().macroArgs = macro_GetCurrentArgs();
|
||||||
|
|
||||||
struct FileStackNamedNode *fileInfo = (struct FileStackNamedNode *)malloc(sizeof(*fileInfo));
|
struct FileStackNamedNode *fileInfo = (struct FileStackNamedNode *)malloc(sizeof(*fileInfo));
|
||||||
|
|
||||||
@@ -416,20 +408,20 @@ void fstk_RunMacro(char const *macroName, struct MacroArgs *args)
|
|||||||
fileInfo->name->append("::");
|
fileInfo->name->append("::");
|
||||||
fileInfo->name->append(macro->name);
|
fileInfo->name->append(macro->name);
|
||||||
|
|
||||||
newContext((struct FileStackNode *)fileInfo);
|
struct Context &context = newContext((struct FileStackNode *)fileInfo);
|
||||||
contextStack->lexerState = lexer_OpenFileView("MACRO", macro->macro.value, macro->macro.size,
|
context.lexerState = lexer_OpenFileView("MACRO", macro->macro.value, macro->macro.size,
|
||||||
macro->fileLine);
|
macro->fileLine);
|
||||||
if (!contextStack->lexerState)
|
if (!context.lexerState)
|
||||||
fatalerror("Failed to set up lexer for macro invocation\n");
|
fatalerror("Failed to set up lexer for macro invocation\n");
|
||||||
lexer_SetStateAtEOL(contextStack->lexerState);
|
lexer_SetStateAtEOL(context.lexerState);
|
||||||
contextStack->uniqueID = macro_UseNewUniqueID();
|
context.uniqueID = macro_UseNewUniqueID();
|
||||||
macro_UseNewArgs(args);
|
macro_UseNewArgs(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool newReptContext(int32_t reptLineNo, char *body, size_t size)
|
static bool newReptContext(int32_t reptLineNo, char *body, size_t size)
|
||||||
{
|
{
|
||||||
uint32_t reptDepth = contextStack->fileInfo->type == NODE_REPT
|
uint32_t reptDepth = contextStack.top().fileInfo->type == NODE_REPT
|
||||||
? ((struct FileStackReptNode *)contextStack->fileInfo)->iters->size()
|
? ((struct FileStackReptNode *)contextStack.top().fileInfo)->iters->size()
|
||||||
: 0;
|
: 0;
|
||||||
struct FileStackReptNode *fileInfo = (struct FileStackReptNode *)malloc(sizeof(*fileInfo));
|
struct FileStackReptNode *fileInfo = (struct FileStackReptNode *)malloc(sizeof(*fileInfo));
|
||||||
|
|
||||||
@@ -442,19 +434,20 @@ static bool newReptContext(int32_t reptLineNo, char *body, size_t size)
|
|||||||
fileInfo->node.type = NODE_REPT;
|
fileInfo->node.type = NODE_REPT;
|
||||||
if (reptDepth) {
|
if (reptDepth) {
|
||||||
// Copy all parent iter counts
|
// Copy all parent iter counts
|
||||||
*fileInfo->iters = *((struct FileStackReptNode *)contextStack->fileInfo)->iters;
|
*fileInfo->iters = *((struct FileStackReptNode *)contextStack.top().fileInfo)->iters;
|
||||||
}
|
}
|
||||||
fileInfo->iters->insert(fileInfo->iters->begin(), 1);
|
fileInfo->iters->insert(fileInfo->iters->begin(), 1);
|
||||||
|
|
||||||
newContext((struct FileStackNode *)fileInfo);
|
struct Context &context = newContext((struct FileStackNode *)fileInfo);
|
||||||
// Correct our line number, which currently points to the `ENDR` line
|
|
||||||
contextStack->fileInfo->lineNo = reptLineNo;
|
|
||||||
|
|
||||||
contextStack->lexerState = lexer_OpenFileView("REPT", body, size, reptLineNo);
|
// Correct our line number, which currently points to the `ENDR` line
|
||||||
if (!contextStack->lexerState)
|
context.fileInfo->lineNo = reptLineNo;
|
||||||
|
|
||||||
|
context.lexerState = lexer_OpenFileView("REPT", body, size, reptLineNo);
|
||||||
|
if (!context.lexerState)
|
||||||
fatalerror("Failed to set up lexer for REPT block\n");
|
fatalerror("Failed to set up lexer for REPT block\n");
|
||||||
lexer_SetStateAtEOL(contextStack->lexerState);
|
lexer_SetStateAtEOL(context.lexerState);
|
||||||
contextStack->uniqueID = macro_UseNewUniqueID();
|
context.uniqueID = macro_UseNewUniqueID();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,8 +458,8 @@ void fstk_RunRept(uint32_t count, int32_t reptLineNo, char *body, size_t size)
|
|||||||
if (!newReptContext(reptLineNo, body, size))
|
if (!newReptContext(reptLineNo, body, size))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
contextStack->nbReptIters = count;
|
contextStack.top().nbReptIters = count;
|
||||||
contextStack->forName = NULL;
|
contextStack.top().forName = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step,
|
void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step,
|
||||||
@@ -495,23 +488,25 @@ void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step,
|
|||||||
if (!newReptContext(reptLineNo, body, size))
|
if (!newReptContext(reptLineNo, body, size))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
contextStack->nbReptIters = count;
|
struct Context &context = contextStack.top();
|
||||||
contextStack->forValue = start;
|
|
||||||
contextStack->forStep = step;
|
context.nbReptIters = count;
|
||||||
contextStack->forName = strdup(symName);
|
context.forValue = start;
|
||||||
if (!contextStack->forName)
|
context.forStep = step;
|
||||||
|
context.forName = strdup(symName);
|
||||||
|
if (!context.forName)
|
||||||
fatalerror("Not enough memory for FOR symbol name: %s\n", strerror(errno));
|
fatalerror("Not enough memory for FOR symbol name: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void fstk_StopRept(void)
|
void fstk_StopRept(void)
|
||||||
{
|
{
|
||||||
// Prevent more iterations
|
// Prevent more iterations
|
||||||
contextStack->nbReptIters = 0;
|
contextStack.top().nbReptIters = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fstk_Break(void)
|
bool fstk_Break(void)
|
||||||
{
|
{
|
||||||
if (contextStack->fileInfo->type != NODE_REPT) {
|
if (contextStack.top().fileInfo->type != NODE_REPT) {
|
||||||
error("BREAK can only be used inside a REPT/FOR block\n");
|
error("BREAK can only be used inside a REPT/FOR block\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -522,7 +517,7 @@ bool fstk_Break(void)
|
|||||||
|
|
||||||
void fstk_NewRecursionDepth(size_t newDepth)
|
void fstk_NewRecursionDepth(size_t newDepth)
|
||||||
{
|
{
|
||||||
if (contextDepth > newDepth)
|
if (contextStack.size() > newDepth + 1)
|
||||||
fatalerror("Recursion limit (%zu) exceeded\n", newDepth);
|
fatalerror("Recursion limit (%zu) exceeded\n", newDepth);
|
||||||
maxRecursionDepth = newDepth;
|
maxRecursionDepth = newDepth;
|
||||||
}
|
}
|
||||||
@@ -535,33 +530,28 @@ void fstk_Init(char const *mainPath, size_t maxDepth)
|
|||||||
fatalerror("Failed to open main file\n");
|
fatalerror("Failed to open main file\n");
|
||||||
lexer_SetState(state);
|
lexer_SetState(state);
|
||||||
char const *fileName = lexer_GetFileName();
|
char const *fileName = lexer_GetFileName();
|
||||||
struct Context *context = (struct Context *)malloc(sizeof(*contextStack));
|
|
||||||
struct FileStackNamedNode *fileInfo = (struct FileStackNamedNode *)malloc(sizeof(*fileInfo));
|
struct FileStackNamedNode *fileInfo = (struct FileStackNamedNode *)malloc(sizeof(*fileInfo));
|
||||||
|
|
||||||
if (!context)
|
|
||||||
fatalerror("Failed to allocate memory for main context: %s\n", strerror(errno));
|
|
||||||
if (fileInfo)
|
if (fileInfo)
|
||||||
fileInfo->name = new(std::nothrow) std::string(fileName);
|
fileInfo->name = new(std::nothrow) std::string(fileName);
|
||||||
if (!fileInfo || !fileInfo->name)
|
if (!fileInfo || !fileInfo->name)
|
||||||
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));
|
||||||
|
|
||||||
context->fileInfo = (struct FileStackNode *)fileInfo;
|
struct Context &context = contextStack.emplace();
|
||||||
|
|
||||||
|
context.fileInfo = (struct FileStackNode *)fileInfo;
|
||||||
// lineNo and nbReptIters are unused on the top-level context
|
// lineNo and nbReptIters are unused on the top-level context
|
||||||
context->fileInfo->parent = NULL;
|
context.fileInfo->parent = NULL;
|
||||||
context->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
|
||||||
context->fileInfo->referenced = false;
|
context.fileInfo->referenced = false;
|
||||||
context->fileInfo->type = NODE_FILE;
|
context.fileInfo->type = NODE_FILE;
|
||||||
|
|
||||||
context->parent = NULL;
|
context.lexerState = state;
|
||||||
context->lexerState = state;
|
context.uniqueID = macro_UndefUniqueID();
|
||||||
context->uniqueID = macro_UndefUniqueID();
|
context.nbReptIters = 0;
|
||||||
context->nbReptIters = 0;
|
context.forValue = 0;
|
||||||
context->forValue = 0;
|
context.forStep = 0;
|
||||||
context->forStep = 0;
|
context.forName = NULL;
|
||||||
context->forName = NULL;
|
|
||||||
|
|
||||||
// Now that it's set up properly, register the context
|
|
||||||
contextStack = context;
|
|
||||||
|
|
||||||
maxRecursionDepth = maxDepth;
|
maxRecursionDepth = maxDepth;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user