summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/astnode.cpp1
-rw-r--r--src/astnode.h1
-rw-r--r--src/command.cpp49
-rw-r--r--src/command.h8
-rw-r--r--src/commandset.cpp17
-rw-r--r--src/commandset.h2
-rw-r--r--src/game.cpp5
-rw-r--r--src/game.h2
-rw-r--r--src/gamebuilder.cpp16
-rw-r--r--src/gamebuilder.h1
-rw-r--r--src/gamestate.cpp55
-rw-r--r--src/gamestate.h2
-rw-r--r--src/main.cpp10
-rw-r--r--src/parser.y2
-rw-r--r--src/situation.cpp11
-rw-r--r--src/situation.h8
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 )
41 case AstNode::tIn: return f << "tIn"; 41 case AstNode::tIn: return f << "tIn";
42 case AstNode::tGoto: return f << "tGoto"; 42 case AstNode::tGoto: return f << "tGoto";
43 case AstNode::tSwap: return f << "tSwap"; 43 case AstNode::tSwap: return f << "tSwap";
44 case AstNode::tStoreRev: return f << "tStoreRev";
44 45
45 case AstNode::tLeafLiteral: return f << "!tLeafLiteral!"; 46 case AstNode::tLeafLiteral: return f << "!tLeafLiteral!";
46 case AstNode::tVarName: return f << "tVarName"; 47 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:
31 tIn = 0x01000013, 31 tIn = 0x01000013,
32 tGoto = 0x01000014, 32 tGoto = 0x01000014,
33 tSwap = 0x01000015, 33 tSwap = 0x01000015,
34 tStoreRev = 0x01000016,
34 35
35 tLeafLiteral = 0x02000000, 36 tLeafLiteral = 0x02000000,
36 tVarName = 0x02000001, 37 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 @@
1#include "command.h" 1#include "command.h"
2 2
3#include "astbranch.h" 3#include "astbranch.h"
4#include "gamestate.h"
4 5
5#include <bu/sio.h> 6#include <bu/sio.h>
6using namespace Bu; 7using namespace Bu;
@@ -25,6 +26,18 @@ void Command::addParam( const Bu::String &sValue )
25 lChunks.append( Chunk( false, sValue ) ); 26 lChunks.append( Chunk( false, sValue ) );
26} 27}
27 28
29Bu::StringList Command::getParamList() const
30{
31 Bu::StringList lRev;
32 for( ChunkList::const_iterator i = lChunks.begin(); i; i++ )
33 {
34 if( !(*i).bLiteral )
35 lRev.prepend( (*i).sValue );
36 }
37
38 return lRev;
39}
40
28void Command::setAst( class AstBranch *pAst ) 41void Command::setAst( class AstBranch *pAst )
29{ 42{
30 this->pAst = pAst; 43 this->pAst = pAst;
@@ -44,3 +57,39 @@ void Command::print()
44 sio << *pAst << sio.nl; 57 sio << *pAst << sio.nl;
45} 58}
46 59
60bool Command::matches( const Bu::StringList &lCmd )
61{
62 ChunkList::iterator iChunk = lChunks.begin();
63 Bu::StringList::const_iterator iCmd = lCmd.begin();
64
65 for( ; iChunk && iCmd; iChunk++, iCmd++ )
66 {
67 if( (*iChunk).bLiteral )
68 {
69 if( (*iChunk).sValue != *iCmd )
70 return false;
71 }
72 }
73
74 if( (bool)iChunk != (bool)iCmd )
75 return false;
76
77 return true;
78}
79
80void Command::exec( class GameState &gState, const Bu::StringList &lCmd )
81{
82 ChunkList::iterator iChunk = lChunks.begin();
83 Bu::StringList::const_iterator iCmd = lCmd.begin();
84
85 for( ; iChunk && iCmd; iChunk++, iCmd++ )
86 {
87 if( !(*iChunk).bLiteral )
88 {
89 gState.push( Variable( *iCmd ) );
90 }
91 }
92
93 gState.parse( pAst );
94}
95
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:
12 void addLiteral( const Bu::String &sValue ); 12 void addLiteral( const Bu::String &sValue );
13 void addParam( const Bu::String &sValue ); 13 void addParam( const Bu::String &sValue );
14 14
15 /**
16 * Get the list of parameters IN REVERSE ORDER.
17 */
18 Bu::StringList getParamList() const;
19
15 void setAst( class AstBranch *pAst ); 20 void setAst( class AstBranch *pAst );
16 21
17 void print(); 22 void print();
18 23
24 bool matches( const Bu::StringList &lCmd );
25 void exec( class GameState &gState, const Bu::StringList &lCmd );
26
19private: 27private:
20 class Chunk 28 class Chunk
21 { 29 {
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 @@
2 2
3#include "command.h" 3#include "command.h"
4 4
5#include <bu/sio.h>
6using namespace Bu;
7
5CommandSet::CommandSet() 8CommandSet::CommandSet()
6{ 9{
7} 10}
@@ -19,3 +22,17 @@ void CommandSet::addCommand( class Command *pCmd )
19 lCommand.append( pCmd ); 22 lCommand.append( pCmd );
20} 23}
21 24
25bool CommandSet::dispatch( class GameState &gState, const Bu::StringList &lCmd )
26{
27 for( CommandList::iterator i = lCommand.begin(); i; i++ )
28 {
29 if( (*i)->matches( lCmd ) )
30 {
31 (*i)->exec( gState, lCmd );
32 return true;
33 }
34 }
35
36 return false;
37}
38
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:
12 12
13 void addCommand( class Command *pCmd ); 13 void addCommand( class Command *pCmd );
14 14
15 bool dispatch( class GameState &gState, const Bu::StringList &lCmd );
16
15private: 17private:
16 typedef Bu::List<class Command *> CommandList; 18 typedef Bu::List<class Command *> CommandList;
17 CommandList lCommand; 19 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 )
38 return hSituation.get( sName ); 38 return hSituation.get( sName );
39} 39}
40 40
41bool Game::execCommand( class GameState &gState, const Bu::StringList &lCmd )
42{
43 return csGlobal.dispatch( gState, lCmd );
44}
45
41void Game::addFunction( Function *pFunc ) 46void Game::addFunction( Function *pFunc )
42{ 47{
43 hFunction.insert( pFunc->getName(), pFunc ); 48 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:
20 Variable getParam( const Bu::String &sName ) const; 20 Variable getParam( const Bu::String &sName ) const;
21 Situation *getSituation( const Bu::String &sName ); 21 Situation *getSituation( const Bu::String &sName );
22 22
23 bool execCommand( class GameState &gState, const Bu::StringList &lCmd );
24
23private: 25private:
24 void addFunction( Function *pFunc ); 26 void addFunction( Function *pFunc );
25 27
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()
62 for( Bu::StringList::iterator i = lRev.begin(); i; i++ ) 62 for( Bu::StringList::iterator i = lRev.begin(); i; i++ )
63 { 63 {
64 addVarRef( *i, sidLocal ); 64 addVarRef( *i, sidLocal );
65 addNode( AstNode::tSwap ); 65 addNode( AstNode::tStoreRev );
66 addNode( AstNode::tStore );
67 } 66 }
68} 67}
69 68
@@ -171,6 +170,17 @@ void GameBuilder::addCommandParam( const Bu::String &sValue )
171 pCurCmd->addParam( sValue ); 170 pCurCmd->addParam( sValue );
172} 171}
173 172
173void GameBuilder::endCommandParams()
174{
175 Bu::StringList lParams = pCurCmd->getParamList();
176
177 for( Bu::StringList::iterator i = lParams.begin(); i; i++ )
178 {
179 addVarRef( *i, sidLocal );
180 addNode( AstNode::tStoreRev );
181 }
182}
183
174void GameBuilder::closeCommand() 184void GameBuilder::closeCommand()
175{ 185{
176 pCurCmd->setAst( pCurRoot ); 186 pCurCmd->setAst( pCurRoot );
@@ -182,7 +192,7 @@ void GameBuilder::closeCommand()
182 } 192 }
183 else 193 else
184 { 194 {
185 delete pCurCmd; 195 pCurSit->csLocal.addCommand( pCurCmd );
186 } 196 }
187 pCurCmd = NULL; 197 pCurCmd = NULL;
188} 198}
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:
40 void beginCommand( const Bu::String &sValue ); 40 void beginCommand( const Bu::String &sValue );
41 void addCommandLiteral( const Bu::String &sValue ); 41 void addCommandLiteral( const Bu::String &sValue );
42 void addCommandParam( const Bu::String &sValue ); 42 void addCommandParam( const Bu::String &sValue );
43 void endCommandParams();
43 void closeCommand(); 44 void closeCommand();
44 45
45private: 46private:
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 )
65 pGame->getFunction( sName )->call( *this ); 65 pGame->getFunction( sName )->call( *this );
66} 66}
67 67
68void GameState::execCommand( const Bu::String &sCmd )
69{
70 Bu::StringList lCmd = tokenize( sCmd );
71
72 if( !pGame->getSituation( sCurSituation )->execCommand( *this, lCmd ) )
73 {
74 if( !pGame->execCommand( *this, lCmd ) )
75 {
76 throw Bu::ExceptionBase("No such command exists.");
77 }
78 }
79}
80
68bool GameState::hasVariable( const Bu::String &sName, ScopeId id ) 81bool GameState::hasVariable( const Bu::String &sName, ScopeId id )
69{ 82{
70 switch( id ) 83 switch( id )
@@ -169,6 +182,39 @@ Variable GameState::deref( const Variable &src )
169 return src; 182 return src;
170} 183}
171 184
185Bu::StringList GameState::tokenize( const Bu::String &sSrc )
186{
187 Bu::StringList lRet;
188 Bu::String sToken;
189 bool bWs = true;
190 Bu::String::const_iterator i = sSrc.begin();
191
192 while( i )
193 {
194 for(; i; i++ )
195 {
196 if( *i != ' ' && *i != '\t' && *i != '\n' && *i != '\r' )
197 break;
198 }
199 for(; i; i++ )
200 {
201 if( i == ' ' || i == '\t' || *i == '\n' || *i == '\r' )
202 {
203 break;
204 }
205
206 sToken.append( *i );
207 }
208 if( sToken.getSize() > 0 )
209 {
210 lRet.append( sToken );
211 sToken.clear();
212 }
213 }
214
215 return lRet;
216}
217
172Variable GameState::popDeref() 218Variable GameState::popDeref()
173{ 219{
174 Variable v = lStack.peekPop(); 220 Variable v = lStack.peekPop();
@@ -245,6 +291,15 @@ void GameState::parse( const AstBranch::NodeList &lCode )
245 setVariable( r.sName, y, r.sid ); 291 setVariable( r.sName, y, r.sid );
246 } 292 }
247 break; 293 break;
294
295 case AstNode::tStoreRev:
296 {
297 Variable dst = pop();
298 Variable y = popDeref();
299 VariableRef r = dst.getVariableRef();
300 setVariable( r.sName, y, r.sid );
301 }
302 break;
248 303
249 case AstNode::tAnd: 304 case AstNode::tAnd:
250 { 305 {
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:
25 void push( const Variable &v ) { lStack.push( v ); } 25 void push( const Variable &v ) { lStack.push( v ); }
26 26
27 void callFunction( const Bu::String &sName ); 27 void callFunction( const Bu::String &sName );
28 void execCommand( const Bu::String &sCmd );
28 29
29 bool hasVariable( const Bu::String &sName, ScopeId id ); 30 bool hasVariable( const Bu::String &sName, ScopeId id );
30 void delVariable( const Bu::String &sName, ScopeId id ); 31 void delVariable( const Bu::String &sName, ScopeId id );
@@ -32,6 +33,7 @@ public:
32 void setVariable( const Bu::String &sName, const Variable &v, ScopeId id=sidLocal ); 33 void setVariable( const Bu::String &sName, const Variable &v, ScopeId id=sidLocal );
33 34
34 Variable deref( const Variable &src ); 35 Variable deref( const Variable &src );
36 Bu::StringList tokenize( const Bu::String &sSrc );
35 37
36private: 38private:
37 void parse( const AstBranch::NodeList &lCode ); 39 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 @@
3#include "gamestate.h" 3#include "gamestate.h"
4#include "parser.tab.h" 4#include "parser.tab.h"
5 5
6#include <bu/sio.h>
7using namespace Bu;
8
6typedef void *yyscan_t; 9typedef void *yyscan_t;
7void yylex_init( yyscan_t * ); 10void yylex_init( yyscan_t * );
8void yylex_destroy( yyscan_t ); 11void yylex_destroy( yyscan_t );
@@ -30,6 +33,13 @@ int main( int argc, char *argv[] )
30 GameState gs( pGame ); 33 GameState gs( pGame );
31 gs.init(); 34 gs.init();
32 35
36 char buf[1024];
37 sio << ">>" << sio.flush;
38 fgets( buf, 1024, stdin );
39
40 sio << "Read: >" << buf << "<" << sio.nl;
41 gs.execCommand( buf );
42
33 return 0; 43 return 0;
34} 44}
35 45
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
249 ; 249 ;
250 250
251commandDecl: tokCommand ':' tokString { bld.beginCommand( *$3 ); } 251commandDecl: tokCommand ':' tokString { bld.beginCommand( *$3 ); }
252 commandParamList '{' cmpltExprList '}' { bld.closeCommand(); } 252 commandParamList '{' { bld.endCommandParams(); } cmpltExprList '}' { bld.closeCommand(); }
253 ; 253 ;
254 254
255commandParamList: 255commandParamList:
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 )
48 } 48 }
49} 49}
50 50
51void Situation::addCommand( Command *pCmd )
52{
53 csLocal.addCommand( pCmd );
54}
55
56bool Situation::execCommand( class GameState &gState,
57 const Bu::StringList &lCmd )
58{
59 return csLocal.dispatch( gState, lCmd );
60}
61
51Bu::Formatter &operator<<( Bu::Formatter &f, Situation::Mode m ) 62Bu::Formatter &operator<<( Bu::Formatter &f, Situation::Mode m )
52{ 63{
53 switch( m ) 64 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 @@
3 3
4#include <bu/string.h> 4#include <bu/string.h>
5 5
6#include "commandset.h"
7
6class Situation 8class Situation
7{ 9{
10friend class GameBuilder;
8public: 11public:
9 Situation( const Bu::String &sName ); 12 Situation( const Bu::String &sName );
10 virtual ~Situation(); 13 virtual ~Situation();
@@ -18,11 +21,14 @@ public:
18 }; 21 };
19 22
20 void setAst( class AstBranch *pAst, Mode m ); 23 void setAst( class AstBranch *pAst, Mode m );
21
22 void exec( class GameState &gState, Mode m ); 24 void exec( class GameState &gState, Mode m );
23 25
26 void addCommand( Command *pCmd );
27 bool execCommand( class GameState &gState, const Bu::StringList &lCmd );
28
24private: 29private:
25 Bu::String sName; 30 Bu::String sName;
31 CommandSet csLocal;
26 class AstBranch *pAstSetup; 32 class AstBranch *pAstSetup;
27 class AstBranch *pAstEnter; 33 class AstBranch *pAstEnter;
28}; 34};