Add named variadic macro arguments

This commit is contained in:
drmortalwombat 2024-10-03 10:29:42 +02:00
parent 3ba7e0a8a4
commit e1f5bdf48b
2 changed files with 20 additions and 8 deletions

View File

@ -177,7 +177,7 @@ const char* TokenNames[] =
Macro::Macro(const Ident* ident, MacroDict * scope) Macro::Macro(const Ident* ident, MacroDict * scope)
: mIdent(ident), mString(nullptr), mNumArguments(-1), mScope(scope) : mIdent(ident), mString(nullptr), mNumArguments(-1), mScope(scope), mVariadic(false)
{ {
} }
@ -754,6 +754,12 @@ void Scanner::NextPreToken(void)
{ {
macro->AddArgument(mTokenIdent); macro->AddArgument(mTokenIdent);
NextRawToken(); NextRawToken();
if (mToken == TK_ELLIPSIS)
{
macro->mVariadic = true;
NextRawToken();
break;
}
} }
else else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid define argument"); mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid define argument");
@ -828,6 +834,7 @@ void Scanner::NextPreToken(void)
int i = 0; int i = 0;
while ((mTokenString[i] = def->mString[i])) while ((mTokenString[i] = def->mString[i]))
i++; i++;
mTokenStringSize = i;
return; return;
} }
else else
@ -1040,7 +1047,8 @@ void Scanner::NextPreToken(void)
int offset = mOffset; int offset = mOffset;
int level = 0; int level = 0;
bool quote = false; bool quote = false;
while (mLine[offset] && (quote || level > 0 || (mLine[offset] != ',' && mLine[offset] != ')')))
while (mLine[offset] && (quote || level > 0 || (!(!(def->mVariadic && i + 1 == def->mNumArguments) && mLine[offset] == ',') && mLine[offset] != ')')))
{ {
if (mLine[offset] == '"') if (mLine[offset] == '"')
{ {
@ -1060,10 +1068,13 @@ void Scanner::NextPreToken(void)
arg->SetString(mLine + mOffset, offset - mOffset); arg->SetString(mLine + mOffset, offset - mOffset);
mDefineArguments->Insert(arg); mDefineArguments->Insert(arg);
mOffset = offset; mOffset = offset;
if (i + 1 != def->mNumArguments) if (i + 1 != def->mNumArguments)
{ {
if (mLine[mOffset] == ',') if (mLine[mOffset] == ',')
mOffset++; mOffset++;
else if (def->mVariadic && i + 2 == def->mNumArguments && mLine[mOffset] == ')')
;
else else
mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid define expansion argument"); mErrors->Error(mLocation, EERR_INVALID_PREPROCESSOR, "Invalid define expansion argument");
} }
@ -1177,7 +1188,7 @@ void Scanner::NextSkipRawToken(void)
if (mTokenChar == '#') if (mTokenChar == '#')
{ {
if (mOffset == 1 || mStartOfLine) if (!(mAssemblerMode || mPrepCondFalse) || mOffset == 1 || mStartOfLine)
{ {
int n = 0; int n = 0;
char tkprep[128]; char tkprep[128];

View File

@ -190,11 +190,12 @@ public:
void SetString(const char* str, ptrdiff_t length); void SetString(const char* str, ptrdiff_t length);
void AddArgument(const Ident * ident); void AddArgument(const Ident * ident);
const Ident* mIdent; const Ident * mIdent;
const char* mString; const char * mString;
int mNumArguments; int mNumArguments;
const Ident * mArguments[32]; const Ident * mArguments[32];
MacroDict* mScope; MacroDict * mScope;
bool mVariadic;
}; };
typedef Macro* MacroPtr; typedef Macro* MacroPtr;