diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 00ab164..cfcff96 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -350,6 +350,13 @@ bool Declaration::IsSubType(const Declaration* dec) const { if (this == dec) return true; + + if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY) + { + if (dec->mType == DT_TYPE_POINTER) + return mBase->IsSubType(dec->mBase); + } + if (mType != dec->mType) return false; if (mSize != dec->mSize) @@ -367,8 +374,8 @@ bool Declaration::IsSubType(const Declaration* dec) const return true; else if (mType == DT_TYPE_STRUCT || mType == DT_TYPE_ENUM || DT_TYPE_UNION) return false; - else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY) - return mBase->IsSubType(dec->mBase); + else if (mType == DT_TYPE_ARRAY) + return mSize <= dec->mSize && mBase->IsSubType(dec->mBase); else if (mType == DT_TYPE_FUNCTION) { if (!dec->mBase->IsSubType(mBase)) diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 0698e27..e5ac650 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -2187,10 +2187,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* TranslateLogic(procType, proc, block, tblock, fblock, exp->mLeft, inlineMapper); vl = TranslateExpression(procType, proc, tblock, exp->mRight->mLeft, breakBlock, continueBlock, inlineMapper); - vl = Dereference(proc, tblock, vl); - vr = TranslateExpression(procType, proc, fblock, exp->mRight->mRight, breakBlock, continueBlock, inlineMapper); - vr = Dereference(proc, fblock, vr); int ttemp; InterType ttype, stypel, styper; @@ -2201,37 +2198,63 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* Declaration* dtype; if (stypel == IT_POINTER || styper == IT_POINTER) { - if (!vl.mType->IsSame(vr.mType)) + if (vl.mType->mType == DT_TYPE_ARRAY) + vl = Dereference(proc, tblock, vl, 1); + else + vl = Dereference(proc, tblock, vl); + + if (vr.mType->mType == DT_TYPE_ARRAY) + vr = Dereference(proc, fblock, vr, 1); + else + vr = Dereference(proc, fblock, vr); + + if (vl.mType->mBase->IsSubType(vr.mType->mBase)) + dtype = vr.mType; + else if (vr.mType->mBase->IsSubType(vl.mType->mBase)) + dtype = vl.mType; + else + { mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Incompatible conditional types"); + dtype = vl.mType; + } + + Declaration* ntype = new Declaration(dtype->mLocation, DT_TYPE_POINTER); + ntype->mBase = dtype->mBase; + dtype = ntype; ttype = IT_POINTER; - dtype = vl.mType; - } - else if (stypel == styper) - { - ttype = stypel; - dtype = vl.mType; - } - else if (stypel > styper) - { - ttype = stypel; - dtype = vl.mType; - - vr = CoerceType(proc, fblock, vr, dtype); } else { - ttype = styper; - dtype = vr.mType; + vl = Dereference(proc, tblock, vl); + vr = Dereference(proc, fblock, vr); - vl = CoerceType(proc, tblock, vl, dtype); + if (stypel == styper) + { + ttype = stypel; + dtype = vl.mType; + } + else if (stypel > styper) + { + ttype = stypel; + dtype = vl.mType; + + vr = CoerceType(proc, fblock, vr, dtype); + } + else + { + ttype = styper; + dtype = vr.mType; + + vl = CoerceType(proc, tblock, vl, dtype); + } } ttemp = proc->AddTemporary(ttype); InterInstruction * rins = new InterInstruction(); rins->mCode = IC_LOAD_TEMPORARY; - rins->mSrc[0].mType = InterTypeOf(vr.mType); + rins->mSrc[0].mType = ttype; rins->mSrc[0].mTemp = vr.mTemp; rins->mDst.mType = ttype; rins->mDst.mTemp = ttemp; @@ -2239,7 +2262,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterInstruction * lins = new InterInstruction(); lins->mCode = IC_LOAD_TEMPORARY; - lins->mSrc[0].mType = InterTypeOf(vl.mType); + lins->mSrc[0].mType = ttype; lins->mSrc[0].mTemp = vl.mTemp; lins->mDst.mType = ttype; lins->mDst.mTemp = ttemp; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 836319e..ba36501 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1519,7 +1519,7 @@ Expression* Parser::ParseLogicOrExpression(void) Expression* Parser::ParseConditionalExpression(void) { - Expression* exp = ParseLogicAndExpression(); + Expression* exp = ParseLogicOrExpression(); if (mScanner->mToken == TK_QUESTIONMARK) { @@ -1563,7 +1563,7 @@ Expression* Parser::ParseParenthesisExpression(void) Expression* Parser::ParseAssignmentExpression(void) { - Expression* exp = ParseLogicOrExpression(); + Expression* exp = ParseConditionalExpression(); while (mScanner->mToken >= TK_ASSIGN && mScanner->mToken <= TK_ASSIGN_OR) {