diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index de6cb89..c34aa31 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -1181,6 +1181,9 @@ bool Compiler::WriteDbjFile(const char* filename) case DT_TYPE_POINTER: fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"ptr\", eid: %d}", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize, types.IndexOrPush(dec->mBase)); break; + case DT_TYPE_REFERENCE: + fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"ref\", eid: %d}", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize, types.IndexOrPush(dec->mBase)); + break; case DT_TYPE_ENUM: { fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"enum\",\"members\": [\n", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize); diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 7f81eb8..f153ec0 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -963,6 +963,11 @@ bool Declaration::IsSameValue(const Declaration* dec) const bool Declaration::CanAssign(const Declaration* fromType) const { + if (mType == DT_TYPE_REFERENCE) + return fromType->IsSubType(mBase); + else if (fromType->mType == DT_TYPE_REFERENCE) + return this->CanAssign(fromType->mBase); + if (this->IsSame(fromType)) return true; else if (IsNumericType()) diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 842f3fa..350d2bd 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -18,6 +18,7 @@ enum DecType DT_TYPE_FLOAT, DT_TYPE_ENUM, DT_TYPE_POINTER, + DT_TYPE_REFERENCE, DT_TYPE_ARRAY, DT_TYPE_STRUCT, DT_TYPE_UNION, diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index e1a024e..a49882c 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -33,6 +33,7 @@ static inline InterType InterTypeOf(const Declaration* dec) case DT_TYPE_POINTER: case DT_TYPE_FUNCTION: case DT_TYPE_ARRAY: + case DT_TYPE_REFERENCE: return IT_POINTER; } } @@ -69,6 +70,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p { int stemp = v.mTemp; + if (type->mType == DT_TYPE_REFERENCE) + { + if (!type->mBase->IsSubType(v.mType)) + mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_TYPES, "Incompatible type for reference"); + + return v; + } + if (v.mType->IsIntegerType() && type->mType == DT_TYPE_FLOAT) { if (v.mType->mSize == 1) @@ -878,7 +887,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro vdec->mVarIndex = nindex; vdec->mBase = pdec->mBase; - if (pdec->mBase->mType == DT_TYPE_ARRAY) + if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE) ains->mConst.mOperandSize = 2; else ains->mConst.mOperandSize = pdec->mSize; @@ -910,7 +919,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro vr = TranslateExpression(procType, proc, block, texp, breakBlock, continueBlock, inlineMapper, &vp); - if (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION) + if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)) { if (pdec && !pdec->mBase->CanAssign(vr.mType)) mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types"); @@ -943,6 +952,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro { if (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION) vr = Dereference(proc, texp, block, vr, 1); + else if (pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) + vr = Dereference(proc, texp, block, vr, 1); else vr = Dereference(proc, texp, block, vr); @@ -965,7 +976,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro wins->mSrc[1].mTemp = ains->mDst.mTemp; if (pdec) { - if (pdec->mBase->mType == DT_TYPE_ARRAY) + if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE) wins->mSrc[1].mOperandSize = 2; else wins->mSrc[1].mOperandSize = pdec->mSize; @@ -1313,7 +1324,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (!(dec->mBase->mFlags & DTF_DEFINED)) mErrors->Error(dec->mLocation, EERR_VARIABLE_TYPE, "Undefined variable type"); - return ExValue(exp->mDecType, ins->mDst.mTemp, ref); + if (exp->mDecType->mType == DT_TYPE_REFERENCE) + return ExValue(exp->mDecType->mBase, ins->mDst.mTemp, ref + 1); + else + return ExValue(exp->mDecType, ins->mDst.mTemp, ref); } @@ -1325,6 +1339,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); vr = TranslateExpression(procType, proc, block, exp->mRight, 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); + vl.mType = exp->mLeft->mDecType; + } else { vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock, inlineMapper); @@ -1345,7 +1365,35 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* exp->mRight->mDecValue->mLinkerObject->mFlags |= LOBJF_CONST; } - if (vl.mType->mType == DT_TYPE_STRUCT || vl.mType->mType == DT_TYPE_ARRAY || vl.mType->mType == DT_TYPE_UNION) + if (vl.mType->mType == DT_TYPE_REFERENCE) + { + vr = Dereference(proc, exp, block, vr, 1); + 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) + { + InterInstruction* ins = new InterInstruction(exp->mLocation, IC_STORE); + ins->mSrc[0].mType = IT_POINTER; + ins->mSrc[0].mTemp = vr.mTemp; + ins->mSrc[0].mMemory = IM_INDIRECT; + ins->mSrc[0].mOperandSize = 2; + ins->mSrc[0].mStride = vr.mType->mStripe; + + ins->mSrc[1].mType = IT_POINTER; + ins->mSrc[1].mTemp = vl.mTemp; + ins->mSrc[1].mMemory = IM_INDIRECT; + ins->mSrc[1].mOperandSize = 2; + ins->mSrc[1].mStride = vl.mType->mStripe; + + block->Append(ins); + } + } + else if (vl.mType->mType == DT_TYPE_STRUCT || vl.mType->mType == DT_TYPE_ARRAY || vl.mType->mType == DT_TYPE_UNION) { vr = Dereference(proc, exp, block, vr, 1); vl = Dereference(proc, exp, block, vl, 1); @@ -2571,8 +2619,8 @@ 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); - - if (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION) + + if (!(pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) && (vr.mType->mType == DT_TYPE_STRUCT || vr.mType->mType == DT_TYPE_UNION)) { if (pdec && !pdec->mBase->CanAssign(vr.mType)) mErrors->Error(texp->mLocation, EERR_INCOMPATIBLE_TYPES, "Cannot assign incompatible types"); @@ -2608,6 +2656,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vr = Dereference(proc, texp, block, vr, 1); else if (pdec && pdec->mBase->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_INTEGER && texp->mType == EX_CONSTANT && texp->mDecValue->mType == DT_CONST_INTEGER && texp->mDecValue->mInteger == 0) vr = CoerceType(proc, texp, block, vr, pdec->mBase); + else if (pdec && pdec->mBase->mType == DT_TYPE_REFERENCE) + vr = Dereference(proc, texp, block, vr, 1); else vr = Dereference(proc, texp, block, vr); @@ -2634,8 +2684,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* wins->mSrc[1].mTemp = ains->mDst.mTemp; if (pdec) { - if (pdec->mBase->mType == DT_TYPE_ARRAY) + if (pdec->mBase->mType == DT_TYPE_ARRAY || pdec->mBase->mType == DT_TYPE_REFERENCE) + { wins->mSrc[1].mOperandSize = 2; + wins->mSrc[0].mType = IT_POINTER; + } else wins->mSrc[1].mOperandSize = pdec->mSize; } @@ -2715,6 +2768,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* return ExValue(ftype->mBase, vins->mDst.mTemp, 1); } + else if (ftype->mBase->mType == DT_TYPE_REFERENCE) + return ExValue(ftype->mBase->mBase, cins->mDst.mTemp, 1); else return ExValue(ftype->mBase, cins->mDst.mTemp); } @@ -2821,7 +2876,41 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* { vr = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock, inlineMapper); - if (procType->mBase->mType == DT_TYPE_STRUCT) + if (procType->mBase->mType == DT_TYPE_REFERENCE) + { + vr = Dereference(proc, exp, block, vr, 1); + + vr = CoerceType(proc, exp, block, vr, procType->mBase); + + ins->mSrc[0].mType = IT_POINTER; + ins->mSrc[0].mTemp = vr.mTemp; + ins->mSrc[0].mMemory = IM_INDIRECT; + + if (inlineMapper) + { + InterInstruction* ains = new InterInstruction(exp->mLocation, IC_CONSTANT); + ains->mDst.mType = IT_POINTER; + ains->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); + ains->mConst.mOperandSize = procType->mBase->mSize; + ains->mConst.mIntConst = 0; + ains->mConst.mVarIndex = inlineMapper->mResult;; + ains->mConst.mMemory = IM_LOCAL; + block->Append(ains); + + ins->mSrc[1].mType = ains->mDst.mType; + ins->mSrc[1].mTemp = ains->mDst.mTemp; + ins->mSrc[1].mMemory = IM_INDIRECT; + ins->mCode = IC_STORE; + ins->mSrc[1].mOperandSize = ains->mConst.mOperandSize; + ins->mNumOperands = 2; + } + else + { + ins->mCode = IC_RETURN_VALUE; + ins->mNumOperands = 1; + } + } + else if (procType->mBase->mType == DT_TYPE_STRUCT) { vr = Dereference(proc, exp, block, vr, 1); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 989efec..79c3608 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -22696,7 +22696,7 @@ bool NativeCodeBasicBlock::CheckGlobalAddressSumYPointer(const NativeCodeBasicBl yval = (yval + 1) & 255; else if (ins.mType == ASMIT_DEY && yval >= 0) yval = (yval - 1) & 255; - else if (ins.mType == ASMIT_JSR) + else if (ins.mType == ASMIT_JSR || ins.mType == ASMIT_RTS) { if (ins.UsesZeroPage(reg) || ins.UsesZeroPage(reg + 1) || ins.ChangesZeroPage(index)) return false; @@ -39839,7 +39839,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "main"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "data"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index d255906..5258353 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -431,6 +431,34 @@ Declaration* Parser::ParsePostfixDeclaration(void) ndec->mBase = dec; return ndec; } + else if (mScanner->mToken == TK_BINARY_AND && (mCompilerOptions & COPT_CPLUSPLUS)) + { + mScanner->NextToken(); + + Declaration* ndec = new Declaration(mScanner->mLocation, DT_TYPE_REFERENCE); + ndec->mSize = 2; + ndec->mFlags |= DTF_DEFINED; + + for (;;) + { + if (mScanner->mToken == TK_CONST) + { + ndec->mFlags |= DTF_CONST; + mScanner->NextToken(); + } + else if (mScanner->mToken == TK_VOLATILE) + { + ndec->mFlags |= DTF_VOLATILE; + mScanner->NextToken(); + } + else + break; + } + + Declaration* dec = ParsePostfixDeclaration(); + ndec->mBase = dec; + return ndec; + } else if (mScanner->mToken == TK_OPEN_PARENTHESIS) { mScanner->NextToken(); @@ -1855,13 +1883,18 @@ Expression* Parser::ParsePostfixExpression(void) else if (mScanner->mToken == TK_DOT) { mScanner->NextToken(); - if (exp->mDecType->mType == DT_TYPE_STRUCT || exp->mDecType->mType == DT_TYPE_UNION) + Declaration* dtype = exp->mDecType; + + if (dtype->mType == DT_TYPE_REFERENCE) + dtype = dtype->mBase; + + if (dtype->mType == DT_TYPE_STRUCT || dtype->mType == DT_TYPE_UNION) { Expression* nexp = new Expression(mScanner->mLocation, EX_QUALIFY); nexp->mLeft = exp; if (mScanner->mToken == TK_IDENT) { - Declaration* mdec = exp->mDecType->mScope->Lookup(mScanner->mTokenIdent); + Declaration* mdec = dtype->mScope->Lookup(mScanner->mTokenIdent); if (mdec) { nexp->mDecValue = mdec;