Improve C++ compliance
This commit is contained in:
parent
c46870ec10
commit
b7630450f1
|
@ -51,6 +51,8 @@ enum DecType
|
|||
DT_NAMESPACE,
|
||||
DT_BASECLASS,
|
||||
|
||||
DT_TEMPLATE,
|
||||
|
||||
DT_VTABLE
|
||||
};
|
||||
|
||||
|
|
|
@ -545,6 +545,12 @@ int Emulator::Emulate(int startIP, int trace)
|
|||
mIP = mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1;
|
||||
mRegS += 2;
|
||||
}
|
||||
else if (mIP == 0xff81)
|
||||
{
|
||||
printf("------------------ CLEAR ---------------\n");
|
||||
mIP = mMemory[0x101 + mRegS] + 256 * mMemory[0x102 + mRegS] + 1;
|
||||
mRegS += 2;
|
||||
}
|
||||
|
||||
uint8 opcode = mMemory[mIP];
|
||||
AsmInsData d = DecInsData[opcode];
|
||||
|
|
|
@ -80,6 +80,7 @@ enum ErrorID
|
|||
EERR_INVALID_OPERATOR,
|
||||
EERR_MISSING_TEMP,
|
||||
EERR_NON_STATIC_MEMBER,
|
||||
EERR_TEMPLATE_PARAMS,
|
||||
|
||||
ERRR_STACK_OVERFLOW,
|
||||
ERRR_INVALID_NUMBER,
|
||||
|
|
|
@ -13420,6 +13420,18 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedPa
|
|||
sins->mSrc[0].mFinal = false;
|
||||
assert(nins->mSrc[0].mTemp >= 0);
|
||||
|
||||
// Propagate all loads to move temps
|
||||
|
||||
for (int t = j + 1; t < mInstructions.Size(); t++)
|
||||
{
|
||||
InterInstruction* ti = mInstructions[t];
|
||||
if (ti->mCode == IC_LOAD && SameMem(ti->mSrc[0], ins->mSrc[0]))
|
||||
{
|
||||
ti->mCode = IC_LOAD_TEMPORARY;
|
||||
ti->mSrc[0].mTemp = ins->mDst.mTemp;
|
||||
}
|
||||
}
|
||||
|
||||
// Move store behind loop
|
||||
tailBlock->mInstructions.Insert(0, sins);
|
||||
mInstructions.Remove(j);
|
||||
|
@ -16724,7 +16736,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "playSong");
|
||||
CheckFunc = !strcmp(mIdent->mString, "MenuItem::+MenuItem");
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
||||
|
@ -16899,6 +16911,8 @@ void InterCodeProcedure::Close(void)
|
|||
TempForwarding();
|
||||
RemoveUnusedInstructions();
|
||||
|
||||
DisassembleDebug("pre single block loop opt");
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet, mModule->mGlobalVars);
|
||||
|
||||
|
|
|
@ -4111,6 +4111,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
vr = Dereference(proc, exp, block, vr);
|
||||
return CoerceType(proc, exp, block, vr, exp->mDecType);
|
||||
}
|
||||
else if (exp->mDecType->mType == DT_TYPE_VOID)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
vr = Dereference(proc, exp, block, vr);
|
||||
|
|
|
@ -284,6 +284,15 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
|||
if (dec->mScope->Insert(mdec->mIdent, mdec))
|
||||
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
|
||||
|
||||
if (dec->mConst)
|
||||
{
|
||||
Declaration* cmdec = mdec->Clone();
|
||||
cmdec->mBase = mdec->mBase->ToConstType();
|
||||
|
||||
dec->mConst->mScope->Insert(cmdec->mIdent, cmdec);
|
||||
dec->mConst->mSize = dec->mSize;
|
||||
}
|
||||
|
||||
if (mlast)
|
||||
mlast->mNext = mdec;
|
||||
else
|
||||
|
@ -442,6 +451,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
|||
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
||||
{
|
||||
Declaration* dec = nullptr;
|
||||
const Ident* pident = nullptr;
|
||||
|
||||
switch (mScanner->mToken)
|
||||
{
|
||||
|
@ -551,6 +561,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
|||
break;
|
||||
|
||||
case TK_IDENT:
|
||||
pident = mScanner->mTokenIdent;
|
||||
dec = mScope->Lookup(mScanner->mTokenIdent);
|
||||
if (dec && dec->mType == DT_CONST_FUNCTION && mScope->mLevel == SLEVEL_CLASS)
|
||||
dec = mScope->mParent->Lookup(mScanner->mTokenIdent);
|
||||
|
@ -560,6 +571,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
|||
{
|
||||
if (ExpectToken(TK_IDENT))
|
||||
{
|
||||
pident = mScanner->mTokenIdent;
|
||||
dec = dec->mScope->Lookup(mScanner->mTokenIdent);
|
||||
mScanner->NextToken();
|
||||
}
|
||||
|
@ -594,15 +606,9 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
|||
}
|
||||
}
|
||||
else if (!dec)
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Identifier not defined", mScanner->mTokenIdent);
|
||||
mScanner->NextToken();
|
||||
}
|
||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Identifier not defined", pident);
|
||||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_NOT_A_TYPE, "Identifier is no type", mScanner->mTokenIdent);
|
||||
mScanner->NextToken();
|
||||
}
|
||||
mErrors->Error(mScanner->mLocation, EERR_NOT_A_TYPE, "Identifier is no type", dec->mQualIdent);
|
||||
break;
|
||||
|
||||
case TK_ENUM:
|
||||
|
@ -3424,6 +3430,21 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
|
||||
if (mScanner->mToken == TK_OPEN_BRACE)
|
||||
{
|
||||
//
|
||||
// Take parameter names from new declaration
|
||||
//
|
||||
Declaration* npdec = ctdec->mParams, * ppdec = cdec->mBase->mParams;
|
||||
while (npdec && ppdec)
|
||||
{
|
||||
if (npdec->mIdent)
|
||||
{
|
||||
ppdec->mIdent = npdec->mIdent;
|
||||
ppdec->mQualIdent = npdec->mQualIdent;
|
||||
}
|
||||
npdec = npdec->mNext;
|
||||
ppdec = ppdec->mNext;
|
||||
}
|
||||
|
||||
if (cdec->mFlags & DTF_DEFINED)
|
||||
mErrors->Error(cdec->mLocation, EERR_DUPLICATE_DEFINITION, "Function already has a body");
|
||||
|
||||
|
@ -4001,7 +4022,7 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec)
|
|||
texp->mLeft = vexp;
|
||||
texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
||||
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||
texp->mDecType->mBase = pdec->mBase;
|
||||
texp->mDecType->mBase = dec->mBase;
|
||||
texp->mDecType->mSize = 2;
|
||||
|
||||
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
|
@ -4014,12 +4035,13 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec)
|
|||
|
||||
Expression* aexp;
|
||||
|
||||
if (dec->mBase->mCopyConstructor && !(dec->mValue->mType == EX_CALL && dec->mValue->mDecType->mType == DT_TYPE_STRUCT))
|
||||
Declaration* fcons = dec->mBase->mScope->Lookup(dec->mBase->mIdent->PreMangle("+"));
|
||||
|
||||
if (fcons && !(dec->mValue->mType == EX_CALL && dec->mValue->mDecType->mType == DT_TYPE_STRUCT))
|
||||
{
|
||||
Declaration* mdec = dec->mBase->mCopyConstructor;
|
||||
|
||||
Expression* cexp = new Expression(dec->mLocation, EX_CONSTANT);
|
||||
cexp->mDecValue = mdec;
|
||||
cexp->mDecValue = fcons;
|
||||
cexp->mDecType = cexp->mDecValue->mBase;
|
||||
|
||||
aexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||
|
@ -4027,6 +4049,8 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec)
|
|||
aexp->mRight = new Expression(dec->mLocation, EX_LIST);
|
||||
aexp->mRight->mLeft = texp;
|
||||
aexp->mRight->mRight = dec->mValue;
|
||||
|
||||
ResolveOverloadCall(aexp);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4710,6 +4734,8 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
|||
dist += 4;
|
||||
else if (ptype->IsSame(ex->mDecType))
|
||||
;
|
||||
else if (CanCoerceExpression(ex, ptype))
|
||||
dist += 512;
|
||||
else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->mType == DT_TYPE_STRUCT && etype->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
int ncast = 0;
|
||||
|
@ -4771,12 +4797,52 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
|
|||
return dist;
|
||||
}
|
||||
|
||||
bool Parser::CanCoerceExpression(Expression* exp, Declaration* type)
|
||||
{
|
||||
Declaration* tdec = exp->mDecType;
|
||||
while (tdec->mType == DT_TYPE_REFERENCE)
|
||||
tdec = tdec->mBase;
|
||||
while (type->mType == DT_TYPE_REFERENCE)
|
||||
type = type->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)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (type->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
if (!type->IsConstSame(tdec))
|
||||
{
|
||||
Declaration* fcons = type->mScope->Lookup(type->mIdent->PreMangle("+"));
|
||||
if (fcons)
|
||||
{
|
||||
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
|
||||
fcons = fcons->mNext;
|
||||
|
||||
if (fcons)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
||||
{
|
||||
Declaration* tdec = exp->mDecType;
|
||||
while (tdec->mType == DT_TYPE_REFERENCE)
|
||||
tdec = tdec->mBase;
|
||||
|
||||
while (type->mType == DT_TYPE_REFERENCE)
|
||||
type = type->mBase;
|
||||
|
||||
if (tdec->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
|
@ -4802,6 +4868,78 @@ Expression* Parser::CoerceExpression(Expression* exp, Declaration* type)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
if (!type->IsConstSame(tdec))
|
||||
{
|
||||
Declaration* fcons = type->mScope->Lookup(type->mIdent->PreMangle("+"));
|
||||
if (fcons)
|
||||
{
|
||||
while (fcons && !(fcons->mBase->mParams && fcons->mBase->mParams->mNext && !fcons->mBase->mParams->mNext->mNext && fcons->mBase->mParams->mNext->mBase->CanAssign(tdec)))
|
||||
fcons = fcons->mNext;
|
||||
|
||||
if (fcons)
|
||||
{
|
||||
Declaration* vdec = new Declaration(mScanner->mLocation, DT_VARIABLE);
|
||||
|
||||
vdec->mBase = type->ToMutableType();
|
||||
vdec->mVarIndex = mLocalIndex++;
|
||||
vdec->mSize = type->mSize;
|
||||
vdec->mFlags |= DTF_DEFINED;
|
||||
|
||||
Expression* vexp = new Expression(mScanner->mLocation, EX_VARIABLE);
|
||||
vexp->mDecType = vdec->mBase;
|
||||
vexp->mDecValue = vdec;
|
||||
|
||||
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
cexp->mDecValue = fcons;
|
||||
cexp->mDecType = cexp->mDecValue->mBase;
|
||||
|
||||
Expression* fexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||
fexp->mLeft = cexp;
|
||||
|
||||
fexp->mRight = exp;
|
||||
|
||||
Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX);
|
||||
texp->mToken = TK_BINARY_AND;
|
||||
texp->mLeft = vexp;
|
||||
texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
|
||||
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
|
||||
texp->mDecType->mBase = vdec->mBase;
|
||||
texp->mDecType->mSize = 2;
|
||||
|
||||
Expression* lexp = new Expression(mScanner->mLocation, EX_LIST);
|
||||
lexp->mLeft = texp;
|
||||
lexp->mRight = fexp->mRight;
|
||||
fexp->mRight = lexp;
|
||||
|
||||
Expression* dexp = nullptr;
|
||||
if (type->mDestructor)
|
||||
{
|
||||
Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
cexp->mDecValue = type->mDestructor;
|
||||
cexp->mDecType = cexp->mDecValue->mBase;
|
||||
|
||||
dexp = new Expression(mScanner->mLocation, EX_CALL);
|
||||
dexp->mLeft = cexp;
|
||||
dexp->mRight = texp;
|
||||
}
|
||||
|
||||
Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT);
|
||||
|
||||
nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST);
|
||||
nexp->mLeft->mLeft = fexp;
|
||||
nexp->mLeft->mRight = dexp;
|
||||
|
||||
nexp->mRight = vexp;
|
||||
nexp->mDecType = vexp->mDecType;
|
||||
|
||||
return nexp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return exp;
|
||||
}
|
||||
|
@ -4817,13 +4955,19 @@ void Parser::CompleteFunctionDefaultParams(Expression* exp)
|
|||
{
|
||||
if (pexp)
|
||||
{
|
||||
Expression* exp = pexp;
|
||||
|
||||
if (pexp->mType == EX_LIST)
|
||||
{
|
||||
pexp->mLeft = CoerceExpression(pexp->mLeft, pdec->mBase);
|
||||
lexp = pexp;
|
||||
pexp = pexp->mRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
lexp->mRight = CoerceExpression(lexp->mRight, pdec->mBase);
|
||||
pexp = nullptr;
|
||||
}
|
||||
}
|
||||
else if (pdec->mValue)
|
||||
{
|
||||
|
@ -4887,9 +5031,14 @@ Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
|
|||
}
|
||||
|
||||
if (ibest == NOOVERLOAD)
|
||||
mErrors->Error(exp->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching function call");
|
||||
{
|
||||
#if _DEBUG
|
||||
int d = OverloadDistance(exp->mLeft->mDecValue->mBase, exp->mRight);
|
||||
#endif
|
||||
mErrors->Error(exp->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching function call", exp->mLeft->mDecValue->mQualIdent);
|
||||
}
|
||||
else if (nbest > 1)
|
||||
mErrors->Error(exp->mLocation, ERRO_AMBIGUOUS_FUNCTION_CALL, "Ambiguous function call");
|
||||
mErrors->Error(exp->mLocation, ERRO_AMBIGUOUS_FUNCTION_CALL, "Ambiguous function call", exp->mLeft->mDecValue->mQualIdent);
|
||||
else
|
||||
{
|
||||
exp->mLeft->mDecValue = dbest;
|
||||
|
@ -6831,6 +6980,69 @@ Expression* Parser::ParseSwitchStatement(void)
|
|||
return sexp;
|
||||
}
|
||||
|
||||
void Parser::ParseTemplate(void)
|
||||
{
|
||||
ConsumeToken(TK_LESS_THAN);
|
||||
Declaration* tdec = new Declaration(mScanner->mLocation, DT_TEMPLATE);
|
||||
Declaration* ppdec = nullptr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Declaration* pdec = nullptr;
|
||||
|
||||
if (ConsumeTokenIf(TK_CLASS))
|
||||
{
|
||||
if (mScanner->mToken == TK_IDENT)
|
||||
{
|
||||
Declaration* pdec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||
pdec->mIdent = mScanner->mTokenIdent;
|
||||
pdec->mBase = TheVoidTypeDeclaration;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
||||
}
|
||||
else if (ConsumeTokenIf(TK_INT))
|
||||
{
|
||||
if (mScanner->mToken == TK_IDENT)
|
||||
{
|
||||
Declaration* pdec = new Declaration(mScanner->mLocation, DT_ARGUMENT);
|
||||
pdec->mIdent = mScanner->mTokenIdent;
|
||||
pdec->mBase = TheSignedIntTypeDeclaration;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_TEMPLATE_PARAMS, "'class' or 'int' expected as template parameter");
|
||||
|
||||
if (pdec)
|
||||
{
|
||||
if (ppdec)
|
||||
ppdec->mNext = pdec;
|
||||
else
|
||||
tdec->mParams = pdec;
|
||||
ppdec = pdec;
|
||||
}
|
||||
|
||||
if (!ConsumeTokenIf(TK_COMMA))
|
||||
break;
|
||||
}
|
||||
|
||||
ConsumeToken(TK_GREATER_THAN);
|
||||
|
||||
if (mScanner->mToken == TK_CLASS)
|
||||
{
|
||||
// Class template
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Function template
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
|
||||
|
@ -7541,6 +7753,11 @@ void Parser::ParsePragma(void)
|
|||
}
|
||||
ConsumeToken(TK_CLOSE_PARENTHESIS);
|
||||
}
|
||||
else if (!strcmp(mScanner->mTokenIdent->mString, "once"))
|
||||
{
|
||||
mScanner->MarkSourceOnce();
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (!strcmp(mScanner->mTokenIdent->mString, "compile"))
|
||||
{
|
||||
mScanner->NextToken();
|
||||
|
@ -8453,6 +8670,11 @@ void Parser::Parse(void)
|
|||
}
|
||||
else if (mScanner->mToken == TK_SEMICOLON)
|
||||
mScanner->NextToken();
|
||||
else if (mScanner->mToken == TK_TEMPLATE)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
ParseTemplate();
|
||||
}
|
||||
else if (mScanner->mToken == TK_NAMESPACE)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
|
|
|
@ -90,8 +90,11 @@ protected:
|
|||
int OverloadDistance(Declaration* pdec, Expression* pexp);
|
||||
Expression * ResolveOverloadCall(Expression* exp, Expression * exp2 = nullptr);
|
||||
Expression* CoerceExpression(Expression* exp, Declaration* type);
|
||||
bool CanCoerceExpression(Expression* exp, Declaration* type);
|
||||
void CompleteFunctionDefaultParams(Expression* exp);
|
||||
|
||||
void ParseTemplate(void);
|
||||
|
||||
Expression* ParseSimpleExpression(bool lhs);
|
||||
Expression* ParsePrefixExpression(bool lhs);
|
||||
Expression* ParsePostfixExpression(bool lhs);
|
||||
|
|
|
@ -162,6 +162,7 @@ const char* TokenNames[] =
|
|||
"'delete'",
|
||||
"'virtual'",
|
||||
"'operator'",
|
||||
"'template'",
|
||||
};
|
||||
|
||||
|
||||
|
@ -306,6 +307,25 @@ Macro* MacroDict::Lookup(const Ident* ident)
|
|||
}
|
||||
|
||||
|
||||
TokenSequence::TokenSequence(Scanner* scanner)
|
||||
: mNext(nullptr), mLocation(scanner->mLocation), mToken(scanner->mToken),
|
||||
mTokenIdent(scanner->mTokenIdent), mTokenChar(scanner->mTokenChar),
|
||||
mTokenInteger(scanner->mTokenInteger), mTokenNumber(scanner->mTokenNumber),
|
||||
mTokenString(nullptr)
|
||||
{
|
||||
if (mToken == TK_STRING)
|
||||
{
|
||||
int ssize = strlen(scanner->mTokenString);
|
||||
char * str = new char[ssize + 1];
|
||||
strcpy_s(str, ssize + 1, scanner->mTokenString);
|
||||
mTokenString = str;
|
||||
}
|
||||
}
|
||||
|
||||
TokenSequence::~TokenSequence(void)
|
||||
{
|
||||
delete[] mTokenString;
|
||||
}
|
||||
|
||||
Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
||||
: mErrors(errors), mPreprocessor(preprocessor)
|
||||
|
@ -324,6 +344,9 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
|||
mDefineArguments = nullptr;
|
||||
mToken = TK_NONE;
|
||||
mUngetToken = TK_NONE;
|
||||
mReplay = nullptr;
|
||||
|
||||
mOnceDict = new MacroDict();
|
||||
|
||||
NextChar();
|
||||
|
||||
|
@ -336,6 +359,18 @@ Scanner::~Scanner(void)
|
|||
}
|
||||
|
||||
|
||||
TokenSequence* Scanner::Record(void)
|
||||
{
|
||||
return new TokenSequence(this);
|
||||
}
|
||||
|
||||
const TokenSequence* Scanner::Replay(const TokenSequence* replay)
|
||||
{
|
||||
const TokenSequence* seq = mReplay;
|
||||
mReplay = replay;
|
||||
return seq;
|
||||
}
|
||||
|
||||
const char* Scanner::TokenName(Token token) const
|
||||
{
|
||||
return TokenNames[token];
|
||||
|
@ -412,8 +447,32 @@ void Scanner::AddMacro(const Ident* ident, const char* value)
|
|||
mDefines->Insert(macro);
|
||||
}
|
||||
|
||||
void Scanner::MarkSourceOnce(void)
|
||||
{
|
||||
const Ident* fident = Ident::Unique(mPreprocessor->mSource->mFileName);
|
||||
|
||||
Macro* macro = new Macro(fident, nullptr);
|
||||
mOnceDict->Insert(macro);
|
||||
}
|
||||
|
||||
void Scanner::NextToken(void)
|
||||
{
|
||||
if (mReplay)
|
||||
{
|
||||
mLocation = mReplay->mLocation;
|
||||
mToken = mReplay->mToken;
|
||||
|
||||
mTokenIdent = mReplay->mTokenIdent;
|
||||
mTokenChar = mReplay->mTokenChar;
|
||||
mTokenNumber = mReplay->mTokenNumber;
|
||||
mTokenInteger = mReplay->mTokenInteger;
|
||||
if (mReplay->mTokenString)
|
||||
strcpy_s(mTokenString, mReplay->mTokenString);
|
||||
|
||||
mReplay = mReplay->mNext;
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
NextRawToken();
|
||||
|
@ -503,6 +562,8 @@ void Scanner::NextToken(void)
|
|||
{
|
||||
if (!mPreprocessor->OpenSource("Including", mTokenString, true))
|
||||
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString);
|
||||
else if (mOnceDict->Lookup(Ident::Unique(mPreprocessor->mSource->mFileName)))
|
||||
mPreprocessor->CloseSource();
|
||||
}
|
||||
else if (mToken == TK_LESS_THAN)
|
||||
{
|
||||
|
@ -510,6 +571,8 @@ void Scanner::NextToken(void)
|
|||
StringToken('>', 'a');
|
||||
if (!mPreprocessor->OpenSource("Including", mTokenString, false))
|
||||
mErrors->Error(mLocation, EERR_FILE_NOT_FOUND, "Could not open source file", mTokenString);
|
||||
else if (mOnceDict->Lookup(Ident::Unique(mPreprocessor->mSource->mFileName)))
|
||||
mPreprocessor->CloseSource();
|
||||
}
|
||||
}
|
||||
else if (mToken == TK_PREP_DEFINE)
|
||||
|
@ -1426,6 +1489,8 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_DELETE;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "virtual"))
|
||||
mToken = TK_VIRTUAL;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "template"))
|
||||
mToken = TK_TEMPLATE;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "operator"))
|
||||
{
|
||||
NextRawToken();
|
||||
|
|
|
@ -161,6 +161,7 @@ enum Token
|
|||
TK_DELETE,
|
||||
TK_VIRTUAL,
|
||||
TK_OPERATOR,
|
||||
TK_TEMPLATE,
|
||||
|
||||
NUM_TOKENS
|
||||
};
|
||||
|
@ -204,6 +205,24 @@ protected:
|
|||
MacroDict * mParent;
|
||||
};
|
||||
|
||||
class Scanner;
|
||||
|
||||
struct TokenSequence
|
||||
{
|
||||
TokenSequence * mNext;
|
||||
Location mLocation;
|
||||
Token mToken;
|
||||
|
||||
const Ident * mTokenIdent;
|
||||
char mTokenChar;
|
||||
const char * mTokenString;
|
||||
double mTokenNumber;
|
||||
int64 mTokenInteger;
|
||||
|
||||
TokenSequence(Scanner* scanner);
|
||||
~TokenSequence(void);
|
||||
};
|
||||
|
||||
class Scanner
|
||||
{
|
||||
public:
|
||||
|
@ -214,6 +233,9 @@ public:
|
|||
|
||||
void NextToken(void);
|
||||
|
||||
TokenSequence* Record(void);
|
||||
const TokenSequence* Replay(const TokenSequence * sequence);
|
||||
|
||||
void Warning(const char * error);
|
||||
void Error(const char * error);
|
||||
|
||||
|
@ -247,6 +269,7 @@ public:
|
|||
uint64 mCompilerOptions;
|
||||
|
||||
void AddMacro(const Ident* ident, const char* value);
|
||||
void MarkSourceOnce(void);
|
||||
protected:
|
||||
void NextRawToken(void);
|
||||
|
||||
|
@ -261,10 +284,12 @@ protected:
|
|||
|
||||
int mMacroExpansionDepth;
|
||||
|
||||
MacroDict* mDefines, * mDefineArguments;
|
||||
MacroDict* mDefines, * mDefineArguments, * mOnceDict;
|
||||
|
||||
Token mUngetToken;
|
||||
|
||||
const TokenSequence* mReplay;
|
||||
|
||||
void StringToken(char terminator, char mode);
|
||||
void CharToken(char mode);
|
||||
bool NextChar(void);
|
||||
|
|
Loading…
Reference in New Issue