From 9de9d4e733ce872806c569334af4c9ace01db203 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 6 Feb 2012 12:22:27 -0700 Subject: Important bugfix in stack code. Thanks david! --- src/astnode.cpp | 1 + src/astnode.h | 1 + src/functiondelete.cpp | 1 + src/functiondisplay.cpp | 1 + src/functionexit.cpp | 1 + src/gamebuilder.cpp | 88 ++++++++++++++++++++++++++++++++++++++++++++++++- src/gamebuilder.h | 5 +++ src/gamestate.cpp | 8 +++-- src/parser.y | 12 +++---- test.stage | 14 +++++--- 10 files changed, 118 insertions(+), 14 deletions(-) diff --git a/src/astnode.cpp b/src/astnode.cpp index 2417968..81d560f 100644 --- a/src/astnode.cpp +++ b/src/astnode.cpp @@ -46,6 +46,7 @@ Bu::Formatter &operator<<( Bu::Formatter &f, AstNode::Type t ) case AstNode::tAppend: return f << "tAppend"; case AstNode::tInsert: return f << "tInsert"; case AstNode::tIndex: return f << "tIndex"; + case AstNode::tPop: return f << "tPop"; case AstNode::tLeafLiteral: return f << "!tLeafLiteral!"; case AstNode::tVarName: return f << "tVarName"; diff --git a/src/astnode.h b/src/astnode.h index a1215ed..94394f0 100644 --- a/src/astnode.h +++ b/src/astnode.h @@ -36,6 +36,7 @@ public: tAppend = 0x01000018, tInsert = 0x01000019, tIndex = 0x0100001A, + tPop = 0x0100001B, tLeafLiteral = 0x02000000, tVarName = 0x02000001, diff --git a/src/functiondelete.cpp b/src/functiondelete.cpp index c9bfef4..070ffd4 100644 --- a/src/functiondelete.cpp +++ b/src/functiondelete.cpp @@ -15,5 +15,6 @@ void FunctionDelete::call( class GameState &gState ) Variable v = gState.pop(); VariableRef r = v.getVariableRef(); gState.delVariable( r.sName, r.sid ); + gState.push( Variable( Variable::tNull ) ); } diff --git a/src/functiondisplay.cpp b/src/functiondisplay.cpp index 2f2209c..21941c0 100644 --- a/src/functiondisplay.cpp +++ b/src/functiondisplay.cpp @@ -22,6 +22,7 @@ void FunctionDisplay::call( class GameState &gState ) gState.getInterface()->display( pNode ); delete pNode; + gState.push( Variable( Variable::tNull ) ); /* Variable v = gState.popDeref(); sio << "Display: " << v << sio.nl; diff --git a/src/functionexit.cpp b/src/functionexit.cpp index be64f43..5e0088c 100644 --- a/src/functionexit.cpp +++ b/src/functionexit.cpp @@ -13,5 +13,6 @@ FunctionExit::~FunctionExit() void FunctionExit::call( class GameState &gState ) { gState.exit(); + gState.push( Variable( Variable::tNull ) ); } diff --git a/src/gamebuilder.cpp b/src/gamebuilder.cpp index bfeffec..857c348 100644 --- a/src/gamebuilder.cpp +++ b/src/gamebuilder.cpp @@ -19,7 +19,8 @@ GameBuilder::GameBuilder() : pCurRoot( NULL ), pCurCmd( NULL ), pCurFnc( NULL ), - pCurSit( NULL ) + pCurSit( NULL ), + iStackHeight( 0 ) { pGame = new Game(); } @@ -49,6 +50,15 @@ void GameBuilder::parse( const Bu::String &sFile ) fclose( in ); } +void GameBuilder::endCmpltExpr() +{ + while( iStackHeight > 0 ) + { + addNode( AstNode::tPop ); + } + iStackHeight = 0; +} + void GameBuilder::setLiteral( const Variable &v ) { vLiteral = v; @@ -91,9 +101,12 @@ void GameBuilder::endFunctionParams() void GameBuilder::endFunction() { //sio << "Function ended: " << *pCurRoot << sio.nl; + + pCurNode->addNode( new AstLeafLiteral( Variable::tNull ) ); pCurFnc->setAst( pCurRoot ); pCurRoot = pCurNode = NULL; pGame->hFunction.insert( pCurFnc->getName(), pCurFnc ); + iStackHeight = 0; } void GameBuilder::beginSituation( const Bu::String &sName, Situation::InputType tInput ) @@ -123,6 +136,7 @@ void GameBuilder::endSituation() void GameBuilder::addNode( AstNode::Type iType ) { + stackMod( iType ); switch( iType&AstNode::tTypeMask ) { case AstNode::tBranch: @@ -145,6 +159,7 @@ void GameBuilder::addLiteral( const Variable &v ) setLiteral( v ); if( pCurNode ) { + stackMod( AstNode::tLeafLiteral ); pCurNode->addNode( new AstLeafLiteral( v ) ); } } @@ -153,6 +168,7 @@ void GameBuilder::addVarRef( const Bu::String &sName, ScopeId sid ) { if( pCurNode ) { + stackMod( AstNode::tVarName ); pCurNode->addNode( new AstLeafLiteral( AstNode::tVarName, Variable::newVariableName( sName, sid ) ) ); } } @@ -161,10 +177,78 @@ void GameBuilder::addFuncCall( const Bu::String &sName ) { if( pCurNode ) { + stackMod( AstNode::tFuncCall ); pCurNode->addNode( new AstLeafLiteral( AstNode::tFuncCall, sName ) ); } } +void GameBuilder::stackMod( AstNode::Type iType ) +{ + switch( iType ) + { + case AstNode::tNot: + case AstNode::tNegate: + case AstNode::tSwap: + break; + + case AstNode::tComp: + case AstNode::tCompGt: + case AstNode::tCompLt: + case AstNode::tCompGtEq: + case AstNode::tCompLtEq: + case AstNode::tStore: + case AstNode::tAnd: + case AstNode::tOr: + case AstNode::tPlus: + case AstNode::tMinus: + case AstNode::tDivide: + case AstNode::tMultiply: + case AstNode::tPlusStore: + case AstNode::tMinusStore: + case AstNode::tDivideStore: + case AstNode::tMultiplyStore: + case AstNode::tIn: + case AstNode::tGoto: + case AstNode::tStoreRev: + case AstNode::tReturn: // return doesn't pop anything, but it counts as it. + case AstNode::tAppend: + case AstNode::tPop: + case AstNode::tIndex: + iStackHeight--; + break; + + case AstNode::tInsert: + iStackHeight -= 2; + break; + + case AstNode::tLeafLiteral: + case AstNode::tVarName: + case AstNode::tLiteral: + case AstNode::tFuncCall: + iStackHeight++; + break; + + case AstNode::tBranch: + break; + + case AstNode::tScope: + break; + + case AstNode::tIf: + iStackHeight--; + break; + + case AstNode::tForEach: + iStackHeight -= 2; + break; + + case AstNode::tWhile: + iStackHeight -= 1; + break; + + } +} + void GameBuilder::beginGlobal() { bGlobal = true; @@ -219,6 +303,7 @@ void GameBuilder::closeCommand() pCurSit->csLocal.addCommand( pCurCmd ); } pCurCmd = NULL; + iStackHeight = 0; } void GameBuilder::beginOption( const Bu::String &sValue ) @@ -237,5 +322,6 @@ void GameBuilder::closeOption() //pCurCmd->print(); pCurSit->csLocal.addCommand( pCurCmd ); pCurCmd = NULL; + iStackHeight = 0; } diff --git a/src/gamebuilder.h b/src/gamebuilder.h index 80df1bc..f64f50e 100644 --- a/src/gamebuilder.h +++ b/src/gamebuilder.h @@ -15,6 +15,8 @@ public: void parse( const Bu::String &sFile ); + void endCmpltExpr(); + class Game *getGame() { return pGame; } void setLiteral( const Variable &v ); @@ -36,6 +38,8 @@ public: void addVarRef( const Bu::String &sName, ScopeId sid ); void addFuncCall( const Bu::String &sName ); + void stackMod( AstNode::Type iType ); + void beginGlobal(); void closeGlobal(); @@ -58,6 +62,7 @@ private: class AstFunction *pCurFnc; class Situation *pCurSit; Situation::Mode eCurSitMode; + int iStackHeight; }; #endif diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 0a82b99..aeaaaed 100644 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -520,8 +520,8 @@ void GameState::parse( const AstBranch::NodeList &lCode ) bEscape = false; for( AstBranch::NodeList::const_iterator i = lCode.begin(); i; i++ ) { -// sio << "Stack: " << lStack << sio.nl; -// sio << "exec: " << (*i)->getType() << sio.nl; + //sio << "Stack: " << lStack << sio.nl; + //sio << "exec: " << (*i)->getType() << sio.nl; switch( (*i)->getType() ) { // tLeaf @@ -748,6 +748,10 @@ void GameState::parse( const AstBranch::NodeList &lCode ) } break; + case AstNode::tPop: + pop(); + break; + // tLeafLiteral case AstNode::tVarName: case AstNode::tLiteral: diff --git a/src/parser.y b/src/parser.y index b50b897..bbe4840 100644 --- a/src/parser.y +++ b/src/parser.y @@ -160,10 +160,10 @@ cmpltExprList: | cmpltExprList cmpltExpr ; -cmpltExpr: expr ';' - | tokReturn '(' expr ')' ';' { bld.addNode( AstNode::tReturn ); } - | tokReturn '(' ')' ';' { bld.addNode( AstNode::tReturn ); } - | tokGoto '(' expr ')' ';' { bld.addNode( AstNode::tGoto ); } +cmpltExpr: expr ';' { bld.endCmpltExpr(); } + | tokReturn '(' expr ')' ';' { bld.addNode( AstNode::tReturn ); bld.endCmpltExpr();} + | tokReturn '(' ')' ';' { bld.addNode( AstNode::tReturn ); bld.endCmpltExpr();} + | tokGoto '(' expr ')' ';' { bld.addNode( AstNode::tGoto ); bld.endCmpltExpr();} | ifbase | tokFor tokEach { bld.addNode( AstNode::tForEach ); @@ -269,11 +269,11 @@ expr: literal ; funcCallParams: - | expr funcCallParamsEx + | expr funcCallParamsEx { bld.stackMod( AstNode::tPop ); } ; funcCallParamsEx: - | funcCallParamsEx ',' expr + | funcCallParamsEx ',' expr { bld.stackMod( AstNode::tPop ); } ; listValues: expr { bld.addNode( AstNode::tAppend ); } diff --git a/test.stage b/test.stage index d1ba1b0..cc765a4 100644 --- a/test.stage +++ b/test.stage @@ -13,15 +13,19 @@ global } } +function getVal() +{ + global.stuff = {'hi': 5 }; +} + situation <> { setup { - x = [5, 4, 3]; - x = x + [[9, 8, 7]]; - display( debugString( x ) ); - - exit(); + if true then + { + getVal(); + } } enter -- cgit v1.2.3