From 37416a61cb3e4beb571d21159f757c0e2532a2d2 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 18 Jun 2023 10:20:50 +0200 Subject: [PATCH] Add struct inheritance in cpp mode --- oscar64/Declaration.cpp | 22 ++++++++++++++++++---- oscar64/Errors.h | 1 + oscar64/InterCodeGenerator.cpp | 23 ++++++++++++++--------- oscar64/Parser.cpp | 18 +++++++++++++++++- 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index f153ec0..ba35f6f 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -794,7 +794,7 @@ bool Declaration::IsSubType(const Declaration* dec) const if (mType != dec->mType) return false; - if (mSize != dec->mSize) + if (mType != DT_TYPE_STRUCT && mSize != dec->mSize) return false; if (mStripe != dec->mStripe) return false; @@ -810,7 +810,15 @@ bool Declaration::IsSubType(const Declaration* dec) const else if (mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_VOID) return true; else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM) - return mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize); + { + if (mScope == dec->mScope || (mIdent == dec->mIdent && mSize == dec->mSize)) + return true; + + if (dec->mBase) + return IsSubType(dec->mBase); + + return false; + } else if (mType == DT_TYPE_UNION) return false; else if (mType == DT_TYPE_ARRAY) @@ -964,7 +972,7 @@ bool Declaration::IsSameValue(const Declaration* dec) const bool Declaration::CanAssign(const Declaration* fromType) const { if (mType == DT_TYPE_REFERENCE) - return fromType->IsSubType(mBase); + return mBase->IsSubType(fromType); else if (fromType->mType == DT_TYPE_REFERENCE) return this->CanAssign(fromType->mBase); @@ -976,7 +984,13 @@ bool Declaration::CanAssign(const Declaration* fromType) const return true; } else if (mType == DT_TYPE_STRUCT && fromType->mType == DT_TYPE_STRUCT) - return mScope == fromType->mScope || (mIdent == fromType->mIdent && mSize == fromType->mSize); + { + if (mScope == fromType->mScope || (mIdent == fromType->mIdent && mSize == fromType->mSize)) + return true; + if (fromType->mBase) + return this->CanAssign(fromType->mBase); + return false; + } else if (mType == DT_TYPE_POINTER) { if (fromType->mType == DT_TYPE_POINTER || fromType->mType == DT_TYPE_ARRAY) diff --git a/oscar64/Errors.h b/oscar64/Errors.h index 24d9f73..23724de 100644 --- a/oscar64/Errors.h +++ b/oscar64/Errors.h @@ -71,6 +71,7 @@ enum ErrorID ERRR_STRIPE_REQUIRES_FIXED_SIZE_ARRAY, ERRR_CANNOT_FIND_BANK_OF_EXPRESSION, ERRO_NOT_A_NAMESPACE, + ERRO_NOT_A_BASE_CLASS, ERRR_STACK_OVERFLOW, ERRR_INVALID_NUMBER, diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index a49882c..70418cd 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -77,6 +77,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p return v; } + else if (type->mType == DT_TYPE_STRUCT && type->mBase->IsSubType(v.mType)) + { + v.mType = type; + return v; + } if (v.mType->IsIntegerType() && type->mType == DT_TYPE_FLOAT) { @@ -936,15 +941,15 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro cins->mSrc[0].mType = IT_POINTER; cins->mSrc[0].mTemp = vr.mTemp; cins->mSrc[0].mMemory = IM_INDIRECT; - cins->mSrc[0].mOperandSize = vr.mType->mSize; + cins->mSrc[0].mOperandSize = vp.mType->mSize; cins->mSrc[0].mStride = vr.mType->mStripe; cins->mSrc[1].mType = IT_POINTER; cins->mSrc[1].mTemp = ains->mDst.mTemp; cins->mSrc[1].mMemory = IM_INDIRECT; - cins->mSrc[1].mOperandSize = vr.mType->mSize; + cins->mSrc[1].mOperandSize = vp.mType->mSize; - cins->mConst.mOperandSize = vr.mType->mSize; + cins->mConst.mOperandSize = vp.mType->mSize; block->Append(cins); } } @@ -2636,15 +2641,15 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* cins->mSrc[0].mType = IT_POINTER; cins->mSrc[0].mTemp = vr.mTemp; cins->mSrc[0].mMemory = IM_INDIRECT; - cins->mSrc[0].mOperandSize = vr.mType->mSize; + cins->mSrc[0].mOperandSize = vp.mType->mSize; cins->mSrc[0].mStride = vr.mType->mStripe; - cins->mSrc[1].mOperandSize = vr.mType->mSize; + cins->mSrc[1].mOperandSize = vp.mType->mSize; cins->mSrc[1].mType = IT_POINTER; cins->mSrc[1].mTemp = ains->mDst.mTemp; cins->mSrc[1].mMemory = IM_INDIRECT; - cins->mConst.mOperandSize = vr.mType->mSize; + cins->mConst.mOperandSize = vp.mType->mSize; block->Append(cins); } @@ -2969,15 +2974,15 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* cins->mSrc[0].mType = IT_POINTER; cins->mSrc[0].mTemp = vr.mTemp; cins->mSrc[0].mMemory = IM_INDIRECT; - cins->mSrc[0].mOperandSize = vr.mType->mSize; + cins->mSrc[0].mOperandSize = procType->mBase->mSize; cins->mSrc[0].mStride = vr.mType->mStripe; - cins->mSrc[1].mOperandSize = vr.mType->mSize; + cins->mSrc[1].mOperandSize = procType->mBase->mSize; cins->mSrc[1].mType = IT_POINTER; cins->mSrc[1].mTemp = ains->mDst.mTemp; cins->mSrc[1].mMemory = IM_INDIRECT; - cins->mConst.mOperandSize = vr.mType->mSize; + cins->mConst.mOperandSize = procType->mBase->mSize; block->Append(cins); } else diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 5258353..0be34af 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -39,7 +39,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) structName = mScanner->mTokenIdent; mScanner->NextToken(); Declaration* edec = mScope->Lookup(structName); - if (edec && mScanner->mToken != TK_OPEN_BRACE) + if (edec && mScanner->mToken != TK_OPEN_BRACE && mScanner->mToken != TK_COLON) { dec = edec; } @@ -67,6 +67,22 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) dec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS); } + if ((mCompilerOptions & COPT_CPLUSPLUS) && mScanner->mToken == TK_COLON) + { + mScanner->NextToken(); + Declaration* pdec = ParseQualIdent(); + if (pdec) + { + if (pdec->mType == DT_TYPE_STRUCT) + { + dec->mBase = pdec; + dec->mSize = pdec->mSize; + } + else + mErrors->Error(mScanner->mLocation, ERRO_NOT_A_BASE_CLASS, "Not a base class", dec->mIdent); + } + } + if (mScanner->mToken == TK_OPEN_BRACE) { mScanner->NextToken();