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

📄 scriptengine.cpp

📁 自己寫一個語言分析解釋器
💻 CPP
字号:

#include "stdafx.h"

#include "ScriptEngine.h"


CScriptEngine::CScriptEngine() : 
   pstrStore(NULL), 
   pstrScript(NULL), 
   t(OP_END), 
   m_nVars(0), 
   m_nObjects(0),
   m_nStackLevel(0)
{
   ::CoInitialize(NULL);
   RegisterGlobals(this);
   Clear();
   Cancel();
}

CScriptEngine::~CScriptEngine()
{
   Clear();
   ::CoUninitialize();
}

void CScriptEngine::Clear()
{
   int i;
   for( i = 0; i < m_nVars; i++ ) ::VariantClear(&m_vars[i].vValue);
   for( i = 0; i < m_nStackLevel; i++ ) ::VariantClear(&m_Stack[i].vRet);
   m_nVars = 0;
   m_nFunctions = 0;
   m_nStackLevel = 0;
   m_bCancelled = false;
   ::ZeroMemory(m_szErrorMsg, sizeof(m_szErrorMsg));
   ::ZeroMemory(m_szErrorCode, sizeof(m_szErrorCode));
   ::ZeroMemory(m_szErrorLine, sizeof(m_szErrorLine));
   if( pstrStore != NULL ) free(pstrStore);
   pstrStore = NULL;
   pstrScript = NULL;
}

void CScriptEngine::Cancel()
{
   m_bCancelled = true;
}

bool CScriptEngine::RunScriptFromFile(LPCSTR pstrFilename)
{
   HANDLE hFile = ::CreateFile(pstrFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   if( hFile == INVALID_HANDLE_VALUE ) return false;
   DWORD dwSize = ::GetFileSize(hFile, NULL);
   LPSTR pstrCode = (LPSTR) malloc(dwSize + 1);
   DWORD dwRead = 0;
   ::ReadFile(hFile, pstrCode, dwSize, &dwRead, NULL);
   ::CloseHandle(hFile);
   if( dwRead != dwSize ) {
      free(pstrCode);
      return false;
   }
   pstrCode[dwSize] = '\0';
   bool bRes = RunScript(pstrCode);
   free(pstrCode);
   return bRes;
}

bool CScriptEngine::RunScript(LPCSTR pstrCode)
{
   Clear();
   int cchLen = strlen(pstrCode) + 1;
   pstrStore = pstrScript = (LPWSTR) malloc((sizeof(WCHAR) * cchLen));
   if( pstrStore == NULL ) return false;
   pstrStore[0] = '\0';
   ::MultiByteToWideChar(::GetACP(), 0, pstrCode, cchLen, pstrStore, cchLen);
   __run(pstrStore);
   return strlen(m_szErrorMsg) == 0;
}

bool CScriptEngine::Evaluate(LPCSTR pstrCode, VARIANT* pRet)
{ 
   ::ZeroMemory(m_szErrorMsg, sizeof(m_szErrorMsg));
   int cchLen = strlen(pstrCode) + 1;
   LPWSTR pwstr = pstrScript = (LPWSTR) malloc((sizeof(WCHAR) * cchLen));
   if( pwstr == NULL ) return false;
   pwstr[0] = '\0';
   ::MultiByteToWideChar(::GetACP(), 0, pstrCode, cchLen, pwstr, cchLen);
   int iStack = __pushstack();
   __run(pwstr);
   ::VariantCopy(pRet, &m_Stack[iStack - 1].vRet);
   __popstack(iStack);
   free(pwstr);
   return strlen(m_szErrorMsg) == 0;
}

bool CScriptEngine::RegisterObject(LPCSTR pstrName, IScriptCallback* pCallback)
{
   if( m_nObjects >= MAX_OBJECTS ) return false;
   CALLBACKDEF& obj = m_Objects[m_nObjects];
   ::ZeroMemory(&obj, sizeof(obj));
   ::MultiByteToWideChar(::GetACP(), 0, pstrName, -1, obj.szName, (sizeof(obj.szName) / sizeof(WCHAR)) -1);
   obj.pCallback = pCallback;
   m_nObjects++;
   return true;
}

bool CScriptEngine::RegisterGlobals(IScriptCallback* pCallback)
{
   return RegisterObject("", pCallback);
}

void CScriptEngine::GetErrorMessage(int& iLineNum, LPSTR pstrMessage, int cchMessage, LPSTR pstrCode, int cchCode, LPSTR pstrLine, int cchLine)
{
   iLineNum = m_iErrorLineNum;
   if( pstrMessage != NULL ) strncpy(pstrMessage, m_szErrorMsg, cchMessage);
   if( pstrCode != NULL ) strncpy(pstrCode, m_szErrorCode, cchCode);
   if( pstrLine != NULL ) strncpy(pstrLine, m_szErrorLine, cchLine);
}

void CScriptEngine::_InterpretError(EXCEP e)
{
   struct {
      EXCEP e;
      LPCTSTR pstrMessage;
   } Errors[] = 
   {
      { EXCEP_SYNTAXERROR,   "Syntax error" },
      { EXCEP_TYPEMISMATCH,  "Type mismatch" },
      { EXCEP_NAMEEXPECTED,  "Name exptected" },
      { EXCEP_CODEOVERFLOW,  "Compiler limitation reached" },
      { EXCEP_PARAMOVERFLOW, "Too many parameters" },
      { EXCEP_STACKOVERFLOW, "Stack overflow" },
      { EXCEP_SCOPE,         "Invalid scope" },
      { EXCEP_NOTFOUND,      "Undefined" },
      { EXCEP_KEYWORD,       "Keyword expected" },
      { EXCEP_DUPLICATE,     "Duplicated entry" },
      { EXCEP_PAREN,         "Parens mixup" },
      { EXCEP_ARGUMENTS,     "Bad arguments" },
      { EXCEP_ERROR,         "Error" },
      { EXCEP_BREAK,         "Unscoped break statement" },
      { EXCEP_RETURN,        "Unscoped return statement" },
      { EXCEP_CANCELLED,     "Cancelled" }
   };
   for( int i = 0; i < sizeof(Errors)/sizeof(Errors[0]); i++ ) {
      if( Errors[i].e == e ) strcpy(m_szErrorMsg, Errors[i].pstrMessage);
   }
   m_iErrorLineNum = tok.m_iLineNo;
   LPCWSTR p = tok.m_pstr - wcslen(t.value);
   if( p < pstrScript ) p = pstrScript;
   ::WideCharToMultiByte(::GetACP(), 0, p, -1, m_szErrorCode, sizeof(m_szErrorCode), NULL, NULL);
   while( p > pstrScript && *(p - 1) != '\n' ) p--;
   LPCWSTR pLen = p;
   while( *pLen != '\0' && *pLen != '\n' && *pLen != '\r' ) pLen++;
   ::WideCharToMultiByte(::GetACP(), 0, p, -1, m_szErrorLine, min(pLen - p, sizeof(m_szErrorLine) - 1), NULL, NULL);
}

⌨️ 快捷键说明

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