#include "scriptengine.h" #include "lexer.h" #include "parser.h" #include "expression.h" #include #include #include #include ScriptEngine::ScriptEngine() : bRunning( true ) { } ScriptEngine::~ScriptEngine() { } void ScriptEngine::exec( const Bu::String &sExpr ) { Bu::StaticMemBuf mb( sExpr.getStr(), sExpr.getSize() ); exec( sExpr ); } void ScriptEngine::exec( Bu::Stream &sInput ) { Lexer l( sInput ); Parser p( l ); Expression *pExp = p.parse(); exec( pExp ); delete pExp; } void ScriptEngine::exec( Expression *pExpr ) { NumStack sNums; for( Expression::iterator i = pExpr->begin(); i; i++ ) { // Bu::sio << (*i).eType << " - " << sNums << Bu::sio.nl; if( ((*i).eType&Token::mMetaCmd) ) { command( i ); continue; } switch( (*i).eType ) { case Token::tNumber: sNums.push( *(*i).nVal ); break; case Token::tVariable: if( hVarState.has( *(*i).sVal ) ) { sNums.push( hVarState[*(*i).sVal] ); } else { if( sigError.isSet() ) sigError( Bu::String("No such variable: $%1"). arg(*(*i).sVal) ); return; } break; case Token::tPlus: { Number b = sNums.peekPop(); Number a = sNums.peekPop(); sNums.push( a + b ); } break; case Token::tMinus: { Number b = sNums.peekPop(); Number a = sNums.peekPop(); sNums.push( a - b ); } break; case Token::tDivide: { Number b = sNums.peekPop(); Number a = sNums.peekPop(); sNums.push( a / b ); } break; case Token::tMultiply: { Number b = sNums.peekPop(); Number a = sNums.peekPop(); sNums.push( a * b ); } break; case Token::tNegate: sNums.push( -sNums.peekPop() ); break; } } if( sigNumResult.isSet() && !sNums.isEmpty() ) sigNumResult( sNums.peekPop() ); } void ScriptEngine::command( Expression::iterator &i ) { switch( (*i).eType ) { case Token::tCmdExit: bRunning = false; return; case Token::tCmdScale: { if( !(++i) ) { if( sigError.isSet() ) sigError("You must provide a positive integer."); return; } int32_t iScale = strtol( (*i).sVal->getStr(), 0, 10 ); if( iScale < 0 ) { if( sigError.isSet() ) sigError("You must provide a positive integer."); return; } if( sigMessage.isSet() ) sigMessage(Bu::String("Changed scale to: %1").arg( iScale )); for( VarHash::iterator j = hVarState.begin(); j; j++ ) (*j).setScale( iScale ); i++; } break; case Token::tCmdRadix: { if( !(++i) ) { if( sigError.isSet() ) sigError("You must provide a positive integer."); return; } int32_t iRadix = strtol( (*i).sVal->getStr(), 0, 10 ); if( iRadix < 0 ) { if( sigError.isSet() ) sigError("You must provide a positive integer."); return; } if( sigMessage.isSet() ) sigMessage(Bu::String("Changed radix to: %1").arg( iRadix )); hVarState.clear(); // for( VarHash::iterator i = hVarState.begin(); i; i++ ) // (*i).setRadix( iRadix ); i++; } break; case Token::tCmdExtended: /* else if( sCmd == "vars" ) { } else if( sCmd == "help" || sCmd == "?" ) { } else { }*/ break; } if( (*i).eType != Token::tCmdEndParams ) sigError("Too many parameters."); }