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 else
{ {
Expression* thisExp = nullptr;
if (exp->mDecType->mType == DT_TYPE_POINTER && exp->mDecType->mBase->mType == DT_TYPE_FUNCTION) if (exp->mDecType->mType == DT_TYPE_POINTER && exp->mDecType->mBase->mType == DT_TYPE_FUNCTION)
{ {
} }
@ -5752,8 +5754,38 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
} }
else else
{ {
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Function expected for call"); Declaration* tdec = exp->mDecType;
exp->mDecType = TheVoidFunctionTypeDeclaration; 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(); mScanner->NextToken();
@ -5775,23 +5807,38 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
} }
bool parentCall = false; 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) if (nexp->mRight)
{ {
Expression* lexp = new Expression(nexp->mLocation, EX_LIST); Expression* lexp = new Expression(nexp->mLocation, EX_LIST);
lexp->mLeft = texp; lexp->mLeft = thisExp;
lexp->mRight = nexp->mRight; lexp->mRight = nexp->mRight;
nexp->mRight = lexp; nexp->mRight = lexp;
} }
else 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); nexp = ResolveOverloadCall(nexp);

View File

@ -1626,6 +1626,13 @@ void Scanner::NextRawToken(void)
mTokenIdent = Ident::Unique("operator[]"); mTokenIdent = Ident::Unique("operator[]");
break; 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: case TK_ARROW:
mTokenIdent = Ident::Unique("operator->"); mTokenIdent = Ident::Unique("operator->");
break; break;