diff options
-rw-r--r-- | src/astnode.cpp | 1 | ||||
-rw-r--r-- | src/astnode.h | 1 | ||||
-rw-r--r-- | src/command.cpp | 49 | ||||
-rw-r--r-- | src/command.h | 8 | ||||
-rw-r--r-- | src/commandset.cpp | 17 | ||||
-rw-r--r-- | src/commandset.h | 2 | ||||
-rw-r--r-- | src/game.cpp | 5 | ||||
-rw-r--r-- | src/game.h | 2 | ||||
-rw-r--r-- | src/gamebuilder.cpp | 16 | ||||
-rw-r--r-- | src/gamebuilder.h | 1 | ||||
-rw-r--r-- | src/gamestate.cpp | 55 | ||||
-rw-r--r-- | src/gamestate.h | 2 | ||||
-rw-r--r-- | src/main.cpp | 10 | ||||
-rw-r--r-- | src/parser.y | 2 | ||||
-rw-r--r-- | src/situation.cpp | 11 | ||||
-rw-r--r-- | 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 ) | |||
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> |
6 | using namespace Bu; | 7 | using 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 | ||
29 | Bu::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 | |||
28 | void Command::setAst( class AstBranch *pAst ) | 41 | void 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 | ||
60 | bool 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 | |||
80 | void 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 | |||
19 | private: | 27 | private: |
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> | ||
6 | using namespace Bu; | ||
7 | |||
5 | CommandSet::CommandSet() | 8 | CommandSet::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 | ||
25 | bool 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 | |||
15 | private: | 17 | private: |
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 | ||
41 | bool Game::execCommand( class GameState &gState, const Bu::StringList &lCmd ) | ||
42 | { | ||
43 | return csGlobal.dispatch( gState, lCmd ); | ||
44 | } | ||
45 | |||
41 | void Game::addFunction( Function *pFunc ) | 46 | void Game::addFunction( Function *pFunc ) |
42 | { | 47 | { |
43 | hFunction.insert( pFunc->getName(), pFunc ); | 48 | hFunction.insert( pFunc->getName(), pFunc ); |
@@ -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 | |||
23 | private: | 25 | private: |
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 | ||
173 | void 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 | |||
174 | void GameBuilder::closeCommand() | 184 | void 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 | ||
45 | private: | 46 | 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 ) | |||
65 | pGame->getFunction( sName )->call( *this ); | 65 | pGame->getFunction( sName )->call( *this ); |
66 | } | 66 | } |
67 | 67 | ||
68 | void 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 | |||
68 | bool GameState::hasVariable( const Bu::String &sName, ScopeId id ) | 81 | bool 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 | ||
185 | Bu::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 | |||
172 | Variable GameState::popDeref() | 218 | Variable 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 | ||
36 | private: | 38 | private: |
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> | ||
7 | using namespace Bu; | ||
8 | |||
6 | typedef void *yyscan_t; | 9 | typedef void *yyscan_t; |
7 | void yylex_init( yyscan_t * ); | 10 | void yylex_init( yyscan_t * ); |
8 | void yylex_destroy( yyscan_t ); | 11 | void 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 | ||
251 | commandDecl: tokCommand ':' tokString { bld.beginCommand( *$3 ); } | 251 | commandDecl: tokCommand ':' tokString { bld.beginCommand( *$3 ); } |
252 | commandParamList '{' cmpltExprList '}' { bld.closeCommand(); } | 252 | commandParamList '{' { bld.endCommandParams(); } cmpltExprList '}' { bld.closeCommand(); } |
253 | ; | 253 | ; |
254 | 254 | ||
255 | commandParamList: | 255 | 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 ) | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | void Situation::addCommand( Command *pCmd ) | ||
52 | { | ||
53 | csLocal.addCommand( pCmd ); | ||
54 | } | ||
55 | |||
56 | bool Situation::execCommand( class GameState &gState, | ||
57 | const Bu::StringList &lCmd ) | ||
58 | { | ||
59 | return csLocal.dispatch( gState, lCmd ); | ||
60 | } | ||
61 | |||
51 | Bu::Formatter &operator<<( Bu::Formatter &f, Situation::Mode m ) | 62 | Bu::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 | |||
6 | class Situation | 8 | class Situation |
7 | { | 9 | { |
10 | friend class GameBuilder; | ||
8 | public: | 11 | public: |
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 | |||
24 | private: | 29 | private: |
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 | }; |