forked from Mirrors/openclonk
Functions store their containing proplist instead of the C4AulScript
The C4AulScript containing the source of the function was already mostly used to get the relevant proplist or available from context. This will allow more than one proplist plus the global one per scripthost to contain functions.epoxy
parent
d0d27d25f1
commit
507b63a55a
|
@ -2777,7 +2777,7 @@ void InitGameFunctionMap(C4AulScriptEngine *pEngine)
|
|||
}
|
||||
// add all def script funcs
|
||||
for (C4ScriptFnDef *pDef = &C4ScriptGameFnMap[0]; pDef->Identifier; pDef++)
|
||||
new C4AulDefFunc(pEngine, pDef);
|
||||
new C4AulDefFunc(pEngine->GetPropList(), pDef);
|
||||
#define F(f) AddFunc(pEngine, #f, Fn##f)
|
||||
|
||||
AddFunc(pEngine, "GetX", FnGetX);
|
||||
|
|
|
@ -111,8 +111,8 @@ std::string C4AulScript::Translate(const std::string &text) const
|
|||
throw C4LangStringTable::NoSuchTranslation(text);
|
||||
}
|
||||
|
||||
C4AulScriptFunc::C4AulScriptFunc(C4AulScript *pOwner, C4ScriptHost *pOrgScript, const char *pName, const char *Script):
|
||||
C4AulFunc(pOwner, pName),
|
||||
C4AulScriptFunc::C4AulScriptFunc(C4PropListStatic * Parent, C4ScriptHost *pOrgScript, const char *pName, const char *Script):
|
||||
C4AulFunc(Parent, pName),
|
||||
OwnerOverloaded(NULL),
|
||||
ParCount(0),
|
||||
Script(Script),
|
||||
|
@ -123,8 +123,8 @@ C4AulScriptFunc::C4AulScriptFunc(C4AulScript *pOwner, C4ScriptHost *pOrgScript,
|
|||
AddBCC(AB_EOFN);
|
||||
}
|
||||
|
||||
C4AulScriptFunc::C4AulScriptFunc(C4AulScript *pOwner, const C4AulScriptFunc &FromFunc):
|
||||
C4AulFunc(pOwner, FromFunc.GetName()),
|
||||
C4AulScriptFunc::C4AulScriptFunc(C4PropListStatic * Parent, const C4AulScriptFunc &FromFunc):
|
||||
C4AulFunc(Parent, FromFunc.GetName()),
|
||||
OwnerOverloaded(NULL),
|
||||
ParCount(FromFunc.ParCount),
|
||||
Script(FromFunc.Script),
|
||||
|
|
|
@ -194,8 +194,8 @@ public:
|
|||
}
|
||||
C4ScriptHost *pOrgScript; // the orginal script (!= Owner if included or appended)
|
||||
|
||||
C4AulScriptFunc(C4AulScript *pOwner, C4ScriptHost *pOrgScript, const char *pName, const char *Script);
|
||||
C4AulScriptFunc(C4AulScript *pOwner, const C4AulScriptFunc &FromFunc); // copy script/code, etc from given func
|
||||
C4AulScriptFunc(C4PropListStatic * Parent, C4ScriptHost *pOrgScript, const char *pName, const char *Script);
|
||||
C4AulScriptFunc(C4PropListStatic * Parent, const C4AulScriptFunc &FromFunc); // copy script/code, etc from given func
|
||||
~C4AulScriptFunc();
|
||||
|
||||
void ParseFn(C4AulScriptContext* context = NULL);
|
||||
|
|
|
@ -208,10 +208,10 @@ template <> struct C4ValueConv<int> : public C4ValueConv<int32_t> { };
|
|||
class C4AulDefFuncHelper: public C4AulFunc
|
||||
{
|
||||
public:
|
||||
C4AulDefFuncHelper(C4AulScript *pOwner, const char *pName, bool Public,
|
||||
C4AulDefFuncHelper(C4PropListStatic * Parent, const char *pName, bool Public,
|
||||
C4V_Type pt0 = C4V_Any, C4V_Type pt1 = C4V_Any, C4V_Type pt2 = C4V_Any, C4V_Type pt3 = C4V_Any, C4V_Type pt4 = C4V_Any,
|
||||
C4V_Type pt5 = C4V_Any, C4V_Type pt6 = C4V_Any, C4V_Type pt7 = C4V_Any, C4V_Type pt8 = C4V_Any, C4V_Type pt9 = C4V_Any):
|
||||
C4AulFunc(pOwner, pName),
|
||||
C4AulFunc(Parent, pName),
|
||||
Public(Public)
|
||||
{
|
||||
ParType[0] = pt0;
|
||||
|
@ -224,7 +224,7 @@ public:
|
|||
ParType[7] = pt7;
|
||||
ParType[8] = pt8;
|
||||
ParType[9] = pt9;
|
||||
Owner->GetPropList()->SetPropertyByS(Name, C4VFunction(this));
|
||||
Parent->SetPropertyByS(Name, C4VFunction(this));
|
||||
}
|
||||
~C4AulDefFuncHelper()
|
||||
{
|
||||
|
@ -272,8 +272,8 @@ public C4AulDefFuncHelper { \
|
|||
virtual C4V_Type GetRetType() const \
|
||||
{ return C4ValueConv<RType>::Type(); } \
|
||||
/* Constructor, using the base class to create the ParType array */ \
|
||||
C4AulDefFunc##N(C4AulScript *pOwner, const char *pName, Func pFunc, bool Public): \
|
||||
C4AulDefFuncHelper(pOwner, pName, Public LIST(N, CONV_TYPE)), pFunc(pFunc) { } \
|
||||
C4AulDefFunc##N(C4PropListStatic * Parent, const char *pName, Func pFunc, bool Public): \
|
||||
C4AulDefFuncHelper(Parent, pName, Public LIST(N, CONV_TYPE)), pFunc(pFunc) { } \
|
||||
/* Extracts the parameters from C4Values and wraps the return value in a C4Value */ \
|
||||
virtual C4Value Exec(C4PropList * _this, C4Value pPars[], bool fPassErrors) \
|
||||
{ return C4ValueConv<RType>::ToC4V(pFunc(_this LIST(N, CONV_FROM_C4V))); } \
|
||||
|
@ -290,8 +290,8 @@ public C4AulDefFuncHelper { \
|
|||
virtual C4V_Type GetRetType() const \
|
||||
{ return C4ValueConv<RType>::Type(); } \
|
||||
/* Constructor, using the base class to create the ParType array */ \
|
||||
C4AulDefObjectFunc##N(C4AulScript *pOwner, const char *pName, Func pFunc, bool Public): \
|
||||
C4AulDefFuncHelper(pOwner, pName, Public LIST(N, CONV_TYPE)), pFunc(pFunc) { } \
|
||||
C4AulDefObjectFunc##N(C4PropListStatic * Parent, const char *pName, Func pFunc, bool Public): \
|
||||
C4AulDefFuncHelper(Parent, pName, Public LIST(N, CONV_TYPE)), pFunc(pFunc) { } \
|
||||
/* Extracts the parameters from C4Values and wraps the return value in a C4Value */ \
|
||||
virtual C4Value Exec(C4PropList * _this, C4Value pPars[], bool fPassErrors) \
|
||||
{ \
|
||||
|
@ -304,12 +304,12 @@ public C4AulDefFuncHelper { \
|
|||
template <typename RType LIST(N, TYPENAMES)> \
|
||||
inline void AddFunc(C4AulScript * pOwner, const char * Name, RType (*pFunc)(C4PropList * LIST(N, PARS)), bool Public=true) \
|
||||
{ \
|
||||
new C4AulDefFunc##N<RType LIST(N, PARS)>(pOwner, Name, pFunc, Public); \
|
||||
new C4AulDefFunc##N<RType LIST(N, PARS)>(pOwner->GetPropList(), Name, pFunc, Public); \
|
||||
} \
|
||||
template <typename RType LIST(N, TYPENAMES)> \
|
||||
inline void AddFunc(C4AulScript * pOwner, const char * Name, RType (*pFunc)(C4Object * LIST(N, PARS)), bool Public=true) \
|
||||
{ \
|
||||
new C4AulDefObjectFunc##N<RType LIST(N, PARS)>(pOwner, Name, pFunc, Public); \
|
||||
new C4AulDefObjectFunc##N<RType LIST(N, PARS)>(pOwner->GetPropList(), Name, pFunc, Public); \
|
||||
}
|
||||
|
||||
TEMPLATE(0)
|
||||
|
@ -361,7 +361,7 @@ class C4AulDefFunc : C4AulFunc
|
|||
public:
|
||||
C4ScriptFnDef* Def;
|
||||
|
||||
C4AulDefFunc(C4AulScript *pOwner, C4ScriptFnDef* pDef);
|
||||
C4AulDefFunc(C4PropListStatic * Parent, C4ScriptFnDef* pDef);
|
||||
~C4AulDefFunc();
|
||||
|
||||
virtual bool GetPublic() const { return !!Def->Public; }
|
||||
|
|
|
@ -76,7 +76,7 @@ StdStrBuf C4AulScriptContext::ReturnDump(StdStrBuf Dump)
|
|||
Dump.AppendChar(')');
|
||||
}
|
||||
else
|
||||
Dump.Append(Func->Owner->ScriptName);
|
||||
Dump.Append(Func->Parent->GetDataString());
|
||||
// Script
|
||||
if (!fDirectExec && Func->pOrgScript)
|
||||
Dump.AppendFormat(" (%s:%d)",
|
||||
|
@ -1026,10 +1026,6 @@ void C4AulProfiler::Show()
|
|||
|
||||
C4Value C4AulScriptFunc::Exec(C4PropList * p, C4Value pPars[], bool fPassErrors)
|
||||
{
|
||||
// handle easiest case first
|
||||
if (Owner->State != ASS_PARSED) return C4Value();
|
||||
|
||||
// execute
|
||||
return AulExec.Exec(this, p, pPars, fPassErrors);
|
||||
}
|
||||
|
||||
|
@ -1046,7 +1042,7 @@ C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char
|
|||
// profiler
|
||||
AulExec.StartDirectExec();
|
||||
// Add a new function
|
||||
C4AulScriptFunc *pFunc = new C4AulScriptFunc(this, GetScriptHost(), 0, szScript);
|
||||
C4AulScriptFunc *pFunc = new C4AulScriptFunc(GetPropList(), GetScriptHost(), 0, szScript);
|
||||
// Parse function
|
||||
try
|
||||
{
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
#include <C4AulFunc.h>
|
||||
#include <C4Aul.h>
|
||||
|
||||
C4AulFunc::C4AulFunc(C4AulScript *pOwner, const char *pName):
|
||||
C4AulFunc::C4AulFunc(C4PropListStatic * Parent, const char *pName):
|
||||
Parent(Parent),
|
||||
iRefCnt(0),
|
||||
Name(pName ? Strings.RegString(pName) : 0),
|
||||
MapNext(NULL)
|
||||
{
|
||||
Owner = pOwner;
|
||||
// add to global lookuptable with this name
|
||||
if (GetName())
|
||||
::ScriptEngine.FuncLookUp.Add(this);
|
||||
|
@ -40,24 +40,19 @@ StdStrBuf C4AulFunc::GetFullName()
|
|||
{
|
||||
StdStrBuf r;
|
||||
// "lost" function?
|
||||
if (!Owner)
|
||||
if (!Parent)
|
||||
{
|
||||
r.Ref("(unowned) ");
|
||||
}
|
||||
else if (Owner->GetPropList() && Owner->GetPropList()->IsStatic())
|
||||
{
|
||||
r.Take(Owner->GetPropList()->IsStatic()->GetDataString());
|
||||
r.AppendChar('.');
|
||||
}
|
||||
else if (Owner->Engine == Owner)
|
||||
{
|
||||
r.Ref("Global.");
|
||||
}
|
||||
else
|
||||
{
|
||||
r.Ref("(unknown) ");
|
||||
r.Take(Parent->GetDataString());
|
||||
r.AppendChar('.');
|
||||
}
|
||||
r.Append(Name->GetData());
|
||||
if (GetName())
|
||||
r.Append(Name->GetData());
|
||||
else
|
||||
r.Append("(unnamed)");
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,13 +54,13 @@ class C4AulFunc
|
|||
unsigned int iRefCnt;
|
||||
|
||||
public:
|
||||
C4AulFunc(C4AulScript *pOwner, const char *pName);
|
||||
C4AulFunc(C4PropListStatic * Parent, const char *pName);
|
||||
|
||||
// Add/Remove Reference
|
||||
void IncRef() { iRefCnt++; }
|
||||
void DecRef() { if (!--iRefCnt) delete this; }
|
||||
|
||||
C4AulScript *Owner; // owner
|
||||
const C4PropListStatic * Parent;
|
||||
const char * GetName() const { return Name ? Name->GetCStr() : 0; }
|
||||
virtual StdStrBuf GetFullName(); // get a fully classified name (C4ID::Name) for debug output
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ public:
|
|||
pLoopStack(NULL)
|
||||
{ }
|
||||
C4AulParse(C4AulScriptFunc * Fn, C4AulScriptContext* context, enum Type Type):
|
||||
Fn(Fn), Host(Fn->pOrgScript), pOrgScript(Fn->pOrgScript), Engine(Fn->Owner->Engine),
|
||||
Fn(Fn), Host(Fn->pOrgScript), pOrgScript(Fn->pOrgScript), Engine(pOrgScript->Engine),
|
||||
SPos(Fn->Script), TokenSPos(SPos),
|
||||
TokenType(ATT_INVALID),
|
||||
Type(Type),
|
||||
|
@ -239,7 +239,7 @@ void C4AulScript::Warn(const char *pMsg, ...)
|
|||
// display it
|
||||
warning.show();
|
||||
// count warnings
|
||||
++::ScriptEngine.warnCnt;
|
||||
++Engine->warnCnt;
|
||||
}
|
||||
|
||||
void C4AulParse::Warn(const char *pMsg, ...)
|
||||
|
@ -253,7 +253,7 @@ void C4AulParse::Warn(const char *pMsg, ...)
|
|||
if (pOrgScript != Host)
|
||||
DebugLogF(" (as #appendto/#include to %s)", Host->ScriptName.getData());
|
||||
// count warnings
|
||||
++::ScriptEngine.warnCnt;
|
||||
++Engine->warnCnt;
|
||||
}
|
||||
|
||||
void C4AulParse::Error(const char *pMsg, ...)
|
||||
|
@ -1405,7 +1405,7 @@ void C4AulParse::Parse_Script(C4ScriptHost * scripthost)
|
|||
{
|
||||
err.show();
|
||||
// and count (visible only ;) )
|
||||
++::ScriptEngine.errCnt;
|
||||
++Engine->errCnt;
|
||||
}
|
||||
all_ok = false;
|
||||
|
||||
|
@ -1459,16 +1459,16 @@ void C4AulParse::Parse_Function()
|
|||
Error("function definition: name already in use (global constant)");
|
||||
}
|
||||
// get script fn
|
||||
C4AulScript * owner;
|
||||
C4PropListStatic * Parent;
|
||||
if (is_global)
|
||||
owner = Engine;
|
||||
Parent = Engine->GetPropList();
|
||||
else
|
||||
owner = Host;
|
||||
Parent = Host->GetPropList();
|
||||
Fn = 0;
|
||||
C4AulFunc * f = owner->GetPropList()->GetFunc(Idtf);
|
||||
C4AulFunc * f = Parent->GetFunc(Idtf);
|
||||
while (f)
|
||||
{
|
||||
if (f->SFunc() && f->SFunc()->pOrgScript == pOrgScript && f->Owner == owner)
|
||||
if (f->SFunc() && f->SFunc()->pOrgScript == pOrgScript && f->Parent == Parent)
|
||||
{
|
||||
if (Fn)
|
||||
Warn("Duplicate function %s", Idtf);
|
||||
|
@ -1479,9 +1479,9 @@ void C4AulParse::Parse_Function()
|
|||
// first preparser run or a new func in a reloaded script
|
||||
if (!Fn && Type == PREPARSER)
|
||||
{
|
||||
Fn = new C4AulScriptFunc(owner, pOrgScript, Idtf, SPos);
|
||||
Fn->SetOverloaded(owner->GetPropList()->GetFunc(Fn->Name));
|
||||
owner->GetPropList()->SetPropertyByS(Fn->Name, C4VFunction(Fn));
|
||||
Fn = new C4AulScriptFunc(Parent, pOrgScript, Idtf, SPos);
|
||||
Fn->SetOverloaded(Parent->GetFunc(Fn->Name));
|
||||
Parent->SetPropertyByS(Fn->Name, C4VFunction(Fn));
|
||||
}
|
||||
assert(Fn);
|
||||
if (Type == PREPARSER)
|
||||
|
@ -2227,11 +2227,8 @@ void C4AulParse::Parse_Expression(int iParentPrio)
|
|||
Shift();
|
||||
}
|
||||
// check for variable (local)
|
||||
else if (Host && Host->LocalNamed.GetItemNr(Idtf) != -1)
|
||||
else if (Host && Host->GetPropList() == Fn->Parent && Host->LocalNamed.GetItemNr(Idtf) != -1)
|
||||
{
|
||||
// global func?
|
||||
if (Fn->Owner == &::ScriptEngine)
|
||||
throw C4AulParseError(this, "using local variable in global function!");
|
||||
// insert variable by id
|
||||
C4String * pKey = Strings.RegString(Idtf);
|
||||
AddBCC(AB_LOCALN, (intptr_t) pKey);
|
||||
|
@ -2327,9 +2324,8 @@ void C4AulParse::Parse_Expression(int iParentPrio)
|
|||
if (TokenType == ATT_BOPEN)
|
||||
Parse_Params(10, NULL);
|
||||
}
|
||||
else if ((FoundFn = Fn->Owner->GetPropList()->GetFunc(Idtf)))
|
||||
else if ((FoundFn = Fn->Parent->GetFunc(Idtf)))
|
||||
{
|
||||
assert(Host == Fn->Owner || Fn->Owner == Engine || (Host && !Host->GetPropList()));
|
||||
if (Config.Developer.ExtraWarnings && !FoundFn->GetPublic())
|
||||
Warn("using deprecated function %s", Idtf);
|
||||
Shift();
|
||||
|
@ -2899,7 +2895,7 @@ void C4ScriptHost::CopyPropList(C4Set<C4Property> & from, C4PropListStatic * to)
|
|||
{
|
||||
C4AulScriptFunc *sfc;
|
||||
if (sf->pOrgScript != this)
|
||||
sfc = new C4AulScriptFunc(this, *sf);
|
||||
sfc = new C4AulScriptFunc(to, *sf);
|
||||
else
|
||||
sfc = sf;
|
||||
sfc->SetOverloaded(to->GetFunc(sf->Name));
|
||||
|
|
|
@ -83,6 +83,7 @@ public:
|
|||
|
||||
// saved as a reference to a global constant?
|
||||
virtual class C4PropListStatic * IsStatic() { return NULL; }
|
||||
const class C4PropListStatic * IsStatic() const { return const_cast<C4PropList*>(this)->IsStatic(); }
|
||||
// saved as a reference to separately saved objects?
|
||||
virtual bool IsNumbered() const { return false; }
|
||||
// some proplists have references that are not reference-counted
|
||||
|
|
|
@ -135,10 +135,10 @@ bool C4ValueToMatrix(const C4ValueArray& array, StdMeshMatrix* matrix)
|
|||
return true;
|
||||
}
|
||||
|
||||
C4AulDefFunc::C4AulDefFunc(C4AulScript *pOwner, C4ScriptFnDef* pDef):
|
||||
C4AulFunc(pOwner, pDef->Identifier), Def(pDef)
|
||||
C4AulDefFunc::C4AulDefFunc(C4PropListStatic * Parent, C4ScriptFnDef* pDef):
|
||||
C4AulFunc(Parent, pDef->Identifier), Def(pDef)
|
||||
{
|
||||
Owner->GetPropList()->SetPropertyByS(Name, C4VFunction(this));
|
||||
Parent->SetPropertyByS(Name, C4VFunction(this));
|
||||
}
|
||||
|
||||
C4AulDefFunc::~C4AulDefFunc()
|
||||
|
@ -812,7 +812,7 @@ void InitCoreFunctionMap(C4AulScriptEngine *pEngine)
|
|||
|
||||
// add all def script funcs
|
||||
for (C4ScriptFnDef *pDef = &C4ScriptFnMap[0]; pDef->Identifier; pDef++)
|
||||
new C4AulDefFunc(pEngine, pDef);
|
||||
new C4AulDefFunc(pEngine->GetPropList(), pDef);
|
||||
#define F(f) AddFunc(pEngine, #f, Fn##f)
|
||||
F(Abs);
|
||||
F(Min);
|
||||
|
|
|
@ -327,10 +327,10 @@ void C4Value::CompileFunc(StdCompiler *pComp, C4ValueNumbers * numbers)
|
|||
{
|
||||
if (!pComp->isCompiler())
|
||||
{
|
||||
C4PropList * p = getPropList();
|
||||
const C4PropList * p = getPropList();
|
||||
if (getFunction())
|
||||
{
|
||||
p = Data.Fn->Owner->GetPropList();
|
||||
p = Data.Fn->Parent;
|
||||
assert(p);
|
||||
assert(p->GetFunc(Data.Fn->GetName()) == Data.Fn);
|
||||
assert(p->IsStatic());
|
||||
|
|
|
@ -83,7 +83,7 @@ TEST(DirectExecTest, HostUnmodifedByParseTest)
|
|||
TestHost host2 = host;
|
||||
host.test_equality(host2);
|
||||
char szScript[] = "8*5";
|
||||
C4AulScriptFunc *pFunc = new C4AulScriptFunc(&host, host.GetScriptHost(), 0, szScript);
|
||||
C4AulScriptFunc *pFunc = new C4AulScriptFunc(host.GetPropList(), host.GetScriptHost(), 0, szScript);
|
||||
host.test_equality(host2);
|
||||
pFunc->ParseFn();
|
||||
host.test_equality(host2);
|
||||
|
|
Loading…
Reference in New Issue