summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2011-12-29 23:30:49 -0700
committerMike Buland <eichlan@xagasoft.com>2011-12-29 23:30:49 -0700
commit35f71b12dc48a928d98743f607f62b2f6dbe7307 (patch)
treef4297f57e570f52f3776392fc8ed4075db1ab4ac
parentf66458278ce3663397fc985a1253c85b74f011e6 (diff)
downloadstage-35f71b12dc48a928d98743f607f62b2f6dbe7307.tar.gz
stage-35f71b12dc48a928d98743f607f62b2f6dbe7307.tar.bz2
stage-35f71b12dc48a928d98743f607f62b2f6dbe7307.tar.xz
stage-35f71b12dc48a928d98743f607f62b2f6dbe7307.zip
Goto works, scopes work.
-rw-r--r--src/enums.h12
-rw-r--r--src/gamebuilder.cpp6
-rw-r--r--src/gamebuilder.h2
-rw-r--r--src/gamestate.cpp65
-rw-r--r--src/gamestate.h11
-rw-r--r--src/parser.y8
-rw-r--r--src/variable.cpp42
-rw-r--r--src/variable.h15
-rw-r--r--test.stage24
9 files changed, 139 insertions, 46 deletions
diff --git a/src/enums.h b/src/enums.h
new file mode 100644
index 0000000..2577590
--- /dev/null
+++ b/src/enums.h
@@ -0,0 +1,12 @@
1#ifndef ENUMS_H
2#define ENUMS_H
3
4enum ScopeId
5{
6 sidLocal,
7 sidGlobal,
8 sidPlayer,
9 sidSituation
10};
11
12#endif
diff --git a/src/gamebuilder.cpp b/src/gamebuilder.cpp
index d1b4430..87389ff 100644
--- a/src/gamebuilder.cpp
+++ b/src/gamebuilder.cpp
@@ -61,7 +61,7 @@ void GameBuilder::endFunctionParams()
61 61
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 ); 64 addVarRef( *i, sidLocal );
65 addNode( AstNode::tSwap ); 65 addNode( AstNode::tSwap );
66 addNode( AstNode::tStore ); 66 addNode( AstNode::tStore );
67 } 67 }
@@ -128,11 +128,11 @@ void GameBuilder::addLiteral( const Variable &v )
128 } 128 }
129} 129}
130 130
131void GameBuilder::addVarRef( const Bu::String &sName ) 131void GameBuilder::addVarRef( const Bu::String &sName, ScopeId sid )
132{ 132{
133 if( pCurNode ) 133 if( pCurNode )
134 { 134 {
135 pCurNode->addNode( new AstLeafLiteral( AstNode::tVarName, Variable::newVariableName( sName ) ) ); 135 pCurNode->addNode( new AstLeafLiteral( AstNode::tVarName, Variable::newVariableName( sName, sid ) ) );
136 } 136 }
137} 137}
138 138
diff --git a/src/gamebuilder.h b/src/gamebuilder.h
index e4ead71..9e40f48 100644
--- a/src/gamebuilder.h
+++ b/src/gamebuilder.h
@@ -31,7 +31,7 @@ public:
31 void addNode( AstNode::Type iType ); 31 void addNode( AstNode::Type iType );
32 void closeNode(); 32 void closeNode();
33 void addLiteral( const Variable &v ); 33 void addLiteral( const Variable &v );
34 void addVarRef( const Bu::String &sName ); 34 void addVarRef( const Bu::String &sName, ScopeId sid );
35 void addFuncCall( const Bu::String &sName ); 35 void addFuncCall( const Bu::String &sName );
36 36
37 void beginGlobal(); 37 void beginGlobal();
diff --git a/src/gamestate.cpp b/src/gamestate.cpp
index 14a7b53..3f09c3f 100644
--- a/src/gamestate.cpp
+++ b/src/gamestate.cpp
@@ -23,8 +23,10 @@ void GameState::parse( class AstBranch *pAst )
23 throw Bu::ExceptionBase("Nope, nothing doing, you can't parse a non-scope AstBranch."); 23 throw Bu::ExceptionBase("Nope, nothing doing, you can't parse a non-scope AstBranch.");
24 24
25 lsLocal.push( new Scope() ); 25 lsLocal.push( new Scope() );
26 int iDepth = lsLocal.getSize();
26 parse( pAst->getNodeList() ); 27 parse( pAst->getNodeList() );
27 delete lsLocal.peekPop(); 28 if( lsLocal.getSize() == iDepth )
29 delete lsLocal.peekPop();
28} 30}
29 31
30void GameState::init() 32void GameState::init()
@@ -38,6 +40,11 @@ void GameState::init()
38 40
39void GameState::gotoSituation( const Bu::String &sName ) 41void GameState::gotoSituation( const Bu::String &sName )
40{ 42{
43 lStack.clear();
44 for( ScopeList::iterator i = lsLocal.begin(); i; i++ )
45 delete *i;
46 lsLocal.clear();
47
41 Situation *pSit = pGame->getSituation( sName ); 48 Situation *pSit = pGame->getSituation( sName );
42 sCurSituation = sName; 49 sCurSituation = sName;
43 if( !hsSituation.has( sName ) ) 50 if( !hsSituation.has( sName ) )
@@ -46,18 +53,22 @@ void GameState::gotoSituation( const Bu::String &sName )
46 pSit->exec( *this, Situation::modeSetup ); 53 pSit->exec( *this, Situation::modeSetup );
47 } 54 }
48 55
56 // This is here in case you use a goto in a setup mode
57 if( bEscape )
58 return;
59
49 pSit->exec( *this, Situation::modeEnter ); 60 pSit->exec( *this, Situation::modeEnter );
50} 61}
51 62
52void GameState::callFunction( const Bu::String &sName ) 63void GameState::callFunction( const Bu::String &sName )
53{ 64{
54 lsLocal.push( new Scope() );
55 pGame->getFunction( sName )->call( *this ); 65 pGame->getFunction( sName )->call( *this );
56 delete lsLocal.peekPop();
57} 66}
58 67
59Variable GameState::getVariable( const Bu::String &sName, ScopeId id ) 68Variable GameState::getVariable( const Bu::String &sName, ScopeId id )
60{ 69{
70 try
71 {
61 switch( id ) 72 switch( id )
62 { 73 {
63 case sidLocal: 74 case sidLocal:
@@ -72,6 +83,13 @@ Variable GameState::getVariable( const Bu::String &sName, ScopeId id )
72 case sidSituation: 83 case sidSituation:
73 return hsSituation.get( sCurSituation )->get( sName ); 84 return hsSituation.get( sCurSituation )->get( sName );
74 } 85 }
86 }
87 catch( Bu::HashException &e )
88 {
89 throw Bu::ExceptionBase("No %d variable named %s found.",
90 id,
91 sName.getStr() );
92 }
75 93
76 throw Bu::ExceptionBase("Really bad scopeid passed into getVariable"); 94 throw Bu::ExceptionBase("Really bad scopeid passed into getVariable");
77} 95}
@@ -104,7 +122,10 @@ void GameState::setVariable( const Bu::String &sName, const Variable &v,
104Variable GameState::deref( const Variable &src ) 122Variable GameState::deref( const Variable &src )
105{ 123{
106 if( src.getType() == Variable::tVariable ) 124 if( src.getType() == Variable::tVariable )
107 return getVariable( src.getString() ); 125 {
126 VariableRef r = src.getVariableRef();
127 return getVariable( r.sName, r.sid );
128 }
108 return src; 129 return src;
109} 130}
110 131
@@ -112,12 +133,16 @@ Variable GameState::popDeref()
112{ 133{
113 Variable v = lStack.peekPop(); 134 Variable v = lStack.peekPop();
114 if( v.getType() == Variable::tVariable ) 135 if( v.getType() == Variable::tVariable )
115 return getVariable( v.getString() ); 136 {
137 VariableRef r = v.getVariableRef();
138 return getVariable( r.sName, r.sid );
139 }
116 return v; 140 return v;
117} 141}
118 142
119void GameState::parse( const AstBranch::NodeList &lCode ) 143void GameState::parse( const AstBranch::NodeList &lCode )
120{ 144{
145 bEscape = false;
121 for( AstBranch::NodeList::const_iterator i = lCode.begin(); i; i++ ) 146 for( AstBranch::NodeList::const_iterator i = lCode.begin(); i; i++ )
122 { 147 {
123// sio << "Stack: " << lStack << sio.nl; 148// sio << "Stack: " << lStack << sio.nl;
@@ -176,7 +201,8 @@ void GameState::parse( const AstBranch::NodeList &lCode )
176 { 201 {
177 Variable y = popDeref(); 202 Variable y = popDeref();
178 Variable dst = pop(); 203 Variable dst = pop();
179 setVariable( dst.getString(), y ); 204 VariableRef r = dst.getVariableRef();
205 setVariable( r.sName, y, r.sid );
180 } 206 }
181 break; 207 break;
182 208
@@ -242,7 +268,8 @@ void GameState::parse( const AstBranch::NodeList &lCode )
242 { 268 {
243 Variable y = popDeref(); 269 Variable y = popDeref();
244 Variable x = pop(); 270 Variable x = pop();
245 setVariable( x.getString(), getVariable( x.getString() ) + y ); 271 VariableRef r = x.getVariableRef();
272 setVariable( r.sName, getVariable( r.sName, r.sid ) + y, r.sid );
246 } 273 }
247 break; 274 break;
248 275
@@ -250,7 +277,8 @@ void GameState::parse( const AstBranch::NodeList &lCode )
250 { 277 {
251 Variable y = popDeref(); 278 Variable y = popDeref();
252 Variable x = pop(); 279 Variable x = pop();
253 setVariable( x.getString(), getVariable( x.getString() ) - y ); 280 VariableRef r = x.getVariableRef();
281 setVariable( r.sName, getVariable( r.sName, r.sid ) - y, r.sid );
254 } 282 }
255 break; 283 break;
256 284
@@ -258,7 +286,8 @@ void GameState::parse( const AstBranch::NodeList &lCode )
258 { 286 {
259 Variable y = popDeref(); 287 Variable y = popDeref();
260 Variable x = pop(); 288 Variable x = pop();
261 setVariable( x.getString(), getVariable( x.getString() ) / y ); 289 VariableRef r = x.getVariableRef();
290 setVariable( r.sName, getVariable( r.sName, r.sid ) / y, r.sid );
262 } 291 }
263 break; 292 break;
264 293
@@ -266,7 +295,8 @@ void GameState::parse( const AstBranch::NodeList &lCode )
266 { 295 {
267 Variable y = popDeref(); 296 Variable y = popDeref();
268 Variable x = pop(); 297 Variable x = pop();
269 setVariable( x.getString(), getVariable( x.getString() ) * y ); 298 VariableRef r = x.getVariableRef();
299 setVariable( r.sName, getVariable( r.sName, r.sid ) * y, r.sid );
270 } 300 }
271 break; 301 break;
272 302
@@ -276,6 +306,16 @@ void GameState::parse( const AstBranch::NodeList &lCode )
276 306
277 case AstNode::tIn: 307 case AstNode::tIn:
278 case AstNode::tGoto: 308 case AstNode::tGoto:
309 {
310 Variable x = popDeref();
311 if( x.getType() != Variable::tSituation )
312 throw Bu::ExceptionBase("You cannot goto anything but a situation.");
313 gotoSituation( x.getString() );
314 bEscape = true;
315 return;
316 }
317 break;
318
279 case AstNode::tSwap: 319 case AstNode::tSwap:
280 { 320 {
281 Variable y = pop(); 321 Variable y = pop();
@@ -329,6 +369,11 @@ void GameState::parse( const AstBranch::NodeList &lCode )
329 case AstNode::tWhile: 369 case AstNode::tWhile:
330 break; 370 break;
331 } 371 }
372
373 if( bEscape )
374 {
375 return;
376 }
332 } 377 }
333} 378}
334 379
diff --git a/src/gamestate.h b/src/gamestate.h
index 83d8594..6000419 100644
--- a/src/gamestate.h
+++ b/src/gamestate.h
@@ -4,6 +4,7 @@
4#include "astbranch.h" 4#include "astbranch.h"
5#include "variable.h" 5#include "variable.h"
6#include "scope.h" 6#include "scope.h"
7#include "enums.h"
7 8
8class Game; 9class Game;
9 10
@@ -25,14 +26,6 @@ public:
25 26
26 void callFunction( const Bu::String &sName ); 27 void callFunction( const Bu::String &sName );
27 28
28 enum ScopeId
29 {
30 sidLocal,
31 sidGlobal,
32 sidPlayer,
33 sidSituation
34 };
35
36 Variable getVariable( const Bu::String &sName, ScopeId id=sidLocal ); 29 Variable getVariable( const Bu::String &sName, ScopeId id=sidLocal );
37 void setVariable( const Bu::String &sName, const Variable &v, ScopeId id=sidLocal ); 30 void setVariable( const Bu::String &sName, const Variable &v, ScopeId id=sidLocal );
38 31
@@ -51,6 +44,8 @@ private:
51 ScopeHash hsSituation; 44 ScopeHash hsSituation;
52 Bu::String sCurSituation; 45 Bu::String sCurSituation;
53 46
47 bool bEscape;
48
54 VariableList lStack; 49 VariableList lStack;
55}; 50};
56 51
diff --git a/src/parser.y b/src/parser.y
index ccb0c97..484fd25 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -188,10 +188,10 @@ ifnext:
188 | tokElse { bld.addNode( AstNode::tScope ); } ifbase 188 | tokElse { bld.addNode( AstNode::tScope ); } ifbase
189 ; 189 ;
190 190
191varRef: tokIdent { bld.addVarRef( *($1) ); } 191varRef: tokIdent { bld.addVarRef( *($1), sidLocal ); }
192 | tokPlayer '.' tokIdent 192 | tokPlayer '.' tokIdent { bld.addVarRef( *($3), sidPlayer ); }
193 | tokGlobal '.' tokIdent 193 | tokGlobal '.' tokIdent { bld.addVarRef( *($3), sidGlobal ); }
194 | tokSituation '.' tokIdent 194 | tokSituation '.' tokIdent { bld.addVarRef( *($3), sidSituation ); }
195 ; 195 ;
196 196
197literal: tokInt { bld.addLiteral( Variable( $1 ) ); } 197literal: tokInt { bld.addLiteral( Variable( $1 ) ); }
diff --git a/src/variable.cpp b/src/variable.cpp
index 5e2462c..4c5ca4c 100644
--- a/src/variable.cpp
+++ b/src/variable.cpp
@@ -4,6 +4,11 @@
4#include <stdlib.h> 4#include <stdlib.h>
5 5
6typedef Bu::ExceptionBase VariableException; 6typedef Bu::ExceptionBase VariableException;
7
8bool VariableRef::operator==( const VariableRef &rhs ) const
9{
10 return sid == rhs.sid && sName == rhs.sName;
11}
7 12
8Variable::Variable() : 13Variable::Variable() :
9 eType( tNull ), 14 eType( tNull ),
@@ -62,10 +67,11 @@ Variable Variable::newSituationName( const Bu::String &s )
62 return v; 67 return v;
63} 68}
64 69
65Variable Variable::newVariableName( const Bu::String &s ) 70Variable Variable::newVariableName( const Bu::String &s, ScopeId sid )
66{ 71{
67 Variable v( tVariable ); 72 Variable v( tVariable );
68 (*v.sValue) = s; 73 v.rValue->sName = s;
74 v.rValue->sid = sid;
69 return v; 75 return v;
70} 76}
71 77
@@ -86,9 +92,16 @@ double Variable::getFloat() const
86 92
87Bu::String Variable::getString() const 93Bu::String Variable::getString() const
88{ 94{
95 if( eType != tString && eType != tSituation )
96 throw Bu::ExceptionBase("That's not a string.");
89 return *sValue; 97 return *sValue;
90} 98}
91 99
100VariableRef Variable::getVariableRef() const
101{
102 return *rValue;
103}
104
92Variable Variable::to( Type e ) const 105Variable Variable::to( Type e ) const
93{ 106{
94 if( e == eType ) 107 if( e == eType )
@@ -222,10 +235,13 @@ Variable &Variable::operator=( const Variable &rhs )
222 235
223 case tString: 236 case tString:
224 case tSituation: 237 case tSituation:
225 case tVariable:
226 (*sValue) = *rhs.sValue; 238 (*sValue) = *rhs.sValue;
227 break; 239 break;
228 240
241 case tVariable:
242 (*rValue) = *rhs.rValue;
243 break;
244
229 case tList: 245 case tList:
230 (*lValue) = *rhs.lValue; 246 (*lValue) = *rhs.lValue;
231 break; 247 break;
@@ -527,8 +543,10 @@ bool Variable::operator==( const Variable &rhs ) const
527 543
528 case tString: 544 case tString:
529 case tSituation: 545 case tSituation:
530 case tVariable:
531 return (*sValue) == (*rhs.sValue); 546 return (*sValue) == (*rhs.sValue);
547
548 case tVariable:
549 return (*rValue) == (*rhs.rValue);
532 550
533 case tList: 551 case tList:
534 return (*lValue) == (*rhs.lValue); 552 return (*lValue) == (*rhs.lValue);
@@ -678,9 +696,12 @@ void Variable::initType()
678 { 696 {
679 case tString: 697 case tString:
680 case tSituation: 698 case tSituation:
681 case tVariable:
682 sValue = new Bu::String(); 699 sValue = new Bu::String();
683 break; 700 break;
701
702 case tVariable:
703 rValue = new VariableRef();
704 break;
684 705
685 case tList: 706 case tList:
686 lValue = new VList(); 707 lValue = new VList();
@@ -698,9 +719,12 @@ void Variable::deinitType()
698 { 719 {
699 case tString: 720 case tString:
700 case tSituation: 721 case tSituation:
701 case tVariable:
702 delete sValue; 722 delete sValue;
703 break; 723 break;
724
725 case tVariable:
726 delete rValue;
727 break;
704 728
705 case tList: 729 case tList:
706 delete lValue; 730 delete lValue;
@@ -729,8 +753,10 @@ template<> uint32_t Bu::__calcHashCode<Variable>( const Variable &k )
729 753
730 case Variable::tString: 754 case Variable::tString:
731 case Variable::tSituation: 755 case Variable::tSituation:
732 case Variable::tVariable:
733 return Bu::__calcHashCode( *k.sValue ); 756 return Bu::__calcHashCode( *k.sValue );
757
758 case Variable::tVariable:
759 throw VariableException("You cannot use a variable ref as a key in a dictionary.");
734 760
735 case Variable::tList: 761 case Variable::tList:
736 throw VariableException("You cannot use a list as a key in a dictionary."); 762 throw VariableException("You cannot use a list as a key in a dictionary.");
@@ -767,7 +793,7 @@ Bu::Formatter &operator<<( Bu::Formatter &f, const Variable &v )
767 return f << "<<" << *v.sValue << ">>"; 793 return f << "<<" << *v.sValue << ">>";
768 794
769 case Variable::tVariable: 795 case Variable::tVariable:
770 return f << "(varref:\"" << *v.sValue << "\")"; 796 return f << "(varref:\"" << v.rValue->sName << "\")";
771 797
772 case Variable::tList: 798 case Variable::tList:
773 return f << *v.lValue; 799 return f << *v.lValue;
diff --git a/src/variable.h b/src/variable.h
index 42dd865..7f482a3 100644
--- a/src/variable.h
+++ b/src/variable.h
@@ -6,6 +6,17 @@
6#include <bu/string.h> 6#include <bu/string.h>
7#include <bu/hash.h> 7#include <bu/hash.h>
8 8
9#include "enums.h"
10
11class VariableRef
12{
13public:
14 ScopeId sid;
15 Bu::String sName;
16
17 bool operator==( const VariableRef &rhs ) const;
18};
19
9class Variable 20class Variable
10{ 21{
11friend uint32_t Bu::__calcHashCode<Variable>( const Variable &k ); 22friend uint32_t Bu::__calcHashCode<Variable>( const Variable &k );
@@ -35,7 +46,7 @@ public:
35 virtual ~Variable(); 46 virtual ~Variable();
36 47
37 static Variable newSituationName( const Bu::String &s ); 48 static Variable newSituationName( const Bu::String &s );
38 static Variable newVariableName( const Bu::String &s ); 49 static Variable newVariableName( const Bu::String &s, ScopeId sid );
39 50
40 Type getType() const { return eType; } 51 Type getType() const { return eType; }
41 52
@@ -43,6 +54,7 @@ public:
43 int64_t getInt() const; 54 int64_t getInt() const;
44 double getFloat() const; 55 double getFloat() const;
45 Bu::String getString() const; 56 Bu::String getString() const;
57 VariableRef getVariableRef() const;
46 58
47 Variable to( Type e ) const; 59 Variable to( Type e ) const;
48 60
@@ -81,6 +93,7 @@ private:
81 Bu::String *sValue; 93 Bu::String *sValue;
82 VList *lValue; 94 VList *lValue;
83 VHash *hValue; 95 VHash *hValue;
96 VariableRef *rValue;
84 }; 97 };
85}; 98};
86 99
diff --git a/test.stage b/test.stage
index f150baa..c19dac9 100644
--- a/test.stage
+++ b/test.stage
@@ -26,22 +26,24 @@ function sillyDisplay( txt, extra )
26 } 26 }
27} 27}
28 28
29function myGoto( txt )
30{
31 display( txt );
32 goto( txt );
33}
34
29situation <<start>> 35situation <<start>>
30{ 36{
31 setup 37 setup
32 { 38 {
33 name = "Bob"; 39 player.name = "Bob";
40 name = player.name + "o";
34 name += " The Man"; 41 name += " The Man";
35 display("This is the setup phase for start, " + name); 42 display("This is the setup phase for start, " + name);
36 display( 5 <= 1 ); 43 sillyDisplay( "Hello", name == player.name );
37 display( 1 <= 1 ); 44
38 display( 0 <= 1 ); 45 myGoto( <<stuff>> );
39 sillyDisplay( "Hello", true ); 46 display("You shouldn't see this.");
40
41 if name == "Bob The Man" then
42 {
43 display("You are bob");
44 }
45 } 47 }
46 48
47 enter 49 enter
@@ -54,6 +56,6 @@ situation <<stuff>>
54{ 56{
55 enter 57 enter
56 { 58 {
57 display('''Entered stuff'''); 59 display('''Entered stuff''' + player.name);
58 } 60 }
59} 61}