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

📄 interpreter.cpp

📁 自己寫一個語言分析解釋器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      for( int i = 0; i < m_nFunctions; i++ ) {
         if( tName == m_Functions[i].szName ) {
            int iStack = __pushstack();
            tok.Assign(m_Functions[i].pstrCode, m_Functions[i].iLineNo);
            int i = 0;
            t = tok.GetToken();
            while( t == OP_INDENTIFIER ) {
               _variant_t v;
               if( i < nArgs ) v = args[i++];
               __var_define(t, v);
               t = tok.GetToken();
               if( t == OP_COMMA ) t = tok.GetToken();
               else if( t != OP_PAREN_R ) throw EXCEP_PAREN;
            }
            if( t != OP_PAREN_R ) throw EXCEP_PAREN;
            if( tok.GetToken() != OP_BRACE_L ) throw EXCEP_PAREN;
            try {
               __exec(OP_BRACE_R);
            }
            catch( EXCEP e ) {
               if( e != EXCEP_RETURN ) throw e;
               else ::VariantCopy(pVar, &m_Stack[iStack - 1].vRet);
            }
            __popstack(iStack);
            return;
         }
      }
      for( i = 0; i < m_nObjects; i++ ) {
         if( wcslen(m_Objects[i].szName) == 0 ) {
            if( m_Objects[i].pCallback->Method(tName, args, nArgs, pVar) ) {
               if( pVar->vt == VT_ERROR ) throw EXCEP_ERROR;
               return;
            }
         }
      }
   }
   else
   {
      for( i = 0; i < m_nObjects; i++ ) {
         if( wcslen(m_Objects[i].szName) == 0 ) {
            if( m_Objects[i].pCallback->GetProperty(tName, pVar) ) {
               if( pVar->vt == VT_ERROR || pVar->vt == VT_UNKNOWN ) throw EXCEP_ERROR;
               return;
            }
         }
      }
   }
   throw EXCEP_NOTFOUND;
}

void CScriptEngine::__break()
{
   throw EXCEP_BREAK;
}

void CScriptEngine::__return()
{
   if( m_nStackLevel == 0 ) throw EXCEP_SCOPE;
   STACKLEVEL& stack = m_Stack[m_nStackLevel - 1];
   t = tok.GetToken();
   __eval(&stack.vRet);
   if( t != OP_SEMICOLON ) throw EXCEP_SYNTAXERROR;
   for( int i = 0; i < m_nStackLevel - 1; i++ ) ::VariantCopy(&m_Stack[i].vRet, &stack.vRet);
   throw EXCEP_RETURN;
}

void CScriptEngine::__func_define()
{
   if( m_nStackLevel != 0 ) throw EXCEP_SCOPE;
   TOKEN tName = tok.GetToken();
   if( tName != OP_INDENTIFIER ) throw EXCEP_NAMEEXPECTED;
   for( int i = 0; i < m_nFunctions; i++ ) {
      if( t == m_Functions[i].szName ) throw EXCEP_DUPLICATE;
   }
   FUNCTIONDEF& func = m_Functions[m_nFunctions];
   wcscpy(func.szName, tName);
   if( tok.GetToken() != OP_PAREN_L ) throw EXCEP_PAREN;
   func.pstrCode = tok.m_pstr;
   func.iLineNo = tok.m_iLineNo;
   tok.SkipTo(t, OP_PAREN_R);
   if( t != OP_BRACE_L ) throw EXCEP_PAREN;
   tok.SkipTo(t, OP_BRACE_R);
   if( ++m_nFunctions >= MAX_FUNCTIONS ) throw EXCEP_CODEOVERFLOW;
}

void CScriptEngine::__var_getargs(VARIANT* pArgs, int& nArgs)
{
   int nMaxArgs = nArgs;
   nArgs = 0;
   while( t != OP_PAREN_R ) {
      if( nArgs >= nMaxArgs ) throw EXCEP_PARAMOVERFLOW;
      __level0(&pArgs[nArgs++]);
      if( t == OP_COMMA ) t = tok.GetToken();
      else if( t != OP_PAREN_R ) throw EXCEP_PAREN;
   }
   if( t != OP_PAREN_R ) throw EXCEP_PAREN;
   t = tok.GetToken();
}

void CScriptEngine::__var_define()
{
   do {
      TOKEN tName = tok.GetToken();
      if( tName != OP_INDENTIFIER ) throw EXCEP_NAMEEXPECTED;
      int iNameIndex = m_nStackLevel == 0 ? 0 : m_Stack[m_nStackLevel - 1].iVarIndex + 1;
      while( iNameIndex < m_nVars ) {
         if( tName == m_vars[iNameIndex++].szName ) throw EXCEP_DUPLICATE;
      }
      VARIABLE& var = m_vars[m_nVars];
      _variant_t v;
      __var_define(tName, v);
      t = tok.GetToken();
      if( t == OP_EQUAL ) {
         t = tok.GetToken();
         __level0(&var.vValue);
      }
   } while( t == OP_COMMA );
   if( t != OP_SEMICOLON ) throw EXCEP_SYNTAXERROR;
   t = tok.GetToken();
}

void CScriptEngine::__var_define(LPCWSTR pstrName, VARIANT& vValue)
{
   VARIABLE& var = m_vars[m_nVars];
   wcscpy(var.szName, pstrName);
   ::VariantInit(&var.vValue);
   ::VariantCopy(&var.vValue, &vValue);
   if( ++m_nVars >= MAX_VARIABLES ) throw EXCEP_CODEOVERFLOW;
}

