Index operator overload
This commit is contained in:
parent
7f6cf654f6
commit
ef0a79b8f0
|
@ -61,6 +61,7 @@ Supported Features:
|
||||||
* operator overloading (not complete yet)
|
* operator overloading (not complete yet)
|
||||||
* single inheritance of class and struct
|
* single inheritance of class and struct
|
||||||
* const member functions
|
* const member functions
|
||||||
|
* new, delete, new[] and delete[]
|
||||||
|
|
||||||
## Installation and Usage
|
## 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)
|
InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure* proc, Expression* exp, InterCodeBasicBlock*& block, ExValue v, int level)
|
||||||
{
|
{
|
||||||
while (v.mReference > 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);
|
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 (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))
|
if (!vl.mType->CanAssign(vr.mType))
|
||||||
|
@ -1631,6 +1648,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
exp->mRight->mDecValue->mLinkerObject->mFlags |= LOBJF_CONST;
|
exp->mRight->mDecValue->mLinkerObject->mFlags |= LOBJF_CONST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (vl.mType->mType == DT_TYPE_REFERENCE)
|
if (vl.mType->mType == DT_TYPE_REFERENCE)
|
||||||
{
|
{
|
||||||
vr = Dereference(proc, exp, block, vr, 1);
|
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)
|
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);
|
vr = Dereference(proc, exp, block, vr, 1);
|
||||||
vl = Dereference(proc, exp, block, vl, 1);
|
vl = Dereference(proc, exp, block, vl, 1);
|
||||||
|
|
||||||
|
@ -1689,6 +1709,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
}
|
}
|
||||||
else
|
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))
|
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);
|
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);
|
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
vr = TranslateExpression(procType, proc, block, exp->mRight, 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();
|
int stride = vl.mType->Stride();
|
||||||
|
|
||||||
if (vl.mType->mType == DT_TYPE_ARRAY && exp->mRight->mType == EX_CONSTANT && exp->mRight->mDecValue->mType == DT_CONST_INTEGER)
|
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:
|
case EX_QUALIFY:
|
||||||
{
|
{
|
||||||
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
|
|
||||||
|
vl = ToValue(proc, exp, block, vl);
|
||||||
|
|
||||||
vl = Dereference(proc, exp, block, vl, 1);
|
vl = Dereference(proc, exp, block, vl, 1);
|
||||||
|
|
||||||
if (vl.mReference != 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);
|
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
vr = TranslateExpression(procType, proc, block, exp->mRight, 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);
|
vr = Dereference(proc, exp, block, vr);
|
||||||
|
|
||||||
InterInstruction * ins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);
|
InterInstruction * ins = new InterInstruction(exp->mLocation, IC_BINARY_OPERATOR);
|
||||||
|
@ -2243,6 +2275,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
case EX_PREINCDEC:
|
case EX_PREINCDEC:
|
||||||
{
|
{
|
||||||
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
|
vl = ToValue(proc, exp, block, vl);
|
||||||
vl = Dereference(proc, exp, block, vl, 1);
|
vl = Dereference(proc, exp, block, vl, 1);
|
||||||
|
|
||||||
if (vl.mReference != 1)
|
if (vl.mReference != 1)
|
||||||
|
@ -2304,6 +2337,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
case EX_POSTINCDEC:
|
case EX_POSTINCDEC:
|
||||||
{
|
{
|
||||||
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
||||||
|
vl = ToValue(proc, exp, block, vl);
|
||||||
vl = Dereference(proc, exp, block, vl, 1);
|
vl = Dereference(proc, exp, block, vl, 1);
|
||||||
|
|
||||||
if (vl.mReference != 1)
|
if (vl.mReference != 1)
|
||||||
|
@ -2363,6 +2397,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
case EX_PREFIX:
|
case EX_PREFIX:
|
||||||
{
|
{
|
||||||
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
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);
|
InterInstruction * ins = new InterInstruction(exp->mLocation, IC_UNARY_OPERATOR);
|
||||||
|
|
||||||
|
@ -2468,10 +2503,13 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
case EX_RELATIONAL:
|
case EX_RELATIONAL:
|
||||||
{
|
{
|
||||||
vl = TranslateExpression(procType, proc, block, exp->mLeft, destack, breakBlock, continueBlock, inlineMapper);
|
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);
|
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 = 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);
|
vr = Dereference(proc, exp, block, vr, vr.mType->mType == DT_TYPE_ARRAY ? 1 : 0);
|
||||||
|
|
||||||
|
|
||||||
InterInstruction * ins = new InterInstruction(exp->mLocation, IC_RELATIONAL_OPERATOR);
|
InterInstruction * ins = new InterInstruction(exp->mLocation, IC_RELATIONAL_OPERATOR);
|
||||||
|
|
||||||
Declaration* dtype = TheSignedIntTypeDeclaration;
|
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);
|
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 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 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);
|
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 (;;)
|
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);
|
Expression* nexp = new Expression(mScanner->mLocation, EX_INDEX);
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
nexp->mRight = ParseExpression(false);
|
nexp->mRight = ParseExpression(false);
|
||||||
if (mScanner->mToken == TK_CLOSE_BRACKET)
|
ConsumeToken(TK_CLOSE_BRACKET);
|
||||||
mScanner->NextToken();
|
|
||||||
|
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
|
else
|
||||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "']' expected");
|
mErrors->Error(mScanner->mLocation, EERR_INVALID_INDEX, "Array expected for indexing");
|
||||||
nexp->mDecType = exp->mDecType->mBase;
|
|
||||||
if (!nexp->mDecType)
|
if (!nexp->mDecType)
|
||||||
nexp->mDecType = TheVoidTypeDeclaration;
|
nexp->mDecType = TheVoidTypeDeclaration;
|
||||||
exp = nexp;
|
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)
|
else if (exp->mType == EX_BINARY || exp->mType == EX_RELATIONAL)
|
||||||
{
|
{
|
||||||
const Ident* opident = nullptr;
|
const Ident* opident = nullptr;
|
||||||
|
|
|
@ -1504,6 +1504,13 @@ void Scanner::NextRawToken(void)
|
||||||
mTokenIdent = Ident::Unique("operator<=");
|
mTokenIdent = Ident::Unique("operator<=");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TK_OPEN_BRACKET:
|
||||||
|
NextRawToken();
|
||||||
|
if (mToken != TK_CLOSE_BRACKET)
|
||||||
|
mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "']' expected");
|
||||||
|
mTokenIdent = Ident::Unique("operator[]");
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "Invalid operator token");
|
mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "Invalid operator token");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue