Script: '->' also works with proplists

rope
Günther Brammer 2011-10-15 02:30:30 +02:00
parent 04e512fe00
commit 497cd5cffc
2 changed files with 8 additions and 39 deletions

View File

@ -687,25 +687,17 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
C4Value *pPars = pCurVal - C4AUL_MAX_Par + 1; C4Value *pPars = pCurVal - C4AUL_MAX_Par + 1;
C4Value *pTargetVal = pCurVal - C4AUL_MAX_Par; C4Value *pTargetVal = pCurVal - C4AUL_MAX_Par;
// Get call target - "object" or "id" are allowed C4PropList *pDest;
C4Object *pDestObj; C4Def *pDestDef;
if (pTargetVal->CheckConversion(C4V_PropList)) if (pTargetVal->CheckConversion(C4V_PropList))
{ {
// definition call pDest = pTargetVal->_getPropList();
pDestObj = pTargetVal->_getPropList()->GetObject();
pDestDef = pTargetVal->_getPropList()->GetDef();
// definition must be known
if (!pDestDef)
throw new C4AulExecError(pCurCtx->Obj,
FormatString("'->': target not an object or definition").getData());
} }
else else
throw new C4AulExecError(pCurCtx->Obj, throw new C4AulExecError(pCurCtx->Obj,
FormatString("'->': invalid target type %s, expected object or definition", pTargetVal->GetTypeName()).getData()); FormatString("'->': invalid target type %s, expected proplist", pTargetVal->GetTypeName()).getData());
// Search function for given context // Search function for given context
const char * szFuncName = pCPos->Par.s->GetCStr(); C4AulFunc * pFunc = pDest->GetFunc(pCPos->Par.s);
C4AulFunc * pFunc = pDestDef->Script.GetFuncRecursive(szFuncName);
if (!pFunc && pCPos->bccType == AB_CALLFS) if (!pFunc && pCPos->bccType == AB_CALLFS)
{ {
PopValuesUntil(pTargetVal); PopValuesUntil(pTargetVal);
@ -715,18 +707,10 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
// Function not found? // Function not found?
if (!pFunc) if (!pFunc)
{ throw new C4AulExecError(pCurCtx->Obj,
if (pDestObj) FormatString("'->': no function \"%s\" in object \"%s\"", pCPos->Par.s->GetCStr(), pTargetVal->GetDataString().getData()).getData());
throw new C4AulExecError(pCurCtx->Obj,
FormatString("'->': no function \"%s\" in object \"%s\"", szFuncName, pTargetVal->GetDataString().getData()).getData());
else
throw new C4AulExecError(pCurCtx->Obj,
FormatString("'->': no function \"%s\" in definition \"%s\"", szFuncName, pDestDef->GetName()).getData());
}
// Resolve overloads assert(!pFunc->OverloadedBy);
while (pFunc->OverloadedBy)
pFunc = pFunc->OverloadedBy;
// Save current position // Save current position
pCurCtx->CPos = pCPos; pCurCtx->CPos = pCPos;
@ -739,7 +723,7 @@ C4Value C4AulExec::Exec(C4AulBCC *pCPos, bool fPassErrors)
PushNullVals(pFunc->GetParCount() - (pCurVal + 1 - pPars)); PushNullVals(pFunc->GetParCount() - (pCurVal + 1 - pPars));
// Call function // Call function
C4AulBCC *pNewCPos = Call(pFunc, pTargetVal, pPars, pTargetVal->_getPropList()); C4AulBCC *pNewCPos = Call(pFunc, pTargetVal, pPars, pDest);
if (pNewCPos) if (pNewCPos)
{ {
// Jump // Jump

View File

@ -2596,24 +2596,9 @@ void C4AulParseState::Parse_Expression2(int iParentPrio)
Shift(); Shift();
// expect identifier of called function now // expect identifier of called function now
if (TokenType != ATT_IDTF) throw new C4AulParseError(this, "expecting func name after '->'"); if (TokenType != ATT_IDTF) throw new C4AulParseError(this, "expecting func name after '->'");
// search a function with the given name
pFunc = a->Engine->GetFirstFunc(Idtf); pFunc = a->Engine->GetFirstFunc(Idtf);
if (!pFunc)
{
// not failsafe?
if (eCallType != AB_CALLFS && Type == PARSER)
Warn(FormatString("direct object call: function %s not found", Idtf).getData());
// otherwise: nothing to call - just execute parameters and discard them
Shift();
Parse_Params(0, NULL);
// remove target from stack, push a zero value as result
AddBCC(AB_STACK, -1); AddBCC(AB_STACK, +1);
// done
break;
}
if (Type == PARSER) if (Type == PARSER)
pName = ::Strings.RegString(Idtf); pName = ::Strings.RegString(Idtf);
// add call chunk
Shift(); Shift();
Parse_Params(C4AUL_MAX_Par, pName ? pName->GetCStr() : Idtf, pFunc); Parse_Params(C4AUL_MAX_Par, pName ? pName->GetCStr() : Idtf, pFunc);
AddBCC(eCallType, reinterpret_cast<intptr_t>(pName)); AddBCC(eCallType, reinterpret_cast<intptr_t>(pName));