forked from Mirrors/openclonk
Move C4AulScriptFunc into its own source file
parent
514c2b8f34
commit
4c01592196
|
@ -1051,6 +1051,8 @@ src/script/C4AulFunc.h
|
||||||
src/script/C4Aul.h
|
src/script/C4Aul.h
|
||||||
src/script/C4AulLink.cpp
|
src/script/C4AulLink.cpp
|
||||||
src/script/C4AulParse.cpp
|
src/script/C4AulParse.cpp
|
||||||
|
src/script/C4AulScriptFunc.cpp
|
||||||
|
src/script/C4AulScriptFunc.h
|
||||||
src/script/C4PropList.cpp
|
src/script/C4PropList.cpp
|
||||||
src/script/C4PropList.h
|
src/script/C4PropList.h
|
||||||
src/script/C4Script.cpp
|
src/script/C4Script.cpp
|
||||||
|
|
|
@ -23,11 +23,13 @@
|
||||||
// class declarations
|
// class declarations
|
||||||
class C4AbstractApp;
|
class C4AbstractApp;
|
||||||
class C4Action;
|
class C4Action;
|
||||||
struct C4AulContext;
|
struct C4AulBCC;
|
||||||
class C4AulDefFunc;
|
class C4AulDefFunc;
|
||||||
|
class C4AulExec;
|
||||||
class C4AulFunc;
|
class C4AulFunc;
|
||||||
struct C4AulParSet;
|
struct C4AulParSet;
|
||||||
class C4AulScript;
|
class C4AulScript;
|
||||||
|
struct C4AulScriptContext;
|
||||||
class C4AulScriptEngine;
|
class C4AulScriptEngine;
|
||||||
class C4AulScriptFunc;
|
class C4AulScriptFunc;
|
||||||
class C4BltTransform;
|
class C4BltTransform;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <C4Include.h>
|
#include <C4Include.h>
|
||||||
#include <C4Control.h>
|
#include <C4Control.h>
|
||||||
|
|
||||||
|
#include <C4AulExec.h>
|
||||||
#include <C4Object.h>
|
#include <C4Object.h>
|
||||||
#include <C4GameSave.h>
|
#include <C4GameSave.h>
|
||||||
#include <C4GameLobby.h>
|
#include <C4GameLobby.h>
|
||||||
|
|
|
@ -111,46 +111,6 @@ std::string C4AulScript::Translate(const std::string &text) const
|
||||||
throw C4LangStringTable::NoSuchTranslation(text);
|
throw C4LangStringTable::NoSuchTranslation(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
C4AulScriptFunc::C4AulScriptFunc(C4PropListStatic * Parent, C4ScriptHost *pOrgScript, const char *pName, const char *Script):
|
|
||||||
C4AulFunc(Parent, pName),
|
|
||||||
OwnerOverloaded(NULL),
|
|
||||||
ParCount(0),
|
|
||||||
Script(Script),
|
|
||||||
pOrgScript(pOrgScript),
|
|
||||||
tProfileTime(0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < C4AUL_MAX_Par; i++) ParType[i] = C4V_Any;
|
|
||||||
AddBCC(AB_EOFN);
|
|
||||||
}
|
|
||||||
|
|
||||||
C4AulScriptFunc::C4AulScriptFunc(C4PropListStatic * Parent, const C4AulScriptFunc &FromFunc):
|
|
||||||
C4AulFunc(Parent, FromFunc.GetName()),
|
|
||||||
OwnerOverloaded(NULL),
|
|
||||||
ParCount(FromFunc.ParCount),
|
|
||||||
Script(FromFunc.Script),
|
|
||||||
VarNamed(FromFunc.VarNamed),
|
|
||||||
ParNamed(FromFunc.ParNamed),
|
|
||||||
pOrgScript(FromFunc.pOrgScript),
|
|
||||||
tProfileTime(0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < C4AUL_MAX_Par; i++)
|
|
||||||
ParType[i] = FromFunc.ParType[i];
|
|
||||||
AddBCC(AB_EOFN);
|
|
||||||
}
|
|
||||||
|
|
||||||
C4AulScriptFunc::~C4AulScriptFunc()
|
|
||||||
{
|
|
||||||
if (OwnerOverloaded) OwnerOverloaded->DecRef();
|
|
||||||
ClearCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
void C4AulScriptFunc::SetOverloaded(C4AulFunc * f)
|
|
||||||
{
|
|
||||||
if (OwnerOverloaded) OwnerOverloaded->DecRef();
|
|
||||||
OwnerOverloaded = f;
|
|
||||||
if (f) f->IncRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--- C4AulScriptEngine ---*/
|
/*--- C4AulScriptEngine ---*/
|
||||||
|
|
||||||
C4AulScriptEngine::C4AulScriptEngine():
|
C4AulScriptEngine::C4AulScriptEngine():
|
||||||
|
|
|
@ -57,164 +57,6 @@ public:
|
||||||
C4AulExecError(const char *szError);
|
C4AulExecError(const char *szError);
|
||||||
};
|
};
|
||||||
|
|
||||||
// byte code chunk type
|
|
||||||
// some special script functions defined hard-coded to reduce the exec context
|
|
||||||
enum C4AulBCCType
|
|
||||||
{
|
|
||||||
AB_ARRAYA, // array or proplist access
|
|
||||||
AB_ARRAYA_SET,
|
|
||||||
AB_PROP, // proplist access with static key
|
|
||||||
AB_PROP_SET,
|
|
||||||
AB_ARRAY_SLICE, // array slicing
|
|
||||||
AB_ARRAY_SLICE_SET,
|
|
||||||
AB_DUP, // duplicate value from stack
|
|
||||||
AB_STACK_SET, // copy top of stack to stack
|
|
||||||
AB_POP_TO, // pop top of stack to stack
|
|
||||||
AB_LOCALN, // a property of this
|
|
||||||
AB_LOCALN_SET,
|
|
||||||
AB_GLOBALN, // a named global
|
|
||||||
AB_GLOBALN_SET,
|
|
||||||
AB_PAR, // Par statement
|
|
||||||
AB_THIS, // this()
|
|
||||||
AB_FUNC, // function
|
|
||||||
|
|
||||||
AB_PARN_CONTEXT,
|
|
||||||
AB_VARN_CONTEXT,
|
|
||||||
|
|
||||||
// prefix
|
|
||||||
AB_Inc, // ++
|
|
||||||
AB_Dec, // --
|
|
||||||
AB_BitNot, // ~
|
|
||||||
AB_Not, // !
|
|
||||||
AB_Neg, // -
|
|
||||||
|
|
||||||
// postfix
|
|
||||||
AB_Pow, // **
|
|
||||||
AB_Div, // /
|
|
||||||
AB_Mul, // *
|
|
||||||
AB_Mod, // %
|
|
||||||
AB_Sub, // -
|
|
||||||
AB_Sum, // +
|
|
||||||
AB_LeftShift, // <<
|
|
||||||
AB_RightShift, // >>
|
|
||||||
AB_LessThan, // <
|
|
||||||
AB_LessThanEqual, // <=
|
|
||||||
AB_GreaterThan, // >
|
|
||||||
AB_GreaterThanEqual, // >=
|
|
||||||
AB_Equal, // ==
|
|
||||||
AB_NotEqual, // !=
|
|
||||||
AB_BitAnd, // &
|
|
||||||
AB_BitXOr, // ^
|
|
||||||
AB_BitOr, // |
|
|
||||||
|
|
||||||
AB_CALL, // direct object call
|
|
||||||
AB_CALLFS, // failsafe direct call
|
|
||||||
AB_STACK, // push nulls / pop
|
|
||||||
AB_INT, // constant: int
|
|
||||||
AB_BOOL, // constant: bool
|
|
||||||
AB_STRING, // constant: string
|
|
||||||
AB_CPROPLIST, // constant: proplist
|
|
||||||
AB_CARRAY, // constant: array
|
|
||||||
AB_CFUNCTION, // constant: function
|
|
||||||
AB_NIL, // constant: nil
|
|
||||||
AB_NEW_ARRAY, // semi-constant: array
|
|
||||||
AB_NEW_PROPLIST, // create a new proplist
|
|
||||||
AB_JUMP, // jump
|
|
||||||
AB_JUMPAND, // jump if convertible to false, else pop the stack
|
|
||||||
AB_JUMPOR, // jump if convertible to true, else pop the stack
|
|
||||||
AB_JUMPNNIL, // jump if not nil, else pop the stack
|
|
||||||
AB_CONDN, // conditional jump (negated, pops stack)
|
|
||||||
AB_COND, // conditional jump (pops stack)
|
|
||||||
AB_FOREACH_NEXT, // foreach: next element
|
|
||||||
AB_RETURN, // return statement
|
|
||||||
AB_ERR, // parse error at this position
|
|
||||||
AB_DEBUG, // debug break
|
|
||||||
AB_EOFN, // end of function
|
|
||||||
};
|
|
||||||
|
|
||||||
// byte code chunk
|
|
||||||
struct C4AulBCC
|
|
||||||
{
|
|
||||||
C4AulBCCType bccType; // chunk type
|
|
||||||
union
|
|
||||||
{
|
|
||||||
int32_t i;
|
|
||||||
C4String * s;
|
|
||||||
C4PropList * p;
|
|
||||||
C4ValueArray * a;
|
|
||||||
C4AulFunc * f;
|
|
||||||
intptr_t X;
|
|
||||||
} Par; // extra info
|
|
||||||
};
|
|
||||||
|
|
||||||
// execution context
|
|
||||||
struct C4AulScriptContext
|
|
||||||
{
|
|
||||||
C4PropList *Obj;
|
|
||||||
C4Value *Return;
|
|
||||||
C4Value *Pars;
|
|
||||||
C4Value *Vars;
|
|
||||||
C4AulScriptFunc *Func;
|
|
||||||
C4AulBCC *CPos;
|
|
||||||
C4TimeMilliseconds tTime; // initialized only by profiler if active
|
|
||||||
|
|
||||||
void dump(StdStrBuf Dump = StdStrBuf(""));
|
|
||||||
StdStrBuf ReturnDump(StdStrBuf Dump = StdStrBuf(""));
|
|
||||||
};
|
|
||||||
|
|
||||||
// script function class
|
|
||||||
class C4AulScriptFunc : public C4AulFunc
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
C4AulFunc *OwnerOverloaded; // overloaded owner function; if present
|
|
||||||
void SetOverloaded(C4AulFunc *);
|
|
||||||
C4AulScriptFunc *SFunc() { return this; } // type check func...
|
|
||||||
protected:
|
|
||||||
void AddBCC(C4AulBCCType eType, intptr_t = 0, const char * SPos = 0); // add byte code chunk and advance
|
|
||||||
void RemoveLastBCC();
|
|
||||||
void ClearCode();
|
|
||||||
int GetCodePos() const { return Code.size(); }
|
|
||||||
C4AulBCC *GetCodeByPos(int iPos) { return &Code[iPos]; }
|
|
||||||
C4AulBCC *GetLastCode() { return Code.empty() ? NULL : &Code.back(); }
|
|
||||||
std::vector<C4AulBCC> Code;
|
|
||||||
std::vector<const char *> PosForCode;
|
|
||||||
int ParCount;
|
|
||||||
C4V_Type ParType[C4AUL_MAX_Par]; // parameter types
|
|
||||||
|
|
||||||
public:
|
|
||||||
const char *Script; // script pos
|
|
||||||
C4ValueMapNames VarNamed; // list of named vars in this function
|
|
||||||
C4ValueMapNames ParNamed; // list of named pars in this function
|
|
||||||
void AddPar(const char * Idtf)
|
|
||||||
{
|
|
||||||
assert(ParCount < C4AUL_MAX_Par);
|
|
||||||
assert(ParCount == ParNamed.iSize);
|
|
||||||
ParNamed.AddName(Idtf);
|
|
||||||
++ParCount;
|
|
||||||
}
|
|
||||||
C4ScriptHost *pOrgScript; // the orginal script (!= Owner if included or appended)
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
virtual bool GetPublic() const { return true; }
|
|
||||||
virtual int GetParCount() const { return ParCount; }
|
|
||||||
virtual const C4V_Type *GetParType() const { return ParType; }
|
|
||||||
virtual C4V_Type GetRetType() const { return C4V_Any; }
|
|
||||||
virtual C4Value Exec(C4PropList * p, C4Value pPars[], bool fPassErrors=false); // execute func
|
|
||||||
|
|
||||||
int GetLineOfCode(C4AulBCC * bcc);
|
|
||||||
C4AulBCC * GetCode();
|
|
||||||
|
|
||||||
uint32_t tProfileTime; // internally set by profiler
|
|
||||||
|
|
||||||
friend class C4AulParse;
|
|
||||||
friend class C4ScriptHost;
|
|
||||||
};
|
|
||||||
|
|
||||||
class C4AulFuncMap
|
class C4AulFuncMap
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
|
|
||||||
#ifndef NOAULDEBUG
|
#ifndef NOAULDEBUG
|
||||||
|
|
||||||
#include "C4Aul.h"
|
|
||||||
#include "C4NetIO.h"
|
#include "C4NetIO.h"
|
||||||
|
|
||||||
// manages a debugging interface
|
// manages a debugging interface
|
||||||
|
@ -33,7 +32,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool fInit, fConnected;
|
bool fInit, fConnected;
|
||||||
class C4AulExec *pExec;
|
C4AulExec *pExec;
|
||||||
static C4AulDebug *pDebug;
|
static C4AulDebug *pDebug;
|
||||||
C4NetIO::addr_t PeerAddr, AllowedAddr;
|
C4NetIO::addr_t PeerAddr, AllowedAddr;
|
||||||
StdCopyStrBuf Password;
|
StdCopyStrBuf Password;
|
||||||
|
|
|
@ -16,10 +16,11 @@
|
||||||
// executes script functions
|
// executes script functions
|
||||||
|
|
||||||
#include <C4Include.h>
|
#include <C4Include.h>
|
||||||
#include <C4Aul.h>
|
|
||||||
#include <C4AulExec.h>
|
#include <C4AulExec.h>
|
||||||
#include <C4AulDebug.h>
|
|
||||||
|
|
||||||
|
#include <C4Aul.h>
|
||||||
|
#include <C4AulScriptFunc.h>
|
||||||
|
#include <C4AulDebug.h>
|
||||||
#include <C4Object.h>
|
#include <C4Object.h>
|
||||||
#include <C4Config.h>
|
#include <C4Config.h>
|
||||||
#include <C4Game.h>
|
#include <C4Game.h>
|
||||||
|
@ -1024,11 +1025,6 @@ void C4AulProfiler::Show()
|
||||||
// done!
|
// done!
|
||||||
}
|
}
|
||||||
|
|
||||||
C4Value C4AulScriptFunc::Exec(C4PropList * p, C4Value pPars[], bool fPassErrors)
|
|
||||||
{
|
|
||||||
return AulExec.Exec(this, p, pPars, fPassErrors);
|
|
||||||
}
|
|
||||||
|
|
||||||
C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char *szContext, bool fPassErrors, C4AulScriptContext* context)
|
C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char *szContext, bool fPassErrors, C4AulScriptContext* context)
|
||||||
{
|
{
|
||||||
#ifdef DEBUGREC_SCRIPT
|
#ifdef DEBUGREC_SCRIPT
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include <C4Aul.h>
|
#include <C4Aul.h>
|
||||||
#include "C4TimeMilliseconds.h"
|
#include "C4TimeMilliseconds.h"
|
||||||
|
#include <C4AulScriptFunc.h>
|
||||||
|
|
||||||
const int MAX_CONTEXT_STACK = 512;
|
const int MAX_CONTEXT_STACK = 512;
|
||||||
const int MAX_VALUE_STACK = 1024;
|
const int MAX_VALUE_STACK = 1024;
|
||||||
|
@ -36,6 +37,21 @@ const int MAX_VALUE_STACK = 1024;
|
||||||
temporary values
|
temporary values
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// execution context
|
||||||
|
struct C4AulScriptContext
|
||||||
|
{
|
||||||
|
C4PropList *Obj;
|
||||||
|
C4Value *Return;
|
||||||
|
C4Value *Pars;
|
||||||
|
C4Value *Vars;
|
||||||
|
C4AulScriptFunc *Func;
|
||||||
|
C4AulBCC *CPos;
|
||||||
|
C4TimeMilliseconds tTime; // initialized only by profiler if active
|
||||||
|
|
||||||
|
void dump(StdStrBuf Dump = StdStrBuf(""));
|
||||||
|
StdStrBuf ReturnDump(StdStrBuf Dump = StdStrBuf(""));
|
||||||
|
};
|
||||||
|
|
||||||
class C4AulExec
|
class C4AulExec
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
#ifndef INC_C4AulFunc
|
#ifndef INC_C4AulFunc
|
||||||
#define INC_C4AulFunc
|
#define INC_C4AulFunc
|
||||||
|
|
||||||
|
#ifndef INC_C4Value
|
||||||
|
#error Include C4Value.h instead of C4AulFunc.h
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <C4StringTable.h>
|
#include <C4StringTable.h>
|
||||||
|
|
||||||
#define C4AUL_MAX_Par 10 // max number of parameters
|
#define C4AUL_MAX_Par 10 // max number of parameters
|
||||||
|
|
|
@ -19,8 +19,9 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <C4Aul.h>
|
#include <C4Aul.h>
|
||||||
|
|
||||||
#include <C4AulDebug.h>
|
#include <C4AulDebug.h>
|
||||||
|
#include <C4AulExec.h>
|
||||||
|
#include <C4AulScriptFunc.h>
|
||||||
#include <C4Def.h>
|
#include <C4Def.h>
|
||||||
#include <C4Game.h>
|
#include <C4Game.h>
|
||||||
#include <C4Log.h>
|
#include <C4Log.h>
|
||||||
|
@ -783,63 +784,6 @@ void C4AulParse::DumpByteCode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4AulScriptFunc::AddBCC(C4AulBCCType eType, intptr_t X, const char * SPos)
|
|
||||||
{
|
|
||||||
// store chunk
|
|
||||||
C4AulBCC bcc;
|
|
||||||
bcc.bccType = eType;
|
|
||||||
bcc.Par.X = X;
|
|
||||||
Code.push_back(bcc);
|
|
||||||
PosForCode.push_back(SPos);
|
|
||||||
|
|
||||||
switch (eType)
|
|
||||||
{
|
|
||||||
case AB_STRING: case AB_CALL: case AB_CALLFS: case AB_LOCALN: case AB_PROP:
|
|
||||||
/* case AB_LOCALN_SET/AB_PROP_SET: -- expected to already have a reference upon creation, see MakeSetter */
|
|
||||||
bcc.Par.s->IncRef();
|
|
||||||
break;
|
|
||||||
case AB_CARRAY:
|
|
||||||
bcc.Par.a->IncRef();
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void C4AulScriptFunc::RemoveLastBCC()
|
|
||||||
{
|
|
||||||
C4AulBCC *pBCC = &Code.back();
|
|
||||||
switch (pBCC->bccType)
|
|
||||||
{
|
|
||||||
case AB_STRING: case AB_CALL: case AB_CALLFS: case AB_LOCALN: case AB_LOCALN_SET: case AB_PROP: case AB_PROP_SET:
|
|
||||||
pBCC->Par.s->DecRef();
|
|
||||||
break;
|
|
||||||
case AB_CARRAY:
|
|
||||||
pBCC->Par.a->DecRef();
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
Code.pop_back();
|
|
||||||
PosForCode.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
void C4AulScriptFunc::ClearCode()
|
|
||||||
{
|
|
||||||
while(Code.size() > 0)
|
|
||||||
RemoveLastBCC();
|
|
||||||
// This function is now broken until an AddBCC call
|
|
||||||
}
|
|
||||||
|
|
||||||
int C4AulScriptFunc::GetLineOfCode(C4AulBCC * bcc)
|
|
||||||
{
|
|
||||||
return SGetLine(pOrgScript ? pOrgScript->GetScript() : Script, PosForCode[bcc - &Code[0]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
C4AulBCC * C4AulScriptFunc::GetCode()
|
|
||||||
{
|
|
||||||
assert(!Code.empty());
|
|
||||||
return &Code[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool C4ScriptHost::Preparse()
|
bool C4ScriptHost::Preparse()
|
||||||
{
|
{
|
||||||
// handle easiest case first
|
// handle easiest case first
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* OpenClonk, http://www.openclonk.org
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009-2014, The OpenClonk Team and contributors
|
||||||
|
*
|
||||||
|
* Distributed under the terms of the ISC license; see accompanying file
|
||||||
|
* "COPYING" for details.
|
||||||
|
*
|
||||||
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||||
|
* See accompanying file "TRADEMARK" for details.
|
||||||
|
*
|
||||||
|
* To redistribute this file separately, substitute the full license texts
|
||||||
|
* for the above references.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <C4Include.h>
|
||||||
|
#include <C4AulScriptFunc.h>
|
||||||
|
|
||||||
|
#include <C4AulExec.h>
|
||||||
|
#include <C4ScriptHost.h>
|
||||||
|
|
||||||
|
C4AulScriptFunc::C4AulScriptFunc(C4PropListStatic * Parent, C4ScriptHost *pOrgScript, const char *pName, const char *Script):
|
||||||
|
C4AulFunc(Parent, pName),
|
||||||
|
OwnerOverloaded(NULL),
|
||||||
|
ParCount(0),
|
||||||
|
Script(Script),
|
||||||
|
pOrgScript(pOrgScript),
|
||||||
|
tProfileTime(0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < C4AUL_MAX_Par; i++) ParType[i] = C4V_Any;
|
||||||
|
AddBCC(AB_EOFN);
|
||||||
|
}
|
||||||
|
|
||||||
|
C4AulScriptFunc::C4AulScriptFunc(C4PropListStatic * Parent, const C4AulScriptFunc &FromFunc):
|
||||||
|
C4AulFunc(Parent, FromFunc.GetName()),
|
||||||
|
OwnerOverloaded(NULL),
|
||||||
|
ParCount(FromFunc.ParCount),
|
||||||
|
Script(FromFunc.Script),
|
||||||
|
VarNamed(FromFunc.VarNamed),
|
||||||
|
ParNamed(FromFunc.ParNamed),
|
||||||
|
pOrgScript(FromFunc.pOrgScript),
|
||||||
|
tProfileTime(0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < C4AUL_MAX_Par; i++)
|
||||||
|
ParType[i] = FromFunc.ParType[i];
|
||||||
|
AddBCC(AB_EOFN);
|
||||||
|
}
|
||||||
|
|
||||||
|
C4AulScriptFunc::~C4AulScriptFunc()
|
||||||
|
{
|
||||||
|
if (OwnerOverloaded) OwnerOverloaded->DecRef();
|
||||||
|
ClearCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
void C4AulScriptFunc::SetOverloaded(C4AulFunc * f)
|
||||||
|
{
|
||||||
|
if (OwnerOverloaded) OwnerOverloaded->DecRef();
|
||||||
|
OwnerOverloaded = f;
|
||||||
|
if (f) f->IncRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
void C4AulScriptFunc::AddBCC(C4AulBCCType eType, intptr_t X, const char * SPos)
|
||||||
|
{
|
||||||
|
// store chunk
|
||||||
|
C4AulBCC bcc;
|
||||||
|
bcc.bccType = eType;
|
||||||
|
bcc.Par.X = X;
|
||||||
|
Code.push_back(bcc);
|
||||||
|
PosForCode.push_back(SPos);
|
||||||
|
|
||||||
|
switch (eType)
|
||||||
|
{
|
||||||
|
case AB_STRING: case AB_CALL: case AB_CALLFS: case AB_LOCALN: case AB_PROP:
|
||||||
|
/* case AB_LOCALN_SET/AB_PROP_SET: -- expected to already have a reference upon creation, see MakeSetter */
|
||||||
|
bcc.Par.s->IncRef();
|
||||||
|
break;
|
||||||
|
case AB_CARRAY:
|
||||||
|
bcc.Par.a->IncRef();
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void C4AulScriptFunc::RemoveLastBCC()
|
||||||
|
{
|
||||||
|
C4AulBCC *pBCC = &Code.back();
|
||||||
|
switch (pBCC->bccType)
|
||||||
|
{
|
||||||
|
case AB_STRING: case AB_CALL: case AB_CALLFS: case AB_LOCALN: case AB_LOCALN_SET: case AB_PROP: case AB_PROP_SET:
|
||||||
|
pBCC->Par.s->DecRef();
|
||||||
|
break;
|
||||||
|
case AB_CARRAY:
|
||||||
|
pBCC->Par.a->DecRef();
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
Code.pop_back();
|
||||||
|
PosForCode.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void C4AulScriptFunc::ClearCode()
|
||||||
|
{
|
||||||
|
while(Code.size() > 0)
|
||||||
|
RemoveLastBCC();
|
||||||
|
// This function is now broken until an AddBCC call
|
||||||
|
}
|
||||||
|
|
||||||
|
int C4AulScriptFunc::GetLineOfCode(C4AulBCC * bcc)
|
||||||
|
{
|
||||||
|
return SGetLine(pOrgScript ? pOrgScript->GetScript() : Script, PosForCode[bcc - &Code[0]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
C4AulBCC * C4AulScriptFunc::GetCode()
|
||||||
|
{
|
||||||
|
assert(!Code.empty());
|
||||||
|
return &Code[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
C4Value C4AulScriptFunc::Exec(C4PropList * p, C4Value pPars[], bool fPassErrors)
|
||||||
|
{
|
||||||
|
return AulExec.Exec(this, p, pPars, fPassErrors);
|
||||||
|
}
|
|
@ -0,0 +1,165 @@
|
||||||
|
/*
|
||||||
|
* OpenClonk, http://www.openclonk.org
|
||||||
|
*
|
||||||
|
* Copyright (c) 2001-2014, The OpenClonk Team and contributors
|
||||||
|
*
|
||||||
|
* Distributed under the terms of the ISC license; see accompanying file
|
||||||
|
* "COPYING" for details.
|
||||||
|
*
|
||||||
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
||||||
|
* See accompanying file "TRADEMARK" for details.
|
||||||
|
*
|
||||||
|
* To redistribute this file separately, substitute the full license texts
|
||||||
|
* for the above references.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef C4AULSCRIPTFUNC_H_
|
||||||
|
#define C4AULSCRIPTFUNC_H_
|
||||||
|
|
||||||
|
#include <C4Value.h>
|
||||||
|
#include <C4ValueMap.h>
|
||||||
|
|
||||||
|
// byte code chunk type
|
||||||
|
// some special script functions defined hard-coded to reduce the exec context
|
||||||
|
enum C4AulBCCType
|
||||||
|
{
|
||||||
|
AB_ARRAYA, // array or proplist access
|
||||||
|
AB_ARRAYA_SET,
|
||||||
|
AB_PROP, // proplist access with static key
|
||||||
|
AB_PROP_SET,
|
||||||
|
AB_ARRAY_SLICE, // array slicing
|
||||||
|
AB_ARRAY_SLICE_SET,
|
||||||
|
AB_DUP, // duplicate value from stack
|
||||||
|
AB_STACK_SET, // copy top of stack to stack
|
||||||
|
AB_POP_TO, // pop top of stack to stack
|
||||||
|
AB_LOCALN, // a property of this
|
||||||
|
AB_LOCALN_SET,
|
||||||
|
AB_GLOBALN, // a named global
|
||||||
|
AB_GLOBALN_SET,
|
||||||
|
AB_PAR, // Par statement
|
||||||
|
AB_THIS, // this()
|
||||||
|
AB_FUNC, // function
|
||||||
|
|
||||||
|
AB_PARN_CONTEXT,
|
||||||
|
AB_VARN_CONTEXT,
|
||||||
|
|
||||||
|
// prefix
|
||||||
|
AB_Inc, // ++
|
||||||
|
AB_Dec, // --
|
||||||
|
AB_BitNot, // ~
|
||||||
|
AB_Not, // !
|
||||||
|
AB_Neg, // -
|
||||||
|
|
||||||
|
// postfix
|
||||||
|
AB_Pow, // **
|
||||||
|
AB_Div, // /
|
||||||
|
AB_Mul, // *
|
||||||
|
AB_Mod, // %
|
||||||
|
AB_Sub, // -
|
||||||
|
AB_Sum, // +
|
||||||
|
AB_LeftShift, // <<
|
||||||
|
AB_RightShift, // >>
|
||||||
|
AB_LessThan, // <
|
||||||
|
AB_LessThanEqual, // <=
|
||||||
|
AB_GreaterThan, // >
|
||||||
|
AB_GreaterThanEqual, // >=
|
||||||
|
AB_Equal, // ==
|
||||||
|
AB_NotEqual, // !=
|
||||||
|
AB_BitAnd, // &
|
||||||
|
AB_BitXOr, // ^
|
||||||
|
AB_BitOr, // |
|
||||||
|
|
||||||
|
AB_CALL, // direct object call
|
||||||
|
AB_CALLFS, // failsafe direct call
|
||||||
|
AB_STACK, // push nulls / pop
|
||||||
|
AB_INT, // constant: int
|
||||||
|
AB_BOOL, // constant: bool
|
||||||
|
AB_STRING, // constant: string
|
||||||
|
AB_CPROPLIST, // constant: proplist
|
||||||
|
AB_CARRAY, // constant: array
|
||||||
|
AB_CFUNCTION, // constant: function
|
||||||
|
AB_NIL, // constant: nil
|
||||||
|
AB_NEW_ARRAY, // semi-constant: array
|
||||||
|
AB_NEW_PROPLIST, // create a new proplist
|
||||||
|
AB_JUMP, // jump
|
||||||
|
AB_JUMPAND, // jump if convertible to false, else pop the stack
|
||||||
|
AB_JUMPOR, // jump if convertible to true, else pop the stack
|
||||||
|
AB_JUMPNNIL, // jump if not nil, else pop the stack
|
||||||
|
AB_CONDN, // conditional jump (negated, pops stack)
|
||||||
|
AB_COND, // conditional jump (pops stack)
|
||||||
|
AB_FOREACH_NEXT, // foreach: next element
|
||||||
|
AB_RETURN, // return statement
|
||||||
|
AB_ERR, // parse error at this position
|
||||||
|
AB_DEBUG, // debug break
|
||||||
|
AB_EOFN, // end of function
|
||||||
|
};
|
||||||
|
|
||||||
|
// byte code chunk
|
||||||
|
struct C4AulBCC
|
||||||
|
{
|
||||||
|
C4AulBCCType bccType; // chunk type
|
||||||
|
union
|
||||||
|
{
|
||||||
|
int32_t i;
|
||||||
|
C4String * s;
|
||||||
|
C4PropList * p;
|
||||||
|
C4ValueArray * a;
|
||||||
|
C4AulFunc * f;
|
||||||
|
intptr_t X;
|
||||||
|
} Par; // extra info
|
||||||
|
};
|
||||||
|
|
||||||
|
// script function class
|
||||||
|
class C4AulScriptFunc : public C4AulFunc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
C4AulFunc *OwnerOverloaded; // overloaded owner function; if present
|
||||||
|
void SetOverloaded(C4AulFunc *);
|
||||||
|
C4AulScriptFunc *SFunc() { return this; } // type check func...
|
||||||
|
protected:
|
||||||
|
void AddBCC(C4AulBCCType eType, intptr_t = 0, const char * SPos = 0); // add byte code chunk and advance
|
||||||
|
void RemoveLastBCC();
|
||||||
|
void ClearCode();
|
||||||
|
int GetCodePos() const { return Code.size(); }
|
||||||
|
C4AulBCC *GetCodeByPos(int iPos) { return &Code[iPos]; }
|
||||||
|
C4AulBCC *GetLastCode() { return Code.empty() ? NULL : &Code.back(); }
|
||||||
|
std::vector<C4AulBCC> Code;
|
||||||
|
std::vector<const char *> PosForCode;
|
||||||
|
int ParCount;
|
||||||
|
C4V_Type ParType[C4AUL_MAX_Par]; // parameter types
|
||||||
|
|
||||||
|
public:
|
||||||
|
const char *Script; // script pos
|
||||||
|
C4ValueMapNames VarNamed; // list of named vars in this function
|
||||||
|
C4ValueMapNames ParNamed; // list of named pars in this function
|
||||||
|
void AddPar(const char * Idtf)
|
||||||
|
{
|
||||||
|
assert(ParCount < C4AUL_MAX_Par);
|
||||||
|
assert(ParCount == ParNamed.iSize);
|
||||||
|
ParNamed.AddName(Idtf);
|
||||||
|
++ParCount;
|
||||||
|
}
|
||||||
|
C4ScriptHost *pOrgScript; // the orginal script (!= Owner if included or appended)
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
virtual bool GetPublic() const { return true; }
|
||||||
|
virtual int GetParCount() const { return ParCount; }
|
||||||
|
virtual const C4V_Type *GetParType() const { return ParType; }
|
||||||
|
virtual C4V_Type GetRetType() const { return C4V_Any; }
|
||||||
|
virtual C4Value Exec(C4PropList * p, C4Value pPars[], bool fPassErrors=false); // execute func
|
||||||
|
|
||||||
|
int GetLineOfCode(C4AulBCC * bcc);
|
||||||
|
C4AulBCC * GetCode();
|
||||||
|
|
||||||
|
uint32_t tProfileTime; // internally set by profiler
|
||||||
|
|
||||||
|
friend class C4AulParse;
|
||||||
|
friend class C4ScriptHost;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* C4AULSCRIPTFUNC_H_ */
|
Loading…
Reference in New Issue