📄 interpreter.cpp
字号:
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 + -