From 59f94f34ea25ce8613849bad43faf022b9ed5f5d Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 30 Dec 2011 11:00:04 -0700 Subject: Looks like commands work, mostly. --- src/astnode.cpp | 1 + src/astnode.h | 1 + src/command.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/command.h | 8 ++++++++ src/commandset.cpp | 17 +++++++++++++++++ src/commandset.h | 2 ++ src/game.cpp | 5 +++++ src/game.h | 2 ++ src/gamebuilder.cpp | 16 +++++++++++++--- src/gamebuilder.h | 1 + src/gamestate.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/gamestate.h | 2 ++ src/main.cpp | 10 ++++++++++ src/parser.y | 2 +- src/situation.cpp | 11 +++++++++++ src/situation.h | 8 +++++++- 16 files changed, 185 insertions(+), 5 deletions(-) diff --git a/src/astnode.cpp b/src/astnode.cpp index 88363c9..99f6a2e 100644 --- a/src/astnode.cpp +++ b/src/astnode.cpp @@ -41,6 +41,7 @@ Bu::Formatter &operator<<( Bu::Formatter &f, AstNode::Type t ) case AstNode::tIn: return f << "tIn"; case AstNode::tGoto: return f << "tGoto"; case AstNode::tSwap: return f << "tSwap"; + case AstNode::tStoreRev: return f << "tStoreRev"; case AstNode::tLeafLiteral: return f << "!tLeafLiteral!"; case AstNode::tVarName: return f << "tVarName"; diff --git a/src/astnode.h b/src/astnode.h index 63bf64f..7b9e928 100644 --- a/src/astnode.h +++ b/src/astnode.h @@ -31,6 +31,7 @@ public: tIn = 0x01000013, tGoto = 0x01000014, tSwap = 0x01000015, + tStoreRev = 0x01000016, tLeafLiteral = 0x02000000, tVarName = 0x02000001, diff --git a/src/command.cpp b/src/command.cpp index e81d307..2def02f 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -1,6 +1,7 @@ #include "command.h" #include "astbranch.h" +#include "gamestate.h" #include using namespace Bu; @@ -25,6 +26,18 @@ void Command::addParam( const Bu::String &sValue ) lChunks.append( Chunk( false, sValue ) ); } +Bu::StringList Command::getParamList() const +{ + Bu::StringList lRev; + for( ChunkList::const_iterator i = lChunks.begin(); i; i++ ) + { + if( !(*i).bLiteral ) + lRev.prepend( (*i).sValue ); + } + + return lRev; +} + void Command::setAst( class AstBranch *pAst ) { this->pAst = pAst; @@ -44,3 +57,39 @@ void Command::print() sio << *pAst << sio.nl; } +bool Command::matches( const Bu::StringList &lCmd ) +{ + ChunkList::iterator iChunk = lChunks.begin(); + Bu::StringList::const_iterator iCmd = lCmd.begin(); + + for( ; iChunk && iCmd; iChunk++, iCmd++ ) + { + if( (*iChunk).bLiteral ) + { + if( (*iChunk).sValue != *iCmd ) + return false; + } + } + + if( (bool)iChunk != (bool)iCmd ) + return false; + + return true; +} + +void Command::exec( class GameState &gState, const Bu::StringList &lCmd ) +{ + ChunkList::iterator iChunk = lChunks.begin(); + Bu::StringList::const_iterator iCmd = lCmd.begin(); + + for( ; iChunk && iCmd; iChunk++, iCmd++ ) + { + if( !(*iChunk).bLiteral ) + { + gState.push( Variable( *iCmd ) ); + } + } + + gState.parse( pAst ); +} + diff --git a/src/command.h b/src/command.h index f36fc14..f82e87e 100644 --- a/src/command.h +++ b/src/command.h @@ -12,10 +12,18 @@ public: void addLiteral( const Bu::String &sValue ); void addParam( const Bu::String &sValue ); + /** + * Get the list of parameters IN REVERSE ORDER. + */ + Bu::StringList getParamList() const; + void setAst( class AstBranch *pAst ); void print(); + bool matches( const Bu::StringList &lCmd ); + void exec( class GameState &gState, const Bu::StringList &lCmd ); + private: class Chunk { diff --git a/src/commandset.cpp b/src/commandset.cpp index ffd58a5..a125541 100644 --- a/src/commandset.cpp +++ b/src/commandset.cpp @@ -2,6 +2,9 @@ #include "command.h" +#include +using namespace Bu; + CommandSet::CommandSet() { } @@ -19,3 +22,17 @@ void CommandSet::addCommand( class Command *pCmd ) lCommand.append( pCmd ); } +bool CommandSet::dispatch( class GameState &gState, const Bu::StringList &lCmd ) +{ + for( CommandList::iterator i = lCommand.begin(); i; i++ ) + { + if( (*i)->matches( lCmd ) ) + { + (*i)->exec( gState, lCmd ); + return true; + } + } + + return false; +} + diff --git a/src/commandset.h b/src/commandset.h index 593d529..579e1d8 100644 --- a/src/commandset.h +++ b/src/commandset.h @@ -12,6 +12,8 @@ public: void addCommand( class Command *pCmd ); + bool dispatch( class GameState &gState, const Bu::StringList &lCmd ); + private: typedef Bu::List CommandList; CommandList lCommand; diff --git a/src/game.cpp b/src/game.cpp index 87d82b7..b9c7e08 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -38,6 +38,11 @@ Situation *Game::getSituation( const Bu::String &sName ) return hSituation.get( sName ); } +bool Game::execCommand( class GameState &gState, const Bu::StringList &lCmd ) +{ + return csGlobal.dispatch( gState, lCmd ); +} + void Game::addFunction( Function *pFunc ) { hFunction.insert( pFunc->getName(), pFunc ); diff --git a/src/game.h b/src/game.h index 675721c..8e2ec1b 100644 --- a/src/game.h +++ b/src/game.h @@ -20,6 +20,8 @@ public: Variable getParam( const Bu::String &sName ) const; Situation *getSituation( const Bu::String &sName ); + bool execCommand( class GameState &gState, const Bu::StringList &lCmd ); + private: void addFunction( Function *pFunc ); diff --git a/src/gamebuilder.cpp b/src/gamebuilder.cpp index 87389ff..e84d8f7 100644 --- a/src/gamebuilder.cpp +++ b/src/gamebuilder.cpp @@ -62,8 +62,7 @@ void GameBuilder::endFunctionParams() for( Bu::StringList::iterator i = lRev.begin(); i; i++ ) { addVarRef( *i, sidLocal ); - addNode( AstNode::tSwap ); - addNode( AstNode::tStore ); + addNode( AstNode::tStoreRev ); } } @@ -171,6 +170,17 @@ void GameBuilder::addCommandParam( const Bu::String &sValue ) pCurCmd->addParam( sValue ); } +void GameBuilder::endCommandParams() +{ + Bu::StringList lParams = pCurCmd->getParamList(); + + for( Bu::StringList::iterator i = lParams.begin(); i; i++ ) + { + addVarRef( *i, sidLocal ); + addNode( AstNode::tStoreRev ); + } +} + void GameBuilder::closeCommand() { pCurCmd->setAst( pCurRoot ); @@ -182,7 +192,7 @@ void GameBuilder::closeCommand() } else { - delete pCurCmd; + pCurSit->csLocal.addCommand( pCurCmd ); } pCurCmd = NULL; } diff --git a/src/gamebuilder.h b/src/gamebuilder.h index 9e40f48..b1e4d49 100644 --- a/src/gamebuilder.h +++ b/src/gamebuilder.h @@ -40,6 +40,7 @@ public: void beginCommand( const Bu::String &sValue ); void addCommandLiteral( const Bu::String &sValue ); void addCommandParam( const Bu::String &sValue ); + void endCommandParams(); void closeCommand(); private: diff --git a/src/gamestate.cpp b/src/gamestate.cpp index a3758ce..fa014ac 100644 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -65,6 +65,19 @@ void GameState::callFunction( const Bu::String &sName ) pGame->getFunction( sName )->call( *this ); } +void GameState::execCommand( const Bu::String &sCmd ) +{ + Bu::StringList lCmd = tokenize( sCmd ); + + if( !pGame->getSituation( sCurSituation )->execCommand( *this, lCmd ) ) + { + if( !pGame->execCommand( *this, lCmd ) ) + { + throw Bu::ExceptionBase("No such command exists."); + } + } +} + bool GameState::hasVariable( const Bu::String &sName, ScopeId id ) { switch( id ) @@ -169,6 +182,39 @@ Variable GameState::deref( const Variable &src ) return src; } +Bu::StringList GameState::tokenize( const Bu::String &sSrc ) +{ + Bu::StringList lRet; + Bu::String sToken; + bool bWs = true; + Bu::String::const_iterator i = sSrc.begin(); + + while( i ) + { + for(; i; i++ ) + { + if( *i != ' ' && *i != '\t' && *i != '\n' && *i != '\r' ) + break; + } + for(; i; i++ ) + { + if( i == ' ' || i == '\t' || *i == '\n' || *i == '\r' ) + { + break; + } + + sToken.append( *i ); + } + if( sToken.getSize() > 0 ) + { + lRet.append( sToken ); + sToken.clear(); + } + } + + return lRet; +} + Variable GameState::popDeref() { Variable v = lStack.peekPop(); @@ -245,6 +291,15 @@ void GameState::parse( const AstBranch::NodeList &lCode ) setVariable( r.sName, y, r.sid ); } break; + + case AstNode::tStoreRev: + { + Variable dst = pop(); + Variable y = popDeref(); + VariableRef r = dst.getVariableRef(); + setVariable( r.sName, y, r.sid ); + } + break; case AstNode::tAnd: { diff --git a/src/gamestate.h b/src/gamestate.h index 61e18e8..d88fecb 100644 --- a/src/gamestate.h +++ b/src/gamestate.h @@ -25,6 +25,7 @@ public: void push( const Variable &v ) { lStack.push( v ); } void callFunction( const Bu::String &sName ); + void execCommand( const Bu::String &sCmd ); bool hasVariable( const Bu::String &sName, ScopeId id ); void delVariable( const Bu::String &sName, ScopeId id ); @@ -32,6 +33,7 @@ public: void setVariable( const Bu::String &sName, const Variable &v, ScopeId id=sidLocal ); Variable deref( const Variable &src ); + Bu::StringList tokenize( const Bu::String &sSrc ); private: void parse( const AstBranch::NodeList &lCode ); diff --git a/src/main.cpp b/src/main.cpp index 8fe5247..2b20e66 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,6 +3,9 @@ #include "gamestate.h" #include "parser.tab.h" +#include +using namespace Bu; + typedef void *yyscan_t; void yylex_init( yyscan_t * ); void yylex_destroy( yyscan_t ); @@ -30,6 +33,13 @@ int main( int argc, char *argv[] ) GameState gs( pGame ); gs.init(); + char buf[1024]; + sio << ">>" << sio.flush; + fgets( buf, 1024, stdin ); + + sio << "Read: >" << buf << "<" << sio.nl; + gs.execCommand( buf ); + return 0; } diff --git a/src/parser.y b/src/parser.y index 484fd25..55a7968 100644 --- a/src/parser.y +++ b/src/parser.y @@ -249,7 +249,7 @@ dictValues: expr ':' expr ; commandDecl: tokCommand ':' tokString { bld.beginCommand( *$3 ); } - commandParamList '{' cmpltExprList '}' { bld.closeCommand(); } + commandParamList '{' { bld.endCommandParams(); } cmpltExprList '}' { bld.closeCommand(); } ; commandParamList: diff --git a/src/situation.cpp b/src/situation.cpp index 8221b50..86dd5c5 100644 --- a/src/situation.cpp +++ b/src/situation.cpp @@ -48,6 +48,17 @@ void Situation::exec( class GameState &gState, Situation::Mode m ) } } +void Situation::addCommand( Command *pCmd ) +{ + csLocal.addCommand( pCmd ); +} + +bool Situation::execCommand( class GameState &gState, + const Bu::StringList &lCmd ) +{ + return csLocal.dispatch( gState, lCmd ); +} + Bu::Formatter &operator<<( Bu::Formatter &f, Situation::Mode m ) { switch( m ) diff --git a/src/situation.h b/src/situation.h index 4d06fe6..365533a 100644 --- a/src/situation.h +++ b/src/situation.h @@ -3,8 +3,11 @@ #include +#include "commandset.h" + class Situation { +friend class GameBuilder; public: Situation( const Bu::String &sName ); virtual ~Situation(); @@ -18,11 +21,14 @@ public: }; void setAst( class AstBranch *pAst, Mode m ); - void exec( class GameState &gState, Mode m ); + void addCommand( Command *pCmd ); + bool execCommand( class GameState &gState, const Bu::StringList &lCmd ); + private: Bu::String sName; + CommandSet csLocal; class AstBranch *pAstSetup; class AstBranch *pAstEnter; }; -- cgit v1.2.3