forked from Mirrors/openclonk
Script: '->' also works with proplists
parent
04e512fe00
commit
497cd5cffc
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
Loading…
Reference in New Issue