diff --git a/autotest/autotest.bat b/autotest/autotest.bat index 6abe7fa..5665bb2 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -18,6 +18,9 @@ rem @echo off @call :testh opp_vector_string.cpp @if %errorlevel% neq 0 goto :error +@call :testh opp_string_init.cpp +@if %errorlevel% neq 0 goto :error + @call :testh opp_streamtest.cpp @if %errorlevel% neq 0 goto :error diff --git a/autotest/opp_string_init.cpp b/autotest/opp_string_init.cpp new file mode 100644 index 0000000..15c23b5 --- /dev/null +++ b/autotest/opp_string_init.cpp @@ -0,0 +1,193 @@ +#include +#include +#include +#include + +using opp::string; + + +const string s1; +const string s2 = "Hello"; +const string s3{"World"}; + +const string a1[2]; +const string a2[2] = {"Hello", "World"}; +const string a3[2] = {opp::string("Hello"), opp::string("World")}; + + +const string d1[3][2]; +const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}}; +const string d3[3][2] = + {{opp::string("Hello"), opp::string("World")}, + {opp::string("aaa"), opp::string("bbb")}, + {opp::string("ccc"), opp::string("ddd")}}; + +void test_global_init(void) +{ + assert(!strcmp(s1.tocstr(), "")); + assert(!strcmp(s2.tocstr(), "Hello")); + assert(!strcmp(s3.tocstr(), "World")); +} + + +void test_global_ainit(void) +{ + assert(!strcmp(a1[0].tocstr(), "")); + assert(!strcmp(a1[1].tocstr(), "")); + + assert(!strcmp(a2[0].tocstr(), "Hello")); + assert(!strcmp(a2[1].tocstr(), "World")); + + assert(!strcmp(a3[0].tocstr(), "Hello")); + assert(!strcmp(a3[1].tocstr(), "World")); +} + +void test_global_dinit(void) +{ + assert(!strcmp(d1[0][0].tocstr(), "")); + assert(!strcmp(d1[2][1].tocstr(), "")); + + assert(!strcmp(d2[0][0].tocstr(), "Hello")); + assert(!strcmp(d2[2][1].tocstr(), "ddd")); + + assert(!strcmp(d3[0][0].tocstr(), "Hello")); + assert(!strcmp(d3[2][1].tocstr(), "ddd")); +} + + +void test_local_init(void) +{ + const string s1; + const string s2 = "Hello"; + const string s3{"World"}; + + assert(!strcmp(s1.tocstr(), "")); + assert(!strcmp(s2.tocstr(), "Hello")); + assert(!strcmp(s3.tocstr(), "World")); +} + + +void test_local_ainit(void) +{ + const string a1[2]; + const string a2[2] = {"Hello", "World"}; + const string a3[2] = {opp::string("Hello"), opp::string("World")}; + + assert(!strcmp(a1[0].tocstr(), "")); + assert(!strcmp(a1[1].tocstr(), "")); + + assert(!strcmp(a2[0].tocstr(), "Hello")); + assert(!strcmp(a2[1].tocstr(), "World")); + + assert(!strcmp(a3[0].tocstr(), "Hello")); + assert(!strcmp(a3[1].tocstr(), "World")); +} + +void test_local_dinit(void) +{ + const string d1[3][2]; + const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}}; + const string d3[3][2] = + {{opp::string("Hello"), opp::string("World")}, + {opp::string("aaa"), opp::string("bbb")}, + {opp::string("ccc"), opp::string("ddd")}}; + + assert(!strcmp(d1[0][0].tocstr(), "")); + assert(!strcmp(d1[2][1].tocstr(), "")); + + assert(!strcmp(d2[0][0].tocstr(), "Hello")); + assert(!strcmp(d2[2][1].tocstr(), "ddd")); + + assert(!strcmp(d3[0][0].tocstr(), "Hello")); + assert(!strcmp(d3[2][1].tocstr(), "ddd")); +} + +class X +{ +public: + const string s1; + const string s2 = "Hello"; + const string s3; + + const string a1[2]; + const string a2[2] = {"Hello", "World"}; + + const string d1[3][2]; + const string d2[3][2] = {{"Hello", "World"}, {"aaa", "bbb"}, {"ccc", "ddd"}}; + + X() : s3("World") {} +}; + +void test_member_init(void) +{ + X x; + + assert(!strcmp(x.s1.tocstr(), "")); + assert(!strcmp(x.s2.tocstr(), "Hello")); + assert(!strcmp(x.s3.tocstr(), "World")); +} + +void test_member_ainit(void) +{ + X x; + + assert(!strcmp(x.a1[0].tocstr(), "")); + assert(!strcmp(x.a1[1].tocstr(), "")); + + assert(!strcmp(x.a2[0].tocstr(), "Hello")); + assert(!strcmp(x.a2[1].tocstr(), "World")); +} + +void test_member_dinit(void) +{ + X x; + + assert(!strcmp(x.d1[0][0].tocstr(), "")); + assert(!strcmp(x.d1[2][1].tocstr(), "")); + + assert(!strcmp(x.d2[0][0].tocstr(), "Hello")); + assert(!strcmp(x.d2[2][1].tocstr(), "ddd")); +} + +void test_copy_init(void) +{ + X x; + X y(x); + + assert(!strcmp(y.s1.tocstr(), "")); + assert(!strcmp(y.s2.tocstr(), "Hello")); + assert(!strcmp(y.s3.tocstr(), "World")); +} + +void test_copy_ainit(void) +{ + X x; + X y(x); + + assert(!strcmp(y.a1[0].tocstr(), "")); + assert(!strcmp(y.a1[1].tocstr(), "")); + + assert(!strcmp(y.a2[0].tocstr(), "Hello")); + assert(!strcmp(y.a2[1].tocstr(), "World")); +} + +int main(void) +{ + test_global_init(); + test_global_ainit(); + test_global_dinit(); + + for(int i=0; i<10000; i++) + { + test_local_init(); + test_local_ainit(); + } + + test_member_init(); + test_member_ainit(); + + test_copy_init(); + test_copy_ainit(); + + return 0; +} \ No newline at end of file diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 4109c61..3193302 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -147,7 +147,8 @@ void DeclarationScope::End(const Location& loc) Expression::Expression(const Location& loc, ExpressionType type) : mLocation(loc), mEndLocation(loc), mType(type), mLeft(nullptr), mRight(nullptr), mConst(false), mDecType(nullptr), mDecValue(nullptr), mToken(TK_NONE) { - + static uint32 gUID = 0; + mUID = gUID++; } Expression::~Expression(void) @@ -1106,7 +1107,10 @@ Declaration::Declaration(const Location& loc, DecType type) mCompilerOptions(0), mUseCount(0), mTokens(nullptr), mParser(nullptr), mShift(0), mBits(0), mOptFlags(0), mInlayRegion(nullptr), mReferences(nullptr) -{} +{ + static uint32 gUID = 0; + mUID = gUID++; +} Declaration::~Declaration(void) { @@ -2091,6 +2095,7 @@ Declaration* Declaration::ToVolatileType(void) ndec->mCopyConstructor = mCopyConstructor; ndec->mMoveConstructor = mMoveConstructor; ndec->mVectorConstructor = mVectorConstructor; + ndec->mVectorDestructor = mVectorDestructor; ndec->mVectorCopyConstructor = mVectorCopyConstructor; ndec->mVTable = mVTable; @@ -2123,6 +2128,7 @@ Declaration* Declaration::ToConstType(void) ndec->mCopyConstructor = mCopyConstructor; ndec->mMoveConstructor = mMoveConstructor; ndec->mVectorConstructor = mVectorConstructor; + ndec->mVectorDestructor = mVectorDestructor; ndec->mVectorCopyConstructor = mVectorCopyConstructor; ndec->mVTable = mVTable; @@ -2156,6 +2162,7 @@ Declaration* Declaration::ToMutableType(void) ndec->mCopyConstructor = mCopyConstructor; ndec->mMoveConstructor = mMoveConstructor; ndec->mVectorConstructor = mVectorConstructor; + ndec->mVectorDestructor = mVectorDestructor; ndec->mVectorCopyConstructor = mVectorCopyConstructor; ndec->mVTable = mVTable; diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index ad21c97..367e706 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -242,6 +242,8 @@ public: Expression(const Location& loc, ExpressionType type); ~Expression(void); + uint32 mUID; + Location mLocation, mEndLocation; ExpressionType mType; Expression * mLeft, * mRight; @@ -270,6 +272,8 @@ public: Declaration(const Location & loc, DecType type); ~Declaration(void); + uint32 mUID; + Location mLocation, mEndLocation; DecType mType; Token mToken; diff --git a/oscar64/Emulator.cpp b/oscar64/Emulator.cpp index 5f85f0d..5097ac0 100644 --- a/oscar64/Emulator.cpp +++ b/oscar64/Emulator.cpp @@ -538,6 +538,7 @@ int Emulator::Emulate(int startIP, int trace) mMemory[0x1ff] = 0xff; int tcycles = 0, cycles = 0; + int iip = 0; while (mIP != 0) { if (mJiffies) @@ -584,7 +585,10 @@ int Emulator::Emulate(int startIP, int trace) AsmInsData d = DecInsData[opcode]; int addr = 0, taddr; int ip = mIP; - int iip = mMemory[BC_REG_IP] + 256 * mMemory[BC_REG_IP + 1]; + + if (ip == 0x0862) + iip = mMemory[BC_REG_IP] + 256 * mMemory[BC_REG_IP + 1] + mRegY; + bool cross = false, indexed = false; int icycles = 0; diff --git a/oscar64/Errors.h b/oscar64/Errors.h index dde3110..85548c8 100644 --- a/oscar64/Errors.h +++ b/oscar64/Errors.h @@ -110,6 +110,7 @@ enum ErrorID EERR_ASSEMBLER_LIMIT, EERR_INVALID_PREPROCESSOR, + EERR_INVALID_CLASS_INITIALIZER, EFATAL_GENERIC = 4000, EFATAL_OUT_OF_MEMORY, diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index c60e0af..6de798d 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -21975,7 +21975,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "main"); + CheckFunc = !strcmp(mIdent->mString, "test"); CheckCase = false; mEntryBlock = mBlocks[0]; @@ -23819,7 +23819,7 @@ void InterCodeProcedure::Disassemble(FILE* file) void InterCodeProcedure::Disassemble(const char* name, bool dumpSets) { -#if 0 +#if 1 #ifdef _WIN32 FILE* file; static bool initial = true; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index f384eec..cf0cf05 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -719,6 +719,8 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* { DestructStack* destack = nullptr; GotoNode* gotos = nullptr; + dec->mValue->mRight->mDecValue = dec; + dec->mLinkerObject->mFlags &= ~LOBJF_CONST; TranslateExpression(nullptr, mMainInitProc, mMainInitBlock, dec->mValue, destack, gotos, BranchTarget(), BranchTarget(), nullptr); } else if (dec->mValue->mType == EX_VARIABLE && dec->mValue->mDecType->mType == DT_TYPE_ARRAY && dec->mBase->mType == DT_TYPE_POINTER && dec->mBase->CanAssign(dec->mValue->mDecType)) @@ -2200,6 +2202,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* var->mLinkerObject->mVariable = var; dec->mLinkerObject = var->mLinkerObject; var->mIdent = dec->mQualIdent; + var->mDeclaration = dec; dec->mVarIndex = proc->mModule->mGlobalVars.Size(); var->mIndex = dec->mVarIndex; proc->mModule->mGlobalVars.Push(var); @@ -2281,7 +2284,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mConst.mOperandSize = 2; } } - else if (dec->mFlags & DTF_GLOBAL) + else if (dec->mType == DT_CONST_STRUCT || (dec->mFlags & DTF_GLOBAL)) { InitGlobalVariable(proc->mModule, dec); ins->mConst.mMemory = IM_GLOBAL; @@ -2351,7 +2354,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (exp->mType == EX_INITIALIZATION && exp->mRight->mType == EX_CONSTANT && exp->mRight->mDecValue && exp->mRight->mDecValue->mLinkerObject) { - exp->mRight->mDecValue->mLinkerObject->mFlags |= LOBJF_CONST; + if (!(exp->mRight->mDecValue->mFlags & DTF_VAR_ALIASING)) + exp->mRight->mDecValue->mLinkerObject->mFlags |= LOBJF_CONST; } @@ -2661,9 +2665,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* block->Append(ains); if (exp->mDecType->IsReference()) - return ExValue(exp->mDecValue->mBase->mBase, ains->mDst.mTemp, 2); + return ExValue(exp->mDecType->mBase, ains->mDst.mTemp, 2); else - return ExValue(exp->mDecValue->mBase, ains->mDst.mTemp, 1, exp->mDecValue->mBits, exp->mDecValue->mShift); + return ExValue(exp->mDecType, ains->mDst.mTemp, 1, exp->mDecValue->mBits, exp->mDecValue->mShift); } case EX_BINARY: @@ -2689,7 +2693,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ptype->mSize = 2; ptype->mStride = vl.mType->mStride; vl.mReference = 0; - vl.mType = ptype; + vl.mType = exp->mDecType; // ptype; } if (vr.mType->mType == DT_TYPE_POINTER) @@ -3184,7 +3188,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* dec->mBase = vl.mType; dec->mSize = 2; dec->mFlags = DTF_DEFINED; - return ExValue(dec, vl.mTemp, vl.mReference - 1); + return ExValue(exp->mDecType, vl.mTemp, vl.mReference - 1); } case TK_BANKOF: { @@ -5427,6 +5431,17 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int { assert(false); } + else if (data->mType == DT_CONST_CONSTRUCTOR) + { + Declaration* dec = new Declaration(data->mLocation, DT_VARIABLE_REF); + dec->mBase = variable->mDeclaration; + dec->mOffset = offset; + DestructStack* destack = nullptr; + GotoNode* gotos = nullptr; + data->mValue->mRight->mDecValue = dec; + dec->mBase->mFlags |= DTF_VAR_ALIASING; + TranslateExpression(nullptr, mMainInitProc, mMainInitBlock, data->mValue, destack, gotos, BranchTarget(), BranchTarget(), nullptr); + } else if (data->mType == DT_CONST_POINTER) { Expression* exp = data->mValue; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 20c1a90..c6db593 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -45632,7 +45632,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizerIterate4(int i, int pass) mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mType == ASMIT_LDX && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && mIns[i + 3].mType == ASMIT_STX && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && - !mIns[i + 1].ChangesZeroPage(mIns[i + 0].mAddress) && !mIns[i + 1].UsesZeroPage(mIns[i + 3].mAddress)) + !mIns[i + 1].ChangesZeroPage(mIns[i + 0].mAddress) && + !mIns[i + 1].UsesZeroPage(mIns[i + 3].mAddress) && + !mIns[i + 1].ChangesZeroPage(mIns[i + 3].mAddress)) { mIns[i + 0].mLive |= LIVE_CPU_REG_A; @@ -50683,7 +50685,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) mInterProc = proc; mInterProc->mLinkerObject->mNativeProc = this; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "sqrt"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "test"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -51597,7 +51599,6 @@ void NativeCodeProcedure::Optimize(void) } while (changed && t < 20); #endif - BuildDataFlowSets(); ResetVisited(); mEntryBlock->RemoveUnusedResultInstructions(); @@ -52495,6 +52496,7 @@ void NativeCodeProcedure::Optimize(void) else cnt++; + } while (changed); #if 1 diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 9ff2323..da916d5 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -647,6 +647,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio pthis->mBase->mConst->mCopyConstructor = pthis->mBase->mCopyConstructor; pthis->mBase->mConst->mMoveConstructor = pthis->mBase->mMoveConstructor; pthis->mBase->mConst->mVectorConstructor = pthis->mBase->mVectorConstructor; + pthis->mBase->mConst->mVectorDestructor = pthis->mBase->mVectorConstructor; pthis->mBase->mConst->mVectorCopyConstructor = pthis->mBase->mVectorCopyConstructor; } @@ -1440,12 +1441,16 @@ Declaration * Parser::CopyConstantInitializer(int offset, Declaration* dtype, Ex { exp = exp->ConstantDereference(mErrors, mDataSection); + exp = CoerceExpression(exp, dtype); + Declaration* dec = exp->mDecValue; if (exp->mType == EX_CONSTANT) { if (!dtype->CanAssign(exp->mDecType)) + { mErrors->Error(exp->mLocation, EERR_CONSTANT_INITIALIZER, "Incompatible constant initializer"); + } else { if (dec->mType == DT_CONST_FLOAT) @@ -1512,6 +1517,13 @@ Declaration * Parser::CopyConstantInitializer(int offset, Declaration* dtype, Ex dec->mOffset = offset; } } + else if (!dec && exp->mType == EX_CONSTRUCT) + { + dec = new Declaration(exp->mLocation, DT_CONST_CONSTRUCTOR); + dec->mValue = exp; + dec->mBase = exp->mDecType; + dec->mOffset = offset; + } else if (dec && dtype->mType == DT_TYPE_POINTER && (dec->mType == DT_VARIABLE || dec->mType == DT_VARIABLE_REF) && exp->mDecType->mType == DT_TYPE_ARRAY && (dec->mFlags & DTF_GLOBAL)) { if (dtype->CanAssign(exp->mDecType)) @@ -1936,10 +1948,7 @@ Expression* Parser::BuildMemberInitializer(Expression* vexp) 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 = vexp->mDecType; - texp->mDecType->mSize = 2; + texp->mDecType = vexp->mDecType->BuildPointer(mScanner->mLocation); if (fexp->mRight) { @@ -2051,13 +2060,154 @@ void Parser::PrependMemberConstructor(Declaration* pthis, Declaration* cfunc) if (bdec->mType == DT_TYPE_STRUCT && bdec->mDefaultConstructor || dec->mValue) { + bdec = bdec->ToMutableType(); + + Declaration* bpdec = bdec->BuildPointer(mScanner->mLocation); + Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY); qexp->mLeft = thisexp; qexp->mDecValue = dec; Expression* dexp; - if (dec->mValue) + if (bdec->mDefaultConstructor) + { + if (dec->mBase->mType == DT_TYPE_STRUCT) + { + qexp->mDecType = bdec; + + if (dec->mValue) + dexp = BuildVariableInit(qexp, dec->mValue); + else + { + Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX); + pexp->mLeft = qexp; + pexp->mToken = TK_BINARY_AND; + pexp->mDecType = bpdec; + + Declaration* mdec = bdec->mDefaultConstructor; + + Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT); + if (mdec) + { + cexp->mDecValue = mdec; + cexp->mDecType = cexp->mDecValue->mBase; + } + else + mErrors->Error(dec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor"); + + dexp = new Expression(mScanner->mLocation, EX_CALL); + dexp->mLeft = cexp; + dexp->mRight = pexp; + } + } + else + { + qexp->mDecType = dec->mBase->mBase; + + Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX); + pexp->mLeft = qexp; + pexp->mToken = TK_BINARY_AND; + pexp->mDecType = bpdec; + + qexp = pexp; + + if (dec->mValue) + { + int offset = 0; + dexp = BuildVariableArrayInit(qexp, bpdec, dec->mValue->mDecValue, 0, offset); +#if 0 + int offset = 0; + dexp = nullptr; + + Declaration* pdec = dec->mValue->mDecValue->mParams; + while (pdec) + { + if (pdec->mType == DT_CONST_CONSTRUCTOR) + { + if (offset != pdec->mOffset) + mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Incomplete class initializer list"); + + Declaration* icdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + icdec->mBase = TheUnsignedIntTypeDeclaration; + icdec->mInteger = pdec->mOffset / bdec->mSize; + + Expression* icexp = new Expression(mScanner->mLocation, EX_CONSTANT); + icexp->mDecType = icdec->mBase; + icexp->mDecValue = icdec; + + Expression* mexp = new Expression(mScanner->mLocation, EX_BINARY); + mexp->mToken = TK_ADD; + mexp->mLeft = qexp; + mexp->mRight = icexp; + mexp->mDecType = bpdec; + + Expression* pv = new Expression(pdec->mValue->mLocation, EX_CONSTRUCT); + pv->mLeft = new Expression(pdec->mValue->mLeft->mLocation, EX_LIST); + pv->mLeft->mLeft = new Expression(pdec->mValue->mLeft->mLeft->mLocation, EX_CALL); + pv->mLeft->mLeft->mLeft = pdec->mValue->mLeft->mLeft->mLeft; + pv->mLeft->mLeft->mDecType = pdec->mValue->mLeft->mLeft->mDecType; + pv->mLeft->mLeft->mRight = new Expression(pdec->mValue->mLeft->mLeft->mRight->mLocation, EX_LIST); + pv->mLeft->mLeft->mRight->mRight = pdec->mValue->mLeft->mLeft->mRight->mRight; + pv->mLeft->mLeft->mRight->mLeft = mexp; + + if (dexp) + { + Expression* nexp = new Expression(mScanner->mLocation, EX_LIST); + nexp->mLeft = dexp; + nexp->mRight = pv; + dexp = nexp; + } + else + dexp = pv; + + offset += bdec->mSize; + } + else + mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Invalid class initializer"); + + pdec = pdec->mNext; + } +#endif + if (offset != dec->mSize) + mErrors->Error(dec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Incomplete class initializer list"); + } + else + { + while (qexp->mDecType->mType == DT_TYPE_ARRAY) + { + Expression* iexp = new Expression(pthis->mLocation, EX_PREFIX); + iexp->mToken = TK_MUL; + iexp->mLeft = qexp; + iexp->mDecType = qexp->mDecType->mBase; + qexp = iexp; + } + + qexp->mDecType = bpdec; + + Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT); + cexp->mDecValue = bdec->mVectorConstructor; + cexp->mDecType = cexp->mDecValue->mBase; + + Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + ncdec->mBase = TheUnsignedIntTypeDeclaration; + ncdec->mInteger = dec->mSize / bdec->mSize; + + dexp = new Expression(mScanner->mLocation, EX_CALL); + dexp->mLeft = cexp; + dexp->mRight = new Expression(mScanner->mLocation, EX_LIST); + dexp->mRight->mLeft = qexp; + dexp->mRight->mRight = new Expression(mScanner->mLocation, EX_BINARY); + dexp->mRight->mRight->mToken = TK_ADD; + dexp->mRight->mRight->mLeft = qexp; + dexp->mRight->mRight->mDecType = qexp->mDecType; + dexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT); + dexp->mRight->mRight->mRight->mDecType = ncdec->mBase; + dexp->mRight->mRight->mRight->mDecValue = ncdec; + } + } + } + else { qexp->mDecType = bdec; @@ -2067,71 +2217,6 @@ void Parser::PrependMemberConstructor(Declaration* pthis, Declaration* cfunc) dexp->mLeft = qexp; dexp->mRight = dec->mValue; } - else if (dec->mBase->mType == DT_TYPE_STRUCT) - { - qexp->mDecType = bdec; - - Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX); - pexp->mLeft = qexp; - pexp->mToken = TK_BINARY_AND; - pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER); - pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - pexp->mDecType->mBase = bdec; - pexp->mDecType->mSize = 2; - - Declaration* mdec = bdec->mDefaultConstructor; - - Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT); - if (mdec) - { - cexp->mDecValue = mdec; - cexp->mDecType = cexp->mDecValue->mBase; - } - else - mErrors->Error(dec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor"); - - dexp = new Expression(mScanner->mLocation, EX_CALL); - dexp->mLeft = cexp; - dexp->mRight = pexp; - } - else - { - qexp->mDecType = dec->mBase->mBase; - - while (qexp->mDecType->mType == DT_TYPE_ARRAY) - { - Expression* iexp = new Expression(pthis->mLocation, EX_PREFIX); - iexp->mToken = TK_MUL; - iexp->mLeft = qexp; - iexp->mDecType = qexp->mDecType->mBase; - qexp = iexp; - } - - qexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER); - qexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - qexp->mDecType->mBase = bdec; - qexp->mDecType->mSize = 2; - - Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT); - cexp->mDecValue = bdec->mVectorConstructor; - cexp->mDecType = cexp->mDecValue->mBase; - - Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); - ncdec->mBase = TheUnsignedIntTypeDeclaration; - ncdec->mInteger = dec->mSize / bdec->mSize; - - dexp = new Expression(mScanner->mLocation, EX_CALL); - dexp->mLeft = cexp; - dexp->mRight = new Expression(mScanner->mLocation, EX_LIST); - dexp->mRight->mLeft = qexp; - dexp->mRight->mRight = new Expression(mScanner->mLocation, EX_BINARY); - dexp->mRight->mRight->mToken = TK_ADD; - dexp->mRight->mRight->mLeft = qexp; - dexp->mRight->mRight->mDecType = qexp->mDecType; - dexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT); - dexp->mRight->mRight->mRight->mDecType = ncdec->mBase; - dexp->mRight->mRight->mRight->mDecValue = ncdec; - } Expression* sexp = new Expression(mScanner->mLocation, EX_SEQUENCE); @@ -2215,7 +2300,7 @@ void Parser::BuildMemberConstructor(Declaration* pthis, Declaration* cfunc) { Expression* qexp = new Expression(mScanner->mLocation, EX_PREFIX); qexp->mToken = TK_MUL; - qexp->mDecType = pcdec->mBase; + qexp->mDecType = pcdec->mBase->ToMutableType(); qexp->mLeft = pthisexp; Declaration* dec = new Declaration(mScanner->mLocation, DT_CONST_CONSTRUCTOR); @@ -2232,7 +2317,7 @@ void Parser::BuildMemberConstructor(Declaration* pthis, Declaration* cfunc) Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY); qexp->mLeft = thisexp; qexp->mDecValue = dec; - qexp->mDecType = dec->mBase; + qexp->mDecType = dec->mBase->ToMutableType(); Declaration* dec = new Declaration(mScanner->mLocation, DT_CONST_CONSTRUCTOR); dec->mIdent = mScanner->mTokenIdent; @@ -2547,17 +2632,18 @@ void Parser::AddDefaultConstructors(Declaration* pthis) while (bdec->mType == DT_TYPE_ARRAY) bdec = bdec->mBase; + bdec = bdec->ToMutableType(); + if (bdec->mType == DT_TYPE_STRUCT && bdec->mCopyConstructor) { + Declaration* bpdec = bdec->BuildPointer(bdec->mLocation); + if (dec->mBase->mType == DT_TYPE_STRUCT) { Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX); pexp->mLeft = lexp; pexp->mToken = TK_BINARY_AND; - pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER); - pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - pexp->mDecType->mBase = dec->mBase; - pexp->mDecType->mSize = 2; + pexp->mDecType = bpdec; Declaration* mdec = dec->mBase->mCopyConstructor; @@ -2573,15 +2659,15 @@ void Parser::AddDefaultConstructors(Declaration* pthis) } else { - lexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER); - lexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - lexp->mDecType->mBase = bdec; - lexp->mDecType->mSize = 2; + Expression* lpexp = new Expression(pthis->mLocation, EX_PREFIX); + lpexp->mLeft = lexp; + lpexp->mToken = TK_BINARY_AND; + lpexp->mDecType = bpdec; - rexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER); - rexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - rexp->mDecType->mBase = bdec; - rexp->mDecType->mSize = 2; + Expression* rpexp = new Expression(pthis->mLocation, EX_PREFIX); + rpexp->mLeft = rexp; + rpexp->mToken = TK_BINARY_AND; + rpexp->mDecType = bpdec; Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT); cexp->mDecValue = bdec->mVectorCopyConstructor; @@ -2594,9 +2680,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis) mexp = new Expression(mScanner->mLocation, EX_CALL); mexp->mLeft = cexp; mexp->mRight = new Expression(mScanner->mLocation, EX_LIST); - mexp->mRight->mLeft = lexp; + mexp->mRight->mLeft = lpexp; mexp->mRight->mRight = new Expression(mScanner->mLocation, EX_LIST); - mexp->mRight->mRight->mLeft = rexp; + mexp->mRight->mRight->mLeft = rpexp; mexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT); mexp->mRight->mRight->mRight->mDecType = ncdec->mBase; mexp->mRight->mRight->mRight->mDecValue = ncdec; @@ -2722,15 +2808,14 @@ void Parser::AddDefaultConstructors(Declaration* pthis) if (bdec->mType == DT_TYPE_STRUCT && bdec->mCopyAssignment) { + Declaration* bpdec = bdec->BuildPointer(bdec->mLocation); + if (dec->mBase->mType == DT_TYPE_STRUCT) { Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX); pexp->mLeft = lexp; pexp->mToken = TK_BINARY_AND; - pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER); - pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - pexp->mDecType->mBase = dec->mBase; - pexp->mDecType->mSize = 2; + pexp->mDecType = bpdec; Declaration* mdec = bdec->mCopyAssignment; @@ -2746,15 +2831,15 @@ void Parser::AddDefaultConstructors(Declaration* pthis) } else { - lexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER); - lexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - lexp->mDecType->mBase = bdec; - lexp->mDecType->mSize = 2; + Expression* lpexp = new Expression(pthis->mLocation, EX_PREFIX); + lpexp->mLeft = lexp; + lpexp->mToken = TK_BINARY_AND; + lpexp->mDecType = bpdec; - rexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER); - rexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - rexp->mDecType->mBase = bdec; - rexp->mDecType->mSize = 2; + Expression* rpexp = new Expression(pthis->mLocation, EX_PREFIX); + rpexp->mLeft = rexp; + rpexp->mToken = TK_BINARY_AND; + rpexp->mDecType = bpdec; Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT); cexp->mDecValue = bdec->mVectorCopyAssignment; @@ -2767,9 +2852,9 @@ void Parser::AddDefaultConstructors(Declaration* pthis) mexp = new Expression(mScanner->mLocation, EX_CALL); mexp->mLeft = cexp; mexp->mRight = new Expression(mScanner->mLocation, EX_LIST); - mexp->mRight->mLeft = lexp; + mexp->mRight->mLeft = lpexp; mexp->mRight->mRight = new Expression(mScanner->mLocation, EX_LIST); - mexp->mRight->mRight->mLeft = rexp; + mexp->mRight->mRight->mLeft = rpexp; mexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT); mexp->mRight->mRight->mRight->mDecType = ncdec->mBase; mexp->mRight->mRight->mRight->mDecValue = ncdec; @@ -3200,6 +3285,10 @@ void Parser::AppendMemberDestructor(Declaration* pthis) if (bdec->mType == DT_TYPE_STRUCT && bdec->mDestructor) { + bdec = bdec->ToMutableType(); + + Declaration* bpdec = bdec->BuildPointer(pthis->mLocation); + Expression* qexp = new Expression(pthis->mLocation, EX_QUALIFY); qexp->mLeft = thisexp; qexp->mDecValue = dec; @@ -3213,10 +3302,7 @@ void Parser::AppendMemberDestructor(Declaration* pthis) Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX); pexp->mLeft = qexp; pexp->mToken = TK_BINARY_AND; - pexp->mDecType = new Declaration(pthis->mLocation, DT_TYPE_POINTER); - pexp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; - pexp->mDecType->mBase = bdec; - pexp->mDecType->mSize = 2; + pexp->mDecType = bpdec; Expression* cexp = new Expression(pthis->mLocation, EX_CONSTANT); cexp->mDecValue = bdec->mDestructor; @@ -3230,6 +3316,13 @@ void Parser::AppendMemberDestructor(Declaration* pthis) { qexp->mDecType = dec->mBase->mBase; + Expression* pexp = new Expression(pthis->mLocation, EX_PREFIX); + pexp->mLeft = qexp; + pexp->mToken = TK_BINARY_AND; + pexp->mDecType = bpdec; + + qexp = pexp; + while (qexp->mDecType->mType == DT_TYPE_ARRAY) { Expression* iexp = new Expression(pthis->mLocation, EX_PREFIX); @@ -3684,18 +3777,150 @@ Expression* Parser::AddFunctionCallRefReturned(Expression* exp) return ConcatExpression(lexp, rexp); } -void Parser::ParseVariableInit(Declaration* ndec) +Expression* Parser::BuildVariableArrayInit(Expression * texp, Declaration* bpdec, Declaration* pdec, int boffset, int & offset) { - Expression* pexp = nullptr; + Expression* lexp = nullptr; - mScanner->NextToken(); - if (mScanner->mToken != TK_CLOSE_PARENTHESIS) + if (boffset + pdec->mOffset != offset) + mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Incomplete class initializer list"); + + if (pdec->mType == DT_CONST_STRUCT) { - pexp = ParseListExpression(false); - ConsumeToken(TK_CLOSE_PARENTHESIS); + boffset += offset; + + Declaration* edec = pdec->mParams; + while (edec) + { + Expression * iexp = BuildVariableArrayInit(texp, bpdec, edec, boffset, offset); + + if (lexp) + { + Expression* nexp = new Expression(mScanner->mLocation, EX_LIST); + nexp->mLeft = lexp; + nexp->mRight = iexp; + lexp = nexp; + } + else + lexp = iexp; + + edec = edec->mNext; + } + } + else if (pdec->mType == DT_CONST_CONSTRUCTOR) + { + Declaration* icdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + icdec->mBase = TheUnsignedIntTypeDeclaration; + icdec->mInteger = offset / bpdec->mBase->mSize; + + Expression* icexp = new Expression(mScanner->mLocation, EX_CONSTANT); + icexp->mDecType = icdec->mBase; + icexp->mDecValue = icdec; + + Expression* mexp = new Expression(mScanner->mLocation, EX_BINARY); + mexp->mToken = TK_ADD; + mexp->mLeft = texp; + mexp->mRight = icexp; + mexp->mDecType = bpdec; + + Expression* iexp = new Expression(pdec->mValue->mLocation, EX_CONSTRUCT); + iexp->mLeft = new Expression(pdec->mValue->mLeft->mLocation, EX_LIST); + iexp->mLeft->mLeft = new Expression(pdec->mValue->mLeft->mLeft->mLocation, EX_CALL); + iexp->mLeft->mLeft->mLeft = pdec->mValue->mLeft->mLeft->mLeft; + iexp->mLeft->mLeft->mDecType = pdec->mValue->mLeft->mLeft->mDecType; + iexp->mLeft->mLeft->mRight = new Expression(pdec->mValue->mLeft->mLeft->mRight->mLocation, EX_LIST); + iexp->mLeft->mLeft->mRight->mRight = pdec->mValue->mLeft->mLeft->mRight->mRight; + iexp->mLeft->mLeft->mRight->mLeft = mexp; + + lexp = iexp; + + offset += bpdec->mBase->mSize; } else + mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Invalid class initializer"); + + return lexp; +} + +Expression * Parser::BuildVariableInit(Expression* vexp, Expression* pexp) +{ + Declaration* mtype = vexp->mDecType; + + Declaration* fcons = mtype->mScope ? mtype->mScope->Lookup(mtype->mIdent->PreMangle("+"), SLEVEL_CLASS) : nullptr; + + if (mtype->mFlags & DTF_PURE_VIRTUAL) + mErrors->Error(vexp->mLocation, ERRR_INSTANTIATE_ABSTRACT_CLASS, "Cannot instantiate abstract class", mtype->mIdent); + + if (fcons) + { + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = fcons; + cexp->mDecType = cexp->mDecValue->mBase; + + Expression* fexp = new Expression(mScanner->mLocation, EX_CALL); + fexp->mLeft = cexp; + fexp->mRight = pexp; + + 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 = mtype; + 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; + + fexp = ResolveOverloadCall(fexp); + + Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT); + + nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST); + nexp->mLeft->mLeft = fexp; + + nexp->mRight = vexp; + nexp->mDecType = vexp->mDecType; + + return nexp; + } + else if (mtype->CanAssign(pexp->mDecType)) + { + Expression * nexp = new Expression(mScanner->mLocation, EX_INITIALIZATION); + nexp->mToken = TK_ASSIGN; + nexp->mDecType = mtype; + nexp->mLeft = vexp; + nexp->mRight = pexp; + + return nexp; + } + else if (pexp) + mErrors->Error(pexp->mLocation, EERR_INCOMPATIBLE_TYPES, "Can not initialize variable with expression", mtype->mIdent); + + return pexp; +} + +void Parser::ParseVariableInit(Declaration* ndec, Expression* pexp) +{ + if (!pexp) + { + Token ctoken = mScanner->mToken == TK_OPEN_BRACE ? TK_CLOSE_BRACE : TK_CLOSE_PARENTHESIS; + mScanner->NextToken(); + if (mScanner->mToken != ctoken) + { + pexp = ParseListExpression(false); + ConsumeToken(ctoken); + } + else + mScanner->NextToken(); + } Declaration* fcons = ndec->mBase->mScope ? ndec->mBase->mScope->Lookup(ndec->mBase->mIdent->PreMangle("+"), SLEVEL_CLASS) : nullptr; @@ -4647,168 +4872,294 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex mErrors->Error(exp->mLocation, EERR_CONSTANT_TYPE, "Constant integer expression expected"); } - if (ConsumeTokenIf(TK_ASSIGN)) - { - if (pthis && ndec->mBase->mType == DT_TYPE_FUNCTION && mScanner->mToken == TK_INTEGER && mScanner->mTokenInteger == 0) - { - mScanner->NextToken(); - ndec->mValue = new Expression(mScanner->mLocation, EX_ASSUME); - Declaration * fdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); - fdec->mBase = TheBoolTypeDeclaration; - fdec->mInteger = 0; - ndec->mValue->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT); - ndec->mValue->mLeft->mDecValue = fdec; - ndec->mValue->mLeft->mDecType = fdec->mBase; - ndec->mFlags |= DTF_DEFINED | DTF_PURE_VIRTUAL; - } - else - { - ndec->mValue = ParseInitExpression(ndec->mBase); - ndec->mBase = ndec->mBase->DeduceAuto(ndec->mValue->mDecType); - - if (ndec->mFlags & DTF_GLOBAL) - { - if (ndec->mFlags & DTF_ZEROPAGE) - ; - else - ndec->mSection = mDataSection; - } - ndec->mSize = ndec->mBase->mSize; - } - } else if (mScanner->mToken == TK_OPEN_PARENTHESIS && (mCompilerOptions & COPT_CPLUSPLUS)) { ParseVariableInit(ndec); } - else if ((mCompilerOptions & COPT_CPLUSPLUS) && ndec->mType == DT_VARIABLE && !pthis && !(storageFlags & DTF_EXTERN)) + else if (mScanner->mToken == TK_OPEN_BRACE && (mCompilerOptions & COPT_CPLUSPLUS) && ndec->mType == DT_VARIABLE && !pthis && !(storageFlags & DTF_EXTERN)) { - // Find default constructor - - Declaration* bdec = ndec->mBase; - while (bdec && bdec->mType == DT_TYPE_ARRAY) - bdec = bdec->mBase; - - if (bdec->mFlags & DTF_PURE_VIRTUAL) - mErrors->Error(ndec->mLocation, ERRR_INSTANTIATE_ABSTRACT_CLASS, "Cannot instantiate abstract class", ndec->mIdent); - - if (bdec && bdec->mDefaultConstructor) + ParseVariableInit(ndec); + } + else + { + if (ConsumeTokenIf(TK_ASSIGN)) { - bdec = bdec->ToMutableType(); - - Expression* vexp = new Expression(ndec->mLocation, EX_VARIABLE); - vexp->mDecType = ndec->mBase; - vexp->mDecValue = ndec; - - 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_DEFINED; - texp->mDecType->mBase = bdec; - texp->mDecType->mSize = 2; - - if (ndec->mBase->mType == DT_TYPE_STRUCT) + if (pthis && ndec->mBase->mType == DT_TYPE_FUNCTION && mScanner->mToken == TK_INTEGER && mScanner->mTokenInteger == 0) { - Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); - cexp->mDecValue = bdec->mDefaultConstructor; - cexp->mDecType = cexp->mDecValue->mBase; - - Expression* fexp = new Expression(mScanner->mLocation, EX_CALL); - fexp->mLeft = cexp; - fexp->mRight = texp; - - if (bdec->mDefaultConstructor->mFlags & DTF_CONSTEXPR) - ndec->mSection = mDataSection; - - Expression* dexp = nullptr; - if (ndec->mBase->mDestructor) - { - Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); - cexp->mDecValue = ndec->mBase->mDestructor; - cexp->mDecType = cexp->mDecValue->mBase; - - dexp = new Expression(mScanner->mLocation, EX_CALL); - dexp->mLeft = cexp; - dexp->mRight = texp; - } - - Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT); - - nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST); - nexp->mLeft->mLeft = fexp; - nexp->mLeft->mRight = dexp; - - nexp->mRight = vexp; - nexp->mDecType = vexp->mDecType; - - ndec->mValue = nexp; + mScanner->NextToken(); + ndec->mValue = new Expression(mScanner->mLocation, EX_ASSUME); + Declaration * fdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + fdec->mBase = TheBoolTypeDeclaration; + fdec->mInteger = 0; + ndec->mValue->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT); + ndec->mValue->mLeft->mDecValue = fdec; + ndec->mValue->mLeft->mDecType = fdec->mBase; + ndec->mFlags |= DTF_DEFINED | DTF_PURE_VIRTUAL; } else { - Expression* texp = vexp; + ndec->mValue = ParseInitExpression(ndec->mBase); + ndec->mBase = ndec->mBase->DeduceAuto(ndec->mValue->mDecType); - while (texp->mDecType->mBase->mType == DT_TYPE_ARRAY) + if (ndec->mFlags & DTF_GLOBAL) { - Expression* iexp = new Expression(vexp->mLocation, EX_PREFIX); - iexp->mToken = TK_MUL; - iexp->mLeft = texp; - iexp->mDecType = texp->mDecType->mBase; - texp = iexp; + if (ndec->mFlags & DTF_ZEROPAGE) + ; + else + ndec->mSection = mDataSection; } - - //texp->mDecType = bdec->BuildPointer(vexp->mLocation); - - Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); - ncdec->mBase = TheUnsignedIntTypeDeclaration; - ncdec->mInteger = ndec->mSize / bdec->mSize; - - Expression * ncexp = new Expression(mScanner->mLocation, EX_CONSTANT); - ncexp->mDecType = ncdec->mBase; - ncexp->mDecValue = ncdec; - - Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); - cexp->mDecValue = bdec->mVectorConstructor; - cexp->mDecType = cexp->mDecValue->mBase; - - Expression* fexp = new Expression(mScanner->mLocation, EX_CALL); - fexp->mLeft = cexp; - - fexp->mRight = new Expression(mScanner->mLocation, EX_LIST); - fexp->mRight->mLeft = texp; - fexp->mRight->mRight = new Expression(mScanner->mLocation, EX_BINARY); - fexp->mRight->mRight->mToken = TK_ADD; - fexp->mRight->mRight->mLeft = texp; - fexp->mRight->mRight->mDecType = texp->mDecType; - fexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT); - fexp->mRight->mRight->mRight->mDecType = ncdec->mBase; - fexp->mRight->mRight->mRight->mDecValue = ncdec; - - Expression* dexp = nullptr; - if (bdec->mDestructor) - { - Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); - cexp->mDecValue = bdec->mVectorDestructor; - cexp->mDecType = cexp->mDecValue->mBase; - - dexp = new Expression(mScanner->mLocation, EX_CALL); - dexp->mLeft = cexp; - dexp->mRight = fexp->mRight; - } - - Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT); - - nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST); - nexp->mLeft->mLeft = fexp; - nexp->mLeft->mRight = dexp; - - nexp->mRight = vexp; - nexp->mDecType = vexp->mDecType; - - ndec->mValue = nexp; + ndec->mSize = ndec->mBase->mSize; } } - else if (bdec && bdec->mDestructor) - mErrors->Error(ndec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor for class", ndec->mBase->mIdent); + + if ((mCompilerOptions & COPT_CPLUSPLUS) && ndec->mType == DT_VARIABLE && !pthis && !(storageFlags & DTF_EXTERN)) + { + // Find default constructor + + Declaration* bdec = ndec->mBase; + while (bdec && bdec->mType == DT_TYPE_ARRAY) + bdec = bdec->mBase; + + if (bdec->mFlags & DTF_PURE_VIRTUAL) + mErrors->Error(ndec->mLocation, ERRR_INSTANTIATE_ABSTRACT_CLASS, "Cannot instantiate abstract class", ndec->mIdent); + + if (bdec && bdec->mDefaultConstructor) + { + bdec = bdec->ToMutableType(); + + Expression* vexp = new Expression(ndec->mLocation, EX_VARIABLE); + vexp->mDecType = ndec->mBase; + vexp->mDecValue = ndec; + + Expression* texp = new Expression(mScanner->mLocation, EX_PREFIX); + texp->mToken = TK_BINARY_AND; + texp->mLeft = vexp; + texp->mDecType = bdec->BuildPointer(mScanner->mLocation); + + if (ndec->mBase->mType == DT_TYPE_STRUCT) + { + if (ndec->mValue) + { + ParseVariableInit(ndec, ndec->mValue); + } + else + { + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = bdec->mDefaultConstructor; + cexp->mDecType = cexp->mDecValue->mBase; + + Expression* fexp = new Expression(mScanner->mLocation, EX_CALL); + fexp->mLeft = cexp; + fexp->mRight = texp; + + if (bdec->mDefaultConstructor->mFlags & DTF_CONSTEXPR) + ndec->mSection = mDataSection; + + Expression* dexp = nullptr; + if (ndec->mBase->mDestructor) + { + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = ndec->mBase->mDestructor; + cexp->mDecType = cexp->mDecValue->mBase; + + dexp = new Expression(mScanner->mLocation, EX_CALL); + dexp->mLeft = cexp; + dexp->mRight = texp; + } + + Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT); + + nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST); + nexp->mLeft->mLeft = fexp; + nexp->mLeft->mRight = dexp; + + nexp->mRight = vexp; + nexp->mDecType = vexp->mDecType; + + ndec->mValue = nexp; + } + } + else if (ndec->mValue) + { + Expression* lexp = nullptr; + + Declaration* bpdec = bdec->BuildPointer(mScanner->mLocation); + + if (ndec->mValue->mType == EX_CONSTANT) + { + int offset = 0; + lexp = BuildVariableArrayInit(texp, bpdec, ndec->mValue->mDecValue, 0, offset); + +#if 0 + + Declaration * pdec = ndec->mValue->mDecValue->mParams; + while (pdec) + { + if (pdec->mType == DT_CONST_CONSTRUCTOR) + { + if (offset != pdec->mOffset) + mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Incomplete class initializer list"); + + Declaration* icdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + icdec->mBase = TheUnsignedIntTypeDeclaration; + icdec->mInteger = pdec->mOffset / ndec->mBase->mBase->mSize; + + Expression* icexp = new Expression(mScanner->mLocation, EX_CONSTANT); + icexp->mDecType = icdec->mBase; + icexp->mDecValue = icdec; + + Expression* mexp = new Expression(mScanner->mLocation, EX_BINARY); + mexp->mToken = TK_ADD; + mexp->mLeft = texp; + mexp->mRight = icexp; + mexp->mDecType = bpdec; + + pdec->mValue->mLeft->mLeft->mRight->mLeft = mexp; + pdec->mValue->mLeft->mRight = nullptr; + pdec->mValue->mRight = nullptr; + + if (lexp) + { + Expression* nexp = new Expression(mScanner->mLocation, EX_LIST); + nexp->mLeft = lexp; + nexp->mRight = pdec->mValue; + lexp = nexp; + } + else + lexp = pdec->mValue; + + offset += ndec->mBase->mBase->mSize; + } + else + mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Invalid class initializer"); + + pdec = pdec->mNext; + } +#endif + + + if (offset != ndec->mSize) + mErrors->Error(pdec->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Incomplete class initializer list"); + + while (texp->mDecType->mBase->mType == DT_TYPE_ARRAY) + { + Expression* iexp = new Expression(vexp->mLocation, EX_PREFIX); + iexp->mToken = TK_MUL; + iexp->mLeft = texp; + iexp->mDecType = texp->mDecType->mBase; + texp = iexp; + } + + texp->mDecType = bpdec; + + //texp->mDecType = bdec->BuildPointer(vexp->mLocation); + + Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + ncdec->mBase = TheUnsignedIntTypeDeclaration; + ncdec->mInteger = ndec->mSize / bdec->mSize; + + Expression* ncexp = new Expression(mScanner->mLocation, EX_CONSTANT); + ncexp->mDecType = ncdec->mBase; + ncexp->mDecValue = ncdec; + + Expression* dexp = nullptr; + if (bdec->mDestructor) + { + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = bdec->mVectorDestructor; + cexp->mDecType = cexp->mDecValue->mBase; + + dexp = new Expression(mScanner->mLocation, EX_CALL); + dexp->mLeft = cexp; + dexp->mRight = new Expression(mScanner->mLocation, EX_LIST); + dexp->mRight->mLeft = texp; + dexp->mRight->mRight = new Expression(mScanner->mLocation, EX_BINARY); + dexp->mRight->mRight->mToken = TK_ADD; + dexp->mRight->mRight->mLeft = texp; + dexp->mRight->mRight->mDecType = texp->mDecType; + dexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT); + dexp->mRight->mRight->mRight->mDecType = ncdec->mBase; + dexp->mRight->mRight->mRight->mDecValue = ncdec; + } + + Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT); + + nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST); + nexp->mLeft->mLeft = lexp; + nexp->mLeft->mRight = dexp; + + nexp->mRight = vexp; + nexp->mDecType = vexp->mDecType; + + ndec->mValue = nexp; + ndec->mFlags |= DTF_VAR_ALIASING; + } + else + mErrors->Error(ndec->mValue->mLocation, EERR_INVALID_CLASS_INITIALIZER, "Invalid class initializer list"); + } + else + { + Declaration* bpdec = bdec->BuildPointer(mScanner->mLocation); + + while (texp->mDecType->mBase->mType == DT_TYPE_ARRAY) + { + Expression* iexp = new Expression(vexp->mLocation, EX_PREFIX); + iexp->mToken = TK_MUL; + iexp->mLeft = texp; + iexp->mDecType = texp->mDecType->mBase; + texp = iexp; + } + + texp->mDecType = bpdec; + + Declaration* ncdec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + ncdec->mBase = TheUnsignedIntTypeDeclaration; + ncdec->mInteger = ndec->mSize / bdec->mSize; + + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = bdec->mVectorConstructor; + cexp->mDecType = cexp->mDecValue->mBase; + + Expression* fexp = new Expression(mScanner->mLocation, EX_CALL); + fexp->mLeft = cexp; + + fexp->mRight = new Expression(mScanner->mLocation, EX_LIST); + fexp->mRight->mLeft = texp; + fexp->mRight->mRight = new Expression(mScanner->mLocation, EX_BINARY); + fexp->mRight->mRight->mToken = TK_ADD; + fexp->mRight->mRight->mLeft = texp; + fexp->mRight->mRight->mDecType = texp->mDecType; + fexp->mRight->mRight->mRight = new Expression(mScanner->mLocation, EX_CONSTANT); + fexp->mRight->mRight->mRight->mDecType = ncdec->mBase; + fexp->mRight->mRight->mRight->mDecValue = ncdec; + + Expression* dexp = nullptr; + if (bdec->mDestructor) + { + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = bdec->mVectorDestructor; + cexp->mDecType = cexp->mDecValue->mBase; + + dexp = new Expression(mScanner->mLocation, EX_CALL); + dexp->mLeft = cexp; + dexp->mRight = fexp->mRight; + } + + Expression* nexp = new Expression(mScanner->mLocation, EX_CONSTRUCT); + + nexp->mLeft = new Expression(mScanner->mLocation, EX_LIST); + nexp->mLeft->mLeft = fexp; + nexp->mLeft->mRight = dexp; + + nexp->mRight = vexp; + nexp->mDecType = vexp->mDecType; + + ndec->mValue = nexp; + } + } + else if (bdec && bdec->mDestructor) + mErrors->Error(ndec->mLocation, EERR_NO_DEFAULT_CONSTRUCTOR, "No default constructor for class", ndec->mBase->mIdent); + } } if (storageFlags & DTF_EXPORT) diff --git a/oscar64/Parser.h b/oscar64/Parser.h index 8201ca4..7eb356f 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -56,7 +56,9 @@ protected: void AddDefaultConstructors(Declaration* pthis); - void ParseVariableInit(Declaration* ndec); + Expression* BuildVariableArrayInit(Expression* texp, Declaration* bpdec, Declaration* pdec, int boffset, int & offset); + Expression * BuildVariableInit(Expression* vexp, Expression* pexp); + void ParseVariableInit(Declaration* ndec, Expression * pexp = nullptr); Declaration* AddMemberFunction(Declaration* dec, Declaration* mdec); Declaration* FindBaseMemberFunction(Declaration* dec, Declaration* mdec);