summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2011-12-30 22:40:21 -0700
committerMike Buland <eichlan@xagasoft.com>2011-12-30 22:40:21 -0700
commit8bcb83035607371a2326374665e9cc56c662a783 (patch)
treeb46c73e24edff0693f3e4c678bafad874ee9f21e /src
parentba7897ebadbc03d99200fda03a574a57b650e429 (diff)
downloadstage-8bcb83035607371a2326374665e9cc56c662a783.tar.gz
stage-8bcb83035607371a2326374665e9cc56c662a783.tar.bz2
stage-8bcb83035607371a2326374665e9cc56c662a783.tar.xz
stage-8bcb83035607371a2326374665e9cc56c662a783.zip
Wow, dictionaries, nested dictionaries, for loops
They all work. I still think I should change the lists to arrays in the backend so they can be indexed as well as iterated over and appended to.
Diffstat (limited to '')
-rw-r--r--src/astnode.cpp1
-rw-r--r--src/astnode.h1
-rw-r--r--src/functiondisplay.cpp34
-rw-r--r--src/functiondisplay.h3
-rw-r--r--src/gamebuilder.cpp2
-rw-r--r--src/gamestate.cpp125
-rw-r--r--src/gamestate.h4
-rw-r--r--src/main.cpp2
-rw-r--r--src/parser.y25
-rw-r--r--src/variable.cpp35
-rw-r--r--src/variable.h14
11 files changed, 222 insertions, 24 deletions
diff --git a/src/astnode.cpp b/src/astnode.cpp
index 84f6845..2417968 100644
--- a/src/astnode.cpp
+++ b/src/astnode.cpp
@@ -45,6 +45,7 @@ Bu::Formatter &operator<<( Bu::Formatter &f, AstNode::Type t )
45 case AstNode::tReturn: return f << "tReturn"; 45 case AstNode::tReturn: return f << "tReturn";
46 case AstNode::tAppend: return f << "tAppend"; 46 case AstNode::tAppend: return f << "tAppend";
47 case AstNode::tInsert: return f << "tInsert"; 47 case AstNode::tInsert: return f << "tInsert";
48 case AstNode::tIndex: return f << "tIndex";
48 49
49 case AstNode::tLeafLiteral: return f << "!tLeafLiteral!"; 50 case AstNode::tLeafLiteral: return f << "!tLeafLiteral!";
50 case AstNode::tVarName: return f << "tVarName"; 51 case AstNode::tVarName: return f << "tVarName";
diff --git a/src/astnode.h b/src/astnode.h
index 58c4a42..a1215ed 100644
--- a/src/astnode.h
+++ b/src/astnode.h
@@ -35,6 +35,7 @@ public:
35 tReturn = 0x01000017, 35 tReturn = 0x01000017,
36 tAppend = 0x01000018, 36 tAppend = 0x01000018,
37 tInsert = 0x01000019, 37 tInsert = 0x01000019,
38 tIndex = 0x0100001A,
38 39
39 tLeafLiteral = 0x02000000, 40 tLeafLiteral = 0x02000000,
40 tVarName = 0x02000001, 41 tVarName = 0x02000001,
diff --git a/src/functiondisplay.cpp b/src/functiondisplay.cpp
index fa5b79c..4790844 100644
--- a/src/functiondisplay.cpp
+++ b/src/functiondisplay.cpp
@@ -15,7 +15,37 @@ FunctionDisplay::~FunctionDisplay()
15 15
16void FunctionDisplay::call( class GameState &gState ) 16void FunctionDisplay::call( class GameState &gState )
17{ 17{
18 Variable v = gState.popDeref(); 18 Bu::String s = gState.popDeref().to( Variable::tString ).getString();
19 sio << "Display: " << v << sio.nl; 19
20 sio << format( s ) << sio.nl;
21// sio << "Display: " << v << sio.nl;
22}
23
24Bu::String FunctionDisplay::format( const Bu::String &sSrc )
25{
26 Bu::String sRet;
27 bool bWs = true;
28 Bu::String::const_iterator i = sSrc.begin();
29
30 while( i )
31 {
32 for(; i; i++ )
33 {
34 if( *i != ' ' && *i != '\t' && *i != '\n' && *i != '\r' )
35 break;
36 }
37 for(; i; i++ )
38 {
39 if( i == ' ' || i == '\t' || *i == '\n' || *i == '\r' )
40 {
41 sRet.append(' ');
42 break;
43 }
44
45 sRet.append( *i );
46 }
47 }
48
49 return sRet;
20} 50}
21 51
diff --git a/src/functiondisplay.h b/src/functiondisplay.h
index 3b7e828..48e51fe 100644
--- a/src/functiondisplay.h
+++ b/src/functiondisplay.h
@@ -11,6 +11,9 @@ public:
11 11
12 virtual Bu::String getName() const { return "display"; } 12 virtual Bu::String getName() const { return "display"; }
13 virtual void call( class GameState &gState ); 13 virtual void call( class GameState &gState );
14
15private:
16 Bu::String format( const Bu::String &sSrc );
14}; 17};
15 18
16#endif 19#endif
diff --git a/src/gamebuilder.cpp b/src/gamebuilder.cpp
index 791ba6b..d04a642 100644
--- a/src/gamebuilder.cpp
+++ b/src/gamebuilder.cpp
@@ -185,7 +185,7 @@ void GameBuilder::closeCommand()
185{ 185{
186 pCurCmd->setAst( pCurRoot ); 186 pCurCmd->setAst( pCurRoot );
187 pCurRoot = pCurNode = NULL; 187 pCurRoot = pCurNode = NULL;
188// pCurCmd->print(); 188 //pCurCmd->print();
189 if( bGlobal ) 189 if( bGlobal )
190 { 190 {
191 pGame->csGlobal.addCommand( pCurCmd ); 191 pGame->csGlobal.addCommand( pCurCmd );
diff --git a/src/gamestate.cpp b/src/gamestate.cpp
index e8df070..bd3e638 100644
--- a/src/gamestate.cpp
+++ b/src/gamestate.cpp
@@ -120,7 +120,7 @@ void GameState::delVariable( const Bu::String &sName, ScopeId id )
120 throw Bu::ExceptionBase("Really bad scopeid passed into getVariable"); 120 throw Bu::ExceptionBase("Really bad scopeid passed into getVariable");
121} 121}
122 122
123Variable GameState::getVariable( const Bu::String &sName, ScopeId id ) 123Variable &GameState::getVariable( const Bu::String &sName, ScopeId id )
124{ 124{
125 try 125 try
126 { 126 {
@@ -174,12 +174,62 @@ void GameState::setVariable( const Bu::String &sName, const Variable &v,
174 throw Bu::ExceptionBase("Really bad scopeid passed into setVariable"); 174 throw Bu::ExceptionBase("Really bad scopeid passed into setVariable");
175} 175}
176 176
177Variable GameState::deref( const Variable &src ) 177Variable &GameState::deref( Variable &src, bool bCreate )
178{ 178{
179 if( src.getType() == Variable::tVariable ) 179 if( src.getType() == Variable::tVariable )
180 { 180 {
181 VariableRef r = src.getVariableRef(); 181 VariableRef r = src.getVariableRef();
182 return getVariable( r.sName, r.sid ); 182 try
183 {
184 switch( r.sid )
185 {
186 case sidLocal:
187 return lsLocal.peek()->get( r.sName );
188
189 case sidGlobal:
190 return sGlobal.get( r.sName );
191
192 case sidPlayer:
193 return sPlayer.get( r.sName );
194
195 case sidSituation:
196 return hsSituation.get( sCurSituation )->get( r.sName );
197 }
198 }
199 catch( Bu::HashException &e )
200 {
201 if( bCreate )
202 {
203 switch( r.sid )
204 {
205 case sidLocal:
206 lsLocal.peek()->insert( r.sName, Variable() );
207 return lsLocal.peek()->get( r.sName );
208
209 case sidGlobal:
210 sGlobal.insert( r.sName, Variable() );
211 return sGlobal.get( r.sName );
212
213 case sidPlayer:
214 sPlayer.insert( r.sName, Variable() );
215 return sPlayer.get( r.sName );
216
217 case sidSituation:
218 hsSituation.get( sCurSituation )->insert( r.sName, Variable() );
219 return hsSituation.get( sCurSituation )->get( r.sName );
220 }
221 }
222 else
223 {
224 throw Bu::ExceptionBase("No %d variable named %s found.",
225 r.sid,
226 r.sName.getStr() );
227 }
228 }
229 }
230 else if( src.getType() == Variable::tVarPtr )
231 {
232 return *src.getVariablePtr();
183 } 233 }
184 return src; 234 return src;
185} 235}
@@ -231,6 +281,10 @@ Variable GameState::popDeref()
231 VariableRef r = v.getVariableRef(); 281 VariableRef r = v.getVariableRef();
232 return getVariable( r.sName, r.sid ); 282 return getVariable( r.sName, r.sid );
233 } 283 }
284 else if( v.getType() == Variable::tVarPtr )
285 {
286 return *v.getVariablePtr();
287 }
234 return v; 288 return v;
235} 289}
236 290
@@ -294,9 +348,11 @@ void GameState::parse( const AstBranch::NodeList &lCode )
294 case AstNode::tStore: 348 case AstNode::tStore:
295 { 349 {
296 Variable y = popDeref(); 350 Variable y = popDeref();
297 Variable dst = pop(); 351 deref( lStack.peek(), true ) = y;
352/* Variable dst = pop();
353
298 VariableRef r = dst.getVariableRef(); 354 VariableRef r = dst.getVariableRef();
299 setVariable( r.sName, y, r.sid ); 355 setVariable( r.sName, y, r.sid ); */
300 } 356 }
301 break; 357 break;
302 358
@@ -449,7 +505,7 @@ void GameState::parse( const AstBranch::NodeList &lCode )
449 case AstNode::tAppend: 505 case AstNode::tAppend:
450 { 506 {
451 Variable v = popDeref(); 507 Variable v = popDeref();
452 lStack.peek() += v; 508 deref( lStack.peek() ) += v;
453 } 509 }
454 break; 510 break;
455 511
@@ -457,7 +513,16 @@ void GameState::parse( const AstBranch::NodeList &lCode )
457 { 513 {
458 Variable v = popDeref(); 514 Variable v = popDeref();
459 Variable k = popDeref(); 515 Variable k = popDeref();
460 lStack.peek().insert( k, v ); 516 deref( lStack.peek() ).insert( k, v );
517 }
518 break;
519
520 case AstNode::tIndex:
521 {
522 Variable v = popDeref();
523 Variable cx = pop();
524 Variable &c = deref( cx );
525 push( Variable( &c.get( v ) ) );
461 } 526 }
462 break; 527 break;
463 528
@@ -505,7 +570,53 @@ void GameState::parse( const AstBranch::NodeList &lCode )
505 break; 570 break;
506 571
507 case AstNode::tForEach: 572 case AstNode::tForEach:
573 {
574 AstBranch::NodeList lFe =
575 dynamic_cast<const AstBranch *>(*i)->getNodeList();
576 AstBranch::NodeList::const_iterator iEach = lFe.begin();
577 AstBranch::NodeList::const_iterator iIn = iEach+1;
578 AstBranch::NodeList::const_iterator iDo = iIn+1;
579
580 const AstBranch::NodeList &lEachVrs =
581 dynamic_cast<const AstBranch *>(*iEach)->getNodeList();
582 AstBranch::NodeList::const_iterator iEachVrs = lEachVrs.begin();
583
584 bool bUseKey = false;
585 VariableRef vrKey, vrValue;
586 if( lEachVrs.getSize() == 2 )
587 {
588 vrKey = dynamic_cast<const AstLeafLiteral *>(*iEachVrs)->
589 getValue().getVariableRef();
590 iEachVrs++;
591 vrValue = dynamic_cast<const AstLeafLiteral *>(*iEachVrs)->
592 getValue().getVariableRef();
593 bUseKey = true;
594 }
595 else
596 {
597 vrValue = dynamic_cast<const AstLeafLiteral *>(*iEachVrs)->
598 getValue().getVariableRef();
599 }
600
601 parse( dynamic_cast<const AstBranch *>(*iIn)->getNodeList() );
602 Variable vIn = popDeref();
603
604 const AstBranch::NodeList &rDo =
605 dynamic_cast<const AstBranch *>(*iDo)->getNodeList();
508 606
607 if( vIn.getType() == Variable::tDictionary )
608 {
609 const Variable::VariableHash &rHash = vIn.getHash();
610 for( Variable::VariableHash::const_iterator i =
611 rHash.begin(); i; i++ )
612 {
613 if( bUseKey )
614 setVariable( vrKey.sName, i.getKey(), vrKey.sid );
615 setVariable( vrValue.sName, i.getValue(), vrValue.sid );
616 parse( rDo );
617 }
618 }
619 }
509 break; 620 break;
510 621
511 case AstNode::tWhile: 622 case AstNode::tWhile:
diff --git a/src/gamestate.h b/src/gamestate.h
index e32eeaa..5c47ce0 100644
--- a/src/gamestate.h
+++ b/src/gamestate.h
@@ -29,10 +29,10 @@ public:
29 29
30 bool hasVariable( const Bu::String &sName, ScopeId id ); 30 bool hasVariable( const Bu::String &sName, ScopeId id );
31 void delVariable( const Bu::String &sName, ScopeId id ); 31 void delVariable( const Bu::String &sName, ScopeId id );
32 Variable getVariable( const Bu::String &sName, ScopeId id=sidLocal ); 32 Variable &getVariable( const Bu::String &sName, ScopeId id=sidLocal );
33 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 );
34 34
35 Variable deref( const Variable &src ); 35 Variable &deref( Variable &src, bool bCreate=false );
36 Bu::StringList tokenize( const Bu::String &sSrc ); 36 Bu::StringList tokenize( const Bu::String &sSrc );
37 37
38 void exit(); 38 void exit();
diff --git a/src/main.cpp b/src/main.cpp
index 413151a..b3dbba7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -36,7 +36,7 @@ int main( int argc, char *argv[] )
36 while( gs.isRunning() ) 36 while( gs.isRunning() )
37 { 37 {
38 char buf[1024]; 38 char buf[1024];
39 sio << "command> " << sio.flush; 39 sio << sio.nl << "command> " << sio.flush;
40 fgets( buf, 1024, stdin ); 40 fgets( buf, 1024, stdin );
41 41
42 gs.execCommand( buf ); 42 gs.execCommand( buf );
diff --git a/src/parser.y b/src/parser.y
index 707d85d..3dfd737 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -155,7 +155,19 @@ cmpltExpr: expr ';'
155 | tokReturn '(' ')' ';' { bld.addNode( AstNode::tReturn ); } 155 | tokReturn '(' ')' ';' { bld.addNode( AstNode::tReturn ); }
156 | tokGoto '(' expr ')' ';' { bld.addNode( AstNode::tGoto ); } 156 | tokGoto '(' expr ')' ';' { bld.addNode( AstNode::tGoto ); }
157 | ifbase 157 | ifbase
158 | tokFor tokEach forIterator tokIn expr tokDo '{' cmpltExprList '}' 158 | tokFor tokEach {
159 bld.addNode( AstNode::tForEach );
160 bld.addNode( AstNode::tScope );
161 } forIterator tokIn {
162 bld.closeNode();
163 bld.addNode( AstNode::tScope );
164 } expr tokDo '{' {
165 bld.closeNode();
166 bld.addNode( AstNode::tScope );
167 } cmpltExprList '}' {
168 bld.closeNode();
169 bld.closeNode();
170 }
159 | tokWhile { 171 | tokWhile {
160 bld.addNode( AstNode::tWhile ); 172 bld.addNode( AstNode::tWhile );
161 bld.addNode( AstNode::tScope ); 173 bld.addNode( AstNode::tScope );
@@ -168,8 +180,12 @@ cmpltExpr: expr ';'
168 } 180 }
169 ; 181 ;
170 182
171forIterator: tokIdent 183forIterator: tokIdent { bld.addVarRef( *($1), sidLocal ); }
172 | tokIdent ':' tokIdent 184 | tokIdent ':' tokIdent {
185 bld.addVarRef( *($1), sidLocal );
186 bld.addVarRef( *($3), sidLocal );
187 }
188 ;
173 189
174ifbase: tokIf { 190ifbase: tokIf {
175 bld.addNode( AstNode::tIf ); 191 bld.addNode( AstNode::tIf );
@@ -226,7 +242,8 @@ expr: literal
226 | expr tokLtEq expr { bld.addNode( AstNode::tCompLtEq ); } 242 | expr tokLtEq expr { bld.addNode( AstNode::tCompLtEq ); }
227 | expr tokGtEq expr { bld.addNode( AstNode::tCompGtEq ); } 243 | expr tokGtEq expr { bld.addNode( AstNode::tCompGtEq ); }
228 | '(' expr ')' 244 | '(' expr ')'
229 | expr '[' expr ']' 245 | expr '[' expr ']' { bld.addNode( AstNode::tIndex ); }
246 | expr '[' expr ']' '=' expr { bld.addNode( AstNode::tInsert ); }
230 | '[' ']' { bld.addLiteral( Variable( Variable::tList ) ); } 247 | '[' ']' { bld.addLiteral( Variable( Variable::tList ) ); }
231 | '[' { bld.addLiteral( Variable( Variable::tList ) ); } listValues ']' 248 | '[' { bld.addLiteral( Variable( Variable::tList ) ); } listValues ']'
232 | '{' '}' { bld.addLiteral( Variable( Variable::tDictionary ) ); } 249 | '{' '}' { bld.addLiteral( Variable( Variable::tDictionary ) ); }
diff --git a/src/variable.cpp b/src/variable.cpp
index 1e5cc9b..1100c84 100644
--- a/src/variable.cpp
+++ b/src/variable.cpp
@@ -55,6 +55,12 @@ Variable::Variable( const Bu::String &sValue ) :
55 this->sValue = new Bu::String( sValue ); 55 this->sValue = new Bu::String( sValue );
56} 56}
57 57
58Variable::Variable( Variable *pValue ) :
59 eType( tVarPtr ),
60 pValue( pValue )
61{
62}
63
58Variable::~Variable() 64Variable::~Variable()
59{ 65{
60 deinitType(); 66 deinitType();
@@ -102,6 +108,16 @@ VariableRef Variable::getVariableRef() const
102 return *rValue; 108 return *rValue;
103} 109}
104 110
111Variable *Variable::getVariablePtr() const
112{
113 return pValue;
114}
115
116const Variable::VariableHash &Variable::getHash() const
117{
118 return *hValue;
119}
120
105Variable Variable::to( Type e ) const 121Variable Variable::to( Type e ) const
106{ 122{
107 if( e == eType ) 123 if( e == eType )
@@ -227,6 +243,14 @@ bool Variable::has( const Variable &vKey )
227 throw Bu::ExceptionBase("Insert on non-dictionary."); 243 throw Bu::ExceptionBase("Insert on non-dictionary.");
228} 244}
229 245
246Variable &Variable::get( const Variable &vKey )
247{
248 if( eType == tDictionary )
249 return hValue->get( vKey );
250 else
251 throw Bu::ExceptionBase("Insert on non-dictionary.");
252}
253
230Variable &Variable::operator=( const Variable &rhs ) 254Variable &Variable::operator=( const Variable &rhs )
231{ 255{
232 deinitType(); 256 deinitType();
@@ -266,6 +290,10 @@ Variable &Variable::operator=( const Variable &rhs )
266 case tDictionary: 290 case tDictionary:
267 (*hValue) = *rhs.hValue; 291 (*hValue) = *rhs.hValue;
268 break; 292 break;
293
294 case tVarPtr:
295 pValue = rhs.pValue;
296 break;
269 } 297 }
270} 298}
271 299
@@ -725,11 +753,11 @@ void Variable::initType()
725 break; 753 break;
726 754
727 case tList: 755 case tList:
728 lValue = new VList(); 756 lValue = new VariableList();
729 break; 757 break;
730 758
731 case tDictionary: 759 case tDictionary:
732 hValue = new VHash(); 760 hValue = new VariableHash();
733 break; 761 break;
734 } 762 }
735} 763}
@@ -821,6 +849,9 @@ Bu::Formatter &operator<<( Bu::Formatter &f, const Variable &v )
821 849
822 case Variable::tDictionary: 850 case Variable::tDictionary:
823 return f << *v.hValue; 851 return f << *v.hValue;
852
853 case Variable::tVarPtr:
854 return f << "(varptr:" << *v.pValue << ")";
824 } 855 }
825 856
826 return f << "ERROR"; 857 return f << "ERROR";
diff --git a/src/variable.h b/src/variable.h
index 97308c7..22a1b26 100644
--- a/src/variable.h
+++ b/src/variable.h
@@ -44,23 +44,30 @@ public:
44 Variable( double fValue ); 44 Variable( double fValue );
45 Variable( bool bValue ); 45 Variable( bool bValue );
46 Variable( const Bu::String &sValue ); 46 Variable( const Bu::String &sValue );
47 Variable( Variable *pValue );
47 virtual ~Variable(); 48 virtual ~Variable();
48 49
49 static Variable newSituationName( const Bu::String &s ); 50 static Variable newSituationName( const Bu::String &s );
50 static Variable newVariableName( const Bu::String &s, ScopeId sid ); 51 static Variable newVariableName( const Bu::String &s, ScopeId sid );
51 52
52 Type getType() const { return eType; } 53 Type getType() const { return eType; }
54
55 typedef Bu::List<Variable> VariableList;
56 typedef Bu::Hash<Variable, Variable> VariableHash;
53 57
54 bool getBool() const; 58 bool getBool() const;
55 int64_t getInt() const; 59 int64_t getInt() const;
56 double getFloat() const; 60 double getFloat() const;
57 Bu::String getString() const; 61 Bu::String getString() const;
58 VariableRef getVariableRef() const; 62 VariableRef getVariableRef() const;
63 Variable *getVariablePtr() const;
64 const VariableHash &getHash() const;
59 65
60 Variable to( Type e ) const; 66 Variable to( Type e ) const;
61 67
62 void insert( const Variable &vKey, const Variable &vValue ); 68 void insert( const Variable &vKey, const Variable &vValue );
63 bool has( const Variable &vKey ); 69 bool has( const Variable &vKey );
70 Variable &get( const Variable &vKey );
64 71
65 Variable &operator=( const Variable &rhs ); 72 Variable &operator=( const Variable &rhs );
66 Variable &operator+=( const Variable &rhs ); 73 Variable &operator+=( const Variable &rhs );
@@ -86,17 +93,14 @@ private:
86private: 93private:
87 Type eType; 94 Type eType;
88 95
89 typedef Bu::List<Variable> VList;
90 typedef Bu::Hash<Variable, Variable> VHash;
91
92 union 96 union
93 { 97 {
94 int64_t iValue; 98 int64_t iValue;
95 double fValue; 99 double fValue;
96 bool bValue; 100 bool bValue;
97 Bu::String *sValue; 101 Bu::String *sValue;
98 VList *lValue; 102 VariableList *lValue;
99 VHash *hValue; 103 VariableHash *hValue;
100 VariableRef *rValue; 104 VariableRef *rValue;
101 Variable *pValue; 105 Variable *pValue;
102 }; 106 };