⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compiledeval.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

#include "platform/platform.h"
#include "console/console.h"

#include "console/ast.h"
#include "core/tAlgorithm.h"
#include "core/resManager.h"

#include "core/findMatch.h"
#include "console/consoleInternal.h"
#include "core/fileStream.h"
#include "console/compiler.h"

#include "console/simBase.h"
#include "console/telnetDebugger.h"
#include "sim/netStringTable.h"

#include "console/stringStack.h"

using namespace Compiler;

enum EvalConstants {
   MaxStackSize = 1024
};

namespace Con
{
// Current script file name and root, these are registered as
// console variables.
extern StringTableEntry gCurrentFile;
extern StringTableEntry gCurrentRoot;
}

F64 floatStack[MaxStackSize];
U32 intStack[MaxStackSize];

StringStack STR;

U32 g_uFloatIP = 0;
U32 g_uIntIP = 0;

static const char *getNamespaceList(Namespace *ns)
{
   U32 size = 1;
   Namespace * walk;
   for(walk = ns; walk; walk = walk->mParent)
      size += dStrlen(walk->mName) + 4;
   char *ret = Con::getReturnBuffer(size);
   ret[0] = 0;
   for(walk = ns; walk; walk = walk->mParent)
   {
      dStrcat(ret, walk->mName);
      if(walk->mParent)
         dStrcat(ret, " -> ");
   }
   return ret;
}


//------------------------------------------------------------

F64 consoleStringToNumber(const char *str, StringTableEntry file, U32 line)
{
   F64 val = dAtof(str);
   if(val != 0)
      return val;
   else if(!dStricmp(str, "true"))
      return 1;
   else if(!dStricmp(str, "false"))
      return 0;
   else if(file)
   {
      Con::warnf(ConsoleLogEntry::General, "%s (%d): string always evaluates to 0.", file, line);
      return 0;
   }
   return 0;
}


