From 9bcec5bf1791c96dc1a138eae6e3b1e1204760ba Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Wed, 21 Jun 2023 22:07:00 +0200 Subject: [PATCH] Destructors when leaving scopes the normal way --- include/c64/memmap.c | 8 +- oscar64/Declaration.cpp | 2 +- oscar64/Declaration.h | 5 +- oscar64/Errors.h | 1 + oscar64/GlobalAnalyzer.cpp | 12 ++ oscar64/InterCodeGenerator.cpp | 213 +++++++++++++++++++++++---------- oscar64/InterCodeGenerator.h | 11 +- oscar64/Parser.cpp | 132 ++++++++++++++++++-- 8 files changed, 305 insertions(+), 79 deletions(-) diff --git a/include/c64/memmap.c b/include/c64/memmap.c index 359a5d0..c2c061f 100644 --- a/include/c64/memmap.c +++ b/include/c64/memmap.c @@ -27,7 +27,7 @@ __asm IRQTrampoline tsx lda $0105, x pha - jmp ($fffa) + jmp ($fffe) } __asm NMITrampoline @@ -45,13 +45,13 @@ __asm NMITrampoline tsx lda $0105, x pha - jmp ($fffe) + jmp ($fffa) } void mmap_trampoline(void) { - *((void **)0xfffa) = IRQTrampoline; - *((void **)0xfffe) = NMITrampoline; + *((void **)0xfffa) = NMITrampoline; + *((void **)0xfffe) = IRQTrampoline; } #pragma native(mmap_trampoline) diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index ee4bc30..3f0af85 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -17,7 +17,7 @@ DeclarationScope::~DeclarationScope(void) const Ident* DeclarationScope::Mangle(const Ident* ident) const { - if (mName) + if (mName && ident) { char buffer[200]; strcpy_s(buffer, mName->mString); diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index df00664..418c3fe 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -94,6 +94,7 @@ 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_FUNC_DESTRUCTOR = (1ULL << 44); static const uint64 DTF_VAR_ALIASING = (1ULL << 48); @@ -167,6 +168,7 @@ enum ExpressionType EX_ELSE, EX_FOR, EX_DO, + EX_SCOPE, EX_BREAK, EX_CONTINUE, EX_TYPE, @@ -181,7 +183,8 @@ enum ExpressionType EX_DEFAULT, EX_CONDITIONAL, EX_ASSUME, - EX_BANKOF + EX_BANKOF, + EX_CONSTRUCT }; class Expression diff --git a/oscar64/Errors.h b/oscar64/Errors.h index 8e157ab..1e2333c 100644 --- a/oscar64/Errors.h +++ b/oscar64/Errors.h @@ -28,6 +28,7 @@ enum ErrorID EWARN_MISSING_RETURN_STATEMENT, EWARN_UNREACHABLE_CODE, EWARN_NULL_POINTER_DEREFERENCED, + EWARN_DESTRUCTOR_MISMATCH, EERR_GENERIC = 3000, EERR_FILE_NOT_FOUND, diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index b51e40a..d944a59 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -744,6 +744,18 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo exp = exp->mRight; } while (exp); break; + + case EX_SCOPE: + Analyze(exp->mLeft, procDec, false); + break; + + case EX_CONSTRUCT: + if (exp->mLeft->mLeft) + Analyze(exp->mLeft->mLeft, procDec, false); + if (exp->mLeft->mRight) + Analyze(exp->mLeft->mRight, procDec, false); + return Analyze(exp->mRight, procDec, false); + case EX_WHILE: procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 70418cd..7f04894 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -856,8 +856,27 @@ void InterCodeGenerator::BuildSwitchTree(InterCodeProcedure* proc, Expression* e } } +void InterCodeGenerator::UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack* bottom) +{ + while (stack && stack != bottom) + { + if (stack->mDestruct) + { + DestructStack* destack = nullptr; + TranslateExpression(procType, proc, block, stack->mDestruct, destack, nullptr, nullptr, nullptr); + } + + stack = stack->mNext; + } + + if (stack != bottom) + mErrors->Error(proc->mLocation, EWARN_DESTRUCTOR_MISMATCH, "Destructor sequence mismatch"); +} + InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr) { + DestructStack* destack = nullptr; + ExValue vl, vr; Declaration* fdec = exp->mLeft->mDecValue; @@ -922,7 +941,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1); - vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock, inlineMapper, &vp); + vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp); if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)) { @@ -1014,7 +1033,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro rdec->mSize = rdec->mBase->mSize; } - vl = TranslateExpression(ftype, proc, block, fexp, nullptr, nullptr, &nmapper); + vl = TranslateExpression(ftype, proc, block, fexp, destack, nullptr, nullptr, &nmapper); InterInstruction* jins = new InterInstruction(exp->mLocation, IC_JUMP); block->Append(jins); @@ -1040,7 +1059,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro return ExValue(TheVoidTypeDeclaration); } -InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, ExValue* lrexp) +InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, ExValue* lrexp) { Declaration* dec; ExValue vl, vr; @@ -1054,11 +1073,27 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_SEQUENCE: case EX_LIST: - vr = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); exp = exp->mRight; if (!exp) return ExValue(TheVoidTypeDeclaration); break; + case EX_CONSTRUCT: + { + if (exp->mLeft->mLeft) + TranslateExpression(procType, proc, block, exp->mLeft->mLeft, destack, breakBlock, continueBlock, inlineMapper); + + if (exp->mLeft->mRight) + { + DestructStack* de = new DestructStack(); + de->mNext = destack; + de->mDestruct = exp->mLeft->mRight; + destack = de; + } + + exp = exp->mRight; + } + break; case EX_CONSTANT: dec = exp->mDecValue; switch (dec->mType) @@ -1182,7 +1217,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case DT_CONST_POINTER: { - vl = TranslateExpression(procType, proc, block, dec->mValue, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, dec->mValue, destack, breakBlock, continueBlock, inlineMapper); vl.mReference--; vl.mType = exp->mDecType; return vl; @@ -1341,19 +1376,19 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* { if (exp->mLeft->mDecType && exp->mLeft->mDecType->mType == DT_TYPE_STRUCT) { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper, &vl); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper, &vl); } else if (exp->mType == EX_INITIALIZATION && exp->mLeft->mDecType && exp->mLeft->mDecType->mType == DT_TYPE_REFERENCE) { - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl.mType = exp->mLeft->mDecType; } else { - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); } if (exp->mToken == TK_ASSIGN || !(vl.mType->mType == DT_TYPE_POINTER && vr.mType->IsIntegerType() && (exp->mToken == TK_ASSIGN_ADD || exp->mToken == TK_ASSIGN_SUB))) @@ -1600,8 +1635,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_INDEX: { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); int stride = vl.mType->Stride(); @@ -1657,7 +1692,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_QUALIFY: { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = Dereference(proc, exp, block, vl, 1); if (vl.mReference != 1) @@ -1684,8 +1719,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_BINARY: { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); vr = Dereference(proc, exp, block, vr); InterInstruction * ins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR); @@ -1981,7 +2016,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_PREINCDEC: { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = Dereference(proc, exp, block, vl, 1); if (vl.mReference != 1) @@ -2042,7 +2077,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_POSTINCDEC: { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = Dereference(proc, exp, block, vl, 1); if (vl.mReference != 1) @@ -2101,7 +2136,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_PREFIX: { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); InterInstruction * ins = new InterInstruction(exp->mLocation, IC_UNARY_OPERATOR); @@ -2182,9 +2217,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_RELATIONAL: { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = Dereference(proc, exp, block, vl, vl.mType->mType == DT_TYPE_ARRAY ? 1 : 0); - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); vr = Dereference(proc, exp, block, vr, vr.mType->mType == DT_TYPE_ARRAY ? 1 : 0); InterInstruction * ins = new InterInstruction(exp->mLocation, IC_RELATIONAL_OPERATOR); @@ -2287,7 +2322,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (!strcmp(iname->mString, "fabs")) { - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); vr = Dereference(proc, exp, block, vr); if (decf->mBase->mParams->CanAssign(vr.mType)) @@ -2306,7 +2341,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } else if (!strcmp(iname->mString, "floor")) { - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); vr = Dereference(proc, exp, block, vr); if (decf->mBase->mParams->CanAssign(vr.mType)) @@ -2325,7 +2360,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } else if (!strcmp(iname->mString, "ceil")) { - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); vr = Dereference(proc, exp, block, vr); if (decf->mBase->mParams->CanAssign(vr.mType)) @@ -2350,13 +2385,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if ((tex->mDecType->mType == DT_TYPE_ARRAY && tex->mDecType->mSize <= 256) || (sex->mDecType->mType == DT_TYPE_ARRAY && sex->mDecType->mSize <= 256)) { - vl = TranslateExpression(procType, proc, block, tex, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, tex, destack, breakBlock, continueBlock, inlineMapper); if (vl.mType->mType == DT_TYPE_ARRAY) vl = Dereference(proc, exp, block, vl, 1); else vl = Dereference(proc, exp, block, vl); - vr = TranslateExpression(procType, proc, block, sex, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, sex, destack, breakBlock, continueBlock, inlineMapper); if (vr.mType->mType == DT_TYPE_ARRAY) vr = Dereference(proc, exp, block, vr, 1); else @@ -2387,13 +2422,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* Expression* tex = exp->mRight->mLeft, * sex = exp->mRight->mRight->mLeft, * nex = exp->mRight->mRight->mRight; if (nex && nex->mType == EX_CONSTANT && nex->mDecValue->mType == DT_CONST_INTEGER && nex->mDecValue->mInteger < 512) { - vl = TranslateExpression(procType, proc, block, tex, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, tex, destack, breakBlock, continueBlock, inlineMapper); if (vl.mType->mType == DT_TYPE_ARRAY) vl = Dereference(proc, exp, block, vl, 1); else vl = Dereference(proc, exp, block, vl); - vr = TranslateExpression(procType, proc, block, sex, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, sex, destack, breakBlock, continueBlock, inlineMapper); if (vr.mType->mType == DT_TYPE_ARRAY) vr = Dereference(proc, exp, block, vr, 1); else @@ -2478,7 +2513,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } else { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = Dereference(proc, exp, block, vl); int atotal = 0; @@ -2623,7 +2658,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ExValue vp(pdec ? pdec->mBase : TheSignedIntTypeDeclaration, ains->mDst.mTemp, 1); - vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock, inlineMapper, &vp); + vr = TranslateExpression(procType, proc, block, texp, destack, breakBlock, continueBlock, inlineMapper, &vp); if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)) { @@ -2879,7 +2914,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterInstruction * ins = new InterInstruction(exp->mLocation, IC_RETURN); if (exp->mLeft) { - vr = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); if (procType->mBase->mType == DT_TYPE_REFERENCE) { @@ -3090,7 +3125,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterCodeBasicBlock* tblock = new InterCodeBasicBlock(proc); InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc); - TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper); + TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, destack, inlineMapper); InterInstruction* ins = new InterInstruction(exp->mLocation, IC_UNREACHABLE); fblock->Append(ins); @@ -3102,7 +3137,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } case EX_LOGICAL_NOT: { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = Dereference(proc, exp, block, vl); InterInstruction * zins = new InterInstruction(exp->mLocation, IC_CONSTANT); @@ -3129,10 +3164,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* #if 1 if (!exp->mRight->mLeft->HasSideEffects() && !exp->mRight->mRight->HasSideEffects()) { - ExValue vc = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + ExValue vc = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); - vl = TranslateExpression(procType, proc, block, exp->mRight->mLeft, breakBlock, continueBlock, inlineMapper); - vr = TranslateExpression(procType, proc, block, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mRight->mLeft, destack, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight->mRight, destack, breakBlock, continueBlock, inlineMapper); vc = Dereference(proc, exp, block, vc); @@ -3224,10 +3259,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc); InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); - TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper); + TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, destack, inlineMapper); - vl = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, breakBlock, continueBlock, inlineMapper); - vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, destack, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, destack, breakBlock, continueBlock, inlineMapper); int ttemp; InterType ttype, stypel, styper; @@ -3322,7 +3357,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_TYPECAST: { - vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); + vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); InterInstruction * ins = new InterInstruction(exp->mLocation, IC_CONVERSION_OPERATOR); @@ -3431,7 +3466,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc); InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); - TranslateLogic(procType, proc, block, tblock, fblock, exp, inlineMapper); + TranslateLogic(procType, proc, block, tblock, fblock, exp, destack, inlineMapper); int ttemp = proc->AddTemporary(IT_BOOL); @@ -3459,8 +3494,23 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } break; + case EX_SCOPE: + { + DestructStack* odestack = destack; + + TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); + + UnwindDestructStack(procType, proc, block, destack, odestack); + destack = odestack; + + return ExValue(TheVoidTypeDeclaration); + + } break; + case EX_WHILE: { + DestructStack* odestack = destack; + InterInstruction * jins0 = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP); @@ -3472,19 +3522,30 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* block->Append(jins0); block->Close(cblock, nullptr); - TranslateLogic(procType, proc, cblock, bblock, eblock, exp->mLeft, inlineMapper); + TranslateLogic(procType, proc, cblock, bblock, eblock, exp->mLeft, destack, inlineMapper); + + DestructStack* idestack = destack; + + vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, eblock, lblock, inlineMapper); + + UnwindDestructStack(procType, proc, bblock, destack, idestack); + destack = idestack; - vr = TranslateExpression(procType, proc, bblock, exp->mRight, eblock, lblock, inlineMapper); bblock->Append(jins1); bblock->Close(lblock, nullptr); block = eblock; + UnwindDestructStack(procType, proc, block, destack, odestack); + destack = odestack; + return ExValue(TheVoidTypeDeclaration); } case EX_IF: { + DestructStack* odestack = destack; + InterInstruction * jins0 = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP); @@ -3492,27 +3553,41 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterCodeBasicBlock* fblock = new InterCodeBasicBlock(proc); InterCodeBasicBlock* eblock = new InterCodeBasicBlock(proc); - TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper); + TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, destack, inlineMapper); + + DestructStack* itdestack = destack; + vr = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, destack, breakBlock, continueBlock, inlineMapper); + UnwindDestructStack(procType, proc, tblock, destack, itdestack); + destack = itdestack; - vr = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, breakBlock, continueBlock, inlineMapper); tblock->Append(jins0); tblock->Close(eblock, nullptr); if (exp->mRight->mRight) - vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper); + { + DestructStack* ifdestack = destack; + vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, destack, breakBlock, continueBlock, inlineMapper); + UnwindDestructStack(procType, proc, fblock, destack, ifdestack); + destack = ifdestack; + } fblock->Append(jins1); fblock->Close(eblock, nullptr); block = eblock; + UnwindDestructStack(procType, proc, block, destack, odestack); + destack = odestack; + return ExValue(TheVoidTypeDeclaration); } case EX_FOR: { + DestructStack* odestack = destack; + // assignment if (exp->mLeft->mRight) - TranslateExpression(procType, proc, block, exp->mLeft->mRight, breakBlock, continueBlock, inlineMapper); + TranslateExpression(procType, proc, block, exp->mLeft->mRight, destack, breakBlock, continueBlock, inlineMapper); InterInstruction* jins0 = new InterInstruction(exp->mLocation, IC_JUMP); InterInstruction* jins1 = new InterInstruction(exp->mLocation, IC_JUMP); @@ -3530,27 +3605,37 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* // condition if (exp->mLeft->mLeft->mLeft) - TranslateLogic(procType, proc, cblock, bblock, eblock, exp->mLeft->mLeft->mLeft, inlineMapper); + TranslateLogic(procType, proc, cblock, bblock, eblock, exp->mLeft->mLeft->mLeft, destack, inlineMapper); else { cblock->Append(jins1); cblock->Close(bblock, nullptr); } - vr = TranslateExpression(procType, proc, bblock, exp->mRight, eblock, iblock, inlineMapper); + // Body + + DestructStack* idestack = destack; + + vr = TranslateExpression(procType, proc, bblock, exp->mRight, destack, eblock, iblock, inlineMapper); + + UnwindDestructStack(procType, proc, bblock, destack, idestack); + destack = idestack; bblock->Append(jins2); bblock->Close(iblock, nullptr); // increment if (exp->mLeft->mLeft->mRight) - TranslateExpression(procType, proc, iblock, exp->mLeft->mLeft->mRight, breakBlock, continueBlock, inlineMapper); + TranslateExpression(procType, proc, iblock, exp->mLeft->mLeft->mRight, destack, breakBlock, continueBlock, inlineMapper); iblock->Append(jins3); iblock->Close(lblock, nullptr); block = eblock; + UnwindDestructStack(procType, proc, block, destack, odestack); + destack = odestack; + return ExValue(TheVoidTypeDeclaration); } @@ -3565,9 +3650,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* block->Append(jins); block->Close(cblock, nullptr); - vr = TranslateExpression(procType, proc, cblock, exp->mRight, eblock, cblock, inlineMapper); + vr = TranslateExpression(procType, proc, cblock, exp->mRight, destack, eblock, cblock, inlineMapper); - TranslateLogic(procType, proc, cblock, lblock, eblock, exp->mLeft, inlineMapper); + TranslateLogic(procType, proc, cblock, lblock, eblock, exp->mLeft, destack, inlineMapper); block = eblock; @@ -3576,7 +3661,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_SWITCH: { - vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); + vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vl = Dereference(proc, exp, block, vl); vl = CoerceType(proc, exp, block, vl, TheSignedIntTypeDeclaration); @@ -3645,7 +3730,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } if (cexp->mRight) - TranslateExpression(procType, proc, block, cexp->mRight, eblock, continueBlock, inlineMapper); + TranslateExpression(procType, proc, block, cexp->mRight, destack, eblock, continueBlock, inlineMapper); sexp = sexp->mRight; } @@ -3809,30 +3894,30 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int } } -void InterCodeGenerator::TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, InlineMapper* inlineMapper) +void InterCodeGenerator::TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, InlineMapper* inlineMapper) { switch (exp->mType) { case EX_LOGICAL_NOT: - TranslateLogic(procType, proc, block, fblock, tblock, exp->mLeft, inlineMapper); + TranslateLogic(procType, proc, block, fblock, tblock, exp->mLeft, destack, inlineMapper); break; case EX_LOGICAL_AND: { InterCodeBasicBlock* ablock = new InterCodeBasicBlock(proc); - TranslateLogic(procType, proc, block, ablock, fblock, exp->mLeft, inlineMapper); - TranslateLogic(procType, proc, ablock, tblock, fblock, exp->mRight, inlineMapper); + TranslateLogic(procType, proc, block, ablock, fblock, exp->mLeft, destack, inlineMapper); + TranslateLogic(procType, proc, ablock, tblock, fblock, exp->mRight, destack, inlineMapper); break; } case EX_LOGICAL_OR: { InterCodeBasicBlock* oblock = new InterCodeBasicBlock(proc); - TranslateLogic(procType, proc, block, tblock, oblock, exp->mLeft, inlineMapper); - TranslateLogic(procType, proc, oblock, tblock, fblock, exp->mRight, inlineMapper); + TranslateLogic(procType, proc, block, tblock, oblock, exp->mLeft, destack, inlineMapper); + TranslateLogic(procType, proc, oblock, tblock, fblock, exp->mRight, destack, inlineMapper); break; } default: { - ExValue vr = TranslateExpression(procType, proc, block, exp, nullptr, nullptr, inlineMapper); + ExValue vr = TranslateExpression(procType, proc, block, exp, destack, nullptr, nullptr, inlineMapper); vr = Dereference(proc, exp, block, vr); if (!vr.mType->IsSimpleType()) @@ -3937,7 +4022,11 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod } #endif - TranslateExpression(dec->mBase, proc, exitBlock, exp, nullptr, nullptr, nullptr); + DestructStack* destack = nullptr; + + TranslateExpression(dec->mBase, proc, exitBlock, exp, destack, nullptr, nullptr, nullptr); + + UnwindDestructStack(dec->mBase, proc, exitBlock, destack, nullptr); } else mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString); diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 870633c..9b5e7f5 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -11,6 +11,12 @@ public: InterCodeGenerator(Errors * errors, Linker * linker); ~InterCodeGenerator(void); + struct DestructStack + { + Expression * mDestruct; + DestructStack* mNext; + }; + struct ExValue { Declaration* mType; @@ -57,9 +63,10 @@ protected: ExValue Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, int level = 0); ExValue CoerceType(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, Declaration * type, bool checkTrunc = true); - ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr); - void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, InlineMapper* inlineMapper); + ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, DestructStack*& destack, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr); + void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp, DestructStack*& destack, InlineMapper* inlineMapper); ExValue TranslateInline(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock, InlineMapper* inlineMapper, bool inlineConstexpr); + void UnwindDestructStack(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock*& block, DestructStack* stack, DestructStack * bottom); void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, InterVariable * variable); }; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 762a34d..f37e49c 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -118,7 +118,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) if (mCompilerOptions & COPT_NATIVE) mdec->mFlags |= DTF_NATIVE; - if (!(mdec->mFlags & DTF_FUNC_CONSTRUCTOR)) + if (!(mdec->mFlags & (DTF_FUNC_CONSTRUCTOR | DTF_FUNC_DESTRUCTOR))) { Declaration* pdec = dec->mScope->Insert(mdec->mIdent, mdec); @@ -1166,7 +1166,7 @@ void Parser::PrependThisArgument(Declaration* fdec, Declaration* pthis) Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool expression, Declaration* pthis) { - bool definingType = false; + bool definingType = false, destructor = false; uint64 storageFlags = 0, typeFlags = 0; Declaration* bdec; @@ -1282,6 +1282,65 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex } } + if ((mCompilerOptions & COPT_CPLUSPLUS) && pthis && mScanner->mToken == TK_BINARY_NOT) + { + // Destructor declaration + mScanner->NextToken(); + if (mScanner->mToken == TK_IDENT) + { + if (mScanner->mTokenIdent != pthis->mBase->mIdent) + mErrors->Error(mScanner->mLocation, EERR_INVALID_IDENTIFIER, "Wrong class name for destructor", pthis->mIdent); + mScanner->NextToken(); + } + else + mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected"); + + Declaration* ctdec = ParseFunctionDeclaration(TheVoidTypeDeclaration); + + if (ctdec->mParams) + mErrors->Error(ctdec->mLocation, EERR_WRONG_PARAMETER, "Destructor can't have parameter"); + + 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_DESTRUCTOR; + + cdec->mSection = mCodeSection; + cdec->mBase->mFlags |= typeFlags; + + if (mCompilerOptions & COPT_NATIVE) + cdec->mFlags |= DTF_NATIVE; + + if (pthis->mBase->mDestructor) + mErrors->Error(ctdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate destrcutor definition"); + else + pthis->mBase->mDestructor = cdec; + + char dname[100]; + strcpy_s(dname, "~"); + strcat_s(dname, pthis->mBase->mIdent->mString); + cdec->mIdent = Ident::Unique(dname); + cdec->mQualIdent = pthis->mBase->mScope->Mangle(cdec->mIdent); + + if (mScanner->mToken == TK_OPEN_BRACE) + { + cdec->mCompilerOptions = mCompilerOptions; + cdec->mBase->mCompilerOptions = mCompilerOptions; + + cdec->mVarIndex = -1; + + cdec->mValue = ParseFunction(cdec->mBase); + + cdec->mFlags |= DTF_DEFINED; + cdec->mNumVars = mLocalIndex; + } + + return cdec; + } + bdec = ParseBaseTypeDeclaration(typeFlags); } @@ -1647,8 +1706,24 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex ResolveOverloadCall(cexp, fexp->mRight); - Expression* nexp = new Expression(mScanner->mLocation, EX_SEQUENCE); - nexp->mLeft = fexp; + 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; @@ -1686,8 +1761,24 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex fexp->mRight = texp; - Expression* nexp = new Expression(mScanner->mLocation, EX_SEQUENCE); - nexp->mLeft = fexp; + 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; } @@ -1755,7 +1846,7 @@ Expression* Parser::ParseDeclarationExpression(Declaration * pdec) { Expression* nexp; - if ((mCompilerOptions & COPT_CPLUSPLUS) && dec->mValue->mType == EX_SEQUENCE) + if ((mCompilerOptions & COPT_CPLUSPLUS) && dec->mValue->mType == EX_CONSTRUCT) { nexp = dec->mValue; @@ -2462,8 +2553,24 @@ Expression* Parser::ParsePostfixExpression(bool lhs) ResolveOverloadCall(cexp, fexp->mRight); - Expression* nexp = new Expression(mScanner->mLocation, EX_SEQUENCE); - nexp->mLeft = fexp; + Expression* dexp = nullptr; + if (exp->mDecType->mBase->mDestructor) + { + Expression* cexp = new Expression(mScanner->mLocation, EX_CONSTANT); + cexp->mDecValue = exp->mDecType->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; @@ -2981,6 +3088,8 @@ Expression* Parser::ParseStatement(void) mScanner->NextToken(); if (mScanner->mToken != TK_CLOSE_BRACE) { + Expression* sexp = new Expression(mScanner->mLocation, EX_SCOPE); + Expression* pexp = nullptr; do { @@ -3002,12 +3111,17 @@ Expression* Parser::ParseStatement(void) exp = nexp; } while (mScanner->mToken != TK_CLOSE_BRACE && mScanner->mToken != TK_EOF); + if (mScanner->mToken != TK_CLOSE_BRACE) mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "'}' expected"); exp->mEndLocation = mScanner->mLocation; mScope->End(mScanner->mLocation); mScanner->NextToken(); + + sexp->mLeft = exp; + + exp = sexp; } else {