diff options
| author | Mike Buland <eichlan@xagasoft.com> | 2012-01-03 00:08:48 -0700 |
|---|---|---|
| committer | Mike Buland <eichlan@xagasoft.com> | 2012-01-03 00:08:48 -0700 |
| commit | 8b9a15a755ebc6681ff6be808615e375cb567080 (patch) | |
| tree | c836f3a7a338e6bcc1fe88fe1207819005b92a83 | |
| parent | 340de5ebabbc60727b2aeb85b9faa72a75f1628b (diff) | |
| download | stage-8b9a15a755ebc6681ff6be808615e375cb567080.tar.gz stage-8b9a15a755ebc6681ff6be808615e375cb567080.tar.bz2 stage-8b9a15a755ebc6681ff6be808615e375cb567080.tar.xz stage-8b9a15a755ebc6681ff6be808615e375cb567080.zip | |
New functions, fixes, and a working bloodfields.
| -rw-r--r-- | bloodfields.stage | 152 | ||||
| -rw-r--r-- | src/functionfloat.cpp | 17 | ||||
| -rw-r--r-- | src/functionfloat.h | 16 | ||||
| -rw-r--r-- | src/functioninteger.cpp | 17 | ||||
| -rw-r--r-- | src/functioninteger.h | 16 | ||||
| -rw-r--r-- | src/functionrandom.cpp | 9 | ||||
| -rw-r--r-- | src/game.cpp | 4 | ||||
| -rw-r--r-- | src/gamebuilder.cpp | 2 | ||||
| -rw-r--r-- | src/parser.l | 8 | ||||
| -rw-r--r-- | src/parser.y | 6 | ||||
| -rw-r--r-- | src/variable.cpp | 34 | ||||
| -rw-r--r-- | support/vim/syntax/stage.vim | 2 | ||||
| -rw-r--r-- | test.stage | 12 |
13 files changed, 256 insertions, 39 deletions
diff --git a/bloodfields.stage b/bloodfields.stage index 7b61dd4..91bee08 100644 --- a/bloodfields.stage +++ b/bloodfields.stage | |||
| @@ -6,6 +6,11 @@ global | |||
| 6 | { | 6 | { |
| 7 | exit(); | 7 | exit(); |
| 8 | } | 8 | } |
| 9 | |||
| 10 | command: "exit" | ||
| 11 | { | ||
| 12 | exit(); | ||
| 13 | } | ||
| 9 | } | 14 | } |
| 10 | 15 | ||
| 11 | situation <<start>> | 16 | situation <<start>> |
| @@ -14,19 +19,19 @@ situation <<start>> | |||
| 14 | { | 19 | { |
| 15 | global.enemyTypes = { | 20 | global.enemyTypes = { |
| 16 | 1: { | 21 | 1: { |
| 17 | 'name': 'Snail', | 22 | 'name': 'snail', |
| 18 | 'action': 'bites', | 23 | 'action': 'oozes on', |
| 19 | 'hp': 3, | 24 | 'hp': 3, |
| 20 | 'attack': 2 | 25 | 'attack': 2 |
| 21 | }, | 26 | }, |
| 22 | 2: { | 27 | 2: { |
| 23 | 'name': 'Wolf', | 28 | 'name': 'wolf', |
| 24 | 'action': 'bites', | 29 | 'action': 'bites', |
| 25 | 'hp': 7, | 30 | 'hp': 7, |
| 26 | 'attack': 3 | 31 | 'attack': 3 |
| 27 | }, | 32 | }, |
| 28 | 3: { | 33 | 3: { |
| 29 | 'name': 'Snake', | 34 | 'name': 'snake', |
| 30 | 'action': 'strikes at', | 35 | 'action': 'strikes at', |
| 31 | 'hp': 3, | 36 | 'hp': 3, |
| 32 | 'attack': 3 | 37 | 'attack': 3 |
| @@ -35,17 +40,17 @@ situation <<start>> | |||
| 35 | 40 | ||
| 36 | global.enemyMods = { | 41 | global.enemyMods = { |
| 37 | 1: { | 42 | 1: { |
| 38 | 'name': 'Pathetic', | 43 | 'name': 'pathetic', |
| 39 | 'hp': 0, | 44 | 'hp': 0, |
| 40 | 'attack': 0 | 45 | 'attack': 0 |
| 41 | }, | 46 | }, |
| 42 | 2: { | 47 | 2: { |
| 43 | 'name': 'Sickly', | 48 | 'name': 'sickly', |
| 44 | 'hp': 3, | 49 | 'hp': 3, |
| 45 | 'attack': 1 | 50 | 'attack': 1 |
| 46 | }, | 51 | }, |
| 47 | 3: { | 52 | 3: { |
| 48 | 'name': 'Wimpy', | 53 | 'name': 'wimpy', |
| 49 | 'hp': 5, | 54 | 'hp': 5, |
| 50 | 'attack': 2 | 55 | 'attack': 2 |
| 51 | } | 56 | } |
| @@ -54,7 +59,9 @@ situation <<start>> | |||
| 54 | player.hpMax = 10; | 59 | player.hpMax = 10; |
| 55 | player.hpCur = player.hpMax; | 60 | player.hpCur = player.hpMax; |
| 56 | player.xp = 0; | 61 | player.xp = 0; |
| 62 | player.level = 1; | ||
| 57 | player.attack = 3; | 63 | player.attack = 3; |
| 64 | player.potions = 1; | ||
| 58 | 65 | ||
| 59 | global.bJustTravelled = false; | 66 | global.bJustTravelled = false; |
| 60 | 67 | ||
| @@ -64,16 +71,23 @@ situation <<start>> | |||
| 64 | 71 | ||
| 65 | function status() | 72 | function status() |
| 66 | { | 73 | { |
| 74 | display('You have ' + (100-player.xp) + ' xp until your next level.'); | ||
| 67 | display('You have ' + player.hpCur + ' of ' + player.hpMax + ' hp.'); | 75 | display('You have ' + player.hpCur + ' of ' + player.hpMax + ' hp.'); |
| 76 | display('You are carrying ' + player.potions + ' potions.'); | ||
| 68 | } | 77 | } |
| 69 | 78 | ||
| 70 | function look() | 79 | function look() |
| 71 | { | 80 | { |
| 72 | if( exists(global.enemy) )then | 81 | if exists(global.enemy) then |
| 73 | { | 82 | { |
| 74 | display('''You are standing in a field of wheat. You see a ''' + | 83 | display('''You are standing in a field of wheat. You see a ''' + |
| 75 | global.enemy['name'] + ''' in front of you.'''); | 84 | global.enemy['name'] + ''' in front of you.'''); |
| 76 | } | 85 | } |
| 86 | else if exists( global.treasure ) then | ||
| 87 | { | ||
| 88 | display('''You are standing in a field of wheat. You find a ''' + | ||
| 89 | global.treasure['name'] + ''' lying here!'''); | ||
| 90 | } | ||
| 77 | else | 91 | else |
| 78 | { | 92 | { |
| 79 | display('''You are standing in a field of wheat.'''); | 93 | display('''You are standing in a field of wheat.'''); |
| @@ -86,12 +100,24 @@ function mkEnemy() | |||
| 86 | eid = random( 1, 3 ); | 100 | eid = random( 1, 3 ); |
| 87 | global.enemy = global.enemyTypes[eid]; | 101 | global.enemy = global.enemyTypes[eid]; |
| 88 | 102 | ||
| 89 | mod = 1; | 103 | mod = player.level; |
| 104 | if mod > 3 then | ||
| 105 | { | ||
| 106 | mod = 3; | ||
| 107 | } | ||
| 90 | global.enemy['name'] = global.enemyMods[mod]['name'] + ' ' + | 108 | global.enemy['name'] = global.enemyMods[mod]['name'] + ' ' + |
| 91 | global.enemy['name']; | 109 | global.enemy['name']; |
| 92 | global.enemy['attack'] = global.enemy['attack'] + | 110 | global.enemy['attack'] = global.enemy['attack'] + |
| 93 | global.enemyMods[mod]['attack']; | 111 | global.enemyMods[mod]['attack']; |
| 94 | global.enemy['hp'] = global.enemy['hp'] + global.enemyMods[mod]['hp']; | 112 | global.enemy['hp'] = global.enemy['hp'] + global.enemyMods[mod]['hp']; |
| 113 | global.enemy['level'] = mod; | ||
| 114 | } | ||
| 115 | |||
| 116 | function mkTreasure() | ||
| 117 | { | ||
| 118 | global.treasure = { | ||
| 119 | 'name': 'potion' | ||
| 120 | }; | ||
| 95 | } | 121 | } |
| 96 | 122 | ||
| 97 | function rollAttack( attack ) | 123 | function rollAttack( attack ) |
| @@ -107,7 +133,26 @@ function playerAttack() | |||
| 107 | ' damage.'); | 133 | ' damage.'); |
| 108 | if global.enemy['hp'] <= 0 then | 134 | if global.enemy['hp'] <= 0 then |
| 109 | { | 135 | { |
| 110 | display('You killed the ' + global.enemy['name'] + '!'); | 136 | xp = 10; |
| 137 | display('You killed the ' + global.enemy['name'] + '! You gained ' + | ||
| 138 | xp + ' experience points.'); | ||
| 139 | player.xp += xp; | ||
| 140 | if player.xp >= 100 then | ||
| 141 | { | ||
| 142 | player.xp -= 100; | ||
| 143 | player.level += 1; | ||
| 144 | player.hpMax += integer(random(0.25,0.75)*player.hpMax); | ||
| 145 | player.hpCur = player.hpMax; | ||
| 146 | display("You have leveled! Welcome to level " + player.level ); | ||
| 147 | } | ||
| 148 | |||
| 149 | select = random(1, 3); | ||
| 150 | if select == 1 then | ||
| 151 | { | ||
| 152 | display('It looks like the ' + global.enemy['name'] + | ||
| 153 | ' dropped something...'); | ||
| 154 | mkTreasure(); | ||
| 155 | } | ||
| 111 | delete( global.enemy ); | 156 | delete( global.enemy ); |
| 112 | } | 157 | } |
| 113 | } | 158 | } |
| @@ -123,22 +168,37 @@ function enemyAttack() | |||
| 123 | display('The ' + global.enemy['name'] + ' killed you!'); | 168 | display('The ' + global.enemy['name'] + ' killed you!'); |
| 124 | exit(); | 169 | exit(); |
| 125 | } | 170 | } |
| 171 | else | ||
| 172 | { | ||
| 173 | display('''You have ''' + player.hpCur + ''' hp left.'''); | ||
| 174 | } | ||
| 126 | } | 175 | } |
| 127 | 176 | ||
| 128 | situation <<travel>> | 177 | situation <<travel>> |
| 129 | { | 178 | { |
| 179 | command: "hi" | ||
| 180 | { | ||
| 181 | display("Yup, you're in travel."); | ||
| 182 | } | ||
| 183 | |||
| 130 | enter | 184 | enter |
| 131 | { | 185 | { |
| 132 | delete( global.enemy ); | 186 | delete( global.enemy ); |
| 133 | 187 | ||
| 134 | display('You wander aimlessly through the seemingly endless field of wheat.'); | 188 | display('You wander aimlessly through the seemingly endless field of wheat.'); |
| 135 | 189 | ||
| 136 | select = random(1,3); | 190 | select = random(1,6); |
| 137 | if select == 1 then | 191 | if select <= 4 then // 66% of the time, enemy! |
| 138 | { | 192 | { |
| 139 | mkEnemy(); | 193 | mkEnemy(); |
| 140 | display('''There's a ''' + global.enemy['name'] + ''' here!'''); | 194 | display('''There's a ''' + global.enemy['name'] + ''' here!'''); |
| 141 | } | 195 | } |
| 196 | else if select == 6 then // 16% of the time, treasure! | ||
| 197 | { | ||
| 198 | mkTreasure(); | ||
| 199 | display('''You find a ''' + global.treasure['name'] + | ||
| 200 | ''' lying here!'''); | ||
| 201 | } | ||
| 142 | 202 | ||
| 143 | global.bJustTravelled = true; | 203 | global.bJustTravelled = true; |
| 144 | 204 | ||
| @@ -161,11 +221,64 @@ situation <<field>> | |||
| 161 | } | 221 | } |
| 162 | } | 222 | } |
| 163 | 223 | ||
| 224 | command: "take" | ||
| 225 | { | ||
| 226 | if exists(global.treasure) then | ||
| 227 | { | ||
| 228 | if global.treasure['name'] == 'potion' then | ||
| 229 | { | ||
| 230 | display('''You pickup the ''' + global.treasure['name'] + | ||
| 231 | ''' and put it in your pocket.'''); | ||
| 232 | player.potions += 1; | ||
| 233 | delete( global.treasure ); | ||
| 234 | } | ||
| 235 | } | ||
| 236 | else | ||
| 237 | { | ||
| 238 | display('''There's nothing here to take...'''); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | command: 'drink' | ||
| 243 | { | ||
| 244 | if player.potions == 0 then | ||
| 245 | { | ||
| 246 | display('''You don't have anything to drink!'''); | ||
| 247 | } | ||
| 248 | else | ||
| 249 | { | ||
| 250 | if player.hpCur == player.hpMax then | ||
| 251 | { | ||
| 252 | display('''You're already as healthy as can be! | ||
| 253 | Save the potions for when you're more injured.'''); | ||
| 254 | } | ||
| 255 | else | ||
| 256 | { | ||
| 257 | player.potions -= 1; | ||
| 258 | gain = integer( random( 0.25, 0.5 ) * player.hpMax ); | ||
| 259 | player.hpCur += gain; | ||
| 260 | if player.hpCur > player.hpMax then | ||
| 261 | { | ||
| 262 | gain -= player.hpCur - player.hpMax; | ||
| 263 | player.hpCur = player.hpMax; | ||
| 264 | } | ||
| 265 | display('''That really hit the spot! The potion restored ''' + | ||
| 266 | gain + ''' hp!'''); | ||
| 267 | goto( <<field>> ); | ||
| 268 | } | ||
| 269 | } | ||
| 270 | } | ||
| 271 | |||
| 164 | command: "look" | 272 | command: "look" |
| 165 | { | 273 | { |
| 166 | look(); | 274 | look(); |
| 167 | } | 275 | } |
| 168 | 276 | ||
| 277 | command: "status" | ||
| 278 | { | ||
| 279 | status(); | ||
| 280 | } | ||
| 281 | |||
| 169 | command: "walk" | 282 | command: "walk" |
| 170 | { | 283 | { |
| 171 | if not exists(global.enemy) then | 284 | if not exists(global.enemy) then |
| @@ -174,11 +287,17 @@ situation <<field>> | |||
| 174 | } | 287 | } |
| 175 | else | 288 | else |
| 176 | { | 289 | { |
| 177 | display("You can't walk around with an enemy in front of you! | 290 | display("You can't leave, the " + global.enemy['name'] + |
| 178 | You can try to flee if you'd like..."); | 291 | ' is blocking your path.'); |
| 179 | } | 292 | } |
| 180 | } | 293 | } |
| 181 | 294 | ||
| 295 | command: "help" | ||
| 296 | { | ||
| 297 | display("Available commands are: walk, status, look, attack, take, | ||
| 298 | drink"); | ||
| 299 | } | ||
| 300 | |||
| 182 | setup | 301 | setup |
| 183 | { | 302 | { |
| 184 | look(); | 303 | look(); |
| @@ -192,11 +311,6 @@ situation <<field>> | |||
| 192 | { | 311 | { |
| 193 | enemyAttack(); | 312 | enemyAttack(); |
| 194 | } | 313 | } |
| 195 | status(); | ||
| 196 | // look(); | ||
| 197 | } | ||
| 198 | else | ||
| 199 | { | ||
| 200 | } | 314 | } |
| 201 | global.bJustTravelled = false; | 315 | global.bJustTravelled = false; |
| 202 | } | 316 | } |
diff --git a/src/functionfloat.cpp b/src/functionfloat.cpp new file mode 100644 index 0000000..7d6a0a5 --- /dev/null +++ b/src/functionfloat.cpp | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #include "functionfloat.h" | ||
| 2 | |||
| 3 | #include "gamestate.h" | ||
| 4 | |||
| 5 | FunctionFloat::FunctionFloat() | ||
| 6 | { | ||
| 7 | } | ||
| 8 | |||
| 9 | FunctionFloat::~FunctionFloat() | ||
| 10 | { | ||
| 11 | } | ||
| 12 | |||
| 13 | void FunctionFloat::call( class GameState &gState ) | ||
| 14 | { | ||
| 15 | gState.push( gState.popDeref().to( Variable::tFloat ) ); | ||
| 16 | } | ||
| 17 | |||
diff --git a/src/functionfloat.h b/src/functionfloat.h new file mode 100644 index 0000000..ca72151 --- /dev/null +++ b/src/functionfloat.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | #ifndef FUNCTION_FLOAT_H | ||
| 2 | #define FUNCTION_FLOAT_H | ||
| 3 | |||
| 4 | #include "function.h" | ||
| 5 | |||
| 6 | class FunctionFloat : public Function | ||
| 7 | { | ||
| 8 | public: | ||
| 9 | FunctionFloat(); | ||
| 10 | virtual ~FunctionFloat(); | ||
| 11 | |||
| 12 | virtual Bu::String getName() const { return "float"; } | ||
| 13 | virtual void call( class GameState &gState ); | ||
| 14 | }; | ||
| 15 | |||
| 16 | #endif | ||
diff --git a/src/functioninteger.cpp b/src/functioninteger.cpp new file mode 100644 index 0000000..049f9ca --- /dev/null +++ b/src/functioninteger.cpp | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #include "functioninteger.h" | ||
| 2 | |||
| 3 | #include "gamestate.h" | ||
| 4 | |||
| 5 | FunctionInteger::FunctionInteger() | ||
| 6 | { | ||
| 7 | } | ||
| 8 | |||
| 9 | FunctionInteger::~FunctionInteger() | ||
| 10 | { | ||
| 11 | } | ||
| 12 | |||
| 13 | void FunctionInteger::call( class GameState &gState ) | ||
| 14 | { | ||
| 15 | gState.push( gState.popDeref().to( Variable::tInt ) ); | ||
| 16 | } | ||
| 17 | |||
diff --git a/src/functioninteger.h b/src/functioninteger.h new file mode 100644 index 0000000..2832c20 --- /dev/null +++ b/src/functioninteger.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | #ifndef FUNCTION_INTEGER_H | ||
| 2 | #define FUNCTION_INTEGER_H | ||
| 3 | |||
| 4 | #include "function.h" | ||
| 5 | |||
| 6 | class FunctionInteger : public Function | ||
| 7 | { | ||
| 8 | public: | ||
| 9 | FunctionInteger(); | ||
| 10 | virtual ~FunctionInteger(); | ||
| 11 | |||
| 12 | virtual Bu::String getName() const { return "integer"; } | ||
| 13 | virtual void call( class GameState &gState ); | ||
| 14 | }; | ||
| 15 | |||
| 16 | #endif | ||
diff --git a/src/functionrandom.cpp b/src/functionrandom.cpp index 2665a14..ec302b3 100644 --- a/src/functionrandom.cpp +++ b/src/functionrandom.cpp | |||
| @@ -20,10 +20,17 @@ void FunctionRandom::call( class GameState &gState ) | |||
| 20 | if( vHigh.getType() != vLow.getType() ) | 20 | if( vHigh.getType() != vLow.getType() ) |
| 21 | throw Bu::ExceptionBase("Different types in random!"); | 21 | throw Bu::ExceptionBase("Different types in random!"); |
| 22 | 22 | ||
| 23 | double dRand = random()/(double)(RAND_MAX-1); | ||
| 23 | if( vLow.getType() == Variable::tInt ) | 24 | if( vLow.getType() == Variable::tInt ) |
| 24 | { | 25 | { |
| 25 | gState.push( Variable( (int64_t)( | 26 | gState.push( Variable( (int64_t)( |
| 26 | (random()%(vHigh.getInt()-vLow.getInt()+1ll))+vLow.getInt() | 27 | (dRand*(vHigh.getInt()-vLow.getInt()+1ll))+vLow.getInt() |
| 28 | ) ) ); | ||
| 29 | } | ||
| 30 | else if( vLow.getType() == Variable::tFloat ) | ||
| 31 | { | ||
| 32 | gState.push( Variable( (double)( | ||
| 33 | (dRand*(vHigh.getFloat()-vLow.getFloat()))+vLow.getFloat() | ||
| 27 | ) ) ); | 34 | ) ) ); |
| 28 | } | 35 | } |
| 29 | } | 36 | } |
diff --git a/src/game.cpp b/src/game.cpp index c19b039..3a432d9 100644 --- a/src/game.cpp +++ b/src/game.cpp | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | #include "functiondelete.h" | 5 | #include "functiondelete.h" |
| 6 | #include "functionexit.h" | 6 | #include "functionexit.h" |
| 7 | #include "functionrandom.h" | 7 | #include "functionrandom.h" |
| 8 | #include "functioninteger.h" | ||
| 9 | #include "functionfloat.h" | ||
| 8 | 10 | ||
| 9 | Game::Game() | 11 | Game::Game() |
| 10 | { | 12 | { |
| @@ -14,6 +16,8 @@ Game::Game() | |||
| 14 | addFunction( new FunctionDelete() ); | 16 | addFunction( new FunctionDelete() ); |
| 15 | addFunction( new FunctionExit() ); | 17 | addFunction( new FunctionExit() ); |
| 16 | addFunction( new FunctionRandom() ); | 18 | addFunction( new FunctionRandom() ); |
| 19 | addFunction( new FunctionInteger() ); | ||
| 20 | addFunction( new FunctionFloat() ); | ||
| 17 | } | 21 | } |
| 18 | 22 | ||
| 19 | Game::~Game() | 23 | Game::~Game() |
diff --git a/src/gamebuilder.cpp b/src/gamebuilder.cpp index d04a642..3cf2e1f 100644 --- a/src/gamebuilder.cpp +++ b/src/gamebuilder.cpp | |||
| @@ -88,7 +88,7 @@ void GameBuilder::beginSituationMode( Situation::Mode m ) | |||
| 88 | 88 | ||
| 89 | void GameBuilder::closeSituationMode() | 89 | void GameBuilder::closeSituationMode() |
| 90 | { | 90 | { |
| 91 | //sio << "Set situation mode " << eCurSitMode << " to " << *pCurRoot << sio.nl; | 91 | // sio << "Set situation <<" << pCurSit->getName() << ">> mode " << eCurSitMode << " to " << *pCurRoot << sio.nl; |
| 92 | pCurSit->setAst( pCurRoot, eCurSitMode ); | 92 | pCurSit->setAst( pCurRoot, eCurSitMode ); |
| 93 | pCurRoot = pCurNode = NULL; | 93 | pCurRoot = pCurNode = NULL; |
| 94 | } | 94 | } |
diff --git a/src/parser.l b/src/parser.l index 7b11765..e0bc340 100644 --- a/src/parser.l +++ b/src/parser.l | |||
| @@ -67,7 +67,7 @@ null { return tokNull; } | |||
| 67 | 67 | ||
| 68 | [a-zA-Z_][a-zA-Z0-9_]* { yylval->sValue = new Bu::String( yytext ); return tokIdent; } | 68 | [a-zA-Z_][a-zA-Z0-9_]* { yylval->sValue = new Bu::String( yytext ); return tokIdent; } |
| 69 | 69 | ||
| 70 | [1-9][0-9]* { | 70 | -?[1-9][0-9]* { |
| 71 | yylval->iValue = strtoll( yytext, NULL, 10 ); | 71 | yylval->iValue = strtoll( yytext, NULL, 10 ); |
| 72 | return tokInt; | 72 | return tokInt; |
| 73 | } | 73 | } |
| @@ -76,10 +76,10 @@ null { return tokNull; } | |||
| 76 | return tokInt; | 76 | return tokInt; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | ([1-9][0-9]*)?\.[0-9]* { | 79 | -?([1-9][0-9]*|0)?\.[0-9]* { |
| 80 | printf("Parsing float: %s\n", yytext ); | 80 | // printf("Parsing float: %s\n", yytext ); |
| 81 | yylval->dValue = strtod( yytext, NULL ); | 81 | yylval->dValue = strtod( yytext, NULL ); |
| 82 | printf("Final float: %f\n", yylval->dValue ); | 82 | // printf("Final float: %f\n", yylval->dValue ); |
| 83 | return tokFloat; | 83 | return tokFloat; |
| 84 | } | 84 | } |
| 85 | 85 | ||
diff --git a/src/parser.y b/src/parser.y index 3dfd737..2e9eead 100644 --- a/src/parser.y +++ b/src/parser.y | |||
| @@ -54,7 +54,7 @@ void yyerror( YYLTYPE *llocp, yyscan_t yyscanner, GameBuilder &, const char *err | |||
| 54 | %token tokDo | 54 | %token tokDo |
| 55 | %token tokIn | 55 | %token tokIn |
| 56 | %token tokIf | 56 | %token tokIf |
| 57 | %token tokThen | 57 | %token tokThen "then" |
| 58 | %token tokElse | 58 | %token tokElse |
| 59 | %token tokNot | 59 | %token tokNot |
| 60 | %token tokCommand | 60 | %token tokCommand |
| @@ -204,7 +204,9 @@ ifnext: | |||
| 204 | | tokElse { bld.addNode( AstNode::tScope ); } '{' cmpltExprList '}' { | 204 | | tokElse { bld.addNode( AstNode::tScope ); } '{' cmpltExprList '}' { |
| 205 | bld.closeNode(); | 205 | bld.closeNode(); |
| 206 | } | 206 | } |
| 207 | | tokElse { bld.addNode( AstNode::tScope ); } ifbase | 207 | | tokElse { bld.addNode( AstNode::tScope ); } ifbase { |
| 208 | bld.closeNode(); | ||
| 209 | } | ||
| 208 | ; | 210 | ; |
| 209 | 211 | ||
| 210 | varRef: tokIdent { bld.addVarRef( *($1), sidLocal ); } | 212 | varRef: tokIdent { bld.addVarRef( *($1), sidLocal ); } |
diff --git a/src/variable.cpp b/src/variable.cpp index 965e1af..2ea8334 100644 --- a/src/variable.cpp +++ b/src/variable.cpp | |||
| @@ -463,7 +463,6 @@ Variable Variable::operator+( const Variable &rhs ) const | |||
| 463 | { | 463 | { |
| 464 | return *this + rhs.to( eNew ); | 464 | return *this + rhs.to( eNew ); |
| 465 | } | 465 | } |
| 466 | throw VariableException("Adding between dissimilar types is not yet supported."); | ||
| 467 | } | 466 | } |
| 468 | else | 467 | else |
| 469 | { | 468 | { |
| @@ -509,7 +508,16 @@ Variable Variable::operator-( const Variable &rhs ) const | |||
| 509 | { | 508 | { |
| 510 | if( eType != rhs.eType ) | 509 | if( eType != rhs.eType ) |
| 511 | { | 510 | { |
| 512 | throw VariableException("Subtracting between dissimilar types is not yet supported."); | 511 | Type eNew = bestType( eType, rhs.eType ); |
| 512 | |||
| 513 | if( eType != eNew ) | ||
| 514 | { | ||
| 515 | return to( eNew ) - rhs; | ||
| 516 | } | ||
| 517 | else | ||
| 518 | { | ||
| 519 | return *this - rhs.to( eNew ); | ||
| 520 | } | ||
| 513 | } | 521 | } |
| 514 | else | 522 | else |
| 515 | { | 523 | { |
| @@ -551,7 +559,16 @@ Variable Variable::operator*( const Variable &rhs ) const | |||
| 551 | { | 559 | { |
| 552 | if( eType != rhs.eType ) | 560 | if( eType != rhs.eType ) |
| 553 | { | 561 | { |
| 554 | throw VariableException("Subtracting between dissimilar types is not yet supported."); | 562 | Type eNew = bestType( eType, rhs.eType ); |
| 563 | |||
| 564 | if( eType != eNew ) | ||
| 565 | { | ||
| 566 | return to( eNew ) * rhs; | ||
| 567 | } | ||
| 568 | else | ||
| 569 | { | ||
| 570 | return *this * rhs.to( eNew ); | ||
| 571 | } | ||
| 555 | } | 572 | } |
| 556 | else | 573 | else |
| 557 | { | 574 | { |
| @@ -592,7 +609,16 @@ Variable Variable::operator/( const Variable &rhs ) const | |||
| 592 | { | 609 | { |
| 593 | if( eType != rhs.eType ) | 610 | if( eType != rhs.eType ) |
| 594 | { | 611 | { |
| 595 | throw VariableException("Subtracting between dissimilar types is not yet supported."); | 612 | Type eNew = bestType( eType, rhs.eType ); |
| 613 | |||
| 614 | if( eType != eNew ) | ||
| 615 | { | ||
| 616 | return to( eNew ) / rhs; | ||
| 617 | } | ||
| 618 | else | ||
| 619 | { | ||
| 620 | return *this / rhs.to( eNew ); | ||
| 621 | } | ||
| 596 | } | 622 | } |
| 597 | else | 623 | else |
| 598 | { | 624 | { |
diff --git a/support/vim/syntax/stage.vim b/support/vim/syntax/stage.vim index 34da126..45e1346 100644 --- a/support/vim/syntax/stage.vim +++ b/support/vim/syntax/stage.vim | |||
| @@ -19,7 +19,7 @@ syn keyword Statement setup enter | |||
| 19 | syn keyword Todo TODO FIXME XXX | 19 | syn keyword Todo TODO FIXME XXX |
| 20 | syn keyword Type function command situation game global player | 20 | syn keyword Type function command situation game global player |
| 21 | syn keyword Constant null true false | 21 | syn keyword Constant null true false |
| 22 | syn keyword Builtins display goto exists delete exit return | 22 | syn keyword Builtins display goto exists delete exit return random integer float |
| 23 | 23 | ||
| 24 | syn cluster CommentGroup contains=Todo | 24 | syn cluster CommentGroup contains=Todo |
| 25 | 25 | ||
| @@ -17,13 +17,11 @@ situation <<start>> | |||
| 17 | { | 17 | { |
| 18 | setup | 18 | setup |
| 19 | { | 19 | { |
| 20 | stuff = {}; | 20 | for each i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] do |
| 21 | stuff['bob'] = {'joe': 'hi', 'sub': {1: 5, 2: 8} }; | 21 | { |
| 22 | stuff['bob']['sub'][55] = "aoeu"; | 22 | display( random(0.25, 0.5)*10 ); |
| 23 | stuff['bob'] = 'hia'; | 23 | } |
| 24 | stuff['joe'] = stuff['bob']; | 24 | display( 0.25 * 10.0 ); |
| 25 | stuff['joe'] += 'aoeu'; | ||
| 26 | display( stuff['bob']['sub'][55] ); | ||
| 27 | exit(); | 25 | exit(); |
| 28 | } | 26 | } |
| 29 | 27 | ||
