From 532bf517184f987abaeb57c637904d88b4206f94 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Wed, 13 Sep 2023 17:24:38 +0200 Subject: [PATCH] Range for loop with reference iteration --- oscar64/Declaration.cpp | 24 +++++++++ oscar64/Declaration.h | 1 + oscar64/InterCode.cpp | 2 +- oscar64/InterCodeGenerator.cpp | 12 +++-- oscar64/Parser.cpp | 90 +++++++++++++++++++++++++++------- 5 files changed, 106 insertions(+), 23 deletions(-) diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 8fb23a2..1597fc8 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -964,6 +964,30 @@ Declaration* Declaration::NonRefBase(void) return this; } +Declaration* Declaration::DeduceAuto(Declaration * dec) +{ + if (mType == DT_TYPE_AUTO || IsReference() && mBase->mType == DT_TYPE_AUTO) + { + dec = dec->NonRefBase(); + + if (dec->mType == DT_TYPE_ARRAY) + dec = dec->mBase->BuildPointer(mLocation); + + if (mFlags & DTF_CONST) + dec = dec->ToConstType(); + else + dec = dec->ToMutableType(); + + if (IsReference()) + dec = dec->BuildReference(mLocation); + + return dec; + } + else + return this; +} + + Declaration* Declaration::BuildConstRValueRef(const Location& loc) { Declaration* pdec = new Declaration(loc, DT_TYPE_RVALUEREF); diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index a4d1b70..d4cd6a2 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -310,6 +310,7 @@ public: Declaration* BuildRValueRef(const Location& loc); Declaration* BuildConstRValueRef(const Location& loc); Declaration* NonRefBase(void); + Declaration* DeduceAuto(Declaration* dec); DecType ValueType(void) const; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 28be3a2..0cfc4e0 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -17102,7 +17102,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "main"); + CheckFunc = !strcmp(mIdent->mString, "test"); mEntryBlock = mBlocks[0]; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 256d784..f1e7198 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -2034,13 +2034,19 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (vl.mType->IsReference()) { - vr = Dereference(proc, exp, block, vr, 1); + if (vr.mType->IsReference()) + vr = Dereference(proc, exp, block, vr, 0); + else + { + vr = Dereference(proc, exp, block, vr, 1); + if (vr.mReference != 1) + mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an addressable expression"); + } + vl = Dereference(proc, exp, block, vl, 2); if (vl.mReference != 2) mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not a left hand reference expression"); - if (vr.mReference != 1) - mErrors->Error(exp->mLeft->mLocation, EERR_NOT_AN_LVALUE, "Not an addressable expression"); if (vr.mTemp != vl.mTemp) { diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 5629a23..94acaa0 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -4168,20 +4168,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex if (ConsumeTokenIf(TK_ASSIGN)) { ndec->mValue = ParseInitExpression(ndec->mBase); - if (ndec->mBase->mType == DT_TYPE_AUTO) - { - if (ndec->mBase->mFlags & DTF_CONST) - ndec->mBase = ndec->mValue->mDecType->ToConstType(); - else - ndec->mBase = ndec->mValue->mDecType; - - if (ndec->mBase->mType == DT_TYPE_ARRAY) - { - ndec->mBase = ndec->mBase->Clone(); - ndec->mBase->mType = DT_TYPE_POINTER; - ndec->mBase->mSize = 2; - } - } + ndec->mBase = ndec->mBase->DeduceAuto(ndec->mValue->mDecType); if (ndec->mFlags & DTF_GLOBAL) { @@ -7055,6 +7042,71 @@ Expression* Parser::CheckOperatorOverload(Expression* exp) } } } + else if (exp->mType == EX_INITIALIZATION) + { + Declaration* tdec = exp->mLeft->mDecType; + if (tdec->mType == DT_TYPE_STRUCT && exp->mToken == TK_ASSIGN) + { + Declaration* fcons = tdec->mScope ? tdec->mScope->Lookup(tdec->mIdent->PreMangle("+"), SLEVEL_CLASS) : nullptr; + if (fcons) + { + Declaration* mtype = tdec->ToMutableType(); + + Expression* vexp = exp->mLeft; + + 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 = exp->mRight; + + 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* dexp = nullptr; + if (tdec->mDestructor) + { + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = tdec->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; + + exp = nexp; + } + } + } else if (exp->mType == EX_INDEX) { Declaration* tdec = exp->mLeft->mDecType; @@ -7690,8 +7742,8 @@ Expression* Parser::ParseStatement(void) endVarDec->mFlags |= DTF_DEFINED; Declaration* valueVarDec = initExp->mDecValue; - if (valueVarDec->mBase->mType == DT_TYPE_AUTO) - valueVarDec->mBase = containerExp->mDecType->mBase; + valueVarDec->mBase = valueVarDec->mBase->DeduceAuto(containerExp->mDecType->mBase); + valueVarDec->mSize = valueVarDec->mBase->mSize; initExp = new Expression(mScanner->mLocation, EX_LIST); initExp->mLeft = new Expression(mScanner->mLocation, EX_INITIALIZATION); @@ -7814,7 +7866,7 @@ Expression* Parser::ParseStatement(void) conditionExp->mRight->mDecValue = endVarDec; conditionExp = CheckOperatorOverload(conditionExp); - bodyExp = new Expression(mScanner->mLocation, EX_ASSIGNMENT); + bodyExp = new Expression(mScanner->mLocation, EX_INITIALIZATION); bodyExp->mToken = TK_ASSIGN; bodyExp->mLeft = new Expression(mScanner->mLocation, EX_VARIABLE); @@ -7826,8 +7878,8 @@ Expression* Parser::ParseStatement(void) bodyExp->mRight->mLeft->mDecValue = iterVarDec; bodyExp->mRight = CheckOperatorOverload(bodyExp->mRight); - if (valueVarDec->mBase->mType == DT_TYPE_AUTO) - valueVarDec->mBase = bodyExp->mRight->mDecType->NonRefBase(); + valueVarDec->mBase = valueVarDec->mBase->DeduceAuto(bodyExp->mRight->mDecType); + valueVarDec->mSize = valueVarDec->mBase->mSize; bodyExp->mLeft->mDecType = valueVarDec->mBase; bodyExp->mLeft->mDecValue = valueVarDec;