Improve operator overloading

This commit is contained in:
drmortalwombat 2023-07-14 07:48:48 +02:00
parent 6178bb1f9d
commit fa60c2e658
11 changed files with 387 additions and 128 deletions

View File

@ -9,7 +9,7 @@ private:
public:
string(void);
string(const string & s);
__noinline string(const char * s);
string(const char * s);
string(char c);
~string(void);

View File

@ -334,6 +334,7 @@ void Compiler::BuildVTables(void)
Expression* ecall = new Expression(mdec->mLocation, EX_DISPATCH);
ecall->mLeft = new Expression(mdec->mLocation, EX_INDEX);
ecall->mLeft->mDecType = mdec->mBase;
ecall->mDecType = vtabt->mBase;
ecall->mLeft->mLeft = new Expression(mdec->mLocation, EX_VARIABLE);
ecall->mLeft->mLeft->mDecType = vtabt;

View File

@ -92,8 +92,8 @@ Declaration* DeclarationScope::Lookup(const Ident* ident, ScopeLevel limit)
if (mHashSize > 0)
{
int hm = mHashSize - 1;
int hi = ident->mHash & hm;
unsigned int hm = mHashSize - 1;
unsigned int hi = ident->mHash & hm;
while (mHash[hi].mIdent)
{
@ -103,14 +103,17 @@ Declaration* DeclarationScope::Lookup(const Ident* ident, ScopeLevel limit)
}
}
if (limit == SLEVEL_SCOPE)
return nullptr;
for (int i = 0; i < mUsed.Size(); i++)
{
Declaration* dec = mUsed[i]->Lookup(ident);
Declaration* dec = mUsed[i]->Lookup(ident, limit);
if (dec)
return dec;
}
return mParent ? mParent->Lookup(ident) : nullptr;
return mParent ? mParent->Lookup(ident, limit) : nullptr;
}
void DeclarationScope::End(const Location& loc)
@ -811,6 +814,24 @@ int Declaration::Stride(void) const
return mStride > 0 ? mStride : mBase->mSize;
}
Declaration* Declaration::BuildConstPointer(const Location& loc)
{
Declaration* pdec = new Declaration(loc, DT_TYPE_POINTER);
pdec->mBase = this;
pdec->mFlags = DTF_DEFINED | DTF_CONST;
pdec->mSize = 2;
return pdec;
}
Declaration* Declaration::BuildConstReference(const Location& loc)
{
Declaration* pdec = new Declaration(loc, DT_TYPE_REFERENCE);
pdec->mBase = this;
pdec->mFlags = DTF_DEFINED | DTF_CONST;
pdec->mSize = 2;
return pdec;
}
Declaration* Declaration::BuildPointer(const Location& loc)
{
Declaration* pdec = new Declaration(loc, DT_TYPE_POINTER);
@ -1022,6 +1043,9 @@ bool Declaration::IsSubType(const Declaration* dec) const
if (this == dec)
return true;
if (mType == DT_TYPE_REFERENCE && dec->mType == DT_TYPE_REFERENCE)
return mBase->IsSubType(dec->mBase);
if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY)
{
if (dec->mType == DT_TYPE_POINTER)

View File

@ -109,12 +109,13 @@ class Declaration;
enum ScopeLevel
{
SLEVEL_SCOPE,
SLEVEL_GLOBAL,
SLEVEL_STATIC,
SLEVEL_NAMESPACE,
SLEVEL_CLASS,
SLEVEL_FUNCTION,
SLEVEL_LOCAL
SLEVEL_LOCAL,
};
class DeclarationScope
@ -283,6 +284,8 @@ public:
Declaration* BuildPointer(const Location& loc);
Declaration* BuildReference(const Location& loc);
Declaration* BuildConstPointer(const Location& loc);
Declaration* BuildConstReference(const Location& loc);
int Stride(void) const;
};

View File

@ -80,6 +80,7 @@ enum ErrorID
EERR_NO_DEFAULT_CONSTRUCTOR,
EERR_INVALID_OPERATOR,
EERR_MISSING_TEMP,
EERR_NON_STATIC_MEMBER,
ERRR_STACK_OVERFLOW,
ERRR_INVALID_NUMBER,

View File

