diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index ff2dce2..ee4bc30 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -636,6 +636,7 @@ Declaration::Declaration(const Location& loc, DecType type) : mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mConst(nullptr), + mConstructor(nullptr), mDestructor(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1), mCompilerOptions(0), mUseCount(0) diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 47d0c64..df00664 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -93,6 +93,7 @@ static const uint64 DTF_FPARAM_CONST = (1ULL << 40); static const uint64 DTF_FPARAM_NOCONST = (1ULL << 41); static const uint64 DTF_FUNC_THIS = (1ULL << 42); +static const uint64 DTF_FUNC_CONSTRUCTOR = (1ULL << 43); static const uint64 DTF_VAR_ALIASING = (1ULL << 48); @@ -214,7 +215,7 @@ public: Location mLocation, mEndLocation; DecType mType; Token mToken; - Declaration* mBase, *mParams, * mNext, * mConst; + Declaration* mBase, *mParams, * mNext, * mConst, * mConstructor, * mDestructor; Expression* mValue; DeclarationScope* mScope; int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment, mFastCallBase, mFastCallSize, mStride, mStripe; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 15b1913..3e8963b 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -16624,6 +16624,7 @@ void InterCodeProcedure::Close(void) if (var && !var->mTemp && !var->mLinkerObject) { var->mLinkerObject = mModule->mLinker->AddObject(mLocation, var->mIdent, mLinkerObject->mStackSection, LOT_BSS); + var->mLinkerObject->mFlags |= LOBJF_LOCAL_VAR; var->mLinkerObject->AddSpace(var->mSize); var->mIndex = mModule->mGlobalVars.Size(); mModule->mGlobalVars.Push(var); diff --git a/oscar64/Linker.h b/oscar64/Linker.h index e3ee519..ab6b3a8 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -151,6 +151,8 @@ static const uint32 LOBJF_ARG_REG_Y = 0x00004000; static const uint32 LOBJF_RET_REG_A = 0x00010000; static const uint32 LOBJF_RET_REG_X = 0x00020000; +static const uint32 LOBJF_LOCAL_VAR = 0x00100000; +static const uint32 LOBJF_LOCAL_USED = 0x00200000; class LinkerObjectRange { diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 7d1ba92..d713f80 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -26983,6 +26983,150 @@ bool NativeCodeBasicBlock::ReverseBitfieldForwarding(void) return changed; } +struct NativeCodeLoadStorePair +{ + NativeCodeInstruction mLoad, mStore; +}; + +bool NativeCodeBasicBlock::RemoveLocalUnusedLinkerObjects(void) +{ + bool changed = false; + + if (!mVisited) + { + mVisited = true; + + + for (int i = 0; i < mIns.Size(); i++) + { + NativeCodeInstruction& ins(mIns[i]); + if (ins.mLinkerObject && (ins.mLinkerObject->mFlags & LOBJF_LOCAL_VAR) && !(ins.mLinkerObject->mFlags & LOBJF_LOCAL_USED)) + { + ins.mType = ASMIT_NOP; + ins.mMode = ASMIM_IMPLIED; + changed = true; + } + } + + if (mTrueJump && mTrueJump->RemoveLocalUnusedLinkerObjects()) + changed = true; + if (mFalseJump && mFalseJump->RemoveLocalUnusedLinkerObjects()) + changed = true; + } + + return changed; +} + +void NativeCodeBasicBlock::MarkLocalUsedLinkerObjects(void) +{ + if (!mVisited) + { + mVisited = true; + + for (int i = 0; i < mIns.Size(); i++) + { + NativeCodeInstruction& ins(mIns[i]); + if (ins.mLinkerObject) + { + if (ins.mMode == ASMIM_IMMEDIATE_ADDRESS && ins.UsesAddress()) + ins.mLinkerObject->mFlags |= LOBJF_LOCAL_USED; + } + } + + if (mTrueJump) mTrueJump->MarkLocalUsedLinkerObjects(); + if (mFalseJump) mFalseJump->MarkLocalUsedLinkerObjects(); + } +} + +bool NativeCodeBasicBlock::AbsoluteValueForwarding(void) +{ + bool changed = false; + + if (!mVisited) + { + mVisited = true; + + ExpandingArray pairs; + + int ains = -1; + + for (int i = 0; i < mIns.Size(); i++) + { + // Check content of accu + if (mIns[i].mType == ASMIT_LDA) + { + if (mIns[i].mMode == ASMIM_IMMEDIATE || mIns[i].mMode == ASMIM_ZERO_PAGE) + ains = i; + else if (mIns[i].mMode == ASMIM_ABSOLUTE && !(mIns[i].mFlags & NCIF_VOLATILE)) + { + int j = 0; + while (j < pairs.Size() && !pairs[j].mStore.SameEffectiveAddress(mIns[i])) + j++; + if (j < pairs.Size()) + { + mIns[i].CopyMode(pairs[j].mLoad); + ains = i; + changed = true; + } + else + ains = -1; + } + else + ains = -1; + } + else if (mIns[i].ChangesAccu()) + ains = -1; + else if (ains >= 0 && mIns[ains].MayBeChangedOnAddress(mIns[i])) + ains = -1; + + if (ains >= 0 && mIns[i].mType == ASMIT_STA && mIns[i].mMode == ASMIM_ABSOLUTE && !(mIns[i].mFlags & NCIF_VOLATILE)) + { + int j = 0; + while (j < pairs.Size() && !pairs[j].mStore.SameEffectiveAddress(mIns[i])) + j++; + if (j < pairs.Size()) + { + pairs[j].mLoad = mIns[ains]; + pairs[j].mStore = mIns[i]; + } + else + { + NativeCodeLoadStorePair pair; + pair.mLoad = mIns[ains]; + pair.mStore = mIns[i]; + pairs.Push(pair); + } + } + else if (mIns[i].mType == ASMIT_JSR) + { + pairs.SetSize(0); + ains = -1; + } + else if (mIns[i].ChangesAddress()) + { + int j = 0, k = 0; + while (j < pairs.Size()) + { + if (!pairs[j].mLoad.MayBeChangedOnAddress(mIns[i]) && !pairs[j].mStore.MayBeChangedOnAddress(mIns[i])) + { + if (k != j) + pairs[k] = pairs[j]; + k++; + } + j++; + } + pairs.SetSize(k); + } + } + + if (mTrueJump && mTrueJump->AbsoluteValueForwarding()) + changed = true; + if (mFalseJump && mFalseJump->AbsoluteValueForwarding()) + changed = true; + } + + return changed; +} bool NativeCodeBasicBlock::OffsetValueForwarding(const ValueNumberingDataSet& data) { @@ -39853,7 +39997,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "data"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "sprintf"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -40572,6 +40716,19 @@ void NativeCodeProcedure::Optimize(void) } } + if (step == 9) + { + ResetVisited(); + if (mEntryBlock->AbsoluteValueForwarding()) + { + changed = true; + + BuildDataFlowSets(); + ResetVisited(); + mEntryBlock->RemoveUnusedResultInstructions(); + } + } + #if _DEBUG ResetVisited(); mEntryBlock->CheckBlocks(); @@ -41051,6 +41208,15 @@ void NativeCodeProcedure::Optimize(void) } #endif + if (step == 10) + { + ResetVisited(); + mEntryBlock->MarkLocalUsedLinkerObjects(); + + ResetVisited(); + if (mEntryBlock->RemoveLocalUnusedLinkerObjects()) + changed = true; + } #endif if (step == 8) diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 9cb807a..1479b4d 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -465,6 +465,10 @@ public: bool BitFieldForwarding(const NativeRegisterDataSet& data); bool ReverseBitfieldForwarding(void); bool OffsetValueForwarding(const ValueNumberingDataSet & data); + bool AbsoluteValueForwarding(void); + + void MarkLocalUsedLinkerObjects(void); + bool RemoveLocalUnusedLinkerObjects(void); void CollectEntryBlocks(NativeCodeBasicBlock* block); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index a838821..912327e 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -118,30 +118,33 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) if (mCompilerOptions & COPT_NATIVE) mdec->mFlags |= DTF_NATIVE; - Declaration* pdec = dec->mScope->Insert(mdec->mIdent, mdec); - - if (pdec) + if (!(mdec->mFlags & DTF_FUNC_CONSTRUCTOR)) { - if (pdec->mType == DT_CONST_FUNCTION) + Declaration* pdec = dec->mScope->Insert(mdec->mIdent, mdec); + + if (pdec) { - Declaration* pcdec = nullptr; - - while (pdec && !mdec->mBase->IsSameParams(pdec->mBase)) + if (pdec->mType == DT_CONST_FUNCTION) { - pcdec = pdec; - pdec = pdec->mNext; - } + Declaration* pcdec = nullptr; - if (!pdec) - pcdec->mNext = mdec; + while (pdec && !mdec->mBase->IsSameParams(pdec->mBase)) + { + pcdec = pdec; + pdec = pdec->mNext; + } + + if (!pdec) + pcdec->mNext = mdec; + else + mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent); + } else mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent); } - else + else if (mCompilationUnits->mScope->Insert(mdec->mQualIdent, mdec)) mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent); } - else if (mCompilationUnits->mScope->Insert(mdec->mQualIdent, mdec)) - mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent); if (!(mdec->mFlags & DTF_DEFINED)) ConsumeToken(TK_SEMICOLON); @@ -595,82 +598,88 @@ Declaration* Parser::ParsePostfixDeclaration(void) } else if (mScanner->mToken == TK_OPEN_PARENTHESIS) { - Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION); - ndec->mSize = 0; - Declaration* pdec = nullptr; - mScanner->NextToken(); - if (mScanner->mToken != TK_CLOSE_PARENTHESIS) - { - int vi = 0; - for(;;) - { - if (mScanner->mToken == TK_ELLIPSIS) - { - ndec->mFlags |= DTF_VARIADIC; - mScanner->NextToken(); - break; - } - - Declaration* bdec = ParseBaseTypeDeclaration(0); - Declaration* adec = ParsePostfixDeclaration(); - - adec = ReverseDeclaration(adec, bdec); - - if (adec->mBase->mType == DT_TYPE_VOID) - { - if (pdec) - mErrors->Error(pdec->mLocation, EERR_WRONG_PARAMETER, "Invalid void argument"); - break; - } - else - { - if (!(adec->mBase->mFlags & DTF_DEFINED) && adec->mBase->mType != DT_TYPE_ARRAY) - mErrors->Error(adec->mLocation, EERR_UNDEFINED_OBJECT, "Type of argument not defined"); - - adec->mType = DT_ARGUMENT; - adec->mVarIndex = vi; - adec->mOffset = 0; - if (adec->mBase->mType == DT_TYPE_ARRAY) - { - Declaration * ndec = new Declaration(adec->mBase->mLocation, DT_TYPE_POINTER); - ndec->mBase = adec->mBase->mBase; - ndec->mSize = 2; - ndec->mFlags |= DTF_DEFINED; - adec->mBase = ndec; - } - - adec->mSize = adec->mBase->mSize; - - vi += adec->mSize; - if (pdec) - pdec->mNext = adec; - else - ndec->mParams = adec; - pdec = adec; - - if (mScanner->mToken == TK_COMMA) - mScanner->NextToken(); - else - break; - } - } - - if (mScanner->mToken == TK_CLOSE_PARENTHESIS) - mScanner->NextToken(); - else - mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "')' expected"); - } - else - mScanner->NextToken(); - ndec->mBase = dec; - ndec->mFlags |= DTF_DEFINED; - dec = ndec; + dec = ParseFunctionDeclaration(dec); } else return dec; } } +Declaration * Parser::ParseFunctionDeclaration(Declaration* bdec) +{ + Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_FUNCTION); + ndec->mSize = 0; + Declaration* pdec = nullptr; + mScanner->NextToken(); + if (mScanner->mToken != TK_CLOSE_PARENTHESIS) + { + int vi = 0; + for (;;) + { + if (mScanner->mToken == TK_ELLIPSIS) + { + ndec->mFlags |= DTF_VARIADIC; + mScanner->NextToken(); + break; + } + + Declaration* bdec = ParseBaseTypeDeclaration(0); + Declaration* adec = ParsePostfixDeclaration(); + + adec = ReverseDeclaration(adec, bdec); + + if (adec->mBase->mType == DT_TYPE_VOID) + { + if (pdec) + mErrors->Error(pdec->mLocation, EERR_WRONG_PARAMETER, "Invalid void argument"); + break; + } + else + { + if (!(adec->mBase->mFlags & DTF_DEFINED) && adec->mBase->mType != DT_TYPE_ARRAY) + mErrors->Error(adec->mLocation, EERR_UNDEFINED_OBJECT, "Type of argument not defined"); + + adec->mType = DT_ARGUMENT; + adec->mVarIndex = vi; + adec->mOffset = 0; + if (adec->mBase->mType == DT_TYPE_ARRAY) + { + Declaration* ndec = new Declaration(adec->mBase->mLocation, DT_TYPE_POINTER); + ndec->mBase = adec->mBase->mBase; + ndec->mSize = 2; + ndec->mFlags |= DTF_DEFINED; + adec->mBase = ndec; + } + + adec->mSize = adec->mBase->mSize; + + vi += adec->mSize; + if (pdec) + pdec->mNext = adec; + else + ndec->mParams = adec; + pdec = adec; + + if (mScanner->mToken == TK_COMMA) + mScanner->NextToken(); + else + break; + } + } + + if (mScanner->mToken == TK_CLOSE_PARENTHESIS) + mScanner->NextToken(); + else + mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "')' expected"); + } + else + mScanner->NextToken(); + ndec->mBase = bdec; + ndec->mFlags |= DTF_DEFINED; + + return ndec; +} + Declaration* Parser::ReverseDeclaration(Declaration* odec, Declaration* bdec) { Declaration* cdec = odec->mBase; @@ -1124,6 +1133,29 @@ Expression* Parser::ParseInitExpression(Declaration* dtype) return exp; } +void Parser::PrependThisArgument(Declaration* fdec, Declaration* pthis) +{ + Declaration* adec = new Declaration(fdec->mLocation, DT_ARGUMENT); + + adec->mVarIndex = 0; + adec->mOffset = 0; + adec->mBase = pthis; + adec->mSize = adec->mBase->mSize; + adec->mNext = fdec->mParams; + adec->mIdent = adec->mQualIdent = Ident::Unique("this"); + + Declaration* p = adec->mBase->mParams; + while (p) + { + p->mVarIndex += 2; + p = p->mNext; + } + + fdec->mParams = adec; + + fdec->mFlags |= DTF_FUNC_THIS; +} + Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool expression, Declaration* pthis) { bool definingType = false; @@ -1247,6 +1279,88 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex Declaration* rdec = nullptr, * ldec = nullptr; + if (mCompilerOptions & COPT_CPLUSPLUS) + { + if (bdec && pthis && bdec == pthis->mBase && mScanner->mToken == TK_OPEN_PARENTHESIS) + { + Declaration* ctdec = ParseFunctionDeclaration(TheVoidTypeDeclaration); + + PrependThisArgument(ctdec, pthis); + + Declaration* cdec = new Declaration(ctdec->mLocation, DT_CONST_FUNCTION); + cdec->mBase = ctdec; + + cdec->mFlags |= cdec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE); + cdec->mFlags |= DTF_FUNC_CONSTRUCTOR; + + cdec->mSection = mCodeSection; + cdec->mBase->mFlags |= typeFlags; + + if (mCompilerOptions & COPT_NATIVE) + cdec->mFlags |= DTF_NATIVE; + + Declaration* pdec = pthis->mBase->mConstructor; + if (pdec) + { + while (pdec && !cdec->mBase->IsSameParams(pdec->mBase)) + pdec = pdec->mNext; + } + + if (pdec) + { + if (!cdec->mBase->IsSame(pdec->mBase)) + mErrors->Error(cdec->mLocation, EERR_DECLARATION_DIFFERS, "Function declaration differs"); + else if (cdec->mFlags & ~pdec->mFlags & (DTF_HWINTERRUPT | DTF_INTERRUPT | DTF_FASTCALL | DTF_NATIVE)) + mErrors->Error(cdec->mLocation, EERR_DECLARATION_DIFFERS, "Function call type declaration differs"); + else + { + // + // Take parameter names from new declaration + // + Declaration* npdec = cdec->mBase->mParams, * ppdec = pdec->mBase->mParams; + while (npdec && ppdec) + { + if (npdec->mIdent) + { + ppdec->mIdent = npdec->mIdent; + ppdec->mQualIdent = npdec->mQualIdent; + } + npdec = npdec->mNext; + ppdec = ppdec->mNext; + } + } + + cdec = pdec; + } + else + { + cdec->mNext = pthis->mBase->mConstructor; + pthis->mBase->mConstructor = cdec; + } + + cdec->mIdent = pthis->mBase->mIdent; + cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent); + + if (mScanner->mToken == TK_OPEN_BRACE) + { + if (cdec->mFlags & DTF_DEFINED) + mErrors->Error(cdec->mLocation, EERR_DUPLICATE_DEFINITION, "Function already has a body"); + + cdec->mCompilerOptions = mCompilerOptions; + cdec->mBase->mCompilerOptions = mCompilerOptions; + + cdec->mVarIndex = -1; + + cdec->mValue = ParseFunction(cdec->mBase); + + cdec->mFlags |= DTF_DEFINED; + cdec->mNumVars = mLocalIndex; + } + + return cdec; + } + } + for (;;) { Declaration* ndec = ParsePostfixDeclaration(); @@ -1288,25 +1402,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex { if (ndec->mBase->mType == DT_TYPE_FUNCTION && pthis) { - Declaration* adec = new Declaration(ndec->mLocation, DT_ARGUMENT); - - adec->mVarIndex = 0; - adec->mOffset = 0; - adec->mBase = pthis; - adec->mSize = adec->mBase->mSize; - adec->mNext = ndec->mBase->mParams; - adec->mIdent = adec->mQualIdent = Ident::Unique("this"); - - Declaration* p = adec->mBase->mParams; - while (p) - { - p->mVarIndex += 2; - p = p->mNext; - } - - ndec->mBase->mParams = adec; - - ndec->mBase->mFlags |= DTF_FUNC_THIS; + PrependThisArgument(ndec->mBase, pthis); } if (variable) @@ -1625,7 +1721,7 @@ Declaration* Parser::ParseQualIdent(void) return dec; } -Expression* Parser::ParseSimpleExpression(void) +Expression* Parser::ParseSimpleExpression(bool lhs) { Declaration* dec; Expression* exp = nullptr, * rexp = nullptr; @@ -1641,6 +1737,15 @@ Expression* Parser::ParseSimpleExpression(void) case TK_VOID: case TK_UNSIGNED: case TK_SIGNED: + if (lhs) + exp = ParseDeclarationExpression(nullptr); + else + { + exp = new Expression(mScanner->mLocation, EX_TYPE); + exp->mDecValue = nullptr; + exp->mDecType = ParseBaseTypeDeclaration(0); + } + break; case TK_CONST: case TK_VOLATILE: case TK_STRUCT: @@ -1651,6 +1756,7 @@ Expression* Parser::ParseSimpleExpression(void) case TK_STRIPED: exp = ParseDeclarationExpression(nullptr); break; + case TK_CHARACTER: dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); dec->mInteger = mCharMap[(unsigned char)mScanner->mTokenInteger]; @@ -1864,7 +1970,14 @@ Expression* Parser::ParseSimpleExpression(void) } else if (dec->mType <= DT_TYPE_FUNCTION) { - exp = ParseDeclarationExpression(dec); + if (lhs) + exp = ParseDeclarationExpression(dec); + else + { + exp = new Expression(mScanner->mLocation, EX_TYPE); + exp->mDecValue = nullptr; + exp->mDecType = dec; + } } else { @@ -1887,7 +2000,7 @@ Expression* Parser::ParseSimpleExpression(void) case TK_OPEN_PARENTHESIS: mScanner->NextToken(); - exp = ParseExpression(); + exp = ParseExpression(true); if (mScanner->mToken == TK_CLOSE_PARENTHESIS) mScanner->NextToken(); else @@ -1916,7 +2029,7 @@ Expression* Parser::ParseSimpleExpression(void) Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST); nexp->mDecType = exp->mDecType; nexp->mLeft = exp; - nexp->mRight = ParsePrefixExpression(); + nexp->mRight = ParsePrefixExpression(false); exp = nexp->ConstantFold(mErrors); } } @@ -2153,9 +2266,9 @@ void Parser::ResolveOverloadCall(Expression* cexp, Expression* pexp) } } -Expression* Parser::ParsePostfixExpression(void) +Expression* Parser::ParsePostfixExpression(bool lhs) { - Expression* exp = ParseSimpleExpression(); + Expression* exp = ParseSimpleExpression(lhs); for (;;) { @@ -2166,7 +2279,7 @@ Expression* Parser::ParsePostfixExpression(void) mScanner->NextToken(); Expression* nexp = new Expression(mScanner->mLocation, EX_INDEX); nexp->mLeft = exp; - nexp->mRight = ParseExpression(); + nexp->mRight = ParseExpression(false); if (mScanner->mToken == TK_CLOSE_BRACKET) mScanner->NextToken(); else @@ -2178,40 +2291,115 @@ Expression* Parser::ParsePostfixExpression(void) } else if (mScanner->mToken == TK_OPEN_PARENTHESIS) { - if (exp->mDecType->mType == DT_TYPE_POINTER && exp->mDecType->mBase->mType == DT_TYPE_FUNCTION) - { - } - else if (exp->mDecType->mType == DT_TYPE_FUNCTION) + if (exp->mType == EX_TYPE) { + if (exp->mDecType->mConstructor) + { + Declaration* tdec = new Declaration(mScanner->mLocation, DT_VARIABLE); + + tdec->mBase = exp->mDecType; + tdec->mVarIndex = mLocalIndex++; + tdec->mSize = exp->mDecType->mSize; + tdec->mFlags |= DTF_DEFINED; + + Expression* vexp = new Expression(mScanner->mLocation, EX_VARIABLE); + vexp->mDecType = exp->mDecType; + vexp->mDecValue = tdec; + + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = exp->mDecType->mConstructor; + cexp->mDecType = cexp->mDecValue->mBase; + + Expression* fexp = new Expression(mScanner->mLocation, EX_CALL); + fexp->mLeft = cexp; + + mScanner->NextToken(); + if (mScanner->mToken != TK_CLOSE_PARENTHESIS) + { + fexp->mRight = ParseListExpression(); + ConsumeToken(TK_CLOSE_PARENTHESIS); + } + else + { + fexp->mRight = nullptr; + mScanner->NextToken(); + } + + Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX); + texp->mToken = TK_BINARY_AND; + texp->mLeft = vexp; + texp->mDecType = new Declaration(mScanner->mLocation, DT_TYPE_POINTER); + texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; + texp->mDecType->mBase = exp->mDecType; + texp->mDecType->mSize = 2; + + if (fexp->mRight) + { + Expression* lexp = new Expression(mScanner->mLocation, EX_LIST); + lexp->mLeft = texp; + lexp->mRight = fexp->mRight; + fexp->mRight = lexp; + } + else + fexp->mRight = texp; + + ResolveOverloadCall(cexp, fexp->mRight); + + Expression* nexp = new Expression(mScanner->mLocation, EX_SEQUENCE); + nexp->mLeft = fexp; + nexp->mRight = vexp; + nexp->mDecType = vexp->mDecType; + + exp = nexp; + } + else + { + Expression* nexp = new Expression(mScanner->mLocation, EX_TYPECAST); + nexp->mDecType = exp->mDecType; + nexp->mLeft = exp; + mScanner->NextToken(); + nexp->mRight = ParseListExpression(); + ConsumeToken(TK_CLOSE_PARENTHESIS); + exp = nexp->ConstantFold(mErrors); + } } else { - mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Function expected for call"); - exp->mDecType = TheVoidFunctionTypeDeclaration; - } + if (exp->mDecType->mType == DT_TYPE_POINTER && exp->mDecType->mBase->mType == DT_TYPE_FUNCTION) + { + } + else if (exp->mDecType->mType == DT_TYPE_FUNCTION) + { + } + else + { + mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Function expected for call"); + exp->mDecType = TheVoidFunctionTypeDeclaration; + } - mScanner->NextToken(); - Expression* nexp = new Expression(mScanner->mLocation, EX_CALL); - if (mInlineCall) - nexp->mType = EX_INLINE; - mInlineCall = false; - - nexp->mLeft = exp; - if (mScanner->mToken != TK_CLOSE_PARENTHESIS) - { - nexp->mRight = ParseListExpression(); - ConsumeToken(TK_CLOSE_PARENTHESIS); - } - else - { - nexp->mRight = nullptr; mScanner->NextToken(); + Expression* nexp = new Expression(mScanner->mLocation, EX_CALL); + if (mInlineCall) + nexp->mType = EX_INLINE; + mInlineCall = false; + + nexp->mLeft = exp; + if (mScanner->mToken != TK_CLOSE_PARENTHESIS) + { + nexp->mRight = ParseListExpression(); + ConsumeToken(TK_CLOSE_PARENTHESIS); + } + else + { + nexp->mRight = nullptr; + mScanner->NextToken(); + } + + ResolveOverloadCall(exp, nexp->mRight); + nexp->mDecType = exp->mDecType->mBase; + + exp = nexp; } - - ResolveOverloadCall(exp, nexp->mRight); - nexp->mDecType = exp->mDecType->mBase; - - exp = nexp; } else if (mScanner->mToken == TK_INC || mScanner->mToken == TK_DEC) { @@ -2283,7 +2471,7 @@ Expression* Parser::ParsePostfixExpression(void) } -Expression* Parser::ParsePrefixExpression(void) +Expression* Parser::ParsePrefixExpression(bool lhs) { if (mScanner->mToken == TK_SUB || mScanner->mToken == TK_BINARY_NOT || mScanner->mToken == TK_LOGICAL_NOT || mScanner->mToken == TK_MUL || mScanner->mToken == TK_INC || mScanner->mToken == TK_DEC || mScanner->mToken == TK_BINARY_AND || @@ -2293,7 +2481,7 @@ Expression* Parser::ParsePrefixExpression(void) if (mScanner->mToken == TK_LOGICAL_NOT) { mScanner->NextToken(); - nexp = ParsePrefixExpression(); + nexp = ParsePrefixExpression(false); nexp = nexp->LogicInvertExpression(); } else if (mScanner->mToken == TK_INC || mScanner->mToken == TK_DEC) @@ -2301,7 +2489,7 @@ Expression* Parser::ParsePrefixExpression(void) nexp = new Expression(mScanner->mLocation, EX_PREINCDEC); nexp->mToken = mScanner->mToken; mScanner->NextToken(); - nexp->mLeft = ParsePrefixExpression();; + nexp->mLeft = ParsePrefixExpression(false);; nexp->mDecType = nexp->mLeft->mDecType; } else @@ -2309,7 +2497,7 @@ Expression* Parser::ParsePrefixExpression(void) nexp = new Expression(mScanner->mLocation, EX_PREFIX); nexp->mToken = mScanner->mToken; mScanner->NextToken(); - nexp->mLeft = ParsePrefixExpression(); + nexp->mLeft = ParsePrefixExpression(false); if (nexp->mToken == TK_MUL) { if (nexp->mLeft->mDecType->mType == DT_TYPE_POINTER || nexp->mLeft->mDecType->mType == DT_TYPE_ARRAY) @@ -2343,12 +2531,12 @@ Expression* Parser::ParsePrefixExpression(void) return nexp->ConstantFold(mErrors); } else - return ParsePostfixExpression(); + return ParsePostfixExpression(lhs); } -Expression* Parser::ParseMulExpression(void) +Expression* Parser::ParseMulExpression(bool lhs) { - Expression* exp = ParsePrefixExpression(); + Expression* exp = ParsePrefixExpression(lhs); while (mScanner->mToken == TK_MUL || mScanner->mToken == TK_DIV || mScanner->mToken == TK_MOD) { @@ -2356,7 +2544,7 @@ Expression* Parser::ParseMulExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParsePrefixExpression(); + nexp->mRight = ParsePrefixExpression(false); if (nexp->mLeft->mDecType->mType == DT_TYPE_FLOAT || nexp->mRight->mDecType->mType == DT_TYPE_FLOAT) nexp->mDecType = TheFloatTypeDeclaration; @@ -2369,9 +2557,9 @@ Expression* Parser::ParseMulExpression(void) return exp; } -Expression* Parser::ParseAddExpression(void) +Expression* Parser::ParseAddExpression(bool lhs) { - Expression* exp = ParseMulExpression(); + Expression* exp = ParseMulExpression(lhs); while (mScanner->mToken == TK_ADD || mScanner->mToken == TK_SUB) { @@ -2379,7 +2567,7 @@ Expression* Parser::ParseAddExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseMulExpression(); + nexp->mRight = ParseMulExpression(false); if (nexp->mLeft->mDecType->mType == DT_TYPE_POINTER && nexp->mRight->mDecType->IsIntegerType()) nexp->mDecType = nexp->mLeft->mDecType; else if (nexp->mRight->mDecType->mType == DT_TYPE_POINTER && nexp->mLeft->mDecType->IsIntegerType()) @@ -2415,9 +2603,9 @@ Expression* Parser::ParseAddExpression(void) return exp; } -Expression* Parser::ParseShiftExpression(void) +Expression* Parser::ParseShiftExpression(bool lhs) { - Expression* exp = ParseAddExpression(); + Expression* exp = ParseAddExpression(lhs); while (mScanner->mToken == TK_LEFT_SHIFT || mScanner->mToken == TK_RIGHT_SHIFT) { @@ -2425,7 +2613,7 @@ Expression* Parser::ParseShiftExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseAddExpression(); + nexp->mRight = ParseAddExpression(false); nexp->mDecType = exp->mDecType; exp = nexp->ConstantFold(mErrors); @@ -2434,9 +2622,9 @@ Expression* Parser::ParseShiftExpression(void) return exp; } -Expression* Parser::ParseRelationalExpression(void) +Expression* Parser::ParseRelationalExpression(bool lhs) { - Expression* exp = ParseShiftExpression(); + Expression* exp = ParseShiftExpression(lhs); while (mScanner->mToken >= TK_EQUAL && mScanner->mToken <= TK_LESS_EQUAL) { @@ -2444,7 +2632,7 @@ Expression* Parser::ParseRelationalExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseShiftExpression(); + nexp->mRight = ParseShiftExpression(false); nexp->mDecType = TheBoolTypeDeclaration; exp = nexp->ConstantFold(mErrors); @@ -2453,9 +2641,9 @@ Expression* Parser::ParseRelationalExpression(void) return exp; } -Expression* Parser::ParseBinaryAndExpression(void) +Expression* Parser::ParseBinaryAndExpression(bool lhs) { - Expression* exp = ParseRelationalExpression(); + Expression* exp = ParseRelationalExpression(lhs); while (mScanner->mToken == TK_BINARY_AND) { @@ -2463,7 +2651,7 @@ Expression* Parser::ParseBinaryAndExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseRelationalExpression(); + nexp->mRight = ParseRelationalExpression(false); nexp->mDecType = exp->mDecType; exp = nexp->ConstantFold(mErrors); @@ -2472,9 +2660,9 @@ Expression* Parser::ParseBinaryAndExpression(void) return exp; } -Expression* Parser::ParseBinaryXorExpression(void) +Expression* Parser::ParseBinaryXorExpression(bool lhs) { - Expression* exp = ParseBinaryAndExpression(); + Expression* exp = ParseBinaryAndExpression(lhs); while (mScanner->mToken == TK_BINARY_XOR) { @@ -2482,7 +2670,7 @@ Expression* Parser::ParseBinaryXorExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseBinaryAndExpression(); + nexp->mRight = ParseBinaryAndExpression(false); nexp->mDecType = exp->mDecType; exp = nexp->ConstantFold(mErrors); } @@ -2490,9 +2678,9 @@ Expression* Parser::ParseBinaryXorExpression(void) return exp; } -Expression* Parser::ParseBinaryOrExpression(void) +Expression* Parser::ParseBinaryOrExpression(bool lhs) { - Expression* exp = ParseBinaryXorExpression(); + Expression* exp = ParseBinaryXorExpression(lhs); while (mScanner->mToken == TK_BINARY_OR) { @@ -2500,7 +2688,7 @@ Expression* Parser::ParseBinaryOrExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseBinaryXorExpression(); + nexp->mRight = ParseBinaryXorExpression(false); nexp->mDecType = exp->mDecType; exp = nexp->ConstantFold(mErrors); } @@ -2508,9 +2696,9 @@ Expression* Parser::ParseBinaryOrExpression(void) return exp; } -Expression* Parser::ParseLogicAndExpression(void) +Expression* Parser::ParseLogicAndExpression(bool lhs) { - Expression* exp = ParseBinaryOrExpression(); + Expression* exp = ParseBinaryOrExpression(lhs); while (mScanner->mToken == TK_LOGICAL_AND) { @@ -2518,7 +2706,7 @@ Expression* Parser::ParseLogicAndExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseBinaryOrExpression(); + nexp->mRight = ParseBinaryOrExpression(false); nexp->mDecType = TheBoolTypeDeclaration; exp = nexp->ConstantFold(mErrors); } @@ -2526,9 +2714,9 @@ Expression* Parser::ParseLogicAndExpression(void) return exp; } -Expression* Parser::ParseLogicOrExpression(void) +Expression* Parser::ParseLogicOrExpression(bool lhs) { - Expression* exp = ParseLogicAndExpression(); + Expression* exp = ParseLogicAndExpression(lhs); while (mScanner->mToken == TK_LOGICAL_OR) { @@ -2536,7 +2724,7 @@ Expression* Parser::ParseLogicOrExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseLogicAndExpression(); + nexp->mRight = ParseLogicAndExpression(false); nexp->mDecType = TheBoolTypeDeclaration; exp = nexp->ConstantFold(mErrors); } @@ -2544,9 +2732,9 @@ Expression* Parser::ParseLogicOrExpression(void) return exp; } -Expression* Parser::ParseConditionalExpression(void) +Expression* Parser::ParseConditionalExpression(bool lhs) { - Expression* exp = ParseLogicOrExpression(); + Expression* exp = ParseLogicOrExpression(lhs); if (mScanner->mToken == TK_QUESTIONMARK) { @@ -2556,9 +2744,9 @@ Expression* Parser::ParseConditionalExpression(void) Expression* texp = new Expression(mScanner->mLocation, EX_SEQUENCE); nexp->mRight = texp; - texp->mLeft = ParseLogicOrExpression(); + texp->mLeft = ParseLogicOrExpression(false); ConsumeToken(TK_COLON); - texp->mRight = ParseConditionalExpression(); + texp->mRight = ParseConditionalExpression(false); nexp->mDecType = texp->mLeft->mDecType; exp = nexp->ConstantFold(mErrors); @@ -2569,7 +2757,7 @@ Expression* Parser::ParseConditionalExpression(void) Expression* Parser::ParseRExpression(void) { - return ParseConditionalExpression(); + return ParseConditionalExpression(false); } Expression* Parser::ParseParenthesisExpression(void) @@ -2579,7 +2767,7 @@ Expression* Parser::ParseParenthesisExpression(void) else mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "'(' expected"); - Expression* exp = ParseExpression(); + Expression* exp = ParseExpression(true); if (mScanner->mToken == TK_CLOSE_PARENTHESIS) mScanner->NextToken(); @@ -2589,9 +2777,9 @@ Expression* Parser::ParseParenthesisExpression(void) return exp; } -Expression* Parser::ParseAssignmentExpression(void) +Expression* Parser::ParseAssignmentExpression(bool lhs) { - Expression* exp = ParseConditionalExpression(); + Expression* exp = ParseConditionalExpression(lhs); if (mScanner->mToken >= TK_ASSIGN && mScanner->mToken <= TK_ASSIGN_OR) { @@ -2599,7 +2787,7 @@ Expression* Parser::ParseAssignmentExpression(void) nexp->mToken = mScanner->mToken; nexp->mLeft = exp; mScanner->NextToken(); - nexp->mRight = ParseAssignmentExpression(); + nexp->mRight = ParseAssignmentExpression(false); nexp->mDecType = exp->mDecType; exp = nexp; assert(exp->mDecType); @@ -2608,14 +2796,14 @@ Expression* Parser::ParseAssignmentExpression(void) return exp; } -Expression* Parser::ParseExpression(void) +Expression* Parser::ParseExpression(bool lhs) { - return ParseAssignmentExpression(); + return ParseAssignmentExpression(lhs); } Expression* Parser::ParseListExpression(void) { - Expression* exp = ParseExpression(); + Expression* exp = ParseExpression(true); if (mScanner->mToken == TK_COMMA) { Expression* nexp = new Expression(mScanner->mLocation, EX_LIST); @@ -2779,7 +2967,7 @@ Expression* Parser::ParseStatement(void) // Assignment if (mScanner->mToken != TK_SEMICOLON) - initExp = ParseExpression(); + initExp = ParseExpression(true); if (mScanner->mToken == TK_SEMICOLON) mScanner->NextToken(); else @@ -2787,7 +2975,7 @@ Expression* Parser::ParseStatement(void) // Condition if (mScanner->mToken != TK_SEMICOLON) - conditionExp = ParseExpression(); + conditionExp = ParseExpression(false); if (mScanner->mToken == TK_SEMICOLON) mScanner->NextToken(); @@ -2796,7 +2984,7 @@ Expression* Parser::ParseStatement(void) // Iteration if (mScanner->mToken != TK_CLOSE_PARENTHESIS) - iterateExp = ParseExpression(); + iterateExp = ParseExpression(false); if (mScanner->mToken == TK_CLOSE_PARENTHESIS) mScanner->NextToken(); else @@ -4259,7 +4447,7 @@ void Parser::ParsePragma(void) { if (mScanner->mToken != TK_COMMA) { - exp = ParseExpression(); + exp = ParseExpression(false); if (exp->mDecValue && exp->mDecValue->mType == DT_VARIABLE) dstart = exp->mDecValue; } @@ -4268,7 +4456,7 @@ void Parser::ParsePragma(void) { if (mScanner->mToken != TK_COMMA) { - exp = ParseExpression(); + exp = ParseExpression(false); if (exp->mDecValue && exp->mDecValue->mType == DT_VARIABLE) dend = exp->mDecValue; } diff --git a/oscar64/Parser.h b/oscar64/Parser.h index 7f5b660..44bcc7e 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -38,6 +38,9 @@ protected: void ParsePragma(void); + Declaration * ParseFunctionDeclaration(Declaration* bdec); + void PrependThisArgument(Declaration* fdec, Declaration * pthis); + Declaration* ParseBaseTypeDeclaration(uint64 flags); Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression, Declaration * pthis = nullptr); Declaration* ParseStructDeclaration(uint64 flags, DecType dt); @@ -69,21 +72,21 @@ protected: int OverloadDistance(Declaration* pdec, Expression* pexp); void ResolveOverloadCall(Expression* cexp, Expression* pexp); - Expression* ParseSimpleExpression(void); - Expression* ParsePrefixExpression(void); - Expression* ParsePostfixExpression(void); - Expression* ParseMulExpression(void); - Expression* ParseAddExpression(void); - Expression* ParseShiftExpression(void); - Expression* ParseRelationalExpression(void); - Expression* ParseBinaryAndExpression(void); - Expression* ParseBinaryXorExpression(void); - Expression* ParseBinaryOrExpression(void); - Expression* ParseLogicAndExpression(void); - Expression* ParseLogicOrExpression(void); - Expression* ParseConditionalExpression(void); - Expression* ParseAssignmentExpression(void); - Expression* ParseExpression(void); + Expression* ParseSimpleExpression(bool lhs); + Expression* ParsePrefixExpression(bool lhs); + Expression* ParsePostfixExpression(bool lhs); + Expression* ParseMulExpression(bool lhs); + Expression* ParseAddExpression(bool lhs); + Expression* ParseShiftExpression(bool lhs); + Expression* ParseRelationalExpression(bool lhs); + Expression* ParseBinaryAndExpression(bool lhs); + Expression* ParseBinaryXorExpression(bool lhs); + Expression* ParseBinaryOrExpression(bool lhs); + Expression* ParseLogicAndExpression(bool lhs); + Expression* ParseLogicOrExpression(bool lhs); + Expression* ParseConditionalExpression(bool lhs); + Expression* ParseAssignmentExpression(bool lhs); + Expression* ParseExpression(bool lhs); Expression* ParseRExpression(void); Expression* ParseListExpression(void);