Add tok_directive and support $ in identifiers

This commit is contained in:
Duncan Ogilvie 2025-09-10 03:12:30 +02:00
parent da57cd3059
commit da5f499ca4
3 changed files with 34 additions and 8 deletions

View File

@ -120,6 +120,22 @@ Lexer::Token Lexer::getToken(size_t & tokenLineIndex)
return getToken(tokenLineIndex); return getToken(tokenLineIndex);
} }
//directive
if (mLastChar == '#')
{
tokenLineIndex = mState.LineIndex - 1;
std::string directive;
while (true)
{
nextChar();
if (mLastChar == EOF || mLastChar == '\r' || mLastChar == '\n')
break;
directive += (char)mLastChar;
}
mState.Directive = directive;
return tok_directive;
}
//character literal //character literal
if(mLastChar == '\'') if(mLastChar == '\'')
{ {
@ -186,7 +202,7 @@ Lexer::Token Lexer::getToken(size_t & tokenLineIndex)
else else
return reportError(StringUtils::sprintf("invalid escape sequence \"\\%c\" in character literal", mLastChar)); return reportError(StringUtils::sprintf("invalid escape sequence \"\\%c\" in character literal", mLastChar));
} }
charLit += mLastChar; charLit += (char)mLastChar;
} }
} }
@ -258,19 +274,19 @@ Lexer::Token Lexer::getToken(size_t & tokenLineIndex)
} }
//identifier/keyword //identifier/keyword
if(isalpha(mLastChar) || mLastChar == '_' || (mLastChar == ':' && peekChar() == ':')) //[a-zA-Z_] if(isalpha(mLastChar) || mLastChar == '$' || mLastChar == '_' || (mLastChar == ':' && peekChar() == ':')) //[a-zA-Z$_]
{ {
tokenLineIndex = mState.LineIndex - 1; tokenLineIndex = mState.LineIndex - 1;
mState.IdentifierStr = mLastChar; mState.IdentifierStr = (char)mLastChar;
if (mLastChar == ':') //consume the '::' if (mLastChar == ':') //consume the '::'
{ {
mState.IdentifierStr += ':'; mState.IdentifierStr += ':';
nextChar(); nextChar();
} }
nextChar(); nextChar();
while(isalnum(mLastChar) || mLastChar == '_' || (mLastChar == ':' && peekChar() == ':')) //[0-9a-zA-Z_] while(isalnum(mLastChar) || mLastChar == '_' || mLastChar == '$' || (mLastChar == ':' && peekChar() == ':')) //[0-9a-zA-Z$_]
{ {
mState.IdentifierStr.push_back(mLastChar); mState.IdentifierStr.push_back((char)mLastChar);
if(mLastChar == ':') //consume the '::' if(mLastChar == ':') //consume the '::'
{ {
mState.IdentifierStr += ':'; mState.IdentifierStr += ':';
@ -310,10 +326,10 @@ Lexer::Token Lexer::getToken(size_t & tokenLineIndex)
if(isdigit(mLastChar)) //[0-9] if(isdigit(mLastChar)) //[0-9]
{ {
tokenLineIndex = mState.LineIndex - 1; tokenLineIndex = mState.LineIndex - 1;
mNumStr = mLastChar; mNumStr = (char)mLastChar;
while(isdigit(nextChar())) //[0-9]* while(isdigit(nextChar())) //[0-9]*
mNumStr += mLastChar; mNumStr += (char)mLastChar;
auto error = convertNumber(mNumStr.c_str(), mState.NumberVal, 10); auto error = convertNumber(mNumStr.c_str(), mState.NumberVal, 10);
if(error) if(error)
@ -478,6 +494,8 @@ std::string Lexer::TokString(const TokenState & ts)
s = ts.CharLit; s = ts.CharLit;
return StringUtils::sprintf("'%s'", StringUtils::Escape(s).c_str()); return StringUtils::sprintf("'%s'", StringUtils::Escape(s).c_str());
} }
case tok_directive:
return "#" + ts.Directive;
default: default:
{ {
auto found = mReverseTokenMap.find(ts.Token); auto found = mReverseTokenMap.find(ts.Token);

View File

@ -22,10 +22,11 @@ public:
#undef DEF_KEYWORD #undef DEF_KEYWORD
//others //others
tok_identifier, //[a-zA-Z_][a-zA-Z0-9_] tok_identifier, //[a-zA-Z$_][a-zA-Z0-9$_]
tok_number, //(0x[0-9a-fA-F]+)|([0-9]+) tok_number, //(0x[0-9a-fA-F]+)|([0-9]+)
tok_stringlit, //"([^\\"]|\\([\\"'?abfnrtv0]|x[0-9a-fA-f]{2}))*" tok_stringlit, //"([^\\"]|\\([\\"'?abfnrtv0]|x[0-9a-fA-f]{2}))*"
tok_charlit, //'([^\\]|\\([\\"'?abfnrtv0]|x[0-9a-fA-f]{2}))' tok_charlit, //'([^\\]|\\([\\"'?abfnrtv0]|x[0-9a-fA-f]{2}))'
tok_directive, //#([^\r\n]+)
//operators //operators
#define DEF_OP_TRIPLE(enumval, ch1, ch2, ch3) tok_##enumval, #define DEF_OP_TRIPLE(enumval, ch1, ch2, ch3) tok_##enumval,
@ -46,6 +47,7 @@ public:
std::string StringLit; //tok_stringlit std::string StringLit; //tok_stringlit
char CharLit = '\0'; //tok_charlit char CharLit = '\0'; //tok_charlit
std::string ErrorMessage; //tok_error std::string ErrorMessage; //tok_error
std::string Directive; //tok_directive
size_t CurLine = 0; size_t CurLine = 0;
size_t LineIndex = 0; size_t LineIndex = 0;
@ -68,6 +70,7 @@ public:
StringLit.clear(); StringLit.clear();
CharLit = '\0'; CharLit = '\0';
ErrorMessage.clear(); ErrorMessage.clear();
Directive.clear();
} }
void Throw(const std::string& reason) const void Throw(const std::string& reason) const

View File

@ -474,6 +474,11 @@ std::string preprocess(const std::string& input, std::string& error, const std::
//printf("#pragma once"); //printf("#pragma once");
// TODO: implement something? // TODO: implement something?
} }
else if (type == "pack")
{
if (emitting())
final.push_back(line);
}
else else
{ {
t.error("unsupported #pragma type '" + type + "'"); t.error("unsupported #pragma type '" + type + "'");