102 #define ReturnIfTranslationAvailable(script, key) do \
104 const auto &s = script; \
105 const auto &k = key; \
110 return ::Strings.RegString(s->Translate(k).c_str()); \
112 catch (C4LangStringTable::NoSuchTranslation &) {} \
116 if (!
text ||
text->GetData().isNull())
return nullptr;
118 if (_this && _this->
GetDef())
123 DebugLogF(R
"(WARNING: Translate: no translation for string "%s")", text->GetCStr());
127 #undef ReturnIfTranslationAvailable
140 if (pCtx->Obj == obj)
155 PushValue(pnPars[i]);
176 while (pCurCtx > pOldCtx)
181 PopValuesUntil(pPars - 1);
205 PushInt(pCPos->
Par.i);
209 PushBool(!!pCPos->
Par.i);
213 PushString(pCPos->
Par.s);
217 PushPropList(pCPos->
Par.p);
221 PushArray(pCPos->
Par.a);
225 PushFunction(pCPos->
Par.f);
233 PushValue(pCurVal[pCPos->
Par.i]);
236 pCurVal[pCPos->
Par.i] = pCurVal[0];
239 pCurVal[pCPos->
Par.i] = pCurVal[0];
248 throw C4AulExecError((std::string(
"syntax error: ") + pCPos->
Par.s->GetCStr()).c_str());
258 throw C4AulExecError(
"can't access local variables without this");
264 throw C4AulExecError(
"can't access local variables without this");
278 C4Value *pPropList = pCurVal - 1;
284 pPropList->
Set(pCurVal[0]);
320 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
328 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
329 if (!pPar2->_getInt())
332 if (pPar1->
_getInt()==INT32_MIN && pPar2->_getInt()==-1)
341 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
349 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
351 if (pPar1->
_getInt()==INT32_MIN && pPar2->_getInt()==-1)
353 if (pPar2->_getInt())
363 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
371 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
379 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
387 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
395 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
403 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
411 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
419 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
426 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
433 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
441 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
449 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
457 C4Value *pPar1 = pCurVal - 1, *pPar2 = pCurVal;
469 for (
int i = 0; i < pCPos->
Par.i; i++)
470 (*pArray)[i] = pCurVal[i - pCPos->
Par.i + 1];
473 PopValues(pCPos->
Par.i);
483 for (
int i = 0; i < pCPos->
Par.i; i++)
484 pPropList->
SetPropertyByS(pCurVal[-2 * i - 1]._getStr(), pCurVal[-2 * i]);
486 PopValues(pCPos->
Par.i * 2);
487 PushPropList(pPropList);
493 C4Value *pIndex = pCurVal, *pStruct = pCurVal - 1, *pResult = pCurVal - 1;
495 if(CheckArrayAccess(pStruct, pIndex) ==
C4V_Array)
502 C4PropList *pPropList = pStruct->_getPropList();
512 C4Value *pValue = pCurVal, *pIndex = pCurVal - 1, *pStruct = pCurVal - 2, *pResult = pCurVal - 2;
514 if(CheckArrayAccess(pStruct, pIndex) ==
C4V_Array)
516 if (pStruct->_getArray()->IsFrozen())
518 pStruct->_getArray()->SetItem(pIndex->_getInt(), *pValue);
523 C4PropList *pPropList = pStruct->_getPropList();
536 C4Value &StartIndex = pCurVal[-1];
537 C4Value &EndIndex = pCurVal[0];
557 C4Value &StartIndex = pCurVal[-2];
558 C4Value &EndIndex = pCurVal[-1];
580 if (pCPos->
Par.i < 0)
581 PopValues(-pCPos->
Par.i);
583 PushNullVals(pCPos->
Par.i);
588 pCPos += pCPos->
Par.i;
595 pCPos += pCPos->
Par.i;
607 pCPos += pCPos->
Par.i;
617 if (pCurVal[0].GetType() !=
C4V_Nil)
620 pCPos += pCPos->
Par.i;
633 pCPos += pCPos->
Par.i;
642 pCPos += pCPos->
Par.i;
650 if (iTraceStart >= 0)
653 Buf.AppendChars(
'>', ContextStackSize() - iTraceStart);
664 PopValuesUntil(pCurCtx->
Pars - 1);
670 if (pCurVal != pReturn)
671 pReturn->
Set(*pCurVal);
677 PopValuesUntil(pReturn);
680 pCPos = pCurCtx->
CPos + 1;
692 pCurCtx->
CPos = pCPos;
695 C4AulBCC *pJump = Call(pFunc, pPars, pPars,
nullptr);
718 PushPropList(pCurCtx->
Obj);
725 int iItem = pCurVal->
_getInt();
729 if (!pCurVal[-1].CheckConversion(
C4V_Array))
737 pCurVal[pCPos->
Par.i] = pArray->
GetItem(iItem);
739 pCurVal->
SetInt(iItem + 1);
765 PopValuesUntil(pTargetVal);
775 pCurCtx->
CPos = pCPos;
780 PopValues(pCurVal + 1 - pPars - pFunc->
GetParCount());
782 PushNullVals(pFunc->
GetParCount() - (pCurVal + 1 - pPars));
785 C4AulBCC *pNewCPos = Call(pFunc, pTargetVal, pPars, pDest);
799 pDebug->DebugStep(pCPos, pCurVal);
814 pCurCtx->
CPos = pCPos;
824 assert(pCurCtx >= Contexts);
825 pContext = pCurCtx->
Obj;
850 if (pContext && !pContext->
Status)
868 sCallText.
Append(
"(Snull)");
872 sCallText.Append(s->GetData());
888 if (pReturn > pCurVal)
889 PushValue(pFunc->
Exec(pContext, pPars,
true));
891 pReturn->
Set(pFunc->
Exec(pContext, pPars,
true));
893 assert(pCtx == pCurCtx);
897 PopValuesUntil(pReturn);
908 iTraceStart = ContextStackSize();
911 void C4AulExec::StartProfiling(
C4ScriptHost *pProfiledScript)
914 if (fProfiling) StopProfiling();
917 this->pProfiledScript = pProfiledScript;
919 tDirectExecStart = tNow;
920 tDirectExecTotal = 0;
929 *++pCurCtx = rContext;
931 if (iTraceStart >= 0)
934 Buf.AppendChars(
'>', ContextStackSize() - iTraceStart);
941 void C4AulExec::PopContext()
943 if (pCurCtx < Contexts)
953 if (iTraceStart >= 0)
955 if (ContextStackSize() <= iTraceStart)
965 AulExec.StartProfiling(pScript);
974 if (!
AulExec.IsProfiling())
return;
978 Profiler.CollectEntry(
nullptr,
AulExec.tDirectExecTotal);
982 Profiler.CollectTimes();
986 void C4AulProfiler::CollectEntry(
C4AulScriptFunc *pFunc, uint32_t tProfileTime)
989 if (!tProfileTime)
return;
997 void C4AulProfiler::Show()
1000 std::sort(Times.rbegin(), Times.rend());
1002 Log(
"Profiler statistics:");
1003 Log(
"==============================");
1004 for (
auto & e : Times)
1006 LogF(
"%05ums\t%s", e.tProfileTime, e.pFunc ? (e.pFunc->GetFullName().getData()) :
"Direct exec");
1008 Log(
"==============================");
1025 else if (p && p->
GetDef())
1028 auto pFunc = std::make_unique<C4AulScriptFunc>(script,
nullptr,
nullptr, szScript);
1077 void C4AulProfiler::ResetTimes()
1083 ResetTimes(pScript->GetPropList());
1086 void C4AulProfiler::CollectTimes()
1092 CollectTimes(pScript->GetPropList());
#define ReturnIfTranslationAvailable(script, key)
const int MAX_CONTEXT_STACK
C4AulScriptEngine ScriptEngine
constexpr bool DEBUGREC_SCRIPT
bool Log(const char *szMessage)
bool DebugLog(const char *strMessage)
bool LogF(const char *strMessage,...)
bool DebugLogF(const char *strMessage ...)
void AddDbgRec(C4RecordChunkType eType, const void *pData, int iSize)
C4GameScriptHost GameScript
int SGetLine(const char *szText, const char *cpPosition)
int Pow(int base, int exponent)
StdStrBuf FormatString(const char *szFmt,...)
static C4AulDebug * GetDebugger()
virtual void OnError(const char *msg)=0
const char * what() const noexcept override
C4AulExecError(const char *szError)
void ClearPointers(C4Object *)
static bool FnLogCallStack(C4PropList *_this)
C4AulScriptContext * GetContext(int iLevel)
C4Value DirectExec(C4PropList *p, const char *szScript, const char *szContext, bool fPassErrors=false, C4AulScriptContext *context=nullptr, bool parse_function=false)
C4Value Exec(C4AulScriptFunc *pSFunc, C4PropList *p, C4Value pPars[], bool fPassErrors)
static C4String * FnTranslate(C4PropList *_this, C4String *text)
int GetContextDepth() const
const char * GetName() const
virtual C4AulScriptFunc * SFunc()
bool CheckParTypes(const C4Value pPars[], bool fPassErrors) const
C4Value Exec(C4PropList *p=nullptr, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
C4PropListStatic * Parent
virtual int GetParCount() const
static void StopProfiling()
static void StartProfiling(C4ScriptHost *pScript)
C4AulErrorHandler * GetErrorHandler() const
C4PropListStatic * GetPropList()
C4ValueMapData GlobalNamed
void ParseDirectExecStatement(C4AulScriptEngine *Engine, C4AulScriptContext *context=nullptr)
void ParseDirectExecFunc(C4AulScriptEngine *Engine, C4AulScriptContext *context=nullptr)
int GetLineOfCode(C4AulBCC *bcc)
C4ScriptHost * pOrgScript
int GetParCount() const override
C4PropListStatic * GetPropList() override
virtual C4Object * GetObject()
C4AulFunc * GetFunc(C4PropertyName k) const
virtual class C4PropListStatic * IsStatic()
C4String * EnumerateOwnFuncs(C4String *prev=nullptr) const
virtual bool GetPropertyByS(const C4String *k, C4Value *pResult) const
virtual C4PropListNumbered * GetPropListNumbered()
virtual C4Def const * GetDef() const
virtual void SetPropertyByS(C4String *k, const C4Value &to)
static C4PropList * New(C4PropList *prototype=nullptr)
StdStrBuf GetDataString() const
virtual C4PropListStatic * GetPropList()
const char * GetScript() const
static C4TimeMilliseconds Now()
const C4Value & GetItem(int32_t iElem) const
void SetSlice(int32_t startIndex, int32_t endIndex, const C4Value &Val)
C4ValueArray * GetSlice(int32_t startIndex, int32_t endIndex)
ALWAYS_INLINE bool CheckConversion(C4V_Type vtToType) const
StdStrBuf GetDataString(int depth=10, const class C4PropListStatic *ignore_reference_parent=nullptr) const
C4PropList * _getPropList() const
C4String * getStr() const
void SetArray(C4ValueArray *Array)
C4ValueArray * _getArray() const
bool IsIdenticalTo(const C4Value &cmp) const
void Set(const C4Value &nValue)
C4String * _getStr() const
const char * GetTypeName() const
C4Value * GetItem(const char *strName)
void AppendFormat(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
const char * getData() const
void AppendChar(char cChar)
void Append(const char *pnData, size_t iChars)
C4Value Par[C4AUL_MAX_Par]
void dump(StdStrBuf Dump=StdStrBuf(""))
StdStrBuf ReturnDump(StdStrBuf Dump=StdStrBuf(""))