Add iterators to string

This commit is contained in:
drmortalwombat 2023-10-08 16:27:52 +02:00
parent e084035a71
commit 33d692194a
12 changed files with 371 additions and 198 deletions

View File

@ -1,4 +1,5 @@
#include "ctype.h"
#include "conio.h"
#define CC_CTRL 0x00
#define CC_BREAK 0x01
@ -86,3 +87,19 @@ bool isxdigit(char c)
{
return (c < 128) && (_cinfo[c] & CC_HEX);
}
char tolower(char c)
{
if (c >= 'A' && c <= 'Z')
return c + ('a' - 'A');
else
return c;
}
char toupper(char c)
{
if (c >= 'a' && c <= 'z')
return c + ('A' - 'a');
else
return c;
}

View File

@ -25,6 +25,9 @@ inline bool isdigit(char c);
inline bool isxdigit(char c);
char tolower(char c);
char toupper(char c);
#pragma compile("ctype.c")

View File

@ -965,6 +965,19 @@ istream & istream::operator>>(char * p)
return *this;
}
istream & istream::operator>>(string & s)
{
doskipws();
s.clear();
char c = get();
while (c > ' ')
{
s += c;
c = get();
}
return *this;
}
cistream::cistream(void)
{}

View File

@ -132,6 +132,7 @@ public:
istream & operator>>(float & val);
istream & operator>>(char * p);
istream & operator>>(string & s);
istream(void);
protected:

View File

@ -94,6 +94,12 @@ string::~string(void)
{
free(cstr);
}
void string::clear(void)
{
free(cstr);
cstr = nullptr;
}
void string::copyseg(char * p, char at, char num) const
{
@ -476,6 +482,37 @@ inline char string::operator[](char t) const
return cstr[t + 1];
}
char * string::begin(void)
{
return cstr ? cstr + 1 : nullptr;
}
const char * string::begin(void) const
{
return cstr ? cstr + 1 : nullptr;
}
const char * string::cbegin(void) const
{
return cstr ? cstr + 1 : nullptr;
}
char * string::end(void)
{
return cstr ? cstr + 1 + cstr[0] : nullptr;
}
const char * string::end(void) const
{
return cstr ? cstr + 1 + cstr[0] : nullptr;
}
const char * string::cend(void) const
{
return cstr ? cstr + 1 + cstr[0] : nullptr;
}
string string::substr(char pos, char len) const
{
if (!cstr || len == 0 || pos >= cstr[0])

View File

@ -21,6 +21,8 @@ public:
unsigned size(void) const;
void clear(void);
string & operator=(const string & s);
string & operator=(string && s);
string & operator=(const char * s);
@ -57,6 +59,14 @@ public:
char & operator[](char t);
char operator[](char t) const;
char * begin(void);
const char * begin(void) const;
const char * cbegin(void) const;
char * end(void);
const char * end(void) const;
const char * cend(void) const;
const char * tocstr(void) const;
string substr(char pos, char len) const;

View File

@ -1501,7 +1501,7 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
}
else if (tdec->mType == DT_TYPE_POINTER)
{
if (fdec->mType == DT_TYPE_POINTER)
if (fdec->mType == DT_TYPE_POINTER || fdec->mType == DT_TYPE_ARRAY)
return ResolveTemplate(fdec->mBase, tdec->mBase);
else
return false;
@ -1510,6 +1510,8 @@ bool Declaration::ResolveTemplate(Declaration* fdec, Declaration* tdec)
{
if (fdec->mType == DT_TYPE_ARRAY)
fdec = fdec->mBase->BuildPointer(fdec->mLocation);
else if (fdec->mType == DT_TYPE_FUNCTION)
fdec = fdec->BuildPointer(fdec->mLocation);
Declaration* pdec;
if (tdec->mBase)
@ -1816,6 +1818,9 @@ bool Declaration::IsSubType(const Declaration* dec) const
if (this == dec)
return true;
if (mType == DT_TYPE_VOID)
return true;
if (IsReference() && dec->IsReference())
return mBase->IsSubType(dec->mBase);
@ -1996,8 +2001,10 @@ bool Declaration::IsTemplateSameParams(const Declaration* dec, const Declaration
{
if (mType == DT_TYPE_FUNCTION && dec->mType == DT_TYPE_FUNCTION)
{
// Skip this pointer for now
Declaration* ld = mParams->mNext, * rd = dec->mParams;
Declaration* ld = mParams, * rd = dec->mParams;
if (mFlags & DTF_FUNC_THIS)
ld = ld->mNext;
while (ld && rd)
{
if (!ld->mBase->IsTemplateSame(rd->mBase, tdec))
@ -2112,7 +2119,7 @@ bool Declaration::IsSame(const Declaration* dec) const
return mInteger == dec->mInteger;
else if (mType == DT_TYPE_INTEGER)
return true;
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID)
else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID || mType == DT_TYPE_AUTO)
return true;
else if (mType == DT_TYPE_ENUM)
return mIdent == dec->mIdent;

View File

@ -3539,6 +3539,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
{
vr.mReference++;
vr = Dereference(proc, texp, block, vr);
vr.mType = vr.mType->mBase;
}
else
vr = Dereference(proc, texp, block, vr);

View File

@ -25968,7 +25968,7 @@ bool NativeCodeBasicBlock::Check16BitSum(int at, NativeRegisterSum16Info& info)
return false;
}
bool NativeCodeBasicBlock::IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair)
bool NativeCodeBasicBlock::IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair, bool fchanged)
{
if (at == 0 && mVisited)
return false;
@ -25977,70 +25977,80 @@ bool NativeCodeBasicBlock::IsFinalZeroPageUse(const NativeCodeBasicBlock* block,
{
mPatched = true;
if (at == 0)
if (at != 0 || (mEntryRequiredRegs[from] || mEntryRequiredRegs[to] || (pair && (mEntryRequiredRegs[from + 1] || mEntryRequiredRegs[to + 1]))))
{
mPatched = true;
if (at == 0)
{
mPatched = true;
if (mNumEntries > 1)
{
for (int i = 0; i < mEntryBlocks.Size(); i++)
if (!mEntryBlocks[i]->IsDominatedBy(block))
return false;
}
}
while (at < mIns.Size())
{
if (mIns[at].mMode == ASMIM_ZERO_PAGE)
{
if (mIns[at].mAddress == to)
return false;
if (pair && mIns[at].mAddress == to + 1)
return false;
}
else if (mIns[at].mMode == ASMIM_INDIRECT_Y)
{
if (mIns[at].mAddress == to)
return false;
if (mIns[at].mAddress + 1 == to)
return false;
if (pair && mIns[at].mAddress == to + 1)
return false;
if (!pair && mIns[at].mAddress == from)
return false;
if (mIns[at].mAddress + 1 == from)
return false;
if (pair && mIns[at].mAddress == from + 1)
return false;
}
else if (mIns[at].mType == ASMIT_JSR)
{
LinkerObject* lo = mIns[at].mLinkerObject;
if (lo)
if (mNumEntries > 1)
{
for (int i = 0; i < lo->mNumTemporaries; i++)
fchanged = true;
for (int i = 0; i < mEntryBlocks.Size(); i++)
if (mEntryBlocks[i] != block && !mEntryBlocks[i]->IsDominatedBy(block))
return false;
}
}
while (at < mIns.Size())
{
if (mIns[at].mMode == ASMIM_ZERO_PAGE)
{
if (mIns[at].mAddress == to && (fchanged || mIns[at].ChangesAddress()))
return false;
if (pair && mIns[at].mAddress == to + 1 && (fchanged || mIns[at].ChangesAddress()))
return false;
if (mIns[at].mAddress == from && mIns[at].ChangesAddress())
fchanged = true;
if (pair && mIns[at].mAddress == from + 1 && mIns[at].ChangesAddress())
fchanged = true;
}
else if (mIns[at].mMode == ASMIM_INDIRECT_Y)
{
if (mIns[at].mAddress == to)
return false;
if (mIns[at].mAddress + 1 == to)
return false;
if (pair && mIns[at].mAddress == to + 1)
return false;
if (!pair && mIns[at].mAddress == from)
return false;
if (mIns[at].mAddress + 1 == from)
return false;
if (pair && mIns[at].mAddress == from + 1)
return false;
}
else if (mIns[at].mType == ASMIT_JSR)
{
fchanged = true;
LinkerObject* lo = mIns[at].mLinkerObject;
if (lo)
{
if (from >= lo->mTemporaries[i] && from < lo->mTemporaries[i] + lo->mTempSizes[i] ||
to >= lo->mTemporaries[i] && to < lo->mTemporaries[i] + lo->mTempSizes[i])
for (int i = 0; i < lo->mNumTemporaries; i++)
{
if (from >= lo->mTemporaries[i] && from < lo->mTemporaries[i] + lo->mTempSizes[i] ||
to >= lo->mTemporaries[i] && to < lo->mTemporaries[i] + lo->mTempSizes[i])
return false;
}
}
if (mIns[at].mFlags & NCIF_USE_ZP_32_X)
{
if (to >= mIns[at].mParam && to < mIns[at].mParam + 4 ||
from >= mIns[at].mParam && from < mIns[at].mParam + 4)
return false;
}
}
if (mIns[at].mFlags & NCIF_USE_ZP_32_X)
{
if (to >= mIns[at].mParam && to < mIns[at].mParam + 4 ||
from >= mIns[at].mParam && from < mIns[at].mParam + 4)
return false;
}
at++;
}
at++;
if (mTrueJump && !mTrueJump->IsFinalZeroPageUse(block, 0, from, to, pair, fchanged))
return false;
if (mFalseJump && !mFalseJump->IsFinalZeroPageUse(block, 0, from, to, pair, fchanged))
return false;
}
if (mTrueJump && !mTrueJump->IsFinalZeroPageUse(block, 0, from, to, pair))
return false;
if (mFalseJump && !mFalseJump->IsFinalZeroPageUse(block, 0, from, to, pair))
return false;
}
return true;
@ -26065,7 +26075,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
mIns[i + 1].mAddress >= BC_REG_TMP)
{
nproc->ResetPatched();
if (IsFinalZeroPageUse(this, i + 2, mIns[i + 1].mAddress, mIns[i + 0].mAddress, false))
if (IsFinalZeroPageUse(this, i + 2, mIns[i + 1].mAddress, mIns[i + 0].mAddress, false, false))
{
nproc->ResetPatched();
if (ForwardReplaceZeroPage(i + 2, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
@ -26084,7 +26094,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
mIns[i + 1].mAddress >= BC_REG_TMP)
{
nproc->ResetPatched();
if (IsFinalZeroPageUse(this, i + 4, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true))
if (IsFinalZeroPageUse(this, i + 4, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true, false))
{
nproc->ResetPatched();
if (ForwardReplaceZeroPage(i + 4, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
@ -26110,7 +26120,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
mIns[i + 2].mAddress >= BC_REG_TMP)
{
nproc->ResetPatched();
if (IsFinalZeroPageUse(this, i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress, true))
if (IsFinalZeroPageUse(this, i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress, true, false))
{
nproc->ResetPatched();
if (ForwardReplaceZeroPage(i + 6, mIns[i + 2].mAddress, mIns[i + 0].mAddress))
@ -26135,7 +26145,7 @@ bool NativeCodeBasicBlock::ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc)
mIns[i + 1].mAddress >= BC_REG_TMP)
{
nproc->ResetPatched();
if (IsFinalZeroPageUse(this, i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true))
if (IsFinalZeroPageUse(this, i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress, true, false))
{
nproc->ResetPatched();
if (ForwardReplaceZeroPage(i + 5, mIns[i + 1].mAddress, mIns[i + 0].mAddress))
@ -41341,7 +41351,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{
mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "dungeon_rand_path");
CheckFunc = !strcmp(mInterProc->mIdent->mString, "mod<struct lambda#0>");
int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks];
@ -42025,6 +42035,7 @@ void NativeCodeProcedure::Optimize(void)
#if 1
if (step == 2)
{
BuildDataFlowSets();
ResetVisited();
mEntryBlock->ReplaceFinalZeroPageUse(this);
}

View File

@ -543,7 +543,7 @@ public:
bool Check16BitSum(const NativeCodeBasicBlock* block, int origin, int at, int reg);
bool EliminateUpper16BitSum(NativeCodeProcedure* nproc);
bool IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair);
bool IsFinalZeroPageUse(const NativeCodeBasicBlock* block, int at, int from, int to, bool pair, bool fchanged);
bool ReplaceFinalZeroPageUse(NativeCodeProcedure* nproc);
bool ForwardReplaceZeroPage(int at, int from, int to);

View File

@ -297,7 +297,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
mdec->mType = DT_CONST_FUNCTION;
mdec->mSection = mCodeSection;
mdec->mFlags |= DTF_GLOBAL;
mdec->mBase->mFlags |= DTF_FUNC_THIS;
// mdec->mBase->mFlags |= DTF_FUNC_THIS;
if (mCompilerOptions & COPT_NATIVE)
mdec->mFlags |= DTF_NATIVE;
@ -627,7 +627,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
Declaration* Parser::ParseBaseTypeQualify(bool qualified, Declaration* dec, const Ident*& pident)
{
while (dec && (dec->mType == DT_NAMESPACE || (qualified && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_TYPE_TEMPLATE))) && ConsumeTokenIf(TK_COLCOLON))
while (dec && (dec->mType == DT_NAMESPACE || (qualified && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_TYPE_TEMPLATE)) && !dec->mTemplate) && ConsumeTokenIf(TK_COLCOLON))
{
if (ExpectToken(TK_IDENT))
{
@ -3168,7 +3168,7 @@ void Parser::PrependThisArgument(Declaration* fdec, Declaration* pthis)
}
fdec->mParams = adec;
fdec->mClass = pthis;
fdec->mFlags |= DTF_FUNC_THIS;
}
@ -4161,12 +4161,15 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
if (ndec->mBase->mType == DT_TYPE_FUNCTION)
{
if (pthis)
ndec->mBase->mClass = pthis;
if (pthis && !(storageFlags & DTF_STATIC))
{
if (ConsumeTokenIf(TK_CONST))
PrependThisArgument(ndec->mBase, pthis->mBase->ToConstType()->BuildConstPointer(ndec->mLocation));
else
PrependThisArgument(ndec->mBase, pthis);
ndec->mBase->mFlags |= DTF_FUNC_THIS;
}
}
@ -4236,30 +4239,41 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
{
if (pdec->mBase->mFlags & DTF_FUNC_THIS)
{
Declaration* adec = pdec->mBase->mParams->Clone();
adec->mNext = ndec->mBase->mParams;
if (ConsumeTokenIf(TK_CONST))
if (!(ndec->mBase->mFlags & DTF_FUNC_THIS))
{
if (!(adec->mBase->mBase->mFlags & DTF_CONST))
adec->mBase = adec->mBase->mBase->ToConstType()->BuildConstPointer(adec->mLocation);
Declaration* adec = pdec->mBase->mParams->Clone();
adec->mNext = ndec->mBase->mParams;
if (ConsumeTokenIf(TK_CONST))
{
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)
{
p->mVarIndex += 2;
p = p->mNext;
}
ndec->mBase->mParams = adec;
ndec->mBase->mFlags |= DTF_FUNC_THIS;
}
}
else if (ndec->mBase->mFlags & DTF_FUNC_THIS)
{
if (pdec->mBase->mParams)
ndec->mBase->mParams = pdec->mBase->mParams->Clone();
else
{
if (adec->mBase->mBase->mFlags & DTF_CONST)
adec->mBase = adec->mBase->mBase->ToMutableType()->BuildConstPointer(adec->mLocation);
}
Declaration* p = adec->mBase->mParams;
while (p)
{
p->mVarIndex += 2;
p = p->mNext;
}
ndec->mBase->mParams = adec;
ndec->mBase->mFlags |= DTF_FUNC_THIS;
ndec->mBase->mParams = nullptr;
ndec->mBase->mFlags &= ~DTF_FUNC_THIS;
}
if (mCompilerOptions & COPT_CPLUSPLUS)
@ -4777,10 +4791,14 @@ Expression* Parser::ParseLambdaExpression(void)
pdec->mSize = 2;
Expression* einit = nullptr;
bool capture = false;
ConsumeToken(TK_OPEN_BRACKET);
if (!ConsumeTokenIf(TK_CLOSE_BRACKET))
{
capture = true;
// Parse capture list list
do {
bool reference = false;
@ -4880,7 +4898,8 @@ Expression* Parser::ParseLambdaExpression(void)
fdec->mBase = TheConstVoidTypeDeclaration;
}
PrependThisArgument(fdec->mBase, cpdec);
if (capture)
PrependThisArgument(fdec->mBase, cpdec);
fdec->mFlags |= fdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE);
@ -5296,12 +5315,16 @@ Expression* Parser::ParseSimpleExpression(bool lhs)
}
}
if (mThisPointer && mThisPointer->mType == DT_ARGUMENT && !mScope->Lookup(mScanner->mTokenIdent, SLEVEL_FUNCTION))
if (mThisPointer && !mScope->Lookup(mScanner->mTokenIdent, SLEVEL_FUNCTION))
{
int offset;
uint64 flags;
dec = MemberLookup(mThisPointer->mBase->mBase, mScanner->mTokenIdent, offset, flags);
if (mThisPointer->mType == DT_ARGUMENT)
dec = MemberLookup(mThisPointer->mBase->mBase, mScanner->mTokenIdent, offset, flags);
else if (mThisPointer->mType == DT_TYPE_POINTER)
dec = MemberLookup(mThisPointer->mBase, mScanner->mTokenIdent, offset, flags);
if (dec)
{
if (dec->mType == DT_ELEMENT || dec->mType == DT_CONST_FUNCTION)
@ -5670,55 +5693,65 @@ Expression* Parser::ParseQualify(Expression* exp)
}
else if (mdec->mType == DT_CONST_FUNCTION)
{
ConsumeToken(TK_OPEN_PARENTHESIS);
nexp = new Expression(mScanner->mLocation, EX_CALL);
if (mInlineCall)
nexp->mType = EX_INLINE;
mInlineCall = false;
nexp->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
nexp->mLeft->mDecType = mdec->mBase;
nexp->mLeft->mDecValue = mdec;
nexp->mDecType = mdec->mBase;
if (ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
nexp->mRight = nullptr;
else
if (mdec->mBase->mFlags & DTF_FUNC_THIS)
{
nexp->mRight = ParseListExpression(false);
ConsumeToken(TK_CLOSE_PARENTHESIS);
}
ConsumeToken(TK_OPEN_PARENTHESIS);
Expression* texp = new Expression(nexp->mLocation, EX_PREFIX);
texp->mToken = TK_BINARY_AND;
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;
nexp = new Expression(mScanner->mLocation, EX_CALL);
if (mInlineCall)
nexp->mType = EX_INLINE;
mInlineCall = false;
if (nexp->mRight)
{
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp;
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
nexp->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT);
nexp->mLeft->mDecType = mdec->mBase;
nexp->mLeft->mDecValue = mdec;
nexp->mDecType = mdec->mBase;
if (ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
nexp->mRight = nullptr;
else
{
nexp->mRight = ParseListExpression(false);
ConsumeToken(TK_CLOSE_PARENTHESIS);
}
Expression* texp = new Expression(nexp->mLocation, EX_PREFIX);
texp->mToken = TK_BINARY_AND;
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;
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 = nexp->mLeft->mDecType->mBase;
if (nexp->mLeft->mDecType->mFlags & DTF_VIRTUAL)
nexp->mType = EX_VCALL;
exp = nexp;
}
else
nexp->mRight = texp;
nexp = ResolveOverloadCall(nexp);
nexp->mDecType = nexp->mLeft->mDecType->mBase;
if (nexp->mLeft->mDecType->mFlags & DTF_VIRTUAL)
nexp->mType = EX_VCALL;
exp = nexp;
{
nexp = new Expression(mScanner->mLocation, EX_CONSTANT);
nexp->mDecValue = mdec;
nexp->mDecType = mdec->mBase;
exp = nexp;
}
}
}
else if (destructor)
@ -6499,37 +6532,40 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
}
bool parentCall = false;
if (thisExp)
if (exp->mDecType->mFlags & DTF_FUNC_THIS)
{
if (nexp->mRight)
if (thisExp)
{
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = thisExp;
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
}
else
nexp->mRight = thisExp;
}
else
{
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->mLeft = thisExp;
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
}
else
nexp->mRight = texp;
nexp->mRight = thisExp;
}
else
{
if (mThisPointer && mThisPointer->mType == DT_ARGUMENT)
{
Expression* texp = new Expression(mScanner->mLocation, EX_VARIABLE);
texp->mDecType = mThisPointer->mBase;
texp->mDecValue = mThisPointer;
parentCall = true;
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;
parentCall = true;
}
}
}
@ -8210,6 +8246,8 @@ Expression* Parser::ParseFunction(Declaration * dec)
if (dec->mFlags & DTF_FUNC_THIS)
mThisPointer = dec->mParams;
else
mThisPointer = dec->mClass;
mFunctionType = dec;
@ -9220,7 +9258,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
pdec = new Declaration(exp->mLocation, DT_TYPE_TEMPLATE);
pdec->mBase = exp->mDecValue;
}
else if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER)
else if (exp->mType == EX_CONSTANT && (exp->mDecValue->mType == DT_CONST_INTEGER || exp->mDecValue->mType == DT_CONST_TEMPLATE))
{
pdec = new Declaration(exp->mLocation, DT_CONST_TEMPLATE);
pdec->mBase = exp->mDecValue;
@ -9257,6 +9295,9 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
tdec->mBase = bdec;
bdec->mTemplate = tdec;
bdec->mBase = tmpld->mBase->mBase;
tdec->mIdent = tmpld->mIdent;
tdec->mQualIdent = tmpld->mQualIdent;
tdec->mScope->mName = tdec->mIdent;
tdec->mNext = tmpld;
bdec->mIdent = tdec->MangleIdent();
@ -9511,6 +9552,7 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
tdec->mBase = ndec;
ndec->mValue = p->ParseFunction(ndec->mBase);
ndec->mNumVars = mLocalIndex;
ndec->mFlags |= DTF_DEFINED;
ndec->mIdent = ndec->mIdent->Mangle(tdec->mScope->mName->mString);
@ -9518,7 +9560,13 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
}
else
{
tdec->mBase = p->ParseDeclaration(nullptr, true, false, tmpld->mClass, tdec);
Declaration* tpthis = nullptr;
if (tmpld->mClass)
tpthis = tmpld->mClass;
else if (expd && expd->mBase)
tpthis = expd->mBase->BuildConstPointer(tdec->mLocation);
tdec->mBase = p->ParseDeclaration(nullptr, true, false, tpthis, tdec);
}
p->mTemplateScope = nullptr;
@ -9541,15 +9589,19 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
mpdec = mpdec->mNext;
if (mpdec && mpdec->mTemplate)
{
Declaration* rdec;
if (mdec->mTemplate)
{
Declaration * mtdec = p->ParseTemplateExpansion(mpdec->mTemplate, tdec);
mtdec->mClass = mdec->mTemplate->mClass;
mdec->mTemplate = mtdec;
mdec->mTemplate->mBase = mdec;
rdec = mtdec;
}
else
p->ParseTemplateExpansion(mpdec->mTemplate, tdec);
rdec = p->ParseTemplateExpansion(mpdec->mTemplate, tdec);
if (mdec->mBase->mBase->IsAuto())
mdec->mBase->mBase = rdec->mBase->mBase;
}
}
@ -9824,9 +9876,30 @@ void Parser::ParseTemplateDeclarationBody(Declaration * tdec, Declaration * pthi
ConsumeTokenIf(TK_CONSTEXPR);
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
Declaration* adec = ParsePostfixDeclaration();
Declaration* adec = nullptr;
adec = ReverseDeclaration(adec, bdec);
if (ConsumeTokenIf(TK_COLCOLON) && ExpectToken(TK_IDENT) && mScanner->mTokenIdent == bdec->mTemplate->mIdent)
{
mScanner->NextToken();
Declaration* ctdec = ParseFunctionDeclaration(TheVoidTypeDeclaration);
adec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION);
adec->mBase = ctdec;
adec->mIdent = bdec->mTemplate->mIdent->PreMangle("+");
char buffer[200];
strcpy_s(buffer, bdec->mTemplate->mQualIdent->mString);
strcat_s(buffer, "::");
strcat_s(buffer, adec->mIdent->mString);
adec->mQualIdent = Ident::Unique(buffer);
}
else
{
adec = ParsePostfixDeclaration();
adec = ReverseDeclaration(adec, bdec);
}
mTemplateScope = tdec->mScope->mParent;

View File

@ -541,7 +541,7 @@ void Scanner::NextPreToken(void)
mPreprocessorMode = true;
mPrepCondFalse = 0;
NextToken();
NextPreToken();
int64 v = PrepParseConditional();
if (v)
{
@ -612,7 +612,7 @@ void Scanner::NextPreToken(void)
if (mToken == TK_COMMA)
{
mPreprocessorMode = true;
NextToken();
NextPreToken();
int64 loopCount = PrepParseConditional();
mPreprocessorMode = false;
@ -771,7 +771,7 @@ void Scanner::NextPreToken(void)
else if (mToken == TK_PREP_IF)
{
mPreprocessorMode = true;
NextToken();
NextPreToken();
int64 v = PrepParseConditional();
if (v)
mPrepCondDepth++;
@ -789,7 +789,7 @@ void Scanner::NextPreToken(void)
{
const Ident* ident = mTokenIdent;
NextToken();
NextPreToken();
int64 v = PrepParseConditional();
Macro* macro = mDefines->Lookup(ident);
@ -813,7 +813,7 @@ void Scanner::NextPreToken(void)
else if (mToken == TK_PREP_UNTIL)
{
mPreprocessorMode = true;
NextToken();
NextPreToken();
int64 v = PrepParseConditional();
if (mToken != TK_EOL)
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "End of line expected");
@ -1136,14 +1136,14 @@ void Scanner::NextRawToken(void)
}
}
NextChar();
NextToken();
NextPreToken();
}
else if (mTokenChar == '/')
{
NextChar();
while (!IsLineBreak(mTokenChar) && NextChar())
;
NextToken();
NextPreToken();
}
else if (mTokenChar == '=')
{
@ -2237,32 +2237,32 @@ int64 Scanner::PrepParseSimple(void)
case TK_INTEGERL:
case TK_INTEGERUL:
v = mTokenInteger;
NextToken();
NextPreToken();
break;
case TK_SUB:
NextToken();
NextPreToken();
v = -PrepParseSimple();
break;
case TK_LOGICAL_NOT:
NextToken();
NextPreToken();
v = !PrepParseSimple();
break;
case TK_BINARY_NOT:
NextToken();
NextPreToken();
v = ~PrepParseSimple();
break;
case TK_OPEN_PARENTHESIS:
NextToken();
NextPreToken();
v = PrepParseConditional();
if (mToken == TK_CLOSE_PARENTHESIS)
NextToken();
NextPreToken();
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
break;
case TK_IDENT:
if (strcmp(mTokenIdent->mString, "defined") == 0)
{
NextToken();
NextPreToken();
if (mToken == TK_OPEN_PARENTHESIS)
{
NextRawToken();
@ -2277,13 +2277,13 @@ int64 Scanner::PrepParseSimple(void)
v = 1;
else
v = 0;
NextToken();
NextPreToken();
}
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Identifier expected");
if (mToken == TK_CLOSE_PARENTHESIS)
NextToken();
NextPreToken();
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "')' expected");
}
@ -2296,7 +2296,7 @@ int64 Scanner::PrepParseSimple(void)
default:
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Invalid preprocessor token", TokenName(mToken));
if (mToken != TK_EOL)
NextToken();
NextPreToken();
}
return v;
@ -2311,11 +2311,11 @@ int64 Scanner::PrepParseMul(void)
switch (mToken)
{
case TK_MUL:
NextToken();
NextPreToken();
v *= PrepParseSimple();
break;
case TK_DIV:
NextToken();
NextPreToken();
u = PrepParseSimple();
if (u == 0)
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "Division by zero");
@ -2343,11 +2343,11 @@ int64 Scanner::PrepParseAdd(void)
switch (mToken)
{
case TK_ADD:
NextToken();
NextPreToken();
v += PrepParseMul();
break;
case TK_SUB:
NextToken();
NextPreToken();
v -= PrepParseMul();
break;
default:
@ -2364,11 +2364,11 @@ int64 Scanner::PrepParseShift(void)
switch (mToken)
{
case TK_LEFT_SHIFT:
NextToken();
NextPreToken();
v <<= PrepParseAdd();
break;
case TK_RIGHT_SHIFT:
NextToken();
NextPreToken();
v >>= PrepParseAdd();
break;
default:
@ -2385,27 +2385,27 @@ int64 Scanner::PrepParseRel(void)
switch (mToken)
{
case TK_LESS_THAN:
NextToken();
NextPreToken();
v = v < PrepParseShift();
break;
case TK_GREATER_THAN:
NextToken();
NextPreToken();
v = v > PrepParseShift();
break;
case TK_LESS_EQUAL:
NextToken();
NextPreToken();
v = v <= PrepParseShift();
break;
case TK_GREATER_EQUAL:
NextToken();
NextPreToken();
v = v >= PrepParseShift();
break;
case TK_EQUAL:
NextToken();
NextPreToken();
v = v == PrepParseShift();
break;
case TK_NOT_EQUAL:
NextToken();
NextPreToken();
v = v != PrepParseShift();
break;
default:
@ -2420,7 +2420,7 @@ int64 Scanner::PrepParseBinaryAnd(void)
int64 v = PrepParseRel();
while (mToken == TK_BINARY_AND)
{
NextToken();
NextPreToken();
v &= PrepParseRel();
}
return v;
@ -2431,7 +2431,7 @@ int64 Scanner::PrepParseBinaryXor(void)
int64 v = PrepParseBinaryAnd();
while (mToken == TK_BINARY_XOR)
{
NextToken();
NextPreToken();
v ^= PrepParseBinaryAnd();
}
return v;
@ -2442,7 +2442,7 @@ int64 Scanner::PrepParseBinaryOr(void)
int64 v = PrepParseBinaryXor();
while (mToken == TK_BINARY_OR)
{
NextToken();
NextPreToken();
v |= PrepParseBinaryXor();
}
return v;
@ -2453,7 +2453,7 @@ int64 Scanner::PrepParseLogicalAnd(void)
int64 v = PrepParseBinaryOr();
while (mToken == TK_LOGICAL_AND)
{
NextToken();
NextPreToken();
if (!PrepParseBinaryOr())
v = 0;
}
@ -2465,7 +2465,7 @@ int64 Scanner::PrepParseLogicalOr(void)
int64 v = PrepParseLogicalAnd();
while (mToken == TK_LOGICAL_OR)
{
NextToken();
NextPreToken();
if (PrepParseLogicalAnd())
v = 1;
}
@ -2477,10 +2477,10 @@ int64 Scanner::PrepParseConditional(void)
int64 v = PrepParseLogicalOr();
if (mToken == TK_QUESTIONMARK)
{
NextToken();
NextPreToken();
int64 vt = PrepParseConditional();
if (mToken == TK_COLON)
NextToken();
NextPreToken();
else
mErrors->Error(mLocation, ERRR_PREPROCESSOR, "':' expected");
int64 vf = PrepParseConditional();