forked from Mirrors/openclonk
Move Parser from C4AulScript to C4ScriptHost
parent
843642271d
commit
f166fdaed7
|
@ -110,6 +110,7 @@ class C4RegionList;
|
||||||
class C4RoundResult;
|
class C4RoundResult;
|
||||||
class C4RoundResults;
|
class C4RoundResults;
|
||||||
class C4Scenario;
|
class C4Scenario;
|
||||||
|
class C4ScriptHost;
|
||||||
class C4SoundSystem;
|
class C4SoundSystem;
|
||||||
class C4Stream;
|
class C4Stream;
|
||||||
class C4String;
|
class C4String;
|
||||||
|
|
|
@ -153,14 +153,11 @@ C4AulScript::C4AulScript()
|
||||||
{
|
{
|
||||||
// not compiled
|
// not compiled
|
||||||
State = ASS_NONE;
|
State = ASS_NONE;
|
||||||
Script = NULL;
|
|
||||||
Code.clear();
|
|
||||||
LastCode = NULL;
|
|
||||||
IncludesResolved = false;
|
IncludesResolved = false;
|
||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
Strict = MAXSTRICT;
|
Strict = MAXSTRICT;
|
||||||
Preparsing=Resolving=false;
|
Resolving=false;
|
||||||
Temporary = false;
|
Temporary = false;
|
||||||
LocalNamed.Reset();
|
LocalNamed.Reset();
|
||||||
|
|
||||||
|
@ -171,8 +168,6 @@ C4AulScript::C4AulScript()
|
||||||
// prepare include list
|
// prepare include list
|
||||||
Includes.clear();
|
Includes.clear();
|
||||||
Appends.clear();
|
Appends.clear();
|
||||||
|
|
||||||
stringTable = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
C4AulScript::~C4AulScript()
|
C4AulScript::~C4AulScript()
|
||||||
|
@ -202,9 +197,6 @@ void C4AulScript::Clear()
|
||||||
while (Child0) // Child0->Unreg();
|
while (Child0) // Child0->Unreg();
|
||||||
if (Child0->Delete()) delete Child0; else Child0->Unreg();
|
if (Child0->Delete()) delete Child0; else Child0->Unreg();
|
||||||
while (Func0) delete Func0;
|
while (Func0) delete Func0;
|
||||||
// delete script+code
|
|
||||||
Script.Clear();
|
|
||||||
ClearCode();
|
|
||||||
// reset flags
|
// reset flags
|
||||||
State = ASS_NONE;
|
State = ASS_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,7 @@ class C4AulFunc
|
||||||
friend class C4AulScriptEngine;
|
friend class C4AulScriptEngine;
|
||||||
friend class C4AulFuncMap;
|
friend class C4AulFuncMap;
|
||||||
friend class C4AulParseState;
|
friend class C4AulParseState;
|
||||||
|
friend class C4ScriptHost;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
C4AulFunc(C4AulScript *pOwner, const char *pName, bool bAtEnd = true); // constructor
|
C4AulFunc(C4AulScript *pOwner, const char *pName, bool bAtEnd = true); // constructor
|
||||||
|
@ -260,7 +261,7 @@ public:
|
||||||
C4ValueMapNames ParNamed; // list of named pars in this function
|
C4ValueMapNames ParNamed; // list of named pars in this function
|
||||||
int ParCount;
|
int ParCount;
|
||||||
C4V_Type ParType[C4AUL_MAX_Par]; // parameter types
|
C4V_Type ParType[C4AUL_MAX_Par]; // parameter types
|
||||||
C4AulScript *pOrgScript; // the orginal script (!= Owner if included or appended)
|
C4ScriptHost *pOrgScript; // the orginal script (!= Owner if included or appended)
|
||||||
|
|
||||||
C4AulScriptFunc(C4AulScript *pOwner, const char *pName, bool bAtEnd = true) : C4AulFunc(pOwner, pName, bAtEnd),
|
C4AulScriptFunc(C4AulScript *pOwner, const char *pName, bool bAtEnd = true) : C4AulFunc(pOwner, pName, bAtEnd),
|
||||||
OwnerOverloaded(NULL), ParCount(0),
|
OwnerOverloaded(NULL), ParCount(0),
|
||||||
|
@ -270,6 +271,7 @@ public:
|
||||||
ParNamed.Reset(); // safety :)
|
ParNamed.Reset(); // safety :)
|
||||||
} // constructor
|
} // constructor
|
||||||
|
|
||||||
|
void ParseFn(bool fExprOnly = false, C4AulScriptContext* context = NULL);
|
||||||
virtual void UnLink();
|
virtual void UnLink();
|
||||||
|
|
||||||
virtual bool GetPublic() { return true; }
|
virtual bool GetPublic() { return true; }
|
||||||
|
@ -286,11 +288,11 @@ public:
|
||||||
StdStrBuf GetFullName(); // get a fully classified name (C4ID::Name) for debug output
|
StdStrBuf GetFullName(); // get a fully classified name (C4ID::Name) for debug output
|
||||||
int GetLineOfCode(C4AulBCC * bcc);
|
int GetLineOfCode(C4AulBCC * bcc);
|
||||||
C4AulBCC * GetCode();
|
C4AulBCC * GetCode();
|
||||||
C4AulScript * GetCodeOwner();
|
C4ScriptHost * GetCodeOwner();
|
||||||
|
|
||||||
time_t tProfileTime; // internally set by profiler
|
time_t tProfileTime; // internally set by profiler
|
||||||
|
|
||||||
friend class C4AulScript;
|
friend class C4ScriptHost;
|
||||||
};
|
};
|
||||||
|
|
||||||
// defined function class
|
// defined function class
|
||||||
|
@ -370,11 +372,6 @@ public:
|
||||||
// script class
|
// script class
|
||||||
class C4AulScript
|
class C4AulScript
|
||||||
{
|
{
|
||||||
// MSVC maybe needs this.
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
friend class C4AulScript;
|
|
||||||
#endif
|
|
||||||
friend class C4AulDebug;
|
|
||||||
public:
|
public:
|
||||||
C4AulScript(); // constructor
|
C4AulScript(); // constructor
|
||||||
virtual ~C4AulScript(); // destructor
|
virtual ~C4AulScript(); // destructor
|
||||||
|
@ -389,8 +386,8 @@ public:
|
||||||
enum Strict Strict; // new or even newer syntax?
|
enum Strict Strict; // new or even newer syntax?
|
||||||
bool Temporary; // set for DirectExec-scripts; do not parse those
|
bool Temporary; // set for DirectExec-scripts; do not parse those
|
||||||
|
|
||||||
const char *GetScript() const { return Script.getData(); }
|
|
||||||
virtual C4PropList * GetPropList() { return 0; }
|
virtual C4PropList * GetPropList() { return 0; }
|
||||||
|
virtual C4ScriptHost * GetScriptHost() { return 0; }
|
||||||
C4AulFunc *GetFuncRecursive(const char *pIdtf); // search function by identifier, including global funcs
|
C4AulFunc *GetFuncRecursive(const char *pIdtf); // search function by identifier, including global funcs
|
||||||
C4AulScriptFunc *GetSFunc(const char *pIdtf, C4AulAccess AccNeeded, bool fFailSafe = false); // get local sfunc, check access, check '~'-safety
|
C4AulScriptFunc *GetSFunc(const char *pIdtf, C4AulAccess AccNeeded, bool fFailSafe = false); // get local sfunc, check access, check '~'-safety
|
||||||
C4AulScriptFunc *GetSFunc(const char *pIdtf); // get local script function by name
|
C4AulScriptFunc *GetSFunc(const char *pIdtf); // get local script function by name
|
||||||
|
@ -412,6 +409,8 @@ public:
|
||||||
friend class C4AulScriptFunc;
|
friend class C4AulScriptFunc;
|
||||||
friend class C4AulScriptEngine;
|
friend class C4AulScriptEngine;
|
||||||
friend class C4AulParseState;
|
friend class C4AulParseState;
|
||||||
|
friend class C4AulDebug;
|
||||||
|
friend class C4ScriptHost;
|
||||||
|
|
||||||
// Translate a string using the script's lang table
|
// Translate a string using the script's lang table
|
||||||
std::string Translate(const std::string &text) const;
|
std::string Translate(const std::string &text) const;
|
||||||
|
@ -423,12 +422,7 @@ protected:
|
||||||
C4AulScriptEngine *Engine; //owning engine
|
C4AulScriptEngine *Engine; //owning engine
|
||||||
C4AulScript *Owner, *Prev, *Next, *Child0, *ChildL; // tree structure
|
C4AulScript *Owner, *Prev, *Next, *Child0, *ChildL; // tree structure
|
||||||
|
|
||||||
StdStrBuf Script; // script
|
|
||||||
std::vector<C4AulBCC> Code;
|
|
||||||
std::vector<const char *> PosForCode;
|
|
||||||
C4AulBCC * LastCode;
|
|
||||||
C4AulScriptState State; // script state
|
C4AulScriptState State; // script state
|
||||||
bool Preparsing; // set while preparse
|
|
||||||
bool Resolving; // set while include-resolving, to catch circular includes
|
bool Resolving; // set while include-resolving, to catch circular includes
|
||||||
|
|
||||||
std::list<C4ID> Includes; // include list
|
std::list<C4ID> Includes; // include list
|
||||||
|
@ -438,27 +432,16 @@ protected:
|
||||||
C4AulFunc *GetOverloadedFunc(C4AulFunc *ByFunc);
|
C4AulFunc *GetOverloadedFunc(C4AulFunc *ByFunc);
|
||||||
C4AulFunc *GetFunc(const char *pIdtf); // get local function by name
|
C4AulFunc *GetFunc(const char *pIdtf); // get local function by name
|
||||||
|
|
||||||
void AddBCC(C4AulBCCType eType, intptr_t = 0, const char * SPos = 0); // add byte code chunk and advance
|
|
||||||
void RemoveLastBCC();
|
|
||||||
void ClearCode();
|
|
||||||
bool Preparse(); // preparse script; return if successfull
|
|
||||||
void ParseFn(C4AulScriptFunc *Fn, bool fExprOnly = false, C4AulScriptContext* context = NULL); // parse single script function
|
|
||||||
|
|
||||||
bool Parse(); // parse preparsed script; return if successfull
|
|
||||||
|
|
||||||
bool ResolveIncludes(C4DefList *rDefs); // resolve includes
|
bool ResolveIncludes(C4DefList *rDefs); // resolve includes
|
||||||
bool ResolveAppends(C4DefList *rDefs); // resolve appends
|
bool ResolveAppends(C4DefList *rDefs); // resolve appends
|
||||||
bool IncludesResolved;
|
bool IncludesResolved;
|
||||||
void AppendTo(C4AulScript &Scr, bool bHighPrio); // append to given script
|
void AppendTo(C4AulScript &Scr, bool bHighPrio); // append to given script
|
||||||
void UnLink(); // reset to unlinked state
|
virtual void UnLink(); // reset to unlinked state
|
||||||
virtual void AfterLink(); // called after linking is completed; presearch common funcs here
|
virtual void AfterLink(); // called after linking is completed; presearch common funcs here
|
||||||
virtual bool ReloadScript(const char *szPath, const char *szLanguage); // reload given script
|
virtual bool ReloadScript(const char *szPath, const char *szLanguage); // reload given script
|
||||||
|
virtual bool Parse();
|
||||||
|
|
||||||
C4AulScript *FindFirstNonStrictScript(); // find first script that is not #strict
|
C4AulScript *FindFirstNonStrictScript(); // find first script that is not #strict
|
||||||
|
|
||||||
int GetCodePos() const { return Code.size(); }
|
|
||||||
C4AulBCC *GetCodeByPos(int iPos) { return &Code[iPos]; }
|
|
||||||
C4AulBCC *GetLastCode() { return LastCode; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// holds all C4AulScripts
|
// holds all C4AulScripts
|
||||||
|
|
|
@ -267,17 +267,18 @@ void C4AulDebug::ProcessLine(const StdStrBuf &Line)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (script)
|
if (script && script->GetScriptHost())
|
||||||
{
|
{
|
||||||
C4AulBCC* foundDebugChunk = NULL;
|
C4AulBCC* foundDebugChunk = NULL;
|
||||||
const char* scriptText = script->GetScript();
|
C4ScriptHost * sh = script->GetScriptHost();
|
||||||
for (C4AulBCC* chunk = &script->Code[0]; chunk; chunk++)
|
const char* scriptText = sh->GetScript();
|
||||||
|
for (C4AulBCC* chunk = &sh->Code[0]; chunk; chunk++)
|
||||||
{
|
{
|
||||||
switch (chunk->bccType)
|
switch (chunk->bccType)
|
||||||
{
|
{
|
||||||
case AB_DEBUG:
|
case AB_DEBUG:
|
||||||
{
|
{
|
||||||
int lineOfThisOne = SGetLine(scriptText, script->PosForCode[chunk - &script->Code[0]]);
|
int lineOfThisOne = SGetLine(scriptText, sh->PosForCode[chunk - &sh->Code[0]]);
|
||||||
if (lineOfThisOne == line)
|
if (lineOfThisOne == line)
|
||||||
{
|
{
|
||||||
foundDebugChunk = chunk;
|
foundDebugChunk = chunk;
|
||||||
|
|
|
@ -1084,10 +1084,10 @@ C4Value C4AulDefFunc::Exec(C4AulContext *pCallerCtx, C4Value pPars[], bool fPass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class C4DirectExecScript: public C4AulScript
|
class C4DirectExecScript: public C4ScriptHost
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
C4DirectExecScript(C4AulScript * a, C4Object * pObj, const char *szContext): p(NULL)
|
C4DirectExecScript(C4AulScript * a, C4Object * pObj, const char *szContext, C4LangStringTable * stringTable): p(NULL)
|
||||||
{
|
{
|
||||||
ScriptName = FormatString("%s in %s", szContext, a->ScriptName.getData());
|
ScriptName = FormatString("%s in %s", szContext, a->ScriptName.getData());
|
||||||
Strict = a->Strict;
|
Strict = a->Strict;
|
||||||
|
@ -1100,6 +1100,7 @@ public:
|
||||||
}
|
}
|
||||||
// FIXME: calls from definitions
|
// FIXME: calls from definitions
|
||||||
ClearCode();
|
ClearCode();
|
||||||
|
this->stringTable = stringTable;
|
||||||
}
|
}
|
||||||
virtual C4PropList * GetPropList() { return p; }
|
virtual C4PropList * GetPropList() { return p; }
|
||||||
C4PropList * p;
|
C4PropList * p;
|
||||||
|
@ -1115,8 +1116,7 @@ C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char
|
||||||
// profiler
|
// profiler
|
||||||
AulExec.StartDirectExec();
|
AulExec.StartDirectExec();
|
||||||
// Create a new temporary script as child of this script
|
// Create a new temporary script as child of this script
|
||||||
C4AulScript* pScript = new C4DirectExecScript(this, pObj, szContext);
|
C4ScriptHost* pScript = new C4DirectExecScript(this, pObj, szContext, stringTable);
|
||||||
pScript->stringTable = stringTable;
|
|
||||||
pScript->Reg2List(Engine, this);
|
pScript->Reg2List(Engine, this);
|
||||||
// Add a new function
|
// Add a new function
|
||||||
C4AulScriptFunc *pFunc = new C4AulScriptFunc(pScript, 0);
|
C4AulScriptFunc *pFunc = new C4AulScriptFunc(pScript, 0);
|
||||||
|
@ -1125,7 +1125,8 @@ C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char
|
||||||
// Parse function
|
// Parse function
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pScript->ParseFn(pFunc, true, context);
|
assert(pFunc->GetCodeOwner() == pScript);
|
||||||
|
pFunc->ParseFn(true, context);
|
||||||
}
|
}
|
||||||
catch (C4AulError *ex)
|
catch (C4AulError *ex)
|
||||||
{
|
{
|
||||||
|
@ -1135,7 +1136,6 @@ C4Value C4AulScript::DirectExec(C4Object *pObj, const char *szScript, const char
|
||||||
delete pScript;
|
delete pScript;
|
||||||
return C4VNull;
|
return C4VNull;
|
||||||
}
|
}
|
||||||
pFunc->CodePos = 1;
|
|
||||||
pScript->State = ASS_PARSED;
|
pScript->State = ASS_PARSED;
|
||||||
// Execute. The TemporaryScript-parameter makes sure the script will be deleted later on.
|
// Execute. The TemporaryScript-parameter makes sure the script will be deleted later on.
|
||||||
C4Value vRetVal(AulExec.Exec(pFunc, pObj, NULL, fPassErrors, true));
|
C4Value vRetVal(AulExec.Exec(pFunc, pObj, NULL, fPassErrors, true));
|
||||||
|
|
|
@ -161,9 +161,6 @@ void C4AulScript::UnLink()
|
||||||
// do not unlink temporary (e.g., DirectExec-script in ReloadDef)
|
// do not unlink temporary (e.g., DirectExec-script in ReloadDef)
|
||||||
if (Temporary) return;
|
if (Temporary) return;
|
||||||
|
|
||||||
// check if byte code needs to be freed
|
|
||||||
ClearCode();
|
|
||||||
|
|
||||||
if (GetPropList()) GetPropList()->C4PropList::Clear();
|
if (GetPropList()) GetPropList()->C4PropList::Clear();
|
||||||
|
|
||||||
// delete included/appended functions
|
// delete included/appended functions
|
||||||
|
@ -181,10 +178,10 @@ void C4AulScript::UnLink()
|
||||||
|
|
||||||
pFunc = pNextFunc;
|
pFunc = pNextFunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// includes will have to be re-resolved now
|
// includes will have to be re-resolved now
|
||||||
IncludesResolved = false;
|
IncludesResolved = false;
|
||||||
|
|
||||||
|
|
||||||
if (State > ASS_PREPARSED) State = ASS_PREPARSED;
|
if (State > ASS_PREPARSED) State = ASS_PREPARSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,7 +126,7 @@ class C4AulParseState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Type { PARSER, PREPARSER };
|
enum Type { PARSER, PREPARSER };
|
||||||
C4AulParseState(C4AulScriptFunc *Fn, C4AulScript * a, enum Type Type):
|
C4AulParseState(C4AulScriptFunc *Fn, C4ScriptHost * a, enum Type Type):
|
||||||
Fn(Fn), a(a), SPos(Fn ? Fn->Script : a->Script.getData()),
|
Fn(Fn), a(a), SPos(Fn ? Fn->Script : a->Script.getData()),
|
||||||
TokenType(ATT_INVALID),
|
TokenType(ATT_INVALID),
|
||||||
Done(false),
|
Done(false),
|
||||||
|
@ -138,7 +138,7 @@ public:
|
||||||
{ }
|
{ }
|
||||||
~C4AulParseState()
|
~C4AulParseState()
|
||||||
{ while (pLoopStack) PopLoop(); ClearToken(); }
|
{ while (pLoopStack) PopLoop(); ClearToken(); }
|
||||||
C4AulScriptFunc *Fn; C4AulScript * a;
|
C4AulScriptFunc *Fn; C4ScriptHost * a;
|
||||||
const char *SPos; // current position in the script
|
const char *SPos; // current position in the script
|
||||||
char Idtf[C4AUL_MAX_Identifier]; // current identifier
|
char Idtf[C4AUL_MAX_Identifier]; // current identifier
|
||||||
C4AulTokenType TokenType; // current token type
|
C4AulTokenType TokenType; // current token type
|
||||||
|
@ -271,8 +271,8 @@ C4AulParseError::C4AulParseError(C4AulParseState * state, const char *pMsg, cons
|
||||||
if (state->Fn->pOrgScript && state->SPos)
|
if (state->Fn->pOrgScript && state->SPos)
|
||||||
sMessage.AppendFormat(", %s:%d:%d)",
|
sMessage.AppendFormat(", %s:%d:%d)",
|
||||||
state->Fn->pOrgScript->ScriptName.getData(),
|
state->Fn->pOrgScript->ScriptName.getData(),
|
||||||
SGetLine(state->Fn->pOrgScript->Script.getData(), state->SPos),
|
SGetLine(state->Fn->pOrgScript->GetScript(), state->SPos),
|
||||||
SLineGetCharacters(state->Fn->pOrgScript->Script.getData(), state->SPos));
|
SLineGetCharacters(state->Fn->pOrgScript->GetScript(), state->SPos));
|
||||||
else
|
else
|
||||||
sMessage.AppendChar(')');
|
sMessage.AppendChar(')');
|
||||||
}
|
}
|
||||||
|
@ -281,8 +281,8 @@ C4AulParseError::C4AulParseError(C4AulParseState * state, const char *pMsg, cons
|
||||||
// Script name
|
// Script name
|
||||||
sMessage.AppendFormat(" (%s:%d:%d)",
|
sMessage.AppendFormat(" (%s:%d:%d)",
|
||||||
state->a->ScriptName.getData(),
|
state->a->ScriptName.getData(),
|
||||||
SGetLine(state->a->Script.getData(), state->SPos),
|
SGetLine(state->a->GetScript(), state->SPos),
|
||||||
SLineGetCharacters(state->a->Script.getData(), state->SPos));
|
SLineGetCharacters(state->a->GetScript(), state->SPos));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -749,7 +749,7 @@ static const char * GetTTName(C4AulBCCType e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4AulScript::AddBCC(C4AulBCCType eType, intptr_t X, const char * SPos)
|
void C4ScriptHost::AddBCC(C4AulBCCType eType, intptr_t X, const char * SPos)
|
||||||
{
|
{
|
||||||
// store chunk
|
// store chunk
|
||||||
C4AulBCC bcc;
|
C4AulBCC bcc;
|
||||||
|
@ -769,7 +769,7 @@ void C4AulScript::AddBCC(C4AulBCCType eType, intptr_t X, const char * SPos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4AulScript::RemoveLastBCC()
|
void C4ScriptHost::RemoveLastBCC()
|
||||||
{
|
{
|
||||||
C4AulBCC *pBCC = &Code.back();
|
C4AulBCC *pBCC = &Code.back();
|
||||||
switch (pBCC->bccType)
|
switch (pBCC->bccType)
|
||||||
|
@ -787,7 +787,7 @@ void C4AulScript::RemoveLastBCC()
|
||||||
LastCode = NULL;
|
LastCode = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4AulScript::ClearCode()
|
void C4ScriptHost::ClearCode()
|
||||||
{
|
{
|
||||||
while(Code.size() > 0)
|
while(Code.size() > 0)
|
||||||
RemoveLastBCC();
|
RemoveLastBCC();
|
||||||
|
@ -805,12 +805,19 @@ C4AulBCC * C4AulScriptFunc::GetCode()
|
||||||
return &GetCodeOwner()->Code[CodePos];
|
return &GetCodeOwner()->Code[CodePos];
|
||||||
}
|
}
|
||||||
|
|
||||||
C4AulScript * C4AulScriptFunc::GetCodeOwner()
|
C4ScriptHost * C4AulScriptFunc::GetCodeOwner()
|
||||||
{
|
{
|
||||||
return Owner == Owner->Engine ? LinkedTo->Owner : Owner;
|
if (Owner == Owner->Engine)
|
||||||
|
{
|
||||||
|
return LinkedTo->Owner->GetScriptHost();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Owner->GetScriptHost();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool C4AulScript::Preparse()
|
bool C4ScriptHost::Preparse()
|
||||||
{
|
{
|
||||||
// handle easiest case first
|
// handle easiest case first
|
||||||
if (State < ASS_NONE) return false;
|
if (State < ASS_NONE) return false;
|
||||||
|
@ -825,7 +832,7 @@ bool C4AulScript::Preparse()
|
||||||
// belongs to this script?
|
// belongs to this script?
|
||||||
if (Func0->SFunc())
|
if (Func0->SFunc())
|
||||||
if (Func0->SFunc()->pOrgScript == this)
|
if (Func0->SFunc()->pOrgScript == this)
|
||||||
// then desroy linked funcs, too
|
// then destroy linked funcs, too
|
||||||
Func0->DestroyLinked();
|
Func0->DestroyLinked();
|
||||||
// destroy func
|
// destroy func
|
||||||
delete Func0;
|
delete Func0;
|
||||||
|
@ -840,9 +847,6 @@ bool C4AulScript::Preparse()
|
||||||
Engine->nonStrictCnt++;
|
Engine->nonStrictCnt++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// done, reset state var
|
|
||||||
Preparsing=false;
|
|
||||||
|
|
||||||
// #include will have to be resolved now...
|
// #include will have to be resolved now...
|
||||||
IncludesResolved = false;
|
IncludesResolved = false;
|
||||||
|
|
||||||
|
@ -1259,20 +1263,19 @@ void C4AulParseState::UnexpectedToken(const char * Expected)
|
||||||
throw new C4AulParseError(this, FormatString("%s expected, but found %s", Expected, GetTokenName(TokenType)).getData());
|
throw new C4AulParseError(this, FormatString("%s expected, but found %s", Expected, GetTokenName(TokenType)).getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void C4AulScript::ParseFn(C4AulScriptFunc *Fn, bool fExprOnly, C4AulScriptContext* context)
|
void C4AulScriptFunc::ParseFn(bool fExprOnly, C4AulScriptContext* context)
|
||||||
{
|
{
|
||||||
// check if fn overloads other fn (all func tables are built now)
|
// check if fn overloads other fn (all func tables are built now)
|
||||||
// *MUST* check Fn->Owner-list, because it may be the engine (due to linked globals)
|
// *MUST* check Fn->Owner-list, because it may be the engine (due to linked globals)
|
||||||
if ((Fn->OwnerOverloaded = Fn->Owner->GetOverloadedFunc(Fn)))
|
if ((OwnerOverloaded = Owner->GetOverloadedFunc(this)))
|
||||||
if (Fn->Owner == Fn->OwnerOverloaded->Owner)
|
if (Owner == OwnerOverloaded->Owner)
|
||||||
Fn->OwnerOverloaded->OverloadedBy=Fn;
|
OwnerOverloaded->OverloadedBy=this;
|
||||||
// store byte code pos
|
// store byte code pos
|
||||||
// (relative position to code start; code pointer may change while
|
// (relative position to code start; code pointer may change while
|
||||||
// parsing)
|
// parsing)
|
||||||
assert(Fn->GetCodeOwner() == this);
|
CodePos = GetCodeOwner()->Code.size();
|
||||||
Fn->CodePos = Code.size();
|
|
||||||
// parse
|
// parse
|
||||||
C4AulParseState state(Fn, this, C4AulParseState::PARSER);
|
C4AulParseState state(this, GetCodeOwner(), C4AulParseState::PARSER);
|
||||||
state.ContextToExecIn = context;
|
state.ContextToExecIn = context;
|
||||||
// get first token
|
// get first token
|
||||||
state.Shift();
|
state.Shift();
|
||||||
|
@ -1281,7 +1284,7 @@ void C4AulScript::ParseFn(C4AulScriptFunc *Fn, bool fExprOnly, C4AulScriptContex
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.Parse_Expression();
|
state.Parse_Expression();
|
||||||
AddBCC(AB_RETURN, 0, state.SPos);
|
GetCodeOwner()->AddBCC(AB_RETURN, 0, state.SPos);
|
||||||
}
|
}
|
||||||
// done
|
// done
|
||||||
return;
|
return;
|
||||||
|
@ -2927,17 +2930,22 @@ void C4AulParseState::Parse_Const()
|
||||||
|
|
||||||
bool C4AulScript::Parse()
|
bool C4AulScript::Parse()
|
||||||
{
|
{
|
||||||
|
// parse children
|
||||||
|
C4AulScript *s = Child0;
|
||||||
|
while (s) { s->Parse(); s = s->Next; }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool C4ScriptHost::Parse()
|
||||||
|
{
|
||||||
|
C4AulScript::Parse();
|
||||||
if (DEBUG_BYTECODE_DUMP)
|
if (DEBUG_BYTECODE_DUMP)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "parsing %s...\n", ScriptName.getData());
|
fprintf(stderr, "parsing %s...\n", ScriptName.getData());
|
||||||
}
|
}
|
||||||
// parse children
|
|
||||||
C4AulScript *s = Child0;
|
|
||||||
while (s) { s->Parse(); s = s->Next; }
|
|
||||||
// check state
|
// check state
|
||||||
if (State != ASS_LINKED) return false;
|
if (State != ASS_LINKED) return false;
|
||||||
// don't parse global funcs again, as they're parsed already through links
|
|
||||||
if (this == Engine) return false;
|
|
||||||
// delete existing code
|
// delete existing code
|
||||||
ClearCode();
|
ClearCode();
|
||||||
|
|
||||||
|
@ -2958,7 +2966,8 @@ bool C4AulScript::Parse()
|
||||||
// parse function
|
// parse function
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ParseFn(Fn);
|
assert(Fn->GetCodeOwner() == this);
|
||||||
|
Fn->ParseFn();
|
||||||
}
|
}
|
||||||
catch (C4AulError *err)
|
catch (C4AulError *err)
|
||||||
{
|
{
|
||||||
|
@ -3074,7 +3083,7 @@ bool C4AulScript::Parse()
|
||||||
C4AulScript *C4AulScript::FindFirstNonStrictScript()
|
C4AulScript *C4AulScript::FindFirstNonStrictScript()
|
||||||
{
|
{
|
||||||
// self is not #strict?
|
// self is not #strict?
|
||||||
if (Script && Strict < MAXSTRICT) return this;
|
if (Strict < MAXSTRICT) return this;
|
||||||
// search children
|
// search children
|
||||||
C4AulScript *pNonStrScr;
|
C4AulScript *pNonStrScr;
|
||||||
for (C4AulScript *pScr=Child0; pScr; pScr=pScr->Next)
|
for (C4AulScript *pScr=Child0; pScr; pScr=pScr->Next)
|
||||||
|
|
|
@ -35,13 +35,21 @@
|
||||||
|
|
||||||
/*--- C4ScriptHost ---*/
|
/*--- C4ScriptHost ---*/
|
||||||
|
|
||||||
C4ScriptHost::C4ScriptHost() { }
|
C4ScriptHost::C4ScriptHost()
|
||||||
|
{
|
||||||
|
Script = NULL;
|
||||||
|
Code.clear();
|
||||||
|
LastCode = NULL;
|
||||||
|
stringTable = 0;
|
||||||
|
}
|
||||||
C4ScriptHost::~C4ScriptHost() { Clear(); }
|
C4ScriptHost::~C4ScriptHost() { Clear(); }
|
||||||
|
|
||||||
void C4ScriptHost::Clear()
|
void C4ScriptHost::Clear()
|
||||||
{
|
{
|
||||||
C4AulScript::Clear();
|
C4AulScript::Clear();
|
||||||
ComponentHost.Clear();
|
ComponentHost.Clear();
|
||||||
|
Script.Clear();
|
||||||
|
ClearCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool C4ScriptHost::Load(C4Group &hGroup, const char *szFilename,
|
bool C4ScriptHost::Load(C4Group &hGroup, const char *szFilename,
|
||||||
|
|
|
@ -38,11 +38,31 @@ public:
|
||||||
void Clear();
|
void Clear();
|
||||||
bool Load(C4Group &hGroup, const char *szFilename,
|
bool Load(C4Group &hGroup, const char *szFilename,
|
||||||
const char *szLanguage, C4LangStringTable *pLocalTable);
|
const char *szLanguage, C4LangStringTable *pLocalTable);
|
||||||
|
const char *GetScript() const { return Script.getData(); }
|
||||||
|
virtual C4ScriptHost * GetScriptHost() { return this; }
|
||||||
protected:
|
protected:
|
||||||
void SetError(const char *szMessage);
|
void SetError(const char *szMessage);
|
||||||
void MakeScript();
|
void MakeScript();
|
||||||
bool ReloadScript(const char *szPath, const char *szLanguage);
|
bool ReloadScript(const char *szPath, const char *szLanguage);
|
||||||
C4ComponentHost ComponentHost;
|
C4ComponentHost ComponentHost;
|
||||||
|
|
||||||
|
|
||||||
|
void AddBCC(C4AulBCCType eType, intptr_t = 0, const char * SPos = 0); // add byte code chunk and advance
|
||||||
|
void RemoveLastBCC();
|
||||||
|
void ClearCode();
|
||||||
|
bool Preparse(); // preparse script; return if successfull
|
||||||
|
bool Parse(); // parse preparsed script; return if successfull
|
||||||
|
int GetCodePos() const { return Code.size(); }
|
||||||
|
C4AulBCC *GetCodeByPos(int iPos) { return &Code[iPos]; }
|
||||||
|
C4AulBCC *GetLastCode() { return LastCode; }
|
||||||
|
|
||||||
|
StdStrBuf Script; // script
|
||||||
|
std::vector<C4AulBCC> Code;
|
||||||
|
std::vector<const char *> PosForCode;
|
||||||
|
C4AulBCC * LastCode;
|
||||||
|
friend class C4AulParseState;
|
||||||
|
friend class C4AulScriptFunc;
|
||||||
|
friend class C4AulDebug;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue