From 33d692194ade82700282f9d083ea0fc15d3bf153 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 8 Oct 2023 16:27:52 +0200 Subject: [PATCH] Add iterators to string --- include/ctype.c | 17 ++ include/ctype.h | 3 + include/opp/iostream.cpp | 13 ++ include/opp/iostream.h | 1 + include/opp/string.cpp | 37 +++++ include/opp/string.h | 10 ++ oscar64/Declaration.cpp | 15 +- oscar64/InterCodeGenerator.cpp | 1 + oscar64/NativeCodeGenerator.cpp | 129 ++++++++------- oscar64/NativeCodeGenerator.h | 2 +- oscar64/Parser.cpp | 269 ++++++++++++++++++++------------ oscar64/Scanner.cpp | 72 ++++----- 12 files changed, 371 insertions(+), 198 deletions(-) diff --git a/include/ctype.c b/include/ctype.c index bac6f8e..650cb36 100644 --- a/include/ctype.c +++ b/include/ctype.c @@ -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; +} diff --git a/include/ctype.h b/include/ctype.h index 3da3a47..f4f9a61 100644 --- a/include/ctype.h +++ b/include/ctype.h @@ -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") diff --git a/include/opp/iostream.cpp b/include/opp/iostream.cpp index ed44e08..0516c5a 100644 --- a/include/opp/iostream.cpp +++ b/include/opp/iostream.cpp @@ -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) {} diff --git a/include/opp/iostream.h b/include/opp/iostream.h index 5d43bc6..f42d1e5 100644 --- a/include/opp/iostream.h +++ b/include/opp/iostream.h @@ -132,6 +132,7 @@ public: istream & operator>>(float & val); istream & operator>>(char * p); + istream & operator>>(string & s); istream(void); protected: diff --git a/include/opp/string.cpp b/include/opp/string.cpp index b5732a4..f72d1c4 100644 --- a/include/opp/string.cpp +++ b/include/opp/string.cpp @@ -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]) diff --git a/include/opp/string.h b/include/opp/string.h index 35ccd47..7bbb167 100644 --- a/include/opp/string.h +++ b/include/opp/string.h @@ -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; diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 6336f1e..a24e0bc 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -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; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index c20bdbe..f3ecaa6 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -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); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 885615a..97f6ace 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -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"); 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); } diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index aab4daf..c674169 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -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); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 5650e0d..7657234 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -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; diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index 5393807..2a48e37 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -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();