Implement operator()

This commit is contained in:
drmortalwombat 2023-09-11 16:19:11 +02:00
parent 1b50baf852
commit ab49281b0d
2 changed files with 64 additions and 10 deletions

View File

@ -5744,6 +5744,8 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
}
else
{
Expression* thisExp = nullptr;
if (exp->mDecType->mType == DT_TYPE_POINTER && exp->mDecType->mBase->mType == DT_TYPE_FUNCTION)
{
}
@ -5752,8 +5754,38 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
}
else
{
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Function expected for call");
exp->mDecType = TheVoidFunctionTypeDeclaration;
Declaration* tdec = exp->mDecType;
while (tdec->mType == DT_TYPE_REFERENCE || tdec->mType == DT_TYPE_RVALUEREF)
tdec = tdec->mBase;
if (tdec->mType == DT_TYPE_STRUCT && tdec->mScope)
{
const Ident* opident = Ident::Unique("operator()");
Declaration* mdec = tdec->mScope->Lookup(opident);
if (mdec)
{
thisExp = new Expression(exp->mLocation, EX_PREFIX);
thisExp->mToken = TK_BINARY_AND;
thisExp->mLeft = exp;
thisExp->mDecType = exp->mDecType->BuildPointer(exp->mLocation);
exp = new Expression(exp->mLocation, EX_CONSTANT);
exp->mDecValue = mdec;
exp->mDecType = mdec->mBase;
}
else
{
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Function expected for call");
exp->mDecType = TheVoidFunctionTypeDeclaration;
}
}
else
{
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Function expected for call");
exp->mDecType = TheVoidFunctionTypeDeclaration;
}
}
mScanner->NextToken();
@ -5775,23 +5807,38 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
}
bool parentCall = false;
if ((exp->mDecType->mFlags & DTF_FUNC_THIS) && mThisPointer && mThisPointer->mType == DT_ARGUMENT)
if (thisExp)
{
Expression* texp = new Expression(mScanner->mLocation, EX_VARIABLE);
texp->mDecType = mThisPointer->mBase;
texp->mDecValue = mThisPointer;
if (nexp->mRight)
{
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp;
lexp->mLeft = thisExp;
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
}
else
nexp->mRight = texp;
nexp->mRight = thisExp;
}
else
{
if ((exp->mDecType->mFlags & DTF_FUNC_THIS) && mThisPointer && mThisPointer->mType == DT_ARGUMENT)
{
Expression* texp = new Expression(mScanner->mLocation, EX_VARIABLE);
texp->mDecType = mThisPointer->mBase;
texp->mDecValue = mThisPointer;
parentCall = true;
if (nexp->mRight)
{
Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp;
lexp->mRight = nexp->mRight;
nexp->mRight = lexp;
}
else
nexp->mRight = texp;
parentCall = true;
}
}
nexp = ResolveOverloadCall(nexp);

View File

@ -1626,6 +1626,13 @@ void Scanner::NextRawToken(void)
mTokenIdent = Ident::Unique("operator[]");
break;
case TK_OPEN_PARENTHESIS:
NextRawToken();
if (mToken != TK_CLOSE_PARENTHESIS)
mErrors->Error(mLocation, EERR_INVALID_OPERATOR, "')' expected");
mTokenIdent = Ident::Unique("operator()");
break;
case TK_ARROW:
mTokenIdent = Ident::Unique("operator->");
break;