@ -293,10 +293,27 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec, bool head)
Declaration* cf = procDec->mCalled[i];
if (cf->mType == DT_TYPE_FUNCTION)
procDec->mFlags |= DTF_DYNSTACK;
{
for (int i = 0; i < mVariableFunctions.Size(); i++)
{
Declaration* vf = mVariableFunctions[i];
CheckFastcall(vf, false);
if (vf->mBase->IsSame(cf))
{
int n = vf->mBase->mFastCallBase + vf->mBase->mFastCallSize;
if (n > nbase)
nbase = n;
}
}
// procDec->mFlags |= DTF_DYNSTACK;
}
else
CheckFastcall(cf, false);
if (cf->mFlags & DTF_DYNSTACK)
procDec->mFlags |= DTF_DYNSTACK;
// if (!(cf->mBase->mFlags & DTF_FASTCALL))
// procDec->mBase->mFlags |= DTF_STACKCALL;
@ -658,6 +675,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
return exp->mDecValue->mBase;
case EX_DISPATCH:
Analyze(exp->mLeft, procDec, lhs);
RegisterCall(procDec, exp->mLeft->mDecType);
break;
case EX_VCALL:
exp->mType = EX_CALL;
@ -893,6 +911,9 @@ void GlobalAnalyzer::RegisterCall(Declaration* from, Declaration* to)
{
if (from)
{
if (to->mType == DT_VARIABLE || to->mType == DT_ARGUMENT)
to = to->mBase;
if (to->mType == DT_CONST_FUNCTION)
{
if (to->mFlags & DTF_DYNSTACK)

View File

@ -1153,8 +1153,9 @@ void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, I
block->Append(ains);
InterInstruction* wins = new InterInstruction(exp->mLocation, IC_STORE);
wins->mNumOperands = 2;
wins->mSrc[1].mMemory = IM_INDIRECT;
wins->mSrc[0].mType = InterTypeOf(vl.mType);;
wins->mSrc[0].mType = vl.mReference > 0 ? IT_POINTER : InterTypeOf(vl.mType);
wins->mSrc[0].mTemp = vl.mTemp;
wins->mSrc[1].mType = IT_POINTER;
wins->mSrc[1].mTemp = ains->mDst.mTemp;
@ -1168,6 +1169,7 @@ void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, I
vdec = new Declaration(exp->mLocation, DT_VARIABLE);
ains = new InterInstruction(exp->mLocation, IC_CONSTANT);
ains->mNumOperands = 0;
ains->mDst.mType = IT_POINTER;
ains->mDst.mTemp = proc->AddTemporary(ains->mDst.mType);
ains->mConst.mMemory = IM_LOCAL;
@ -1185,8 +1187,9 @@ void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, I
block->Append(ains);
wins = new InterInstruction(exp->mLocation, IC_STORE);
wins->mNumOperands = 2;
wins->mSrc[1].mMemory = IM_INDIRECT;
wins->mSrc[0].mType = InterTypeOf(vr.mType);;
wins->mSrc[0].mType = vr.mReference > 0 ? IT_POINTER : InterTypeOf(vr.mType);;
wins->mSrc[0].mTemp = vr.mTemp;
wins->mSrc[1].mType = IT_POINTER;
wins->mSrc[1].mTemp = ains->mDst.mTemp;
@ -3082,7 +3085,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ExValue vp(ptype ? ptype : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1);
if (pdec && pdec->mBase->mType == DT_TYPE_REFERENCE && texp->mType == EX_CALL)
if (pdec && pdec->mBase->mType == DT_TYPE_REFERENCE && texp->mType == EX_CALL && texp->mDecType->mType != DT_TYPE_REFERENCE)
{
mErrors->Error(texp->mLocation, EERR_MISSING_TEMP, "Missing temporary variable");
#if 0
@ -4030,7 +4033,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{
vr = Dereference(proc, exp, block, vr);
ins->mCode = IC_TYPECAST;
ins->mSrc[0].mType = InterTypeOf(vr.mType);
ins->mSrc[0].mType = vr.mReference > 0 ? IT_POINTER : InterTypeOf(vr.mType);
ins->mSrc[0].mTemp = vr.mTemp;
ins->mDst.mType = InterTypeOf(exp->mDecType);
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
@ -4564,7 +4567,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE));
#if 0
if (proc->mIdent && !strcmp(proc->mIdent->mString, "A::func"))
if (proc->mIdent && !strcmp(proc->mIdent->mString, "main"))
exp->Dump(0);
#endif
#if 0

View File

@ -12929,7 +12929,7 @@ void NativeCodeBasicBlock::FindZeroPageAlias(const NumberSet& statics, NumberSet
}
}
bool NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global)
bool NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global, bool ignorefcall)
{
if (!mVisited)
{
@ -12946,7 +12946,14 @@ bool NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet&
case ASMIM_ABSOLUTE:
if (mIns[i].mType == ASMIT_JSR)
{
if ((mIns[i].mFlags & NCIF_RUNTIME) && !(mIns[i].mFlags & NCIF_FEXEC))
if (mIns[i].mFlags & NCIF_RUNTIME)
{
if (mIns[i].mFlags & NCIF_FEXEC)
{
if (!ignorefcall)
return false;
}
else
{
for (int j = 0; j < 4; j++)
{
@ -12954,6 +12961,7 @@ bool NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet&
locals += BC_REG_WORK + j;
}
}
}
if (mIns[i].mLinkerObject)
{
@ -12996,9 +13004,9 @@ bool NativeCodeBasicBlock::CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet&
}
}
if (mTrueJump && !mTrueJump->CollectZeroPageSet(locals, global))
if (mTrueJump && !mTrueJump->CollectZeroPageSet(locals, global, ignorefcall))
return false;
if (mFalseJump && !mFalseJump->CollectZeroPageSet(locals, global))
if (mFalseJump && !mFalseJump->CollectZeroPageSet(locals, global, ignorefcall))
return false;
}
@ -40372,7 +40380,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
ZeroPageSet zpLocal, zpGlobal;
ResetVisited();
if (mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal))
if (mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal, true))
zpLocal |= zpGlobal;
else
mGenerator->mErrors->Error(mInterProc->mLocation, ERRR_INTERRUPT_TO_COMPLEX, "No recursive functions in interrupt");
@ -40660,7 +40668,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
ZeroPageSet zpLocal, zpGlobal;
ResetVisited();
if (mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal))
if (mEntryBlock->CollectZeroPageSet(zpLocal, zpGlobal, false))
{
zpLocal |= zpGlobal;

View File

@ -550,7 +550,7 @@ public:
void BuildEntryDataSet(const NativeRegisterDataSet& set);
bool ApplyEntryDataSet(void);
bool CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global);
bool CollectZeroPageSet(ZeroPageSet& locals, ZeroPageSet& global, bool ignorefcall);
void CollectZeroPageUsage(NumberSet& used, NumberSet& modified, NumberSet& pairs);
void FindZeroPageAlias(const NumberSet& statics, NumberSet& invalid, uint8* alias, int accu);
bool RemapZeroPage(const uint8* remap);

View File

@ -121,6 +121,8 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
bcdec->mBase = pdec;
bcdec->mFlags = pflags;
dec->mScope->UseScope(pdec->mScope);
if (pdec->mVTable)
needVTable = true;
@ -137,12 +139,17 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
{
Declaration* pthis = nullptr;
DeclarationScope* oscope = mScope;
if (mCompilerOptions & COPT_CPLUSPLUS)
{
pthis = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
pthis->mFlags |= DTF_CONST | DTF_DEFINED;
pthis->mBase = dec;
pthis->mSize = 2;
dec->mScope->mParent = mScope;
mScope = dec->mScope;
}
mScanner->NextToken();
@ -171,6 +178,10 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
flags |= DTF_PRIVATE | DTF_PROTECTED;
ConsumeToken(TK_COLON);
}
else if (ConsumeTokenIf(TK_CLOSE_BRACE))
{
break;
}
else
{
Declaration* mdec = ParseDeclaration(nullptr, false, false, pthis);
@ -201,6 +212,11 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
AddMemberFunction(dec, mdec);
}
else if ((mCompilerOptions & COPT_CPLUSPLUS) && mdec->mType == DT_ANON)
{
ConsumeToken(TK_SEMICOLON);
// anon element
}
else
{
while (mdec)
@ -240,12 +256,6 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
break;
}
}
if (mScanner->mToken == TK_CLOSE_BRACE)
{
mScanner->NextToken();
break;
}
}
}
@ -363,7 +373,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
AddDefaultConstructors(pthis);
// Lookup constructors, have same name as class
Declaration* cdec = dec->mScope->Lookup(dec->mIdent);
Declaration* cdec = dec->mScope->Lookup(dec->mIdent, SLEVEL_SCOPE);
while (cdec)
{
if (cdec->mFlags & DTF_DEFINED)
@ -374,12 +384,14 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
AppendMemberDestructor(pthis);
}
mScope = oscope;
}
return dec;
}
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
{
Declaration* dec = nullptr;
@ -434,11 +446,11 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
case TK_CONST:
mScanner->NextToken();
return ParseBaseTypeDeclaration(flags | DTF_CONST);
return ParseBaseTypeDeclaration(flags | DTF_CONST, qualified);
case TK_VOLATILE:
mScanner->NextToken();
return ParseBaseTypeDeclaration(flags | DTF_VOLATILE);
return ParseBaseTypeDeclaration(flags | DTF_VOLATILE, qualified);
case TK_LONG:
dec = new Declaration(mScanner->mLocation, DT_TYPE_INTEGER);
@ -492,6 +504,19 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
case TK_IDENT:
dec = mScope->Lookup(mScanner->mTokenIdent);
if (dec && dec->mType == DT_CONST_FUNCTION && mScope->mLevel == SLEVEL_CLASS)
dec = mScope->mParent->Lookup(mScanner->mTokenIdent);
mScanner->NextToken();
while (qualified && dec && dec->mType == DT_TYPE_STRUCT && ConsumeTokenIf(TK_COLCOLON))
{
if (ExpectToken(TK_IDENT))
{
dec = dec->mScope->Lookup(mScanner->mTokenIdent);
mScanner->NextToken();
}
}
if (dec && dec->mType <= DT_TYPE_FUNCTION)
{
if (dec->IsSimpleType() && (flags & ~dec->mFlags))
@ -519,7 +544,6 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
dec = ndec;
}
}
mScanner->NextToken();
}
else if (!dec)
{
@ -811,7 +835,7 @@ Declaration * Parser::ParseFunctionDeclaration(Declaration* bdec)
break;
}
Declaration* bdec = ParseBaseTypeDeclaration(0);
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
Declaration* adec = ParsePostfixDeclaration();
adec = ReverseDeclaration(adec, bdec);
@ -1364,7 +1388,7 @@ Expression* Parser::BuildMemberInitializer(Expression* vexp)
else
fexp->mRight = texp;
ResolveOverloadCall(cexp, fexp->mRight);
fexp = ResolveOverloadCall(fexp);
return fexp;
}
@ -1644,7 +1668,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
// Extract constructor and destructor from scope
Declaration* cdec = pthis->mBase->mScope->Lookup(pthis->mBase->mIdent);
Declaration* cdec = pthis->mBase->mScope->Lookup(pthis->mBase->mIdent, SLEVEL_SCOPE);
while (cdec)
{
Declaration* ctdec = cdec->mBase;
@ -1658,11 +1682,11 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
cdec = cdec->mNext;
}
Declaration* ddec = pthis->mBase->mScope->Lookup(dtorident);
Declaration* ddec = pthis->mBase->mScope->Lookup(dtorident, SLEVEL_SCOPE);
if (ddec)
pthis->mBase->mDestructor = ddec;
Declaration* adec = pthis->mBase->mScope->Lookup(Ident::Unique("operator="));
Declaration* adec = pthis->mBase->mScope->Lookup(Ident::Unique("operator="), SLEVEL_SCOPE);
while (adec)
{
Declaration* atdec = adec->mBase;
@ -2893,7 +2917,7 @@ void Parser::ParseVariableInit(Declaration* ndec)
else
mScanner->NextToken();
Declaration* fcons = ndec->mBase->mScope ? ndec->mBase->mScope->Lookup(ndec->mBase->mIdent) : nullptr;
Declaration* fcons = ndec->mBase->mScope ? ndec->mBase->mScope->Lookup(ndec->mBase->mIdent, SLEVEL_CLASS) : nullptr;
if (fcons)
{
@ -2929,7 +2953,7 @@ void Parser::ParseVariableInit(Declaration* ndec)
else
fexp->mRight = texp;
ResolveOverloadCall(cexp, fexp->mRight);
fexp = ResolveOverloadCall(fexp);
Expression* dexp = nullptr;
if (ndec->mBase->mDestructor)
@ -3139,7 +3163,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
return cdec;
}
bdec = ParseBaseTypeDeclaration(typeFlags);
bdec = ParseBaseTypeDeclaration(typeFlags, false);
}
Declaration* rdec = nullptr, * ldec = nullptr;
@ -3164,7 +3188,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
if (mCompilerOptions & COPT_NATIVE)
cdec->mFlags |= DTF_NATIVE;
Declaration* pdec = pthis->mBase->mScope ? pthis->mBase->mScope->Lookup(pthis->mBase->mIdent) : nullptr;
Declaration* pdec = pthis->mBase->mScope ? pthis->mBase->mScope->Lookup(pthis->mBase->mIdent, SLEVEL_CLASS) : nullptr;
if (pdec)
{
while (pdec && !cdec->mBase->IsSameParams(pdec->mBase))
@ -3228,13 +3252,15 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
if (bdec && bdec->mType == DT_TYPE_STRUCT && ConsumeTokenIf(TK_COLCOLON))
{
if (mScanner->mToken == TK_IDENT && mScanner->mTokenIdent == bdec->mIdent)
if (mScanner->mToken == TK_IDENT)
{
if (mScanner->mTokenIdent == bdec->mIdent)
{
mScanner->NextToken();
Declaration* ctdec = ParseFunctionDeclaration(TheVoidTypeDeclaration);
Declaration * bthis = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
Declaration* bthis = new Declaration(mScanner->mLocation, DT_TYPE_POINTER);
bthis->mFlags |= DTF_CONST | DTF_DEFINED;
if (ConsumeTokenIf(TK_CONST))
bthis->mBase = bdec->ToConstType();
@ -3244,7 +3270,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
PrependThisArgument(ctdec, bthis);
Declaration* cdec = bdec->mScope->Lookup(bdec->mIdent);
Declaration* cdec = bdec->mScope->Lookup(bdec->mIdent, SLEVEL_CLASS);
if (cdec)
{
while (cdec && !cdec->mBase->IsSameParams(ctdec))
@ -3287,6 +3313,16 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
return bdec;
}
}
else
{
Declaration* mdec = bdec->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_CLASS);
if (mdec)
bdec = mdec;
else
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Member not found", mScanner->mTokenIdent);
mScanner->NextToken();
}
}
if (ConsumeTokenIf(TK_BINARY_NOT))
{
@ -3375,7 +3411,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
if (ndec->mBase->mType == DT_TYPE_FUNCTION && pthis)
{
if (ConsumeTokenIf(TK_CONST))
PrependThisArgument(ndec->mBase, pthis->mBase->ToConstType()->BuildPointer(ndec->mLocation));
PrependThisArgument(ndec->mBase, pthis->mBase->ToConstType()->BuildConstPointer(ndec->mLocation));
else
PrependThisArgument(ndec->mBase, pthis);
}
@ -3431,7 +3467,15 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
adec->mNext = ndec->mBase->mParams;
if (ConsumeTokenIf(TK_CONST))
adec->mBase = adec->mBase->mBase->ToConstType()->BuildPointer(adec->mLocation);
{
if (!(adec->mBase->mBase->mFlags & DTF_CONST))
adec->mBase = adec->mBase->mBase->ToConstType()->BuildConstPointer(adec->mLocation);
}
else
{
if (adec->mBase->mBase->mFlags & DTF_CONST)
adec->mBase = adec->mBase->mBase->ToMutableType()->BuildConstPointer(adec->mLocation);
}
Declaration* p = adec->mBase->mParams;
while (p)
@ -3866,9 +3910,9 @@ Declaration* Parser::ParseQualIdent(void)
{
if (mScanner->mToken == TK_IDENT)
{
if (dec->mType == DT_NAMESPACE)
if (dec->mType == DT_NAMESPACE || dec->mType == DT_TYPE_STRUCT)
{
Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent);
Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent, SLEVEL_CLASS);
if (ndec)
dec = ndec;
@ -3896,7 +3940,7 @@ Declaration* Parser::ParseQualIdent(void)
Expression* Parser::ParseSimpleExpression(bool lhs)
{
Declaration* dec;
Declaration* dec = nullptr;
Expression* exp = nullptr, * rexp = nullptr;
switch (mScanner->mToken)
@ -3916,7 +3960,7 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
{
exp = new Expression(mScanner->mLocation, EX_TYPE);
exp->mDecValue = nullptr;
exp->mDecType = ParseBaseTypeDeclaration(0);
exp->mDecType = ParseBaseTypeDeclaration(0, true);
}
break;
case TK_CONST:
@ -4097,7 +4141,9 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
dec = MemberLookup(mThisPointer->mBase->mBase, mScanner->mTokenIdent, offset, flags);
if (dec)
{
Expression * texp = new Expression(mScanner->mLocation, EX_VARIABLE);
if (dec->mType == DT_ELEMENT || dec->mType == DT_CONST_FUNCTION)
{
Expression* texp = new Expression(mScanner->mLocation, EX_VARIABLE);
texp->mDecType = mThisPointer->mBase;
texp->mDecValue = mThisPointer;
@ -4108,10 +4154,14 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
exp = ParseQualify(dexp);
}
else
mScanner->NextToken();
}
}
if (!exp)
{
if (!dec)
dec = ParseQualIdent();
if (dec)
{
@ -4156,6 +4206,10 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
exp->mDecType = dec;
}
}
else if (dec->mType == DT_ELEMENT)
{
mErrors->Error(mScanner->mLocation, EERR_NON_STATIC_MEMBER, "Non static member access", mScanner->mTokenIdent);
}
else
{
mErrors->Error(mScanner->mLocation, EERR_INVALID_IDENTIFIER, "Invalid identifier", mScanner->mTokenIdent);
@ -4244,7 +4298,10 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
Declaration* Parser::MemberLookup(Declaration* dtype, const Ident* ident, int & offset, uint64& flags)
{
Declaration* mdec = dtype->mScope->Lookup(ident);
if (ident == dtype->mIdent)
return nullptr;
Declaration* mdec = dtype->mScope->Lookup(ident, SLEVEL_CLASS);
offset = 0;
flags = 0;
@ -4341,6 +4398,9 @@ Expression* Parser::ParseQualify(Expression* exp)
texp->mLeft = exp;
texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED;
if (exp->mDecType->mType == DT_TYPE_REFERENCE)
texp->mDecType->mBase = exp->mDecType->mBase;
else
texp->mDecType->mBase = exp->mDecType;
texp->mDecType->mSize = 2;
@ -4354,7 +4414,8 @@ Expression* Parser::ParseQualify(Expression* exp)
else
nexp->mRight = texp;
ResolveOverloadCall(nexp->mLeft, nexp->mRight);
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
if (nexp->mLeft->mDecType->mFlags & DTF_VIRTUAL)
@ -4406,13 +4467,65 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
etype = etype->mBase;
if (ptype->mType == DT_TYPE_INTEGER && etype->mType == DT_TYPE_INTEGER)
;
{
if (ptype->mSize == etype->mSize)
{
if ((ptype->mFlags & DTF_SIGNED) == (etype->mFlags & DTF_SIGNED))
dist += 0;
else
dist += 4;
}
else if (ptype->mSize > etype->mSize)
{
if (ptype->mFlags & DTF_SIGNED)
{
dist += 1;
}
else if (etype->mFlags & DTF_SIGNED)
{
dist += 4;
}
else
dist += 1;
}
else if (ex->mType == EX_CONSTANT && ex->mDecValue->mType == DT_CONST_INTEGER)
{
int64 v = ex->mDecValue->mInteger;
if (ptype->mFlags & DTF_SIGNED)
{
if (v >= -128 && v <= 127)
dist += 1;
else if (ptype->mSize >= 2 && v >= -32768 && v <= 32767)
dist += 1;
else if (ptype->mSize == 4)
dist += 1;
else
dist += 16;
}
else if (v >= 0)
{
if (v <= 255)
dist += 1;
else if (ptype->mSize >= 2 && v <= 65535)
dist += 1;
else if (ptype->mSize == 4)
dist += 1;
else
dist += 16;
}
else
dist += 16;
}
else
dist += 16;
}
else if (ptype->mType == DT_TYPE_FLOAT && etype->mType == DT_TYPE_FLOAT)
;
dist += 0;
else if (ptype->mType == DT_TYPE_INTEGER && etype->mType == DT_TYPE_FLOAT)
dist += 8;
else if (ptype->mType == DT_TYPE_FLOAT && etype->mType == DT_TYPE_INTEGER)
dist++;
dist += 4;
else if (ptype->IsSame(ex->mDecType))
;
else if (ptype->mType == DT_TYPE_REFERENCE && ptype->mBase->mType == DT_TYPE_STRUCT && etype->mType == DT_TYPE_STRUCT)
@ -4434,6 +4547,8 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
}
else if (ptype->mType == DT_TYPE_POINTER && etype->mType == DT_TYPE_ARRAY && 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
@ -4456,22 +4571,26 @@ int Parser::OverloadDistance(Declaration* fdec, Expression* pexp)
return dist;
}
void Parser::ResolveOverloadCall(Expression* cexp, Expression* pexp)
Expression * Parser::ResolveOverloadCall(Expression* exp, Expression* exp2)
{
if (cexp->mDecValue)
if (exp->mType == EX_CALL && exp->mLeft->mDecValue)
{
Declaration* fdec = cexp->mDecValue;
if (fdec->mType == DT_CONST_FUNCTION && fdec->mNext)
Declaration* fdec = exp->mLeft->mDecValue;
Declaration* fdec2 = exp2 ? exp2->mLeft->mDecValue : nullptr;
if (fdec->mType == DT_CONST_FUNCTION && fdec->mNext || fdec2)
{
Declaration* dbest = nullptr;
Expression* pbest = nullptr;
int ibest = NOOVERLOAD, nbest = 0;
while (fdec)
{
int d = OverloadDistance(fdec->mBase, pexp);
int d = OverloadDistance(fdec->mBase, exp->mRight);
if (d < ibest)
{
dbest = fdec;
pbest = exp->mRight;
ibest = d;
nbest = 1;
}
@ -4480,17 +4599,36 @@ void Parser::ResolveOverloadCall(Expression* cexp, Expression* pexp)
fdec = fdec->mNext;
}
while (fdec2)
{
int d = OverloadDistance(fdec2->mBase, exp2->mRight);
if (d < ibest)
{
dbest = fdec2;
pbest = exp2->mRight;
ibest = d;
nbest = 1;
}
else if (d == ibest)
nbest++;
fdec2 = fdec2->mNext;
}
if (ibest == NOOVERLOAD)
mErrors->Error(cexp->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching function call");
mErrors->Error(exp->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching function call");
else if (nbest > 1)
mErrors->Error(cexp->mLocation, ERRO_AMBIGUOUS_FUNCTION_CALL, "Ambiguous function call");
mErrors->Error(exp->mLocation, ERRO_AMBIGUOUS_FUNCTION_CALL, "Ambiguous function call");
else
{
cexp->mDecValue = dbest;
cexp->mDecType = dbest->mBase;
exp->mLeft->mDecValue = dbest;
exp->mLeft->mDecType = dbest->mBase;
exp->mDecType = dbest->mBase->mBase;
exp->mRight = pbest;
}
}
}
return exp;
}
Expression* Parser::ParsePostfixExpression(bool lhs)
@ -4584,7 +4722,7 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
else
fexp->mRight = texp;
ResolveOverloadCall(cexp, fexp->mRight);
fexp = ResolveOverloadCall(fexp);
Expression* dexp = nullptr;
if (exp->mDecType->mDestructor)
@ -4650,7 +4788,24 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
mScanner->NextToken();
}
ResolveOverloadCall(exp, nexp->mRight);
if ((exp->mDecType->mFlags & DTF_FUNC_THIS) && mThisPointer && mThisPointer->mType == DT_ARGUMENT)
{
Expression* texp = new Expression(mScanner->mLocation, EX_VARIABLE);
texp->mDecType = mThisPointer->mBase;
texp->mDecValue = mThisPointer;
if (nexp->mRight)
{
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp;
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
}
else
nexp->mRight = texp;
}
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = exp->mDecType->mBase;
if (nexp->mLeft->mDecType->mFlags & DTF_VIRTUAL)
@ -4756,7 +4911,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
nexp = new Expression(mScanner->mLocation, EX_PREFIX);
nexp->mToken = TK_NEW;
mScanner->NextToken();
Declaration * dec = ParseBaseTypeDeclaration(0);
Declaration * dec = ParseBaseTypeDeclaration(0, true);
Declaration* sconst = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
sconst->mBase = TheUnsignedIntTypeDeclaration;
@ -4897,7 +5052,7 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
dexp->mLeft = cexp;
dexp->mRight = pexp;
ResolveOverloadCall(cexp, pexp);
dexp = ResolveOverloadCall(dexp);
Expression* sexp = new Expression(mScanner->mLocation, EX_SEQUENCE);
@ -5367,6 +5522,23 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
if (opident)
{
Expression* nexp2 = nullptr;
Declaration* mdec2 = mScope->Lookup(opident);
if (mdec2)
{
nexp2 = new Expression(mScanner->mLocation, EX_CALL);
nexp2->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
nexp2->mLeft->mDecType = mdec2->mBase;
nexp2->mLeft->mDecValue = mdec2;
nexp2->mDecType = mdec2->mBase;
nexp2->mRight = new Expression(mScanner->mLocation, EX_LIST);
nexp2->mRight->mLeft = exp->mLeft;
nexp2->mRight->mRight = exp->mRight;
}
Declaration* mdec = tdec->mScope->Lookup(opident);
if (mdec)
{
@ -5392,7 +5564,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
ResolveOverloadCall(nexp->mLeft, nexp->mRight);
nexp = ResolveOverloadCall(nexp, nexp2);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
exp = nexp;
@ -5405,7 +5577,9 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
Declaration* tdec = exp->mLeft->mDecType;
if (tdec->mType == DT_TYPE_STRUCT)
{
Declaration* mdec = tdec->mScope->Lookup(Ident::Unique("operator[]"));
const Ident* opident = Ident::Unique("operator[]");
Declaration* mdec = tdec->mScope->Lookup(opident);
if (mdec)
{
Expression* nexp = new Expression(mScanner->mLocation, EX_CALL);
@ -5430,7 +5604,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
ResolveOverloadCall(nexp->mLeft, nexp->mRight);
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
exp = nexp;
@ -5477,7 +5651,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
nexp->mRight = texp;
ResolveOverloadCall(nexp->mLeft, nexp->mRight);
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
exp = nexp;
@ -5531,7 +5705,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
lexp->mRight->mDecValue->mBase = TheSignedIntTypeDeclaration;
nexp->mRight = lexp;
ResolveOverloadCall(nexp->mLeft, nexp->mRight);
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
exp = nexp;
@ -5596,7 +5770,27 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
if (opident)
{
Expression* nexp2 = nullptr;
Declaration* mdec2 = mScope->Lookup(opident);
if (mdec2)
{
nexp2 = new Expression(mScanner->mLocation, EX_CALL);
nexp2->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
nexp2->mLeft->mDecType = mdec2->mBase;
nexp2->mLeft->mDecValue = mdec2;
nexp2->mDecType = mdec2->mBase;
nexp2->mRight = new Expression(mScanner->mLocation, EX_LIST);
nexp2->mRight->mLeft = exp->mLeft;
nexp2->mRight->mRight = exp->mRight;
}
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);
@ -5616,7 +5810,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);
@ -5624,7 +5818,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
ResolveOverloadCall(nexp->mLeft, nexp->mRight);
nexp = ResolveOverloadCall(nexp, nexp2);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
exp = nexp;
@ -5678,7 +5872,7 @@ Expression* Parser::CheckOperatorOverload(Expression* exp)
nexp->mRight = texp;
ResolveOverloadCall(nexp->mLeft, nexp->mRight);
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
exp = nexp;
@ -5741,6 +5935,10 @@ Expression* Parser::ParseFunction(Declaration * dec)
mReturnType = dec->mBase;
DeclarationScope* oscope = mScope;
while (mScope->mLevel == SLEVEL_CLASS)
mScope = mScope->mParent;
DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_FUNCTION);
mScope = scope;
@ -5803,7 +6001,7 @@ Expression* Parser::ParseFunction(Declaration * dec)
}
mScope->End(mScanner->mLocation);
mScope = mScope->mParent;
mScope = oscope;
mThisPointer = othis;

View File

@ -54,7 +54,7 @@ protected:
Expression * AddFunctionCallRefReturned(Expression * exp);
Expression* CleanupExpression(Expression* exp);
Declaration* ParseBaseTypeDeclaration(uint64 flags);
Declaration* ParseBaseTypeDeclaration(uint64 flags, bool qualified);
Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr);
Declaration* ParseStructDeclaration(uint64 flags, DecType dt);
@ -87,7 +87,7 @@ protected:
Expression* ParseQualify(Expression * exp);
int OverloadDistance(Declaration* pdec, Expression* pexp);
void ResolveOverloadCall(Expression* cexp, Expression* pexp);
Expression * ResolveOverloadCall(Expression* exp, Expression * exp2 = nullptr);
Expression* ParseSimpleExpression(bool lhs);
Expression* ParsePrefixExpression(bool lhs);