From 5d59aa3e9dffe2912215335ce0b76c67ebbe5a4e Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 1 Dec 2016 15:51:52 -0700 Subject: Signals solve many problems. The command structures will be changed, I think. I want the lexer to actually lex the command names into tokens, then the parser and the engine can both use them to update their state when necesarry. It will be less ambiguous and easier for both sides to stay synchronized. --- src/options.cpp | 15 +++++++++-- src/options.h | 4 +++ src/parser.cpp | 9 +++++++ src/scriptengine.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++-------- src/scriptengine.h | 26 +++++++++++++----- 5 files changed, 110 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/options.cpp b/src/options.cpp index 672858a..3ed2336 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -201,8 +201,9 @@ int Options::execute( Bu::StringArray aArgs ) Parser parser( lex ); Expression *pExp = parser.parse(); ScriptEngine se; - Number n = se.exec( pExp ); - Bu::println( n.toString() ); + se.sigError = Bu::slot( this, &Options::printError ); + se.sigNumResult = Bu::slot( this, &Options::printNumber ); + se.exec( pExp ); exit( 0 ); return aArgs.getSize(); } @@ -328,3 +329,13 @@ int Options::grind( Bu::StringArray aArgs ) return 0; } +void Options::printError( const Bu::String &sMsg ) +{ + Bu::println("ERROR: %1").arg( sMsg ); +} + +void Options::printNumber( const class Number &rNum ) +{ + Bu::println("%1").arg( rNum ); +} + diff --git a/src/options.h b/src/options.h index a7453ab..dc28190 100644 --- a/src/options.h +++ b/src/options.h @@ -24,6 +24,10 @@ private: int iScale; int iRadix; + +private: + void printError( const Bu::String &sMsg ); + void printNumber( const class Number &rNum ); }; #endif diff --git a/src/parser.cpp b/src/parser.cpp index e9388c8..982c342 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -199,6 +199,15 @@ void Parser::statement() if( lex[0].eType == Token::tCommand ) { lex.setMode( Lexer::modeCommand ); + output( lex[0] ); + for(;;) + { + lex.nextToken(); + if( lex[0].eType == Token::tEndOfLine || + lex[0].eType == Token::tEndOfInput ) + break; + output( lex[0] ); + } lex.setMode( Lexer::modeNormal ); } else diff --git a/src/scriptengine.cpp b/src/scriptengine.cpp index 65b6ec2..b65db70 100644 --- a/src/scriptengine.cpp +++ b/src/scriptengine.cpp @@ -5,8 +5,12 @@ #include #include +#include -ScriptEngine::ScriptEngine() +#include + +ScriptEngine::ScriptEngine() : + bRunning( true ) { } @@ -14,23 +18,22 @@ ScriptEngine::~ScriptEngine() { } -Number ScriptEngine::exec( const Bu::String &sExpr ) +void ScriptEngine::exec( const Bu::String &sExpr ) { Bu::StaticMemBuf mb( sExpr.getStr(), sExpr.getSize() ); - return exec( sExpr ); + exec( sExpr ); } -Number ScriptEngine::exec( Bu::Stream &sInput ) +void ScriptEngine::exec( Bu::Stream &sInput ) { Lexer l( sInput ); Parser p( l ); Expression *pExp = p.parse(); - Number n = exec( pExp ); + exec( pExp ); delete pExp; - return n; } -Number ScriptEngine::exec( Expression *pExpr ) +void ScriptEngine::exec( Expression *pExpr ) { NumStack sNums; @@ -49,9 +52,12 @@ Number ScriptEngine::exec( Expression *pExpr ) } else { - throw Bu::ExceptionBase( - Bu::String("No such variable: $%1").arg(*(*i).sVal).end().getStr() - ); + if( sigError.isSet() ) + sigError( + Bu::String("No such variable: $%1"). + arg(*(*i).sVal) + ); + return; } break; @@ -90,9 +96,56 @@ Number ScriptEngine::exec( Expression *pExpr ) case Token::tNegate: sNums.push( -sNums.peekPop() ); break; + + case Token::tCommand: + command( i ); + return; } } - return sNums.peekPop(); + if( sigNumResult.isSet() ) + sigNumResult( sNums.peekPop() ); +} + +void ScriptEngine::command( Expression::iterator &i ) +{ + Bu::String sCmd = *(*i).sVal; + if( sCmd == "exit" || sCmd == "quit" ) + { + bRunning = false; + return; + } + else if( sCmd == "scale" ) + { + 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 i = hVarState.begin(); i; i++ ) + (*i).setScale( iScale ); + } + else if( sCmd == "radix" ) + { + } + else if( sCmd == "vars" ) + { + } + else if( sCmd == "help" || sCmd == "?" ) + { + } + else + { + } } diff --git a/src/scriptengine.h b/src/scriptengine.h index 74924d6..b25c651 100644 --- a/src/scriptengine.h +++ b/src/scriptengine.h @@ -2,11 +2,12 @@ #define SCRIPT_ENGINE_H #include "number.h" +#include "expression.h" #include #include #include - +#include namespace Bu { @@ -16,18 +17,31 @@ class Expression; class ScriptEngine { +private: + typedef Bu::Hash VarHash; + typedef Bu::List NumStack; + public: ScriptEngine(); virtual ~ScriptEngine(); - Number exec( const Bu::String &sExpr ); - Number exec( Bu::Stream &sInput ); - Number exec( Expression *pExpr ); + void exec( const Bu::String &sExpr ); + void exec( Bu::Stream &sInput ); + void exec( Expression *pExpr ); + + bool isRunning() const { return bRunning; } + +public: + Bu::Signal1 sigNumResult; + Bu::Signal1 sigError; + Bu::Signal1 sigMessage; + +private: + void command( Expression::iterator &i ); private: - typedef Bu::Hash VarHash; - typedef Bu::List NumStack; VarHash hVarState; + bool bRunning; }; #endif -- cgit v1.2.3