//------------------------------------------------------------
#ifdef TGE_RPG_SCRIPT
#define TGE_USE_STACK
struct VStrSect
{
	char*		pSection;
	bool		bContent;
	int		cType;
};
static bool processVString(char* vStr,const char*& pOutput)
{
	char	*pPercent;
	pOutput = vStr;
	//pPercent = dStrstr(vStr,(const char*)"%");
	//if(pPercent == 0)
	//	return false;

	/*/////////////////////////////////////////////
	%var
	%f.var
	/*/////////////////////////////////////////////
	static Vector<VStrSect>  s_arSection;
	char	*pCurrent,
		//	*pPrev,
			*pVar,
			*pVar2,
			*pNew,
			*pContent;
	U32	nLen,nMax,n,nBufSize(0);
	char	szVar[256];
	char	cType;

#ifdef TGE_USE_STACK
	static StringStack  s_strStack;
	s_strStack.clear();
#endif
	s_arSection.clear();

	nMax = dStrlen(vStr);
	pCurrent = vStr;
	pPercent	= vStr;
	///*pPrev*/		= pCurrent;
	//for(; pPercent ; pPercent = dStrstr(pPercent,(const char*)"%") )
	for(; pPercent<vStr + nMax;)
	{
		if(*pPercent != '%' && *pPercent != '$')
		{	
			pPercent++;
			continue;
		}

		if(!dIsalpha(pPercent[1]) && pPercent[1] != '_')
		{
			pPercent += (pPercent[1] != 0? 2 : 1);
			continue;
		}

		nLen = pPercent - pCurrent;
		if(*pPercent == '%')
			pPercent ++; //跳过%符,$符不用跳

		//处理 %f.var格式
		if(pPercent[0] && pPercent[1] == '.')
		{	
			cType		= pPercent[0];
			pPercent += 2;
		}
		else
			cType		= 0;

		//变量处理
		if(dIsalpha(pPercent[0]) || pPercent[0] == '_'|| pPercent[0] == '%' || pPercent[0] == '$' )
			pVar = pPercent;
		else
		{
			//pPrev		= pCurrent;
			//pCurrent = pPercent+2;
			pPercent++;
			continue;
		}
		
		if(pPercent[0] == '%' && cType == 0)
			nLen++;
		if(nLen)
		{
			//保存%前的原字符串内容
#ifdef TGE_USE_STACK
			//s_strStack.advance();
			pNew = s_strStack.getStrBuffer(nLen+1);
#else
			pNew = new char[nLen+1];
			pNew[nLen] = 0;
#endif
			dStrncpy(pNew,pCurrent,nLen);
			nBufSize += nLen;

			s_arSection.increment();
			VStrSect& last = s_arSection.last();
			last.pSection	= pNew;
			last.bContent	= false;
			last.cType		= 0;
		}

		//%%转义符处理
		if(pPercent[0] == '%' && cType == 0)
		{
			//pCurrent = pPercent+2;
			//pPrev		= pCurrent;
			pPercent ++;
			pCurrent = pPercent;
			continue;
		}

		////////////////////////////////////
		//截取变量
		if(pVar[0] == '$')
			pVar2 = pVar+1;
		else
			pVar2=pVar;
		for(;pVar2[0] != 0 && (dIsalnum(pVar2[0]) || pVar2[0] == '_' || pVar2[0] == ':');pVar2++);
		nLen = pVar2 - pVar;
		dStrncpy(szVar,pVar,nLen);
		szVar[nLen] = 0;


		//获取变量内容
		if(szVar[0] == '$')
		{

			pContent = (char*)Con::getVariable((const char*)szVar);
		}
		else
		{
        //gEvalState.setCurVarNameCreate(szVar);
        //pContent = (char*)gEvalState.getStringVariable();

			pContent = (char*)Con::getLocalVariable((const char*)szVar);
			if(pContent == 0 || pContent[0] == 0)
				pContent = (char*)Con::getVariable((const char*)szVar);
		}

		//添加内容
		if(pContent)
		{
			s_arSection.increment();
			VStrSect& last = s_arSection.last();
			last.pSection	= pContent;
			last.bContent	= true;
			last.cType		= cType;
			nBufSize += dStrlen(pContent);
		}

		///*pPrev*/		= pCurrent;
		pCurrent = pVar2;
		pPercent = pVar2;
	}//for



	//直接返回,没有变量替换的话
	if(pCurrent == vStr)
		return true;
	
	//保存最的一段内容
	s_arSection.increment();
	VStrSect& last = s_arSection.last();
	last.pSection	= pCurrent;
	last.bContent	= true;
	last.cType		= 0;
	nBufSize += dStrlen(pCurrent);

	//consoleAlloc();
	///////////////////////////////////
	//内容连接
#ifdef TGE_USE_STACK
	//直接把内容写到STR中
	pContent = STR.getStrBuffer(nBufSize+1,false);
#else
	pContent = new char[nBufSize+1];
	pContent[nBufSize] = 0;
#endif
	pCurrent = pContent;
	for(n=0; n<s_arSection.size(); n++)
	{	
		pVar = s_arSection[n].pSection;
		switch(s_arSection[n].cType)
		{
		case 'b':
			dStrcpy(pCurrent,dAtob(pVar)?"true":"false");
			break;
		case 'd':
		case 'i':
			dSprintf(pCurrent,nBufSize - (pCurrent-pContent),"%d",dAtoi(pVar));
			break;
		case 'f':
		case 'g':
			dSprintf(pCurrent,nBufSize - (pCurrent-pContent),"%g",dAtof(pVar));
			break;
		case 's':
		default:
			dStrcpy(pCurrent,pVar);
			break;
		}
		pCurrent += dStrlen(pCurrent);
	}

#ifdef TGE_USE_STACK
	return false; //已经保存到STR中,无须再重做
#else
	//清除
	for(n=0; n<s_arSection.size(); n++)
	{	
		if(!s_arSection[n].bContent)
		{	
			//s_strStack.rewind();
			delete[] s_arSection[n].pSection;
		}
	}

	pOutput = pContent;
	return true;
#endif

}
#endif

//------------------------------------------------------------

namespace Con
{

   char *getReturnBuffer(U32 bufferSize)

   {
      return STR.getReturnBuffer(bufferSize);
   }

   char *getArgBuffer(U32 bufferSize)
   {
      return STR.getArgBuffer(bufferSize);
   }

   char *getFloatArg(F64 arg)
   {

      char *ret = STR.getArgBuffer(32);
      dSprintf(ret, 32, "%g", arg);
      return ret;
   }

