From ef0a79b8f0f991099bf9212841ad36b887b49bc7 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 2 Jul 2023 18:21:40 +0200 Subject: [PATCH] Index operator overload --- README.md | 1 + oscar64/InterCodeGenerator.cpp | 38 ++++++++++++++++++++++ oscar64/InterCodeGenerator.h | 1 + oscar64/Parser.cpp | 58 +++++++++++++++++++++++++++++----- oscar64/Scanner.cpp | 7 ++++ 5 files changed, 97 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 84f3064..a68139f 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ Supported Features: * operator overloading (not complete yet) * single inheritance of class and struct * const member functions +* new, delete, new[] and delete[] ## Installation and Usage diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 314b047..2e094bb 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -38,6 +38,17 @@ static inline InterType InterTypeOf(const Declaration* dec) } } +InterCodeGenerator::ExValue InterCodeGenerator::ToValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v) +{ + if (v.mType->mType == DT_TYPE_REFERENCE) + { + v.mType = v.mType->mBase; + v.mReference++; + } + + return v; +} + InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, int level) { while (v.mReference > level) @@ -1617,6 +1628,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); } + if (exp->mType == EX_ASSIGNMENT) + { + vl = ToValue(proc, exp, block, vl); + vr = ToValue(proc, exp, block, vr); + } + if (exp->mToken == TK_ASSIGN || !(vl.mType->mType == DT_TYPE_POINTER && vr.mType->IsIntegerType() && (exp->mToken == TK_ASSIGN_ADD || exp->mToken == TK_ASSIGN_SUB))) { if (!vl.mType->CanAssign(vr.mType)) @@ -1631,6 +1648,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* exp->mRight->mDecValue->mLinkerObject->mFlags |= LOBJF_CONST; } + if (vl.mType->mType == DT_TYPE_REFERENCE) { vr = Dereference(proc, exp, block, vr, 1); @@ -1661,6 +1679,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } else if (vl.mType->mType == DT_TYPE_STRUCT || vl.mType->mType == DT_TYPE_ARRAY || vl.mType->mType == DT_TYPE_UNION) { + vr = ToValue(proc, exp, block, vr); + vr = Dereference(proc, exp, block, vr, 1); vl = Dereference(proc, exp, block, vl, 1); @@ -1689,6 +1709,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* } else { + vr = ToValue(proc, exp, block, vr); + if (vl.mType->mType == DT_TYPE_POINTER && (vr.mType->mType == DT_TYPE_ARRAY || vr.mType->mType == DT_TYPE_FUNCTION)) { vr = Dereference(proc, exp, block, vr, 1); @@ -1864,6 +1886,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); + vl = ToValue(proc, exp, block, vl); + vr = ToValue(proc, exp, block, vr); + int stride = vl.mType->Stride(); if (vl.mType->mType == DT_TYPE_ARRAY && exp->mRight->mType == EX_CONSTANT && exp->mRight->mDecValue->mType == DT_CONST_INTEGER) @@ -1919,6 +1944,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_QUALIFY: { vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); + + vl = ToValue(proc, exp, block, vl); + vl = Dereference(proc, exp, block, vl, 1); if (vl.mReference != 1) @@ -1947,6 +1975,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* { vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); + + vl = ToValue(proc, exp, block, vl); + vr = ToValue(proc, exp, block, vr); + vr = Dereference(proc, exp, block, vr); InterInstruction * ins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR); @@ -2243,6 +2275,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_PREINCDEC: { vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); + vl = ToValue(proc, exp, block, vl); vl = Dereference(proc, exp, block, vl, 1); if (vl.mReference != 1) @@ -2304,6 +2337,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_POSTINCDEC: { vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); + vl = ToValue(proc, exp, block, vl); vl = Dereference(proc, exp, block, vl, 1); if (vl.mReference != 1) @@ -2363,6 +2397,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_PREFIX: { vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); + vl = ToValue(proc, exp, block, vl); InterInstruction * ins = new InterInstruction(exp->mLocation, IC_UNARY_OPERATOR); @@ -2468,10 +2503,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case EX_RELATIONAL: { vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper); + vl = ToValue(proc, exp, block, vl); vl = Dereference(proc, exp, block, vl, vl.mType->mType == DT_TYPE_ARRAY ? 1 : 0); vr = TranslateExpression(procType, proc, block, exp->mRight, destack, breakBlock, continueBlock, inlineMapper); + vr = ToValue(proc, exp, block, vr); vr = Dereference(proc, exp, block, vr, vr.mType->mType == DT_TYPE_ARRAY ? 1 : 0); + InterInstruction * ins = new InterInstruction(exp->mLocation, IC_RELATIONAL_OPERATOR); Declaration* dtype = TheSignedIntTypeDeclaration; diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 4088beb..cb4f5e2 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -76,6 +76,7 @@ protected: void BuildSwitchTree(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock* block, ExValue v, const SwitchNodeArray& nodes, int left, int right, InterCodeBasicBlock* dblock); + ExValue ToValue(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v); 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, DestructStack*& destack, const BranchTarget & breakBlock, const BranchTarget& continueBlock, InlineMapper * inlineMapper, ExValue * lrexp = nullptr); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 1ab296b..a988f19 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -4256,19 +4256,24 @@ Expression* Parser::ParsePostfixExpression(bool lhs) for (;;) { - if (mScanner->mToken == TK_OPEN_BRACKET) + if (ConsumeTokenIf(TK_OPEN_BRACKET)) { - if (exp->mDecType->mType != DT_TYPE_ARRAY && exp->mDecType->mType != DT_TYPE_POINTER) - mErrors->Error(mScanner->mLocation, EERR_INVALID_INDEX, "Array expected for indexing"); - mScanner->NextToken(); Expression* nexp = new Expression(mScanner->mLocation, EX_INDEX); nexp->mLeft = exp; nexp->mRight = ParseExpression(false); - if (mScanner->mToken == TK_CLOSE_BRACKET) - mScanner->NextToken(); + ConsumeToken(TK_CLOSE_BRACKET); + + if (exp->mDecType->mType == DT_TYPE_STRUCT) + { + nexp = CheckOperatorOverload(nexp); + } + else if (exp->mDecType->mType == DT_TYPE_ARRAY || exp->mDecType->mType == DT_TYPE_POINTER) + { + nexp->mDecType = exp->mDecType->mBase; + } else - mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "']' expected"); - nexp->mDecType = exp->mDecType->mBase; + mErrors->Error(mScanner->mLocation, EERR_INVALID_INDEX, "Array expected for indexing"); + if (!nexp->mDecType) nexp->mDecType = TheVoidTypeDeclaration; exp = nexp; @@ -5139,6 +5144,43 @@ Expression* Parser::CheckOperatorOverload(Expression* exp) } } } + else if (exp->mType == EX_INDEX) + { + Declaration* tdec = exp->mLeft->mDecType; + if (tdec->mType == DT_TYPE_STRUCT) + { + Declaration* mdec = tdec->mScope->Lookup(Ident::Unique("operator[]")); + if (mdec) + { + Expression* nexp = new Expression(mScanner->mLocation, EX_CALL); + + nexp->mLeft = new Expression(mScanner->mLocation, EX_CONSTANT); + nexp->mLeft->mDecType = mdec->mBase; + nexp->mLeft->mDecValue = mdec; + + nexp->mDecType = mdec->mBase; + nexp->mRight = exp->mRight; + + Expression* texp = new Expression(nexp->mLocation, EX_PREFIX); + texp->mToken = TK_BINARY_AND; + texp->mLeft = exp->mLeft; + texp->mDecType = new Declaration(nexp->mLocation, DT_TYPE_POINTER); + texp->mDecType->mFlags |= DTF_CONST | DTF_DEFINED; + texp->mDecType->mBase = exp->mLeft->mDecType; + texp->mDecType->mSize = 2; + + Expression* lexp = new Expression(nexp->mLocation, EX_LIST); + lexp->mLeft = texp; + lexp->mRight = nexp->mRight; + nexp->mRight = lexp; + + ResolveOverloadCall(nexp->mLeft, nexp->mRight); + nexp->mDecType = nexp->mLeft->mDecType->mBase; + + exp = nexp; + } + } + } else if (exp->mType == EX_BINARY || exp->mType == EX_RELATIONAL) { const Ident* opident = nullptr; diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index c68fcba..a072620 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -1504,6 +1504,13 @@ void Scanner::NextRawToken(void) mTokenIdent = Ident::Unique("operator<="); break; + case TK_OPEN_BRACKET: + NextRawToken(); + if (mToken != TK_CLOSE_BRACKET) + mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "']' expected"); + mTokenIdent = Ident::Unique("operator[]"); + break; + default: mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "Invalid operator token"); }