Implement #line directive

This commit is contained in:
drmortalwombat 2023-10-14 15:19:24 +02:00
parent 9156db9c32
commit 4f76ffa311
5 changed files with 31 additions and 3 deletions

View File

@ -569,6 +569,17 @@ This sample generates an array with pointers to screen rows:
#for(i,SCREEN_HEIGHT) Screen + SCREEN_WIDTH * i, #for(i,SCREEN_HEIGHT) Screen + SCREEN_WIDTH * i,
}; };
The preprocessor keeps track of the source location while parsing a file to generate error messages and debug symbols. This is problematic for generated code, where the C source file position does not reflect the actual source position.
The source position can be set with the #line directiv
#line linenum
sets the line number
#line linenum "sourcefile"
sets the line number and source file name
### Linker control ### Linker control

View File

@ -608,6 +608,7 @@ bool SourceFile::Open(const char* name, const char* path, SourceFileMode mode)
*p = '/'; *p = '/';
p++; p++;
} }
strcpy_s(mLocationFileName, mFileName);
mMode = mode; mMode = mode;
mLimit = 0x10000; mLimit = 0x10000;
mFill = 0; mFill = 0;
@ -731,7 +732,7 @@ bool Preprocessor::EmbedData(const char* reason, const char* name, bool local, i
source->mUp = mSource; source->mUp = mSource;
mSource = source; mSource = source;
mLocation.mFileName = mSource->mFileName; mLocation.mFileName = mSource->mLocationFileName;
mLocation.mLine = 0; mLocation.mLine = 0;
mLine[0] = 0; mLine[0] = 0;
@ -791,7 +792,7 @@ bool Preprocessor::OpenSource(const char * reason, const char* name, bool local)
source->mUp = mSource; source->mUp = mSource;
mSource = source; mSource = source;
mLocation.mFileName = mSource->mFileName; mLocation.mFileName = mSource->mLocationFileName;
mLocation.mLine = 0; mLocation.mLine = 0;
mLine[0] = 0; mLine[0] = 0;

View File

@ -39,7 +39,7 @@ enum SourceFileDecoder
class SourceFile class SourceFile
{ {
public: public:
char mFileName[MAXPATHLEN]; char mFileName[MAXPATHLEN], mLocationFileName[MAXPATHLEN];
SourceFile * mUp, * mNext; SourceFile * mUp, * mNext;
Location mLocation; Location mLocation;

View File

@ -143,6 +143,7 @@ const char* TokenNames[] =
"'#ifdef'", "'#ifdef'",
"'#ifndef'", "'#ifndef'",
"'#pragma'", "'#pragma'",
"'#line'",
"'#assign'", "'#assign'",
"'#repeat'", "'#repeat'",
@ -597,6 +598,18 @@ void Scanner::NextPreToken(void)
mPreprocessor->CloseSource(); mPreprocessor->CloseSource();
} }
} }
else if (mToken == TK_PREP_LINE)
{
NextPreToken();
int l = mLocation.mLine;
int64 v = PrepParseConditional();
if (mLocation.mLine == l && mToken == TK_STRING)
{
strcpy_s(mPreprocessor->mSource->mLocationFileName, mTokenString);
NextRawToken();
}
mPreprocessor->mLocation.mLine = v - 1;
}
else if (mToken == TK_PREP_FOR) else if (mToken == TK_PREP_FOR)
{ {
NextRawToken(); NextRawToken();
@ -1384,6 +1397,8 @@ void Scanner::NextRawToken(void)
mToken = TK_PREP_ENDIF; mToken = TK_PREP_ENDIF;
else if (!strcmp(tkprep, "pragma")) else if (!strcmp(tkprep, "pragma"))
mToken = TK_PREP_PRAGMA; mToken = TK_PREP_PRAGMA;
else if (!strcmp(tkprep, "line"))
mToken = TK_PREP_LINE;
else if (!strcmp(tkprep, "assign")) else if (!strcmp(tkprep, "assign"))
mToken = TK_PREP_ASSIGN; mToken = TK_PREP_ASSIGN;
else if (!strcmp(tkprep, "repeat")) else if (!strcmp(tkprep, "repeat"))

View File

@ -141,6 +141,7 @@ enum Token
TK_PREP_IFDEF, TK_PREP_IFDEF,
TK_PREP_IFNDEF, TK_PREP_IFNDEF,
TK_PREP_PRAGMA, TK_PREP_PRAGMA,
TK_PREP_LINE,
TK_PREP_ASSIGN, TK_PREP_ASSIGN,
TK_PREP_REPEAT, TK_PREP_REPEAT,