   char *getIntArg(S32 arg)
   {

      char *ret = STR.getArgBuffer(32);
      dSprintf(ret, 32, "%d", arg);
      return ret;
   }
}

//------------------------------------------------------------

inline void ExprEvalState::setCurVarName(StringTableEntry name)
{
   if(name[0] == '$')
      currentVariable = globalVars.lookup(name);
   else if(stack.size())
      currentVariable = stack.last()->lookup(name);
   if(!currentVariable && gWarnUndefinedScriptVariables)
	   Con::warnf(ConsoleLogEntry::Script, "Variable referenced before assignment: %s", name);
}

inline void ExprEvalState::setCurVarNameCreate(StringTableEntry name)
{
   if(name[0] == '$')
      currentVariable = globalVars.add(name);
   else if(stack.size())
      currentVariable = stack.last()->add(name);
   else
   {
      currentVariable = NULL;
      Con::warnf(ConsoleLogEntry::Script, "Accessing local variable in global scope... failed: %s", name);
   }
}

//------------------------------------------------------------

inline S32 ExprEvalState::getIntVariable()
{
   return currentVariable ? currentVariable->getIntValue() : 0;
}

inline F64 ExprEvalState::getFloatVariable()
{
   return currentVariable ? currentVariable->getFloatValue() : 0;
}

inline const char *ExprEvalState::getStringVariable()
{
   return currentVariable ? currentVariable->getStringValue() : "";
}

//------------------------------------------------------------

inline void ExprEvalState::setIntVariable(S32 val)
{
   AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!");
   currentVariable->setIntValue(val);
}

inline void ExprEvalState::setFloatVariable(F64 val)
{
   AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!");
   currentVariable->setFloatValue(val);
}

inline void ExprEvalState::setStringVariable(const char *val)
{
   AssertFatal(currentVariable != NULL, "Invalid evaluator state - trying to set null variable!");
   currentVariable->setStringValue(val);
}

//------------------------------------------------------------

void CodeBlock::getFunctionArgs(char buffer[1024], U32 ip)
{
   U32 fnArgc = code[ip + 5];
   buffer[0] = 0;
   for(U32 i = 0; i < fnArgc; i++)
   {
      StringTableEntry var = U32toSTE(code[ip + i + 6]);
      
      // Add a comma so it looks nice!
      if(i != 0)
         dStrcat(buffer, ", ");

      dStrcat(buffer, "var ");

      // Try to capture junked parameters
      if(var[0])
        dStrcat(buffer, var+1);
      else
        dStrcat(buffer, "JUNK");
   }
}

const char *CodeBlock::exec(U32 ip, const char *functionName, Namespace *thisNamespace, U32 argc, const char **argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
{
   static char traceBuffer[1024];
   U32 i;

   incRefCount();
   F64 *curFloatTable;
   char *curStringTable;
   STR.clearFunctionOffset();
   StringTableEntry thisFunctionName = NULL;
   bool popFrame = false;
   if(argv)
   {
      // assume this points into a function decl:
      U32 fnArgc = code[ip + 5];
      thisFunctionName = U32toSTE(code[ip]);
      argc = getMin(argc-1, fnArgc); // argv[0] is func name
      if(gEvalState.traceOn)
      {
         traceBuffer[0] = 0;
         dStrcat(traceBuffer, "Entering ");
         if(packageName)
         {
            dStrcat(traceBuffer, "[");
            dStrcat(traceBuffer, packageName);
            dStrcat(traceBuffer, "]");
         }
         if(thisNamespace && thisNamespace->mName)
         {
            dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer),
               "%s::%s(", thisNamespace->mName, thisFunctionName);
         }
         else
         {
            dSprintf(traceBuffer + dStrlen(traceBuffer), sizeof(traceBuffer) - dStrlen(traceBuffer),
               "%s(", thisFunctionName);
         }
         for(i = 0; i < argc; i++)
         {
            dStrcat(traceBuffer, argv[i+1]);
            if(i != argc - 1)
               dStrcat(traceBuffer, ", ");
         }
         dStrcat(traceBuffer, ")");
         Con::printf("%s", traceBuffer);
      }
      gEvalState.pushFrame(thisFunctionName, thisNamespace);
      popFrame = true;
      for(i = 0; i < argc; i++)
      {
         StringTableEntry var = U32toSTE(code[ip + i + 6]);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -