Destructors when leaving scopes the normal way

This commit is contained in:
drmortalwombat 2023-06-21 22:07:00 +02:00
parent daf412a47b
commit 9bcec5bf17
8 changed files with 305 additions and 79 deletions

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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);
};

View File

@ -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
{