void CScriptEngine::__forloop()
{
   if( tok.GetToken() != OP_PAREN_L ) throw EXCEP_PAREN;
   int iStack = __pushstack();
   t = tok.GetToken();
   if( t == OP_VAR ) __var_define(); else __var_assign();
   LPCWSTR pstrEval = tok.m_pstr;
   for( ; ; ) {
      t = tok.GetToken();
      _variant_t eval;
      __eval(&eval);
      if( eval != _variant_t(true) ) break;
      if( t != OP_SEMICOLON ) throw EXCEP_SYNTAXERROR;
      LPCWSTR pstrContinue = tok.m_pstr;
      tok.SkipTo(t, OP_PAREN_R);
      try {
         __block();
      }
      catch( EXCEP e ) {
         if( e == EXCEP_BREAK ) break;
         else throw e;
      }
      tok.m_pstr = pstrContinue;
      t = tok.GetToken();
      if( t != OP_PAREN_R ) __var_assign();
      if( t != OP_PAREN_R ) throw EXCEP_PAREN;
      tok.m_pstr = pstrEval;
   }
   __popstack(iStack);
   tok.SkipTo(t, OP_BRACE_R);
}

void CScriptEngine::__whileloop()
{
   t = tok.GetToken();
   if( t != OP_PAREN_L ) throw EXCEP_PAREN;
   int iStack = __pushstack();
   for( LPCWSTR pstrContinue = tok.m_pstr; ; tok.m_pstr = pstrContinue ) {
      t = tok.GetToken();
      _variant_t eval;
      __eval(&eval);
      if( eval != _variant_t(true) ) break;
      if( t != OP_PAREN_R ) throw EXCEP_PAREN;
      t = tok.GetToken();
      try {
         __block();
      }
      catch( EXCEP e ) {
         if( e == EXCEP_BREAK ) break;
         else throw e;
      }
   }
   __popstack(iStack);
   tok.SkipTo(t, OP_BRACE_R);
}

void CScriptEngine::__ifcondit()
{
   if( tok.GetToken() != OP_PAREN_L ) throw EXCEP_PAREN;
   t = tok.GetToken();
   _variant_t eval;
   __eval(&eval);
   t = tok.GetToken();
   if( eval == _variant_t(true) ) {
      __block();
      while( t == OP_ELSE ) {
         t = tok.GetToken();
         if( t == OP_IF ) {
            t = tok.GetToken();
            tok.SkipTo(t, OP_PAREN_R);
         }
         __skipblock();
      }
   }
   else {
      __skipblock();
      while( t == OP_ELSE ) {
         t = tok.GetToken();
         if( t == OP_IF ) __ifcondit();
         else __block();
      }
   }
}

void CScriptEngine::__switchcondit()
{
   if( tok.GetToken() != OP_PAREN_L ) throw EXCEP_PAREN;
   t = tok.GetToken();
   _variant_t eval;
   __eval(&eval);
   if( t != OP_PAREN_R ) throw EXCEP_PAREN;   
   int iStack = __pushstack();
   if( tok.GetToken() != OP_BRACE_L ) throw EXCEP_PAREN;
   t = tok.GetToken();
   while( t == OP_CASE ) {
      t = tok.GetToken();
      _variant_t val;
      __eval(&val);
      if( t != OP_COLON ) throw EXCEP_SYNTAXERROR;
      if( eval == val ) {
         try {
            __exec(OP_BRACE_R);
         }
         catch( EXCEP e ) {
            if( e != EXCEP_BREAK ) throw e;
         }
         break;
      }
      else {
         while( t != OP_CASE && t != OP_DEFAULT && t != OP_BRACE_R && t != OP_END ) __skipblock();
         if( t == OP_DEFAULT ) {
            if( tok.GetToken() != OP_COLON ) throw EXCEP_SYNTAXERROR;
            t = tok.GetToken();
            __block();
            break;
         }
      }
   }
   __popstack(iStack);
   tok.SkipTo(t, OP_BRACE_R);
   return;
}

void CScriptEngine::__skipblock()
{
   if( t == OP_BRACE_L ) tok.SkipTo(t, OP_BRACE_R);
   else tok.SkipTo(t, OP_SEMICOLON);
}

void CScriptEngine::__statement()
{
   switch( t ) {
   case OP_VAR:
      __var_define();
      break;
   case OP_INDENTIFIER:
      __var_assign();
      break;
   case OP_FUNCTION:
      __func_define();
      break;
   case OP_IF:
      __ifcondit();
      break;
   case OP_FOR:
      __forloop();
      break;
   case OP_WHILE:
      __whileloop();
      break;
   case OP_SWITCH:
      __switchcondit();
      break;
   case OP_BRACE_L:
      __block();
      break;
   case OP_BREAK:
      __break();
      break;
   case OP_RETURN:
      __return();
      return;
   case OP_SEMICOLON:
      t = tok.GetToken();
      break;
   default:
      throw EXCEP_KEYWORD;
   }
}

void CScriptEngine::__exec(OPTYPE Stop)
{
   t = tok.GetToken();
   while( t != OP_END && t != Stop ) {
      __statement();
      if( m_bCancelled ) throw EXCEP_CANCELLED;
   }
}

void CScriptEngine::__run(LPCWSTR pstrCode)
{
   try {
      tok.Assign(pstrCode, 1);
      __exec(OP_END);
   }
   catch( EXCEP e ) {
      _InterpretError(e);
   }
   catch( _com_error c ) {
      _InterpretError(EXCEP_TYPEMISMATCH);
   }
}

⌨️ 快捷键说明

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