Improve cpp code generation

This commit is contained in:
drmortalwombat 2023-07-17 07:52:59 +02:00
parent 18c21b3fda
commit 9cdfad7d34
13 changed files with 331 additions and 23 deletions

View File

@ -44,6 +44,18 @@ string::string(const char * s)
cstr = nullptr;
}
string::string(const char * s, char size)
{
if (size)
{
cstr = malloc(char(size + 2));
cstr[0] = size;
smemcpy(cstr + 1, s, size + 1);
}
else
cstr = nullptr;
}
string::string(char c)
{
cstr = malloc(3);
@ -64,6 +76,11 @@ string::~string(void)
free(cstr);
}
void string::copyseg(char * p, char at, char num) const
{
smemcpy(p, cstr + 1 + at, num);
}
string & string::operator=(const string & s)
{
if (cstr != s.cstr)

View File

@ -10,6 +10,7 @@ public:
string(void);
string(const string & s);
string(const char * s);
string(const char * s, char size);
string(char c);
~string(void);
@ -61,6 +62,8 @@ public:
int find(const string & s, char pos) const;
int find(const char * s, char pos) const;
int find(char c, char pos) const;
void copyseg(char * p, char at, char num) const;
protected:
string(char l, char * b);
};

View File

@ -1238,6 +1238,31 @@ bool Declaration::IsSameParams(const Declaration* dec) const
return false;
}
bool Declaration::IsDerivedFrom(const Declaration* dec) const
{
if (mType != DT_TYPE_FUNCTION || dec->mType != DT_TYPE_FUNCTION)
return false;
if (!(mFlags & DTF_FUNC_THIS) || !(dec->mFlags & DTF_FUNC_THIS))
return false;
if (!mBase->IsSame(dec->mBase))
return false;
Declaration* dl = mParams->mNext, * dr = dec->mParams->mNext;
while (dl && dr)
{
if (!dl->mBase->IsSame(dr->mBase))
return false;
dl = dl->mNext;
dr = dr->mNext;
}
if (dl || dr)
return false;
return true;
}
bool Declaration::IsSame(const Declaration* dec) const
{
if (this == dec)

View File

@ -262,6 +262,7 @@ public:
bool CanAssign(const Declaration* fromType) const;
bool IsSame(const Declaration* dec) const;
bool IsDerivedFrom(const Declaration* dec) const;
bool IsSubType(const Declaration* dec) const;
bool IsConstSame(const Declaration* dec) const;
bool IsSameValue(const Declaration* dec) const;

View File

@ -284,7 +284,7 @@ void GlobalAnalyzer::MarkRecursions(void)
void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
{
if (!(procDec->mBase->mFlags & DTF_FASTCALL) && !(procDec->mBase->mFlags & DTF_STACKCALL) && (procDec->mType == DT_CONST_FUNCTION) && !(procDec->mFlags & DTF_FUNC_ANALYZING))
if (!(procDec->mBase->mFlags & DTF_FASTCALL) && (procDec->mType == DT_CONST_FUNCTION) && !(procDec->mFlags & DTF_FUNC_ANALYZING))
{
procDec->mFlags |= DTF_FUNC_ANALYZING;
int nbase = 0;

View File

@ -15331,7 +15331,7 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
mNativeProcedure(false), mLeafProcedure(false), mCallsFunctionPointer(false), mCalledFunctions(nullptr), mFastCallProcedure(false),
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), mDynamicStack(false),
mSaveTempsLinkerObject(nullptr), mValueReturn(false), mFramePointer(false),
mCheckUnreachable(true),
mCheckUnreachable(true), mReturnType(IT_NONE),
mDeclaration(nullptr)
{
mID = mModule->mProcedures.Size();

View File

@ -604,7 +604,7 @@ public:
LinkerObject * mLinkerObject, * mSaveTempsLinkerObject;
Declaration * mDeclaration;
InterType mReturnType;
uint64 mCompilerOptions;
InterCodeProcedure(InterCodeModule * module, const Location & location, const Ident * ident, LinkerObject* linkerObject);

View File

@ -4591,6 +4591,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
proc->mCompilerOptions = mCompilerOptions;
dec->mVarIndex = proc->mID;
dec->mLinkerObject = proc->mLinkerObject;
proc->mNumLocals = dec->mNumVars;
@ -4632,7 +4633,10 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
proc->mFastCallBase = BC_REG_FPARAMS_END - BC_REG_FPARAMS;
if (dec->mBase->mBase->mType != DT_TYPE_VOID && dec->mBase->mBase->mType != DT_TYPE_STRUCT)
{
proc->mValueReturn = true;
proc->mReturnType = InterTypeOf(dec->mBase->mBase);
}
InterCodeBasicBlock* entryBlock = new InterCodeBasicBlock(proc);

View File

@ -40370,7 +40370,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "test_find");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "getchar");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -40425,7 +40425,25 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
// Place a temporary RTS
mExitBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_RTS, ASMIM_IMPLIED, 0, nullptr, 0));
uint32 rflags = 0;
switch (proc->mReturnType)
{
case IT_BOOL:
case IT_INT8:
rflags = NCIF_LOWER;
break;
case IT_INT16:
case IT_POINTER:
rflags = NCIF_LOWER | NCIF_UPPER;
break;
case IT_INT32:
case IT_FLOAT:
rflags = NCIF_LOWER | NCIF_UPPER | NCIF_LONG;
break;
}
mExitBlock->mIns.Push(NativeCodeInstruction(nullptr, ASMIT_RTS, ASMIM_IMPLIED, 0, nullptr, rflags));
mEntryBlock->mTrueJump = CompileBlock(mInterProc, mInterProc->mBlocks[0]);
mEntryBlock->mBranch = ASMIT_JMP;
@ -40443,7 +40461,6 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
}
#endif
#if 1
if (mExitBlock->mIns[0].mFlags == NCIF_LOWER)
if (mExitBlock->mIns[0].mFlags == NCIF_LOWER)
{
mExitBlock->mIns[0].mFlags = 0;
@ -41021,6 +41038,8 @@ void NativeCodeProcedure::Optimize(void)
mEntryBlock->ReplaceFinalZeroPageUse(this);
}
#endif
int t = 0;
#if 1
do
@ -41029,8 +41048,8 @@ void NativeCodeProcedure::Optimize(void)
BuildDataFlowSets();
ResetVisited();
changed = mEntryBlock->RemoveUnusedResultInstructions();
changed = mEntryBlock->RemoveUnusedResultInstructions();
if (step == 0)
{
@ -41646,8 +41665,10 @@ void NativeCodeProcedure::Optimize(void)
else
cnt++;
} while (changed);
#if 1
ResetVisited();
mEntryBlock->ReduceLocalYPressure();

View File

@ -28,8 +28,52 @@ Parser::~Parser(void)
}
Declaration* Parser::FindBaseMemberFunction(Declaration* dec, Declaration* mdec)
{
const Ident* ident = mdec->mIdent;
if (ident->mString[0] == '~')
{
// this is the destructor, need special search
Declaration * pdec = dec;
Declaration * pmdec = nullptr;
while (pdec->mBase && !pmdec)
{
pdec = pdec->mBase->mBase;
pmdec = pdec->mScope->Lookup(pdec->mIdent->PreMangle("~"));
}
return pmdec;
}
else
{
Declaration * pdec = dec;
Declaration * pmdec = nullptr;
while (pdec->mBase && !pmdec)
{
pdec = pdec->mBase->mBase;
pmdec = pdec->mScope->Lookup(ident);
while (pmdec && !mdec->mBase->IsDerivedFrom(pmdec->mBase))
pmdec = pmdec->mNext;
if (pmdec)
return pmdec;
}
return pmdec;
}
}
void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
{
Declaration* pmdec = FindBaseMemberFunction(dec, mdec);
if (pmdec)
mdec->mBase->mFlags |= pmdec->mBase->mFlags & DTF_VIRTUAL;
Declaration* gdec = mCompilationUnits->mScope->Insert(mdec->mQualIdent, mdec);
if (gdec)
{
@ -50,6 +94,7 @@ void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
dec->mScope->Insert(mdec->mIdent, gdec);
if (dec->mConst)
dec->mConst->mScope->Insert(mdec->mIdent, gdec);
}
else
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
@ -341,7 +386,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
Declaration* vmpdec = nullptr;
while (vmdec && vmdec->mBase->IsSame(mdec->mBase))
while (vmdec && !mdec->mBase->IsDerivedFrom(vmdec->mBase))
{
vmpdec = vmdec;
vmdec = vmdec->mNext;
@ -3162,6 +3207,48 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
return cdec;
}
if ((mCompilerOptions & COPT_CPLUSPLUS) && pthis && mScanner->mToken == TK_OPERATOR)
{
mScanner->NextToken();
bdec = ParseBaseTypeDeclaration(typeFlags, false);
Declaration* ctdec = ParseFunctionDeclaration(bdec);
if (ctdec->mParams)
mErrors->Error(ctdec->mLocation, EERR_WRONG_PARAMETER, "Cast operators can't have parameter");
PrependThisArgument(ctdec, pthis);
Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
cdec->mBase = ctdec;
cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
ctdec->mFlags |= storageFlags & DTF_VIRTUAL;
cdec->mSection = mCodeSection;
cdec->mBase->mFlags |= typeFlags;
if (mCompilerOptions & COPT_NATIVE)
cdec->mFlags |= DTF_NATIVE;
cdec->mIdent = Ident::Unique("(cast)");
cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent);
if (mScanner->mToken == TK_OPEN_BRACE)
{
cdec->mCompilerOptions = mCompilerOptions;
cdec->mBase->mCompilerOptions = mCompilerOptions;
cdec->mVarIndex = -1;
cdec->mValue = ParseFunction(cdec->mBase);
cdec->mFlags |= DTF_DEFINED | DTF_REQUEST_INLINE;
cdec->mNumVars = mLocalIndex;
}
return cdec;
}
bdec = ParseBaseTypeDeclaration(typeFlags, false);
}
@ -3366,6 +3453,46 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
return bdec->mDestructor;
}
else if (ConsumeTokenIf(TK_OPERATOR))
{
Declaration* tdec = ParseBaseTypeDeclaration(0, true);
Declaration* ctdec = ParseFunctionDeclaration(tdec);
if (ctdec->mParams)
mErrors->Error(ctdec->mLocation, EERR_WRONG_PARAMETER, "Cast operators can't have parameter");
Declaration* bthis = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
bthis->mFlags |= DTF_CONST | DTF_DEFINED;
if (ConsumeTokenIf(TK_CONST))
bthis->mBase = bdec->ToConstType();
else
bthis->mBase = bdec;
bthis->mSize = 2;
PrependThisArgument(ctdec, bthis);
Declaration* fdec = bdec->mScope->Lookup(Ident::Unique("(cast)"));
while (fdec && !fdec->mBase->IsSame(ctdec))
fdec = fdec->mNext;
if (fdec)
{
fdec->mCompilerOptions = mCompilerOptions;
fdec->mBase->mCompilerOptions = mCompilerOptions;
fdec->mVarIndex = -1;
fdec->mValue = ParseFunction(fdec->mBase);
fdec->mFlags |= DTF_DEFINED;
fdec->mNumVars = mLocalIndex;
}
else
mErrors->Error(ctdec->mLocation, EERR_DUPLICATE_DEFINITION, "Cast operator not declared", tdec->mIdent);
return fdec;
}
}
}
@ -4536,7 +4663,10 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
int ncast = 0;
Declaration* ext = ex->mDecType;
while (ext && !ext->IsConstSame(ptype->mBase))
{
ncast++;
ext = ext->mBase;
}
if (ext)
{
@ -4548,12 +4678,19 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
else
return NOOVERLOAD;
}
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_ARRAY && ptype->mBase->IsSameMutable(etype->mBase))
else if (ptype->mType == DT_TYPE_POINTER && (etype->mType == DT_TYPE_ARRAY || etype->mType == DT_TYPE_POINTER) && ptype->mBase->IsSameMutable(etype->mBase))
dist += 1;
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_FUNCTION && ptype->mBase->IsSame(etype))
dist += 0;
else if (ptype->IsSubType(etype))
dist += 256;
else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->IsSame(etype))
{
if (ex->mType == EX_VARIABLE)
dist += 1;
else
return NOOVERLOAD;
}
else
return NOOVERLOAD;
@ -4574,6 +4711,41 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
return dist;
}
Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
{
Declaration* tdec = exp->mDecType;
while (tdec->mType == DT_TYPE_REFERENCE)
tdec = tdec->mBase;
if (tdec->mType == DT_TYPE_STRUCT)
{
Declaration* fexp = tdec->mScope->Lookup(Ident::Unique("(cast)"));
if (fexp)
{
while (fexp && !fexp->mBase->mBase->IsSame(type))
fexp = fexp->mNext;
if (fexp)
{
Expression* aexp = new Expression(exp->mLocation, EX_PREFIX);
aexp->mToken = TK_BINARY_AND;
aexp->mDecType = tdec->BuildPointer(exp->mLocation);
aexp->mLeft = exp;
Expression* nexp = new Expression(exp->mLocation, EX_CALL);
nexp->mLeft = new Expression(exp->mLocation, EX_CONSTANT);
nexp->mLeft->mDecType = fexp->mBase;
nexp->mLeft->mDecValue = fexp;
nexp->mRight = aexp;
return nexp;
}
}
}
return exp;
}
Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
{
if (exp->mType == EX_CALL && exp->mLeft->mDecValue)
@ -4647,7 +4819,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
nexp->mRight = ParseExpression(false);
ConsumeToken(TK_CLOSE_BRACKET);
if (exp->mDecType->mType == DT_TYPE_STRUCT)
if (exp->mDecType->mType == DT_TYPE_STRUCT || exp->mDecType->mType == DT_TYPE_REFERENCE && exp->mDecType->mBase->mType == DT_TYPE_STRUCT)
{
nexp = CheckOperatorOverload(nexp);
}
@ -4899,6 +5071,8 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
mScanner->NextToken();
nexp = ParsePrefixExpression(false);
nexp = nexp->LogicInvertExpression();
nexp = CheckOperatorOverload(nexp);
}
else if (mScanner->mToken == TK_INC || mScanner->mToken == TK_DEC)
{
@ -5403,9 +5577,9 @@ Expression* Parser::ParseLogicAndExpression(bool lhs)
{
Expression* nexp = new Expression(mScanner->mLocation, EX_LOGICAL_AND);
nexp->mToken = mScanner->mToken;
nexp->mLeft = exp;
nexp->mLeft = CoerceExpression(exp, TheBoolTypeDeclaration);
mScanner->NextToken();
nexp->mRight = ParseBinaryOrExpression(false);
nexp->mRight = CoerceExpression(ParseBinaryOrExpression(false), TheBoolTypeDeclaration);
nexp->mDecType = TheBoolTypeDeclaration;
exp = nexp->ConstantFold(mErrors);
}
@ -5421,9 +5595,9 @@ Expression* Parser::ParseLogicOrExpression(bool lhs)
{
Expression* nexp = new Expression(mScanner->mLocation, EX_LOGICAL_OR);
nexp->mToken = mScanner->mToken;
nexp->mLeft = exp;
nexp->mLeft = CoerceExpression(exp, TheBoolTypeDeclaration);
mScanner->NextToken();
nexp->mRight = ParseLogicAndExpression(false);
nexp->mRight = CoerceExpression(ParseLogicAndExpression(false), TheBoolTypeDeclaration);
nexp->mDecType = TheBoolTypeDeclaration;
exp = nexp->ConstantFold(mErrors);
}
@ -5438,7 +5612,7 @@ Expression* Parser::ParseConditionalExpression(bool lhs)
if (mScanner->mToken == TK_QUESTIONMARK)
{
Expression* nexp = new Expression(mScanner->mLocation, EX_CONDITIONAL);
nexp->mLeft = exp;
nexp->mLeft = CoerceExpression(exp, TheBoolTypeDeclaration);
mScanner->NextToken();
Expression* texp = new Expression(mScanner->mLocation, EX_SEQUENCE);
nexp->mRight = texp;
@ -5578,6 +5752,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
else if (exp->mType == EX_INDEX)
{
Declaration* tdec = exp->mLeft->mDecType;
while (tdec->mType == DT_TYPE_REFERENCE)
tdec = tdec->mBase;
if (tdec->mType == DT_TYPE_STRUCT)
{
const Ident* opident = Ident::Unique("operator[]");
@ -5599,7 +5776,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mLeft = exp->mLeft;
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
texp->mDecType->mBase = exp->mLeft->mDecType;
texp->mDecType->mBase = tdec;
texp->mDecType->mSize = 2;
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
@ -5851,6 +6028,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
if (opident)
{
Declaration* tdec = exp->mLeft->mDecType;
while (tdec->mType == DT_TYPE_REFERENCE)
tdec = tdec->mBase;
if (tdec->mType == DT_TYPE_STRUCT)
{
Declaration* mdec = tdec->mScope->Lookup(opident);
@ -5870,7 +6050,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
texp->mLeft = exp->mLeft;
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
texp->mDecType->mBase = exp->mLeft->mDecType;
texp->mDecType->mBase = tdec;
texp->mDecType->mSize = 2;
nexp->mRight = texp;
@ -5883,6 +6063,44 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
}
}
}
else if (exp->mType == EX_LOGICAL_NOT)
{
const Ident* opident = Ident::Unique("operator!");
Declaration* tdec = exp->mLeft->mDecType;
while (tdec->mType == DT_TYPE_REFERENCE)
tdec = tdec->mBase;
if (tdec->mType == DT_TYPE_STRUCT)
{
Declaration* mdec = tdec->mScope->Lookup(opident);
if (mdec)
{
Expression* nexp = new Expression(mScanner->mLocation, EX_CALL);
nexp->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
nexp->mLeft->mDecType = mdec->mBase;
nexp->mLeft->mDecValue = mdec;
nexp->mDecType = mdec->mBase;
nexp->mRight = exp->mRight;
Expression* texp = new Expression(nexp->mLocation, EX_PREFIX);
texp->mToken = TK_BINARY_AND;
texp->mLeft = exp->mLeft;
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
texp->mDecType->mBase = tdec;
texp->mDecType->mSize = 2;
nexp->mRight = texp;
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
exp = nexp;
}
}
}
}
return exp;
@ -6080,7 +6298,7 @@ Expression* Parser::ParseStatement(void)
case TK_IF:
mScanner->NextToken();
exp = new Expression(mScanner->mLocation, EX_IF);
exp->mLeft = CleanupExpression(ParseParenthesisExpression());
exp->mLeft = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration);
exp->mRight = new Expression(mScanner->mLocation, EX_ELSE);
exp->mRight->mLeft = ParseStatement();
if (mScanner->mToken == TK_ELSE)
@ -6099,7 +6317,7 @@ Expression* Parser::ParseStatement(void)
mScope = scope;
exp = new Expression(mScanner->mLocation, EX_WHILE);
exp->mLeft = CleanupExpression(ParseParenthesisExpression());
exp->mLeft = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration);
exp->mRight = ParseStatement();
mScope->End(mScanner->mLocation);
@ -6113,7 +6331,7 @@ Expression* Parser::ParseStatement(void)
if (mScanner->mToken == TK_WHILE)
{
mScanner->NextToken();
exp->mLeft = CleanupExpression(ParseParenthesisExpression());
exp->mLeft = CoerceExpression(CleanupExpression(ParseParenthesisExpression()), TheBoolTypeDeclaration);
ConsumeToken(TK_SEMICOLON);
}
else
@ -6147,7 +6365,7 @@ Expression* Parser::ParseStatement(void)
// Condition
if (mScanner->mToken != TK_SEMICOLON)
conditionExp = CleanupExpression(ParseExpression(false));
conditionExp = CoerceExpression(CleanupExpression(ParseExpression(false)), TheBoolTypeDeclaration);
if (mScanner->mToken == TK_SEMICOLON)
mScanner->NextToken();

