From 98c5559c40c17d6dbf402f88fc8274b31657a1df Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Wed, 8 Feb 2012 09:29:15 -0700 Subject: Fixed crash in empty functions. --- src/gamestate.cpp | 658 +++++++++++++++++++++++++++--------------------------- 1 file changed, 331 insertions(+), 327 deletions(-) diff --git a/src/gamestate.cpp b/src/gamestate.cpp index 0434e6d..b009e4c 100644 --- a/src/gamestate.cpp +++ b/src/gamestate.cpp @@ -553,397 +553,401 @@ void GameState::run( const AstBranch::NodeList &lNode, bool bNewScope ) while( !sProg.isEmpty() ) { ProgramCounter &i = sProg.peek(); + if( i ) + { // sio << "Stack: " << lStack << sio.nl; // sio << "exec: " << (*i)->getType() << sio.nl; - switch( (*i)->getType() ) - { - // tLeaf - case AstNode::tNot: + switch( (*i)->getType() ) { - Variable x = popDeref(); - if( x.getType() != Variable::tBool ) - throw Bu::ExceptionBase("Non-bool used with logical not operator."); - push( Variable( !x.getBool() ) ); - } - break; + // tLeaf + case AstNode::tNot: + { + Variable x = popDeref(); + if( x.getType() != Variable::tBool ) + throw Bu::ExceptionBase("Non-bool used with logical not operator."); + push( Variable( !x.getBool() ) ); + } + break; - case AstNode::tComp: - { - push( popDeref() == popDeref() ); - } - break; + case AstNode::tComp: + { + push( popDeref() == popDeref() ); + } + break; - case AstNode::tCompGt: - { - Variable y = popDeref(); - Variable x = popDeref(); - push( x > y ); - } - break; + case AstNode::tCompGt: + { + Variable y = popDeref(); + Variable x = popDeref(); + push( x > y ); + } + break; - case AstNode::tCompLt: - { - Variable y = popDeref(); - Variable x = popDeref(); - push( x < y ); - } - break; + case AstNode::tCompLt: + { + Variable y = popDeref(); + Variable x = popDeref(); + push( x < y ); + } + break; - case AstNode::tCompGtEq: - { - Variable y = popDeref(); - Variable x = popDeref(); - push( x >= y ); - } - break; + case AstNode::tCompGtEq: + { + Variable y = popDeref(); + Variable x = popDeref(); + push( x >= y ); + } + break; - case AstNode::tCompLtEq: - { - Variable y = popDeref(); - Variable x = popDeref(); - push( x <= y ); - } - break; + case AstNode::tCompLtEq: + { + Variable y = popDeref(); + Variable x = popDeref(); + push( x <= y ); + } + break; - case AstNode::tStore: - { - Variable y = popDeref(); - deref( lStack.peek(), true ) = y; -/* Variable dst = pop(); - - VariableRef r = dst.getVariableRef(); - 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::tStore: + { + Variable y = popDeref(); + deref( lStack.peek(), true ) = y; + /* Variable dst = pop(); + + VariableRef r = dst.getVariableRef(); + 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: - { - Variable y = popDeref(); - Variable x = popDeref(); - if( x.getType() != Variable::tBool || - y.getType() != Variable::tBool ) + case AstNode::tAnd: { - throw Bu::ExceptionBase("Non-bool used in logical AND operator."); + Variable y = popDeref(); + Variable x = popDeref(); + if( x.getType() != Variable::tBool || + y.getType() != Variable::tBool ) + { + throw Bu::ExceptionBase("Non-bool used in logical AND operator."); + } + lStack.push( Variable( x.getBool() && y.getBool() ) ); } - lStack.push( Variable( x.getBool() && y.getBool() ) ); - } - break; + break; - case AstNode::tOr: - { - Variable y = popDeref(); - Variable x = popDeref(); - if( x.getType() != Variable::tBool || - y.getType() != Variable::tBool ) + case AstNode::tOr: { - throw Bu::ExceptionBase("Non-bool used in logical OR operator."); + Variable y = popDeref(); + Variable x = popDeref(); + if( x.getType() != Variable::tBool || + y.getType() != Variable::tBool ) + { + throw Bu::ExceptionBase("Non-bool used in logical OR operator."); + } + lStack.push( Variable( x.getBool() || y.getBool() ) ); } - lStack.push( Variable( x.getBool() || y.getBool() ) ); - } - break; + break; - case AstNode::tPlus: - { - Variable y = popDeref(); - Variable x = popDeref(); - lStack.push( x + y ); - } - break; + case AstNode::tPlus: + { + Variable y = popDeref(); + Variable x = popDeref(); + lStack.push( x + y ); + } + break; - case AstNode::tMinus: - { - Variable y = popDeref(); - Variable x = popDeref(); - lStack.push( x - y ); - } - break; + case AstNode::tMinus: + { + Variable y = popDeref(); + Variable x = popDeref(); + lStack.push( x - y ); + } + break; - case AstNode::tDivide: - { - Variable y = popDeref(); - Variable x = popDeref(); - lStack.push( x / y ); - } - break; + case AstNode::tDivide: + { + Variable y = popDeref(); + Variable x = popDeref(); + lStack.push( x / y ); + } + break; - case AstNode::tMultiply: - { - Variable y = popDeref(); - Variable x = popDeref(); - lStack.push( x * y ); - } - break; + case AstNode::tMultiply: + { + Variable y = popDeref(); + Variable x = popDeref(); + lStack.push( x * y ); + } + break; - case AstNode::tPlusStore: - { - Variable y = popDeref(); - deref( lStack.peek(), true ) += y; - } - break; + case AstNode::tPlusStore: + { + Variable y = popDeref(); + deref( lStack.peek(), true ) += y; + } + break; - case AstNode::tMinusStore: - { - Variable y = popDeref(); - deref( lStack.peek(), true ) -= y; - } - break; + case AstNode::tMinusStore: + { + Variable y = popDeref(); + deref( lStack.peek(), true ) -= y; + } + break; - case AstNode::tDivideStore: - { - Variable y = popDeref(); - deref( lStack.peek(), true ) /= y; - } - break; + case AstNode::tDivideStore: + { + Variable y = popDeref(); + deref( lStack.peek(), true ) /= y; + } + break; - case AstNode::tMultiplyStore: - { - Variable y = popDeref(); - deref( lStack.peek(), true ) *= y; - } - break; + case AstNode::tMultiplyStore: + { + Variable y = popDeref(); + deref( lStack.peek(), true ) *= y; + } + break; - case AstNode::tNegate: - push( -popDeref() ); - break; + case AstNode::tNegate: + push( -popDeref() ); + break; - case AstNode::tIn: - { - Variable v = popDeref(); - Variable x = popDeref(); - if( v.getType() == Variable::tDictionary || - v.getType() == Variable::tList ) + case AstNode::tIn: { - push( Variable( v.has( x ) ) ); + Variable v = popDeref(); + Variable x = popDeref(); + if( v.getType() == Variable::tDictionary || + v.getType() == Variable::tList ) + { + push( Variable( v.has( x ) ) ); + } + else + { + throw Bu::ExceptionBase("Invalid type for operator in"); + } } - else + break; + + case AstNode::tGoto: { - throw Bu::ExceptionBase("Invalid type for operator in"); + Variable x = popDeref(); + if( x.getType() != Variable::tSituation ) + throw Bu::ExceptionBase("You cannot goto anything but a situation."); + sGoto = x.getString(); + return; } - } - break; - - case AstNode::tGoto: - { - Variable x = popDeref(); - if( x.getType() != Variable::tSituation ) - throw Bu::ExceptionBase("You cannot goto anything but a situation."); - sGoto = x.getString(); - return; - } - break; + break; - case AstNode::tSwap: - { - Variable y = pop(); - Variable x = pop(); - push( y ); - push( x ); - } - break; + case AstNode::tSwap: + { + Variable y = pop(); + Variable x = pop(); + push( y ); + push( x ); + } + break; - case AstNode::tReturn: - if( bNewScope ) - lsLocal.pop(); - return; + case AstNode::tReturn: + if( bNewScope ) + lsLocal.pop(); + return; - case AstNode::tAppend: - { - Variable v = popDeref(); - deref( lStack.peek() ) += v; - } - break; + case AstNode::tAppend: + { + Variable v = popDeref(); + deref( lStack.peek() ) += v; + } + break; - case AstNode::tInsert: - { - Variable v = popDeref(); - Variable k = popDeref(); - deref( lStack.peek() ).insert( k, v ); - } - break; + case AstNode::tInsert: + { + Variable v = popDeref(); + Variable k = popDeref(); + deref( lStack.peek() ).insert( k, v ); + } + break; - case AstNode::tIndex: - { - Variable v = popDeref(); - Variable cx = pop(); - Variable &c = deref( cx ); - push( Variable( &c.get( v ) ) ); - } - break; + case AstNode::tIndex: + { + Variable v = popDeref(); + Variable cx = pop(); + Variable &c = deref( cx ); + push( Variable( &c.get( v ) ) ); + } + break; - case AstNode::tPop: - pop(); - break; + case AstNode::tPop: + pop(); + break; - case AstNode::tDeref: - push( popDeref() ); - break; + case AstNode::tDeref: + push( popDeref() ); + break; - case AstNode::tExists: - { - Variable v = pop(); - VariableRef r = v.getVariableRef(); - push( Variable( hasVariable( r.sName, r.sid ) ) ); - } - break; + case AstNode::tExists: + { + Variable v = pop(); + VariableRef r = v.getVariableRef(); + push( Variable( hasVariable( r.sName, r.sid ) ) ); + } + break; - case AstNode::tDelete: - { - Variable v = pop(); - VariableRef r = v.getVariableRef(); - delVariable( r.sName, r.sid ); - push( Variable( Variable::tNull ) ); - } - break; + case AstNode::tDelete: + { + Variable v = pop(); + VariableRef r = v.getVariableRef(); + delVariable( r.sName, r.sid ); + push( Variable( Variable::tNull ) ); + } + break; - // tLeafLiteral - case AstNode::tVarName: - case AstNode::tLiteral: - lStack.push( dynamic_cast(*i)->getValue() ); - break; + // tLeafLiteral + case AstNode::tVarName: + case AstNode::tLiteral: + lStack.push( dynamic_cast(*i)->getValue() ); + break; - case AstNode::tFuncCall: - callFunction( - dynamic_cast(*i) - ->getValue().getString() - ); - break; + case AstNode::tFuncCall: + callFunction( + dynamic_cast(*i) + ->getValue().getString() + ); + break; - // tBranch - case AstNode::tScope: - throw Bu::ExceptionBase("Scope? that shouldn't be here..."); - break; + // tBranch + case AstNode::tScope: + throw Bu::ExceptionBase("Scope? that shouldn't be here..."); + break; - case AstNode::tIf: - { - AstBranch::NodeList lIf = - dynamic_cast(*i)->getNodeList(); - Variable v = popDeref(); - if( v.getType() != Variable::tBool ) - throw Bu::ExceptionBase("conditional did not evaluate to boolean."); - AstBranch::NodeList::const_iterator iIf = lIf.begin(); - if( v.getBool() ) - { - i++; - sProg.push( dynamic_cast(*iIf)-> - getNodeList().begin() ); - continue; - } - else - { - iIf++; - if( iIf ) + case AstNode::tIf: + { + AstBranch::NodeList lIf = + dynamic_cast(*i)->getNodeList(); + Variable v = popDeref(); + if( v.getType() != Variable::tBool ) + throw Bu::ExceptionBase("conditional did not evaluate to boolean."); + AstBranch::NodeList::const_iterator iIf = lIf.begin(); + if( v.getBool() ) { i++; sProg.push( dynamic_cast(*iIf)-> getNodeList().begin() ); continue; } - } - } - break; - - case AstNode::tForEach: - { - AstBranch::NodeList lFe = - dynamic_cast(*i)->getNodeList(); - AstBranch::NodeList::const_iterator iEach = lFe.begin(); - AstBranch::NodeList::const_iterator iIn = iEach+1; - AstBranch::NodeList::const_iterator iDo = iIn+1; - - const AstBranch::NodeList &lEachVrs = - dynamic_cast(*iEach)->getNodeList(); - AstBranch::NodeList::const_iterator iEachVrs = lEachVrs.begin(); - - bool bUseKey = false; - VariableRef vrKey, vrValue; - if( lEachVrs.getSize() == 2 ) - { - vrKey = dynamic_cast(*iEachVrs)-> - getValue().getVariableRef(); - iEachVrs++; - vrValue = dynamic_cast(*iEachVrs)-> - getValue().getVariableRef(); - bUseKey = true; - } - else - { - vrValue = dynamic_cast(*iEachVrs)-> - getValue().getVariableRef(); - } - - run( dynamic_cast(*iIn), - false ); - Variable vIn = popDeref(); - - const AstBranch::NodeList &rDo = - dynamic_cast(*iDo)->getNodeList(); - - if( vIn.getType() == Variable::tDictionary ) - { - const Variable::VariableHash &rHash = vIn.getHash(); - for( Variable::VariableHash::const_iterator i = - rHash.begin(); i; i++ ) + else { - if( bUseKey ) - setVariable( vrKey.sName, i.getKey(), vrKey.sid ); - setVariable( vrValue.sName, i.getValue(), vrValue.sid ); - run( rDo, false ); + iIf++; + if( iIf ) + { + i++; + sProg.push( dynamic_cast(*iIf)-> + getNodeList().begin() ); + continue; + } } } - else if( vIn.getType() == Variable::tList ) + break; + + case AstNode::tForEach: { - if( bUseKey ) + AstBranch::NodeList lFe = + dynamic_cast(*i)->getNodeList(); + AstBranch::NodeList::const_iterator iEach = lFe.begin(); + AstBranch::NodeList::const_iterator iIn = iEach+1; + AstBranch::NodeList::const_iterator iDo = iIn+1; + + const AstBranch::NodeList &lEachVrs = + dynamic_cast(*iEach)->getNodeList(); + AstBranch::NodeList::const_iterator iEachVrs = lEachVrs.begin(); + + bool bUseKey = false; + VariableRef vrKey, vrValue; + if( lEachVrs.getSize() == 2 ) { - throw Bu::ExceptionBase("You cannot use key:value pairs as iterators in a for each loop iterating over a list."); + vrKey = dynamic_cast(*iEachVrs)-> + getValue().getVariableRef(); + iEachVrs++; + vrValue = dynamic_cast(*iEachVrs)-> + getValue().getVariableRef(); + bUseKey = true; } - const Variable::VariableArray &rList = vIn.getList(); - for( Variable::VariableArray::const_iterator i = - rList.begin(); i; i++ ) + else { - setVariable( vrValue.sName, *i, vrValue.sid ); - run( rDo, false ); + vrValue = dynamic_cast(*iEachVrs)-> + getValue().getVariableRef(); } - } - } - break; - case AstNode::tWhile: - { - AstBranch::NodeList lWhile = - dynamic_cast(*i)->getNodeList(); - AstBranch::NodeList::const_iterator iTest = lWhile.begin(); - AstBranch::NodeList::const_iterator iDo = iTest+1; + run( dynamic_cast(*iIn), + false ); + Variable vIn = popDeref(); + + const AstBranch::NodeList &rDo = + dynamic_cast(*iDo)->getNodeList(); - for(;;) + if( vIn.getType() == Variable::tDictionary ) + { + const Variable::VariableHash &rHash = vIn.getHash(); + for( Variable::VariableHash::const_iterator i = + rHash.begin(); i; i++ ) + { + if( bUseKey ) + setVariable( vrKey.sName, i.getKey(), vrKey.sid ); + setVariable( vrValue.sName, i.getValue(), vrValue.sid ); + run( rDo, false ); + } + } + else if( vIn.getType() == Variable::tList ) + { + if( bUseKey ) + { + throw Bu::ExceptionBase("You cannot use key:value pairs as iterators in a for each loop iterating over a list."); + } + const Variable::VariableArray &rList = vIn.getList(); + for( Variable::VariableArray::const_iterator i = + rList.begin(); i; i++ ) + { + setVariable( vrValue.sName, *i, vrValue.sid ); + run( rDo, false ); + } + } + } + break; + + case AstNode::tWhile: { - run( dynamic_cast(*iTest)-> - getNodeList(), false ); - Variable v = popDeref(); - if( v.getType() != Variable::tBool ) - throw Bu::ExceptionBase("conditional did not evaluate to boolean."); - if( !v.getBool() ) - break; + AstBranch::NodeList lWhile = + dynamic_cast(*i)->getNodeList(); + AstBranch::NodeList::const_iterator iTest = lWhile.begin(); + AstBranch::NodeList::const_iterator iDo = iTest+1; - run( dynamic_cast(*iDo)-> - getNodeList(), false ); + for(;;) + { + run( dynamic_cast(*iTest)-> + getNodeList(), false ); + Variable v = popDeref(); + if( v.getType() != Variable::tBool ) + throw Bu::ExceptionBase("conditional did not evaluate to boolean."); + if( !v.getBool() ) + break; + + run( dynamic_cast(*iDo)-> + getNodeList(), false ); + } } + break; } - break; - } - if( sGoto.isSet() ) - return; + if( sGoto.isSet() ) + return; + + ++sProg.peek(); + } - ++sProg.peek(); while( !sProg.isEmpty() && !sProg.peek() ) { sProg.pop(); -- cgit v1.2.3