Index operator overload
This commit is contained in:
parent
7f6cf654f6
commit
ef0a79b8f0
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue