Move C4AulScriptFunc into its own source file

epoxy
Günther Brammer 2014-05-30 00:13:48 +02:00
parent 514c2b8f34
commit 4c01592196
12 changed files with 319 additions and 266 deletions

View File

@ -1051,6 +1051,8 @@ src/script/C4AulFunc.h
src/script/C4Aul.h
src/script/C4AulLink.cpp
src/script/C4AulParse.cpp
src/script/C4AulScriptFunc.cpp
src/script/C4AulScriptFunc.h
src/script/C4PropList.cpp
src/script/C4PropList.h
src/script/C4Script.cpp

View File

@ -23,11 +23,13 @@
// class declarations
class C4AbstractApp;
class C4Action;
struct C4AulContext;
struct C4AulBCC;
class C4AulDefFunc;
class C4AulExec;
class C4AulFunc;
struct C4AulParSet;
class C4AulScript;
struct C4AulScriptContext;
class C4AulScriptEngine;
class C4AulScriptFunc;
class C4BltTransform;

View File

@ -20,6 +20,7 @@
#include <C4Include.h>
#include <C4Control.h>
#include <C4AulExec.h>
#include <C4Object.h>
#include <C4GameSave.h>
#include <C4GameLobby.h>

View File

@ -111,46 +111,6 @@ std::string C4AulScript::Translate(const std::string &text) const
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():

View File

@ -57,164 +57,6 @@ public:
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
{
public:

View File

@ -18,7 +18,6 @@
#ifndef NOAULDEBUG
#include "C4Aul.h"
#include "C4NetIO.h"
// manages a debugging interface
@ -33,7 +32,7 @@ public:
private:
bool fInit, fConnected;
class C4AulExec *pExec;
C4AulExec *pExec;
static C4AulDebug *pDebug;
C4NetIO::addr_t PeerAddr, AllowedAddr;
StdCopyStrBuf Password;

View File

@ -16,10 +16,11 @@
// executes script functions
#include <C4Include.h>
#include <C4Aul.h>
#include <C4AulExec.h>
#include <C4AulDebug.h>
#include <C4Aul.h>
#include <C4AulScriptFunc.h>
#include <C4AulDebug.h>
#include <C4Object.h>
#include <C4Config.h>
#include <C4Game.h>
@ -1024,11 +1025,6 @@ void C4AulProfiler::Show()
// 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)
{
#ifdef DEBUGREC_SCRIPT

View File

@ -21,6 +21,7 @@
#include <C4Aul.h>
#include "C4TimeMilliseconds.h"
#include <C4AulScriptFunc.h>
const int MAX_CONTEXT_STACK = 512;
const int MAX_VALUE_STACK = 1024;
@ -36,6 +37,21 @@ const int MAX_VALUE_STACK = 1024;
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
{

View File

@ -17,6 +17,10 @@
#ifndef INC_C4AulFunc
#define INC_C4AulFunc
#ifndef INC_C4Value
#error Include C4Value.h instead of C4AulFunc.h
#endif
#include <C4StringTable.h>
#define C4AUL_MAX_Par 10 // max number of parameters

View File

@ -19,8 +19,9 @@
#include <utility>
#include <C4Aul.h>
#include <C4AulDebug.h>
#include <C4AulExec.h>
#include <C4AulScriptFunc.h>
#include <C4Def.h>
#include <C4Game.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()
{
// handle easiest case first

View File

@ -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);
}

View File

@ -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_ */