From 533310f646f1b1a00250a361f627967c420f1eef Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Thu, 29 Dec 2011 14:13:21 -0700 Subject: Situations & their modes are built. --- src/gamebuilder.cpp | 19 ++++++++++++++++++- src/gamebuilder.h | 5 +++++ src/gamestate.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/gamestate.h | 13 +++++++++++++ src/parser.y | 8 +++++--- src/situation.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/situation.h | 21 ++++++++++++++++++++- test.stage | 13 ++++++++++--- 8 files changed, 170 insertions(+), 11 deletions(-) diff --git a/src/gamebuilder.cpp b/src/gamebuilder.cpp index ee85129..6c42fb0 100644 --- a/src/gamebuilder.cpp +++ b/src/gamebuilder.cpp @@ -7,6 +7,7 @@ #include "astleafliteral.h" #include "astfunction.h" #include "command.h" +#include "situation.h" using namespace Bu; @@ -16,7 +17,8 @@ GameBuilder::GameBuilder() : pCurNode( NULL ), pCurRoot( NULL ), pCurCmd( NULL ), - pCurFnc( NULL ) + pCurFnc( NULL ), + pCurSit( NULL ) { pGame = new Game(); } @@ -58,11 +60,26 @@ void GameBuilder::endFunction() void GameBuilder::beginSituation( const Bu::String &sName ) { + pCurSit = new Situation( sName ); sio << "New situation: " << sName << sio.nl; } +void GameBuilder::beginSituationMode( Situation::Mode m ) +{ + pCurNode = pCurRoot = new AstBranch( AstNode::tScope ); + eCurSitMode = m; +} + +void GameBuilder::closeSituationMode() +{ + sio << "Set situation mode " << eCurSitMode << " to " << *pCurRoot << sio.nl; + pCurSit->setAst( pCurRoot, eCurSitMode ); + pCurRoot = pCurNode = NULL; +} + void GameBuilder::endSituation() { + pGame->hSituation.insert( pCurSit->getName(), pCurSit ); sio << "Situation ended." << sio.nl; } diff --git a/src/gamebuilder.h b/src/gamebuilder.h index bc32f55..9a0493f 100644 --- a/src/gamebuilder.h +++ b/src/gamebuilder.h @@ -5,6 +5,7 @@ #include "variable.h" #include "astnode.h" +#include "situation.h" class GameBuilder { @@ -20,6 +21,8 @@ public: void endFunction(); void beginSituation( const Bu::String &sName ); + void beginSituationMode( Situation::Mode m ); + void closeSituationMode(); void endSituation(); void addNode( AstNode::Type iType ); @@ -44,6 +47,8 @@ private: class AstBranch *pCurRoot; class Command *pCurCmd; class AstFunction *pCurFnc; + class Situation *pCurSit; + Situation::Mode eCurSitMode; }; #endif diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 7649cac..25b53b8 100644 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -18,14 +18,60 @@ void GameState::parse( class AstBranch *pAst ) { if( pAst->getType() != AstNode::tScope ) throw Bu::ExceptionBase("Nope, nothing doing, you can't parse a non-scope AstBranch."); + + lsLocal.push( new Scope() ); parse( pAst->getNodeList() ); + delete lsLocal.peekPop(); } void GameState::callFunction( const Bu::String &sName ) { - lsLocal.push( new Scope() ); pGame->getFunction( sName )->call( *this ); - delete lsLocal.peekPop(); +} + +Variable GameState::getVariable( const Bu::String &sName, ScopeId id ) +{ + switch( id ) + { + case sidLocal: + return lsLocal.peek()->get( sName ); + + case sidGlobal: + return sGlobal.get( sName ); + + case sidPlayer: + return sPlayer.get( sName ); + + case sidSituation: + return hsSituation.get( sCurSituation )->get( sName ); + } + + throw Bu::ExceptionBase("Really bad scopeid passed into getVariable"); +} + +void GameState::setVariable( const Bu::String &sName, const Variable &v, + ScopeId id ) +{ + switch( id ) + { + case sidLocal: + lsLocal.peek()->insert( sName, v ); + return; + + case sidGlobal: + sGlobal.insert( sName, v ); + return; + + case sidPlayer: + sPlayer.insert( sName, v ); + return; + + case sidSituation: + hsSituation.get( sCurSituation )->insert( sName, v ); + return; + } + + throw Bu::ExceptionBase("Really bad scopeid passed into setVariable"); } void GameState::parse( const AstBranch::NodeList &lCode ) diff --git a/src/gamestate.h b/src/gamestate.h index cb02322..7a8f81a 100644 --- a/src/gamestate.h +++ b/src/gamestate.h @@ -20,6 +20,17 @@ public: void callFunction( const Bu::String &sName ); + enum ScopeId + { + sidLocal, + sidGlobal, + sidPlayer, + sidSituation + }; + + Variable getVariable( const Bu::String &sName, ScopeId id=sidLocal ); + void setVariable( const Bu::String &sName, const Variable &v, ScopeId id=sidLocal ); + private: void parse( const AstBranch::NodeList &lCode ); @@ -28,8 +39,10 @@ private: typedef Bu::Hash ScopeHash; Game *pGame; Scope sGlobal; + Scope sPlayer; ScopeList lsLocal; ScopeHash hsSituation; + Bu::String sCurSituation; VariableList lStack; }; diff --git a/src/parser.y b/src/parser.y index e6210d1..8f538a5 100644 --- a/src/parser.y +++ b/src/parser.y @@ -124,11 +124,13 @@ situationMembers: | situationMembers commandDecl ; -situationModeFunc: situationMode '{' cmpltExprList '}' +situationModeFunc: situationMode '{' cmpltExprList '}' { + bld.closeSituationMode(); + } ; -situationMode: tokSetup - | tokEnter +situationMode: tokSetup { bld.beginSituationMode( Situation::modeSetup ); } + | tokEnter { bld.beginSituationMode( Situation::modeEnter ); } ; function: tokFunction tokIdent { bld.beginFunction( *($2) ); } '(' funcParamList ')' '{' cmpltExprList '}' { bld.endFunction(); } diff --git a/src/situation.cpp b/src/situation.cpp index 0d24aa4..d7f98aa 100644 --- a/src/situation.cpp +++ b/src/situation.cpp @@ -1,10 +1,60 @@ #include "situation.h" -Situation::Situation() +#include "astbranch.h" +#include "gamestate.h" + +#include + +Situation::Situation( const Bu::String &sName ) : + sName( sName ), + pAstSetup( NULL ), + pAstEnter( NULL ) { } Situation::~Situation() { + delete pAstSetup; + delete pAstEnter; +} + +void Situation::setAst( class AstBranch *pAst, Situation::Mode m ) +{ + switch( m ) + { + case modeSetup: + pAstSetup = pAst; + break; + + case modeEnter: + pAstEnter = pAst; + break; + } +} + +void Situation::exec( class GameState &gState, Situation::Mode m ) +{ + switch( m ) + { + case modeSetup: + gState.parse( pAstSetup ); + break; + + case modeEnter: + gState.parse( pAstEnter ); + break; + } +} + +Bu::Formatter &operator<<( Bu::Formatter &f, Situation::Mode m ) +{ + switch( m ) + { + case Situation::modeSetup: + return f << "Setup"; + + case Situation::modeEnter: + return f << "Enter"; + } } diff --git a/src/situation.h b/src/situation.h index aed6397..4d06fe6 100644 --- a/src/situation.h +++ b/src/situation.h @@ -1,13 +1,32 @@ #ifndef SITUATION_H #define SITUATION_H +#include + class Situation { public: - Situation(); + Situation( const Bu::String &sName ); virtual ~Situation(); + Bu::String getName() const { return sName; } + + enum Mode + { + modeSetup, + modeEnter, + }; + + void setAst( class AstBranch *pAst, Mode m ); + + void exec( class GameState &gState, Mode m ); + private: + Bu::String sName; + class AstBranch *pAstSetup; + class AstBranch *pAstEnter; }; +Bu::Formatter &operator<<( Bu::Formatter &f, Situation::Mode m ); + #endif diff --git a/test.stage b/test.stage index 13155d3..87e4756 100644 --- a/test.stage +++ b/test.stage @@ -9,12 +9,19 @@ global { command: "eat" object { - pow(5, x*2); + display(object); } } -function hello( a, b, c ) +situation <> { - a[x][y]; + setup + { + display("Hello"); + } + + enter + { + } } -- cgit v1.2.3