View File

@ -50,6 +50,7 @@ protected:
void ParseVariableInit(Declaration* ndec);
void AddMemberFunction(Declaration* dec, Declaration* mdec);
Declaration* FindBaseMemberFunction(Declaration* dec, Declaration* mdec);
Expression * AddFunctionCallRefReturned(Expression * exp);
Expression* CleanupExpression(Expression* exp);
@ -88,6 +89,7 @@ protected:
int OverloadDistance(Declaration* pdec, Expression* pexp);
Expression * ResolveOverloadCall(Expression* exp, Expression * exp2 = nullptr);
Expression* CoerceExpression(Expression* exp, Declaration* type);
Expression* ParseSimpleExpression(bool lhs);
Expression* ParsePrefixExpression(bool lhs);

View File

@ -161,6 +161,7 @@ const char* TokenNames[] =
"'new'",
"'delete'",
"'virtual'",
"'operator'",
};
@ -321,6 +322,7 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
mDefines = new MacroDict();
mDefineArguments = nullptr;
mToken = TK_NONE;
mUngetToken = TK_NONE;
NextChar();
@ -873,7 +875,12 @@ void Scanner::NextToken(void)
void Scanner::NextRawToken(void)
{
if (mToken != TK_EOF)
if (mUngetToken)
{
mToken = mUngetToken;
mUngetToken = TK_NONE;
}
else if (mToken != TK_EOF)
{
mToken = TK_ERROR;
@ -1480,6 +1487,9 @@ void Scanner::NextRawToken(void)
case TK_BINARY_XOR:
mTokenIdent = Ident::Unique("operator^");
break;
case TK_LOGICAL_NOT:
mTokenIdent = Ident::Unique("operator!");
break;
case TK_LEFT_SHIFT:
mTokenIdent = Ident::Unique("operator<<");
@ -1522,7 +1532,11 @@ void Scanner::NextRawToken(void)
break;
default:
mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "Invalid operator token");
// dirty little hack to implement token preview, got to fix
// this with an infinit preview sequence at one point
mUngetToken = mToken;
mToken = TK_OPERATOR;
return;
}
mToken = TK_IDENT;

View File

@ -160,6 +160,7 @@ enum Token
TK_NEW,
TK_DELETE,
TK_VIRTUAL,
TK_OPERATOR,
NUM_TOKENS
};
@ -260,6 +261,8 @@ protected:
MacroDict* mDefines, * mDefineArguments;
Token mUngetToken;
void StringToken(char terminator, char mode);
void CharToken(char mode);
bool NextChar(void);