Improve cpp code generation
This commit is contained in:
parent
18c21b3fda
commit
9cdfad7d34
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue