diff options
Diffstat (limited to '')
| -rw-r--r-- | src/variable.cpp | 892 |
1 files changed, 892 insertions, 0 deletions
diff --git a/src/variable.cpp b/src/variable.cpp new file mode 100644 index 0000000..99bac59 --- /dev/null +++ b/src/variable.cpp | |||
| @@ -0,0 +1,892 @@ | |||
| 1 | #include "variable.h" | ||
| 2 | #include "astleaf.h" | ||
| 3 | #include "bu/sio.h" | ||
| 4 | using Bu::sio; | ||
| 5 | |||
| 6 | #include <stdlib.h> | ||
| 7 | |||
| 8 | Variable::Variable() : | ||
| 9 | eType( typeNone ) | ||
| 10 | { | ||
| 11 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 12 | } | ||
| 13 | |||
| 14 | Variable::Variable( Type t ) : | ||
| 15 | eType( t ) | ||
| 16 | { | ||
| 17 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 18 | if( eType == typeString || eType == typeRef ) | ||
| 19 | { | ||
| 20 | uVal.sVal = new Bu::FString; | ||
| 21 | } | ||
| 22 | else if( eType == typeList ) | ||
| 23 | { | ||
| 24 | uVal.lVal = new VarList; | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | Variable::Variable( int iVal ) : | ||
| 29 | eType( typeInt ) | ||
| 30 | { | ||
| 31 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 32 | uVal.iVal = iVal; | ||
| 33 | } | ||
| 34 | |||
| 35 | Variable::Variable( double fVal ) : | ||
| 36 | eType( typeFloat ) | ||
| 37 | { | ||
| 38 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 39 | uVal.fVal = fVal; | ||
| 40 | } | ||
| 41 | |||
| 42 | Variable::Variable( bool bVal ) : | ||
| 43 | eType( typeBool ) | ||
| 44 | { | ||
| 45 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 46 | uVal.bVal = bVal; | ||
| 47 | } | ||
| 48 | |||
| 49 | Variable::Variable( const Bu::FString &sVal ) : | ||
| 50 | eType( typeString ) | ||
| 51 | { | ||
| 52 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 53 | uVal.sVal = new Bu::FString( sVal ); | ||
| 54 | } | ||
| 55 | |||
| 56 | Variable::Variable( const char *sVal ) : | ||
| 57 | eType( typeString ) | ||
| 58 | { | ||
| 59 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 60 | uVal.sVal = new Bu::FString( sVal ); | ||
| 61 | } | ||
| 62 | |||
| 63 | Variable::Variable( const Variable &v ) : | ||
| 64 | eType( v.eType ) | ||
| 65 | { | ||
| 66 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 67 | if( eType == typeString || eType == typeRef ) | ||
| 68 | { | ||
| 69 | uVal.sVal = new Bu::FString( *v.uVal.sVal ); | ||
| 70 | } | ||
| 71 | else if( eType == typeList ) | ||
| 72 | { | ||
| 73 | uVal.lVal = new VarList( *v.uVal.lVal ); | ||
| 74 | } | ||
| 75 | else | ||
| 76 | { | ||
| 77 | uVal = v.uVal; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | |||
| 81 | Variable::Variable( const class AstLeaf &l ) | ||
| 82 | { | ||
| 83 | switch( l.getDataType() ) | ||
| 84 | { | ||
| 85 | case AstNode::typeDataInt: | ||
| 86 | eType = typeInt; | ||
| 87 | uVal.iVal = l.getIntValue(); | ||
| 88 | break; | ||
| 89 | |||
| 90 | case AstNode::typeDataFloat: | ||
| 91 | eType = typeFloat; | ||
| 92 | uVal.fVal = l.getFloatValue(); | ||
| 93 | break; | ||
| 94 | |||
| 95 | case AstNode::typeDataBool: | ||
| 96 | eType = typeBool; | ||
| 97 | uVal.bVal = l.getBoolValue(); | ||
| 98 | break; | ||
| 99 | |||
| 100 | case AstNode::typeDataString: | ||
| 101 | eType = typeString; | ||
| 102 | uVal.sVal = new Bu::FString( l.getStrValue() ); | ||
| 103 | break; | ||
| 104 | |||
| 105 | case AstNode::typeDataNone: | ||
| 106 | eType = typeNone; | ||
| 107 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 108 | break; | ||
| 109 | |||
| 110 | default: | ||
| 111 | sio << "Unhandled type <<!>>" << sio.nl << sio.nl; | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | } | ||
| 115 | |||
| 116 | Variable::Variable( const StrList &lst ) | ||
| 117 | { | ||
| 118 | if( lst.getSize() == 1 ) | ||
| 119 | { | ||
| 120 | eType = typeString; | ||
| 121 | uVal.sVal = new Bu::FString( lst.first() ); | ||
| 122 | } | ||
| 123 | else | ||
| 124 | { | ||
| 125 | eType = typeList; | ||
| 126 | uVal.lVal = new VarList(); | ||
| 127 | for( StrList::const_iterator i = lst.begin(); i; i++ ) | ||
| 128 | { | ||
| 129 | uVal.lVal->append( Variable( *i ) ); | ||
| 130 | } | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | Variable::Variable( const VarList &lst ) | ||
| 135 | { | ||
| 136 | eType = typeList; | ||
| 137 | uVal.lVal = new VarList( lst ); | ||
| 138 | } | ||
| 139 | |||
| 140 | Variable::~Variable() | ||
| 141 | { | ||
| 142 | if( eType == typeString || eType == typeRef ) | ||
| 143 | { | ||
| 144 | delete uVal.sVal; | ||
| 145 | } | ||
| 146 | else if( eType == typeList ) | ||
| 147 | { | ||
| 148 | delete uVal.lVal; | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | Variable Variable::mkRef( const Bu::FString &sVal ) | ||
| 153 | { | ||
| 154 | Variable v( typeRef ); | ||
| 155 | (*v.uVal.sVal) = sVal; | ||
| 156 | return v; | ||
| 157 | } | ||
| 158 | |||
| 159 | Variable::Type Variable::getType() const | ||
| 160 | { | ||
| 161 | return eType; | ||
| 162 | } | ||
| 163 | |||
| 164 | int Variable::getInt() const | ||
| 165 | { | ||
| 166 | if( eType != typeInt ) throw Bu::ExceptionBase("Wrong variable type."); | ||
| 167 | return uVal.iVal; | ||
| 168 | } | ||
| 169 | |||
| 170 | double Variable::getFloat() const | ||
| 171 | { | ||
| 172 | if( eType != typeFloat ) throw Bu::ExceptionBase("Wrong variable type."); | ||
| 173 | return uVal.fVal; | ||
| 174 | } | ||
| 175 | |||
| 176 | bool Variable::getBool() const | ||
| 177 | { | ||
| 178 | if( eType != typeBool ) throw Bu::ExceptionBase("Wrong variable type."); | ||
| 179 | return uVal.bVal; | ||
| 180 | } | ||
| 181 | |||
| 182 | const Bu::FString &Variable::getString() const | ||
| 183 | { | ||
| 184 | if( eType != typeString && eType != typeRef ) throw Bu::ExceptionBase("Wrong variable type."); | ||
| 185 | return *uVal.sVal; | ||
| 186 | } | ||
| 187 | |||
| 188 | const VarList &Variable::getList() const | ||
| 189 | { | ||
| 190 | if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type."); | ||
| 191 | return *uVal.lVal; | ||
| 192 | } | ||
| 193 | |||
| 194 | int Variable::toInt() const | ||
| 195 | { | ||
| 196 | switch( eType ) | ||
| 197 | { | ||
| 198 | case typeInt: | ||
| 199 | return uVal.iVal; | ||
| 200 | |||
| 201 | case typeFloat: | ||
| 202 | return (int)uVal.fVal; | ||
| 203 | |||
| 204 | case typeBool: | ||
| 205 | return (uVal.bVal)?(1):(0); | ||
| 206 | |||
| 207 | case typeString: | ||
| 208 | case typeRef: | ||
| 209 | return strtol( uVal.sVal->getStr(), NULL, 0 ); | ||
| 210 | |||
| 211 | default: | ||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | return 0; | ||
| 215 | } | ||
| 216 | |||
| 217 | double Variable::toFloat() const | ||
| 218 | { | ||
| 219 | switch( eType ) | ||
| 220 | { | ||
| 221 | case typeInt: | ||
| 222 | return (double)uVal.iVal; | ||
| 223 | |||
| 224 | case typeFloat: | ||
| 225 | return uVal.fVal; | ||
| 226 | |||
| 227 | case typeBool: | ||
| 228 | return (uVal.bVal)?(1.0):(0.0); | ||
| 229 | |||
| 230 | case typeString: | ||
| 231 | case typeRef: | ||
| 232 | return strtod( uVal.sVal->getStr(), NULL ); | ||
| 233 | |||
| 234 | default: | ||
| 235 | return 0.0; | ||
| 236 | } | ||
| 237 | return 0.0; | ||
| 238 | } | ||
| 239 | |||
| 240 | bool Variable::toBool() const | ||
| 241 | { | ||
| 242 | switch( eType ) | ||
| 243 | { | ||
| 244 | case typeInt: | ||
| 245 | return uVal.iVal != 0; | ||
| 246 | |||
| 247 | case typeFloat: | ||
| 248 | return uVal.fVal != 0.0; | ||
| 249 | |||
| 250 | case typeBool: | ||
| 251 | return uVal.bVal; | ||
| 252 | |||
| 253 | case typeString: | ||
| 254 | case typeRef: | ||
| 255 | return (*uVal.sVal) == "true"; | ||
| 256 | |||
| 257 | case typeList: | ||
| 258 | return !(*uVal.lVal).isEmpty(); | ||
| 259 | |||
| 260 | default: | ||
| 261 | return false; | ||
| 262 | } | ||
| 263 | return false; | ||
| 264 | } | ||
| 265 | |||
| 266 | Bu::FString Variable::toString() const | ||
| 267 | { | ||
| 268 | Bu::FString sRet; | ||
| 269 | switch( eType ) | ||
| 270 | { | ||
| 271 | case typeNone: | ||
| 272 | // No type, no data, we return empty string | ||
| 273 | break; | ||
| 274 | |||
| 275 | case typeInt: | ||
| 276 | sRet.format("%d", uVal.iVal ); | ||
| 277 | break; | ||
| 278 | |||
| 279 | case typeFloat: | ||
| 280 | sRet.format("%f", uVal.fVal ); | ||
| 281 | break; | ||
| 282 | |||
| 283 | case typeBool: | ||
| 284 | sRet = (uVal.bVal)?("true"):("false"); | ||
| 285 | break; | ||
| 286 | |||
| 287 | case typeString: | ||
| 288 | case typeRef: | ||
| 289 | sRet = *uVal.sVal; | ||
| 290 | break; | ||
| 291 | |||
| 292 | case typeList: | ||
| 293 | { | ||
| 294 | for( VarList::const_iterator i = uVal.lVal->begin(); i; i++ ) | ||
| 295 | { | ||
| 296 | if( i != uVal.lVal->begin() ) | ||
| 297 | sRet += " "; | ||
| 298 | sRet += (*i).toString(); | ||
| 299 | } | ||
| 300 | } | ||
| 301 | break; | ||
| 302 | |||
| 303 | case typeVersion: | ||
| 304 | break; | ||
| 305 | } | ||
| 306 | |||
| 307 | return sRet; | ||
| 308 | } | ||
| 309 | |||
| 310 | VarList Variable::toList() const | ||
| 311 | { | ||
| 312 | if( eType == typeList ) | ||
| 313 | return *this; | ||
| 314 | return VarList( *this ); | ||
| 315 | } | ||
| 316 | |||
| 317 | Variable Variable::toType( Type eNewType ) const | ||
| 318 | { | ||
| 319 | switch( eNewType ) | ||
| 320 | { | ||
| 321 | case typeNone: | ||
| 322 | return Variable(); | ||
| 323 | |||
| 324 | case typeBool: | ||
| 325 | return Variable( toBool() ); | ||
| 326 | |||
| 327 | case typeInt: | ||
| 328 | return Variable( toInt() ); | ||
| 329 | |||
| 330 | case typeFloat: | ||
| 331 | return Variable( toFloat() ); | ||
| 332 | |||
| 333 | case typeVersion: | ||
| 334 | return Variable(); | ||
| 335 | |||
| 336 | case typeString: | ||
| 337 | return Variable( toString() ); | ||
| 338 | |||
| 339 | case typeList: | ||
| 340 | return Variable( toList() ); | ||
| 341 | |||
| 342 | case typeRef: | ||
| 343 | return Variable::mkRef( toString() ); | ||
| 344 | } | ||
| 345 | throw Bu::ExceptionBase("Unhandled case in Variable toType"); | ||
| 346 | } | ||
| 347 | |||
| 348 | void Variable::append( const Variable &v ) | ||
| 349 | { | ||
| 350 | if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type."); | ||
| 351 | |||
| 352 | if( v.eType == typeList ) | ||
| 353 | { | ||
| 354 | uVal.lVal->append( *v.uVal.lVal ); | ||
| 355 | } | ||
| 356 | else | ||
| 357 | { | ||
| 358 | uVal.lVal->append( v ); | ||
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 | VarList::iterator Variable::begin() | ||
| 363 | { | ||
| 364 | if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type."); | ||
| 365 | |||
| 366 | return uVal.lVal->begin(); | ||
| 367 | } | ||
| 368 | |||
| 369 | VarList::const_iterator Variable::begin() const | ||
| 370 | { | ||
| 371 | if( eType != typeList ) throw Bu::ExceptionBase("Wrong variable type."); | ||
| 372 | |||
| 373 | return const_cast<const VarList *>(uVal.lVal)->begin(); | ||
| 374 | } | ||
| 375 | |||
| 376 | void Variable::doNegate() | ||
| 377 | { | ||
| 378 | switch( eType ) | ||
| 379 | { | ||
| 380 | case typeNone: | ||
| 381 | break; | ||
| 382 | |||
| 383 | case typeBool: | ||
| 384 | throw Bu::ExceptionBase("You cannot negate boolean values."); | ||
| 385 | |||
| 386 | case typeInt: | ||
| 387 | uVal.iVal = -uVal.iVal; | ||
| 388 | break; | ||
| 389 | |||
| 390 | case typeFloat: | ||
| 391 | uVal.fVal = -uVal.fVal; | ||
| 392 | break; | ||
| 393 | |||
| 394 | case typeVersion: | ||
| 395 | throw Bu::ExceptionBase("You cannot negate version values."); | ||
| 396 | |||
| 397 | case typeString: | ||
| 398 | throw Bu::ExceptionBase("You cannot negate string values."); | ||
| 399 | |||
| 400 | case typeList: | ||
| 401 | throw Bu::ExceptionBase("You cannot negate list values."); | ||
| 402 | |||
| 403 | case typeRef: | ||
| 404 | throw Bu::ExceptionBase("You cannot negate reference values."); | ||
| 405 | } | ||
| 406 | } | ||
| 407 | |||
| 408 | void Variable::doNot() | ||
| 409 | { | ||
| 410 | bool bVal = !toBool(); | ||
| 411 | reset( typeBool ); | ||
| 412 | uVal.bVal = bVal; | ||
| 413 | } | ||
| 414 | |||
| 415 | const Variable &Variable::operator=( const Variable &rhs ) | ||
| 416 | { | ||
| 417 | reset( rhs.eType ); | ||
| 418 | if( rhs.eType == typeString || rhs.eType == typeRef ) | ||
| 419 | { | ||
| 420 | uVal.sVal = new Bu::FString( *rhs.uVal.sVal ); | ||
| 421 | } | ||
| 422 | else if( rhs.eType == typeList ) | ||
| 423 | { | ||
| 424 | uVal.lVal = new VarList( *rhs.uVal.lVal ); | ||
| 425 | } | ||
| 426 | else | ||
| 427 | { | ||
| 428 | uVal = rhs.uVal; | ||
| 429 | } | ||
| 430 | |||
| 431 | return *this; | ||
| 432 | } | ||
| 433 | |||
| 434 | const Variable &Variable::operator=( const int &rhs ) | ||
| 435 | { | ||
| 436 | reset( typeInt ); | ||
| 437 | uVal.iVal = rhs; | ||
| 438 | |||
| 439 | return *this; | ||
| 440 | } | ||
| 441 | |||
| 442 | const Variable &Variable::operator=( const double &rhs ) | ||
| 443 | { | ||
| 444 | reset( typeFloat ); | ||
| 445 | uVal.fVal = rhs; | ||
| 446 | |||
| 447 | return *this; | ||
| 448 | } | ||
| 449 | |||
| 450 | const Variable &Variable::operator=( const bool &rhs ) | ||
| 451 | { | ||
| 452 | reset( typeBool ); | ||
| 453 | uVal.bVal = rhs; | ||
| 454 | |||
| 455 | return *this; | ||
| 456 | } | ||
| 457 | |||
| 458 | const Variable &Variable::operator=( const Bu::FString &rhs ) | ||
| 459 | { | ||
| 460 | reset( typeString ); | ||
| 461 | uVal.sVal = new Bu::FString( rhs ); | ||
| 462 | |||
| 463 | return *this; | ||
| 464 | } | ||
| 465 | |||
| 466 | const Variable &Variable::operator+=( const Variable &rhs ) | ||
| 467 | { | ||
| 468 | switch( eType ) | ||
| 469 | { | ||
| 470 | case typeNone: | ||
| 471 | reset( rhs.eType ); | ||
| 472 | if( eType == typeString || eType == typeRef ) | ||
| 473 | { | ||
| 474 | uVal.sVal = new Bu::FString( *rhs.uVal.sVal ); | ||
| 475 | } | ||
| 476 | else if( eType == typeList ) | ||
| 477 | { | ||
| 478 | uVal.lVal = new VarList( *rhs.uVal.lVal ); | ||
| 479 | } | ||
| 480 | else | ||
| 481 | { | ||
| 482 | uVal = rhs.uVal; | ||
| 483 | } | ||
| 484 | break; | ||
| 485 | |||
| 486 | case typeInt: | ||
| 487 | uVal.iVal += rhs.getInt(); | ||
| 488 | break; | ||
| 489 | |||
| 490 | case typeFloat: | ||
| 491 | uVal.fVal += rhs.getFloat(); | ||
| 492 | break; | ||
| 493 | |||
| 494 | case typeBool: | ||
| 495 | throw Bu::ExceptionBase("Can't += with a boolean..."); | ||
| 496 | break; | ||
| 497 | |||
| 498 | case typeString: | ||
| 499 | uVal.sVal->append(" "); | ||
| 500 | uVal.sVal->append( rhs.getString() ); | ||
| 501 | break; | ||
| 502 | |||
| 503 | case typeList: | ||
| 504 | uVal.lVal->append( rhs.getList() ); | ||
| 505 | break; | ||
| 506 | |||
| 507 | case typeVersion: | ||
| 508 | break; | ||
| 509 | |||
| 510 | default: | ||
| 511 | break; | ||
| 512 | } | ||
| 513 | return *this; | ||
| 514 | } | ||
| 515 | |||
| 516 | const Variable &Variable::operator<<( const Variable &rhs ) | ||
| 517 | { | ||
| 518 | switch( eType ) | ||
| 519 | { | ||
| 520 | case typeNone: | ||
| 521 | reset( rhs.eType ); | ||
| 522 | if( eType == typeString ) | ||
| 523 | { | ||
| 524 | uVal.sVal = new Bu::FString( *rhs.uVal.sVal ); | ||
| 525 | } | ||
| 526 | else if( eType == typeList ) | ||
| 527 | { | ||
| 528 | uVal.lVal = new VarList( *rhs.uVal.lVal ); | ||
| 529 | } | ||
| 530 | else | ||
| 531 | { | ||
| 532 | uVal = rhs.uVal; | ||
| 533 | } | ||
| 534 | break; | ||
| 535 | |||
| 536 | case typeString: | ||
| 537 | uVal.sVal->append( rhs.getString() ); | ||
| 538 | break; | ||
| 539 | |||
| 540 | case typeList: | ||
| 541 | uVal.lVal->append( rhs.getList() ); | ||
| 542 | break; | ||
| 543 | |||
| 544 | default: | ||
| 545 | throw Bu::ExceptionBase("Can't << with non-string or non-list."); | ||
| 546 | break; | ||
| 547 | } | ||
| 548 | return *this; | ||
| 549 | } | ||
| 550 | |||
| 551 | bool Variable::operator==( const Variable &rhs ) const | ||
| 552 | { | ||
| 553 | if( eType != rhs.eType ) | ||
| 554 | return false; | ||
| 555 | switch( eType ) | ||
| 556 | { | ||
| 557 | case typeNone: | ||
| 558 | return true; | ||
| 559 | |||
| 560 | case typeInt: | ||
| 561 | return uVal.iVal == rhs.uVal.iVal; | ||
| 562 | |||
| 563 | case typeFloat: | ||
| 564 | return uVal.fVal == rhs.uVal.fVal; | ||
| 565 | |||
| 566 | case typeBool: | ||
| 567 | return uVal.bVal == rhs.uVal.bVal; | ||
| 568 | |||
| 569 | case typeString: | ||
| 570 | case typeRef: | ||
| 571 | return *uVal.sVal == *rhs.uVal.sVal; | ||
| 572 | |||
| 573 | case typeList: | ||
| 574 | return *uVal.lVal == *rhs.uVal.lVal; | ||
| 575 | |||
| 576 | case typeVersion: | ||
| 577 | return false; | ||
| 578 | } | ||
| 579 | |||
| 580 | return false; | ||
| 581 | } | ||
| 582 | |||
| 583 | bool Variable::operator!=( const Variable &rhs ) const | ||
| 584 | { | ||
| 585 | return !(*this == rhs); | ||
| 586 | } | ||
| 587 | |||
| 588 | bool Variable::operator<( const Variable &rhs ) const | ||
| 589 | { | ||
| 590 | Type eTop = Bu::max( eType, rhs.eType ); | ||
| 591 | switch( eTop ) | ||
| 592 | { | ||
| 593 | case typeNone: | ||
| 594 | return false; | ||
| 595 | |||
| 596 | case typeBool: | ||
| 597 | throw Bu::ExceptionBase("You cannot < compare boolean values."); | ||
| 598 | |||
| 599 | case typeInt: | ||
| 600 | return toInt() < rhs.toInt(); | ||
| 601 | |||
| 602 | case typeFloat: | ||
| 603 | return toFloat() < rhs.toFloat(); | ||
| 604 | |||
| 605 | case typeVersion: | ||
| 606 | return true; | ||
| 607 | |||
| 608 | case typeString: | ||
| 609 | return toString() < rhs.toString(); | ||
| 610 | |||
| 611 | case typeList: | ||
| 612 | throw Bu::ExceptionBase("You cannot < compare list values."); | ||
| 613 | |||
| 614 | case typeRef: | ||
| 615 | throw Bu::ExceptionBase("You cannot < compare reference values."); | ||
| 616 | } | ||
| 617 | throw Bu::ExceptionBase("Unhandled case in Variable < compare"); | ||
| 618 | } | ||
| 619 | |||
| 620 | bool Variable::operator>( const Variable &rhs ) const | ||
| 621 | { | ||
| 622 | Type eTop = Bu::max( eType, rhs.eType ); | ||
| 623 | switch( eTop ) | ||
| 624 | { | ||
| 625 | case typeNone: | ||
| 626 | return false; | ||
| 627 | |||
| 628 | case typeBool: | ||
| 629 | throw Bu::ExceptionBase("You cannot > compare boolean values."); | ||
| 630 | |||
| 631 | case typeInt: | ||
| 632 | return toInt() > rhs.toInt(); | ||
| 633 | |||
| 634 | case typeFloat: | ||
| 635 | return toFloat() > rhs.toFloat(); | ||
| 636 | |||
| 637 | case typeVersion: | ||
| 638 | return true; | ||
| 639 | |||
| 640 | case typeString: | ||
| 641 | return toString() > rhs.toString(); | ||
| 642 | |||
| 643 | case typeList: | ||
| 644 | throw Bu::ExceptionBase("You cannot > compare list values."); | ||
| 645 | |||
| 646 | case typeRef: | ||
| 647 | throw Bu::ExceptionBase("You cannot > compare reference values."); | ||
| 648 | } | ||
| 649 | throw Bu::ExceptionBase("Unhandled case in Variable > compare"); | ||
| 650 | } | ||
| 651 | |||
| 652 | bool Variable::operator<=( const Variable &rhs ) const | ||
| 653 | { | ||
| 654 | Type eTop = Bu::max( eType, rhs.eType ); | ||
| 655 | switch( eTop ) | ||
| 656 | { | ||
| 657 | case typeNone: | ||
| 658 | return false; | ||
| 659 | |||
| 660 | case typeBool: | ||
| 661 | throw Bu::ExceptionBase("You cannot <= compare boolean values."); | ||
| 662 | |||
| 663 | case typeInt: | ||
| 664 | return toInt() <= rhs.toInt(); | ||
| 665 | |||
| 666 | case typeFloat: | ||
| 667 | return toFloat() <= rhs.toFloat(); | ||
| 668 | |||
| 669 | case typeVersion: | ||
| 670 | return true; | ||
| 671 | |||
| 672 | case typeString: | ||
| 673 | return toString() <= rhs.toString(); | ||
| 674 | |||
| 675 | case typeList: | ||
| 676 | throw Bu::ExceptionBase("You cannot <= compare list values."); | ||
| 677 | |||
| 678 | case typeRef: | ||
| 679 | throw Bu::ExceptionBase("You cannot <= compare reference values."); | ||
| 680 | } | ||
| 681 | throw Bu::ExceptionBase("Unhandled case in Variable <= compare"); | ||
| 682 | } | ||
| 683 | |||
| 684 | bool Variable::operator>=( const Variable &rhs ) const | ||
| 685 | { | ||
| 686 | Type eTop = Bu::max( eType, rhs.eType ); | ||
| 687 | switch( eTop ) | ||
| 688 | { | ||
| 689 | case typeNone: | ||
| 690 | return false; | ||
| 691 | |||
| 692 | case typeBool: | ||
| 693 | throw Bu::ExceptionBase("You cannot >= compare boolean values."); | ||
| 694 | |||
| 695 | case typeInt: | ||
| 696 | return toInt() >= rhs.toInt(); | ||
| 697 | |||
| 698 | case typeFloat: | ||
| 699 | return toFloat() >= rhs.toFloat(); | ||
| 700 | |||
| 701 | case typeVersion: | ||
| 702 | return true; | ||
| 703 | |||
| 704 | case typeString: | ||
| 705 | return toString() >= rhs.toString(); | ||
| 706 | |||
| 707 | case typeList: | ||
| 708 | throw Bu::ExceptionBase("You cannot >= compare list values."); | ||
| 709 | |||
| 710 | case typeRef: | ||
| 711 | throw Bu::ExceptionBase("You cannot >= compare reference values."); | ||
| 712 | } | ||
| 713 | throw Bu::ExceptionBase("Unhandled case in Variable >= compare"); | ||
| 714 | } | ||
| 715 | |||
| 716 | Variable Variable::operator+( const Variable &rhs ) const | ||
| 717 | { | ||
| 718 | Type eTop = Bu::max( eType, rhs.eType ); | ||
| 719 | switch( eTop ) | ||
| 720 | { | ||
| 721 | case typeNone: | ||
| 722 | return Variable(); | ||
| 723 | |||
| 724 | case typeBool: | ||
| 725 | throw Bu::ExceptionBase("You cannot add boolean values."); | ||
| 726 | |||
| 727 | case typeInt: | ||
| 728 | return Variable( toInt() + rhs.toInt() ); | ||
| 729 | |||
| 730 | case typeFloat: | ||
| 731 | return Variable( toFloat() + rhs.toFloat() ); | ||
| 732 | |||
| 733 | case typeVersion: | ||
| 734 | throw Bu::ExceptionBase("You cannot add version values."); | ||
| 735 | |||
| 736 | case typeString: | ||
| 737 | return Variable( toString() + rhs.toString() ); | ||
| 738 | |||
| 739 | case typeList: | ||
| 740 | return Variable( toList() + rhs.toList() ); | ||
| 741 | |||
| 742 | case typeRef: | ||
| 743 | throw Bu::ExceptionBase("You cannot add reference values."); | ||
| 744 | } | ||
| 745 | throw Bu::ExceptionBase("Unhandled case in Variable add"); | ||
| 746 | } | ||
| 747 | |||
| 748 | Variable Variable::operator-( const Variable &rhs ) const | ||
| 749 | { | ||
| 750 | Type eTop = Bu::max( eType, rhs.eType ); | ||
| 751 | switch( eTop ) | ||
| 752 | { | ||
| 753 | case typeNone: | ||
| 754 | return Variable(); | ||
| 755 | |||
| 756 | case typeBool: | ||
| 757 | throw Bu::ExceptionBase("You cannot subtract boolean values."); | ||
| 758 | |||
| 759 | case typeInt: | ||
| 760 | return Variable( toInt() - rhs.toInt() ); | ||
| 761 | |||
| 762 | case typeFloat: | ||
| 763 | return Variable( toFloat() - rhs.toFloat() ); | ||
| 764 | |||
| 765 | case typeVersion: | ||
| 766 | throw Bu::ExceptionBase("You cannot subtract version values."); | ||
| 767 | |||
| 768 | case typeString: | ||
| 769 | throw Bu::ExceptionBase("You cannot subtract string values."); | ||
| 770 | |||
| 771 | case typeList: | ||
| 772 | throw Bu::ExceptionBase("You cannot subtract list values."); | ||
| 773 | |||
| 774 | case typeRef: | ||
| 775 | throw Bu::ExceptionBase("You cannot subtract reference values."); | ||
| 776 | } | ||
| 777 | throw Bu::ExceptionBase("Unhandled case in Variable subtract"); | ||
| 778 | } | ||
| 779 | |||
| 780 | Variable Variable::operator*( const Variable &rhs ) const | ||
| 781 | { | ||
| 782 | Type eTop = Bu::max( eType, rhs.eType ); | ||
| 783 | switch( eTop ) | ||
| 784 | { | ||
| 785 | case typeNone: | ||
| 786 | return Variable(); | ||
| 787 | |||
| 788 | case typeBool: | ||
| 789 | throw Bu::ExceptionBase("You cannot multiply boolean values."); | ||
| 790 | |||
| 791 | case typeInt: | ||
| 792 | return Variable( toInt() * rhs.toInt() ); | ||
| 793 | |||
| 794 | case typeFloat: | ||
| 795 | return Variable( toFloat() * rhs.toFloat() ); | ||
| 796 | |||
| 797 | case typeVersion: | ||
| 798 | throw Bu::ExceptionBase("You cannot multiply version values."); | ||
| 799 | |||
| 800 | case typeString: | ||
| 801 | throw Bu::ExceptionBase("You cannot multiply string values."); | ||
| 802 | |||
| 803 | case typeList: | ||
| 804 | throw Bu::ExceptionBase("You cannot multiply list values."); | ||
| 805 | |||
| 806 | case typeRef: | ||
| 807 | throw Bu::ExceptionBase("You cannot multiply reference values."); | ||
| 808 | } | ||
| 809 | throw Bu::ExceptionBase("Unhandled case in Variable multiply"); | ||
| 810 | } | ||
| 811 | |||
| 812 | Variable Variable::operator/( const Variable &rhs ) const | ||
| 813 | { | ||
| 814 | Type eTop = Bu::max( eType, rhs.eType ); | ||
| 815 | switch( eTop ) | ||
| 816 | { | ||
| 817 | case typeNone: | ||
| 818 | return Variable(); | ||
| 819 | |||
| 820 | case typeBool: | ||
| 821 | throw Bu::ExceptionBase("You cannot divide boolean values."); | ||
| 822 | |||
| 823 | case typeInt: | ||
| 824 | return Variable( toInt() / rhs.toInt() ); | ||
| 825 | |||
| 826 | case typeFloat: | ||
| 827 | return Variable( toFloat() / rhs.toFloat() ); | ||
| 828 | |||
| 829 | case typeVersion: | ||
| 830 | throw Bu::ExceptionBase("You cannot divide version values."); | ||
| 831 | |||
| 832 | case typeString: | ||
| 833 | throw Bu::ExceptionBase("You cannot divide string values."); | ||
| 834 | |||
| 835 | case typeList: | ||
| 836 | throw Bu::ExceptionBase("You cannot divide list values."); | ||
| 837 | |||
| 838 | case typeRef: | ||
| 839 | throw Bu::ExceptionBase("You cannot divide reference values."); | ||
| 840 | } | ||
| 841 | throw Bu::ExceptionBase("Unhandled case in Variable divide"); | ||
| 842 | } | ||
| 843 | |||
| 844 | void Variable::reset( Type eNewType ) | ||
| 845 | { | ||
| 846 | if( eType == typeString || eType == typeRef ) | ||
| 847 | { | ||
| 848 | delete uVal.sVal; | ||
| 849 | } | ||
| 850 | else if( eType == typeList ) | ||
| 851 | { | ||
| 852 | delete uVal.lVal; | ||
| 853 | } | ||
| 854 | memset( &uVal, 0, sizeof(uVal) ); | ||
| 855 | |||
| 856 | eType = eNewType; | ||
| 857 | } | ||
| 858 | |||
| 859 | Bu::Formatter &operator<<( Bu::Formatter &f, const Variable::Type &t ) | ||
| 860 | { | ||
| 861 | switch( t ) | ||
| 862 | { | ||
| 863 | case Variable::typeNone: f << "*typeless*"; break; | ||
| 864 | case Variable::typeInt: f << "int"; break; | ||
| 865 | case Variable::typeFloat: f << "double"; break; | ||
| 866 | case Variable::typeBool: f << "bool"; break; | ||
| 867 | case Variable::typeString: f << "string"; break; | ||
| 868 | case Variable::typeList: f << "list"; break; | ||
| 869 | case Variable::typeVersion: f << "version"; break; | ||
| 870 | case Variable::typeRef: f << "ref"; break; | ||
| 871 | } | ||
| 872 | return f; | ||
| 873 | } | ||
| 874 | |||
| 875 | Bu::Formatter &operator<<( Bu::Formatter &f, const Variable &v ) | ||
| 876 | { | ||
| 877 | f << "Variable(" << v.getType() << ") = "; | ||
| 878 | switch( v.getType() ) | ||
| 879 | { | ||
| 880 | case Variable::typeNone: break; | ||
| 881 | case Variable::typeInt: f << v.getInt(); break; | ||
| 882 | case Variable::typeFloat: f << v.getFloat(); break; | ||
| 883 | case Variable::typeBool: f << v.getBool(); break; | ||
| 884 | case Variable::typeString: f << v.getString(); break; | ||
| 885 | case Variable::typeList: f << v.getList(); break; | ||
| 886 | case Variable::typeVersion:/*f << v.getVersion();*/ break; | ||
| 887 | case Variable::typeRef: f << v.getString(); break; | ||
| 888 | } | ||
| 889 | |||
| 890 | return f; | ||
| 891 | } | ||
| 892 | |||
