00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "global.hpp"
00017
00018 #include <cmath>
00019 #include <iostream>
00020 #include <string.h>
00021
00022 #include "boost/lexical_cast.hpp"
00023
00024 #include "formatter.hpp"
00025 #include "formula_callable.hpp"
00026 #include "formula_function.hpp"
00027 #include "util.hpp"
00028
00029 namespace {
00030 std::string variant_type_to_string(variant::TYPE type) {
00031 switch(type) {
00032 case variant::TYPE_NULL:
00033 return "null";
00034 case variant::TYPE_INT:
00035 return "int";
00036 case variant::TYPE_DECIMAL:
00037 return "decimal";
00038 case variant::TYPE_CALLABLE:
00039 return "object";
00040 case variant::TYPE_LIST:
00041 return "list";
00042 case variant::TYPE_STRING:
00043 return "string";
00044 case variant::TYPE_MAP:
00045 return "map";
00046 default:
00047 assert(false);
00048 return "invalid";
00049 }
00050 }
00051
00052 std::vector<const char*> call_stack;
00053 }
00054
00055 void push_call_stack(const char* str)
00056 {
00057 call_stack.push_back(str);
00058 }
00059
00060 void pop_call_stack()
00061 {
00062 call_stack.pop_back();
00063 }
00064
00065 std::string get_call_stack()
00066 {
00067 std::string res;
00068 for(std::vector<const char*>::const_iterator i = call_stack.begin();
00069 i != call_stack.end(); ++i) {
00070 if(!*i) {
00071 continue;
00072 }
00073 res += " ";
00074 res += *i;
00075 res += "\n";
00076 }
00077 return res;
00078 }
00079
00080 type_error::type_error(const std::string& str) : game::error(str) {
00081 std::cerr << "ERROR: " << message << "\n" << get_call_stack();
00082 }
00083
00084 variant_iterator::variant_iterator()
00085 : type_(TYPE_NULL)
00086 , list_iterator_()
00087 , map_iterator_()
00088 {
00089 }
00090
00091 variant_iterator::variant_iterator(const variant_iterator& iter)
00092 : type_(iter.type_)
00093 , list_iterator_()
00094 , map_iterator_()
00095 {
00096 switch(type_) {
00097 case TYPE_LIST :
00098 list_iterator_ = iter.list_iterator_;
00099 break;
00100
00101 case TYPE_MAP:
00102 map_iterator_ = iter.map_iterator_;
00103 break;
00104
00105 case TYPE_NULL:
00106
00107 break;
00108 }
00109 }
00110
00111 variant_iterator::variant_iterator(
00112 const std::vector<variant>::iterator& iter)
00113 : type_(TYPE_LIST)
00114 , list_iterator_(iter)
00115 , map_iterator_()
00116 {
00117 }
00118
00119 variant_iterator::variant_iterator(
00120 const std::map<variant, variant>::iterator& iter)
00121 : type_(TYPE_MAP)
00122 , list_iterator_()
00123 , map_iterator_(iter)
00124 {
00125 }
00126
00127 variant variant_iterator::operator*() const
00128 {
00129 if (type_ == TYPE_LIST)
00130 {
00131 return variant( *list_iterator_);
00132 } else if (type_ == TYPE_MAP)
00133 {
00134 game_logic::key_value_pair* p = new game_logic::key_value_pair( map_iterator_->first, map_iterator_->second );
00135 variant res( p );
00136 return res;
00137 } else
00138 return variant();
00139 }
00140
00141 variant_iterator& variant_iterator::operator++()
00142 {
00143 if (type_ == TYPE_LIST)
00144 {
00145 ++list_iterator_;
00146 } else if (type_ == TYPE_MAP)
00147 {
00148 ++map_iterator_;
00149 }
00150
00151 return *this;
00152 }
00153
00154 variant_iterator variant_iterator::operator++(int)
00155 {
00156 variant_iterator iter(*this);
00157 if (type_ == TYPE_LIST)
00158 {
00159 ++list_iterator_;
00160 } else if (type_ == TYPE_MAP)
00161 {
00162 ++map_iterator_;
00163 }
00164
00165 return iter;
00166 }
00167
00168 variant_iterator& variant_iterator::operator=(const variant_iterator& that)
00169 {
00170 if (this == &that)
00171 return *this;
00172 type_ = that.type_;
00173 switch(type_) {
00174 case TYPE_LIST :
00175 list_iterator_ = that.list_iterator_;
00176 break;
00177
00178 case TYPE_MAP:
00179 map_iterator_ = that.map_iterator_;
00180 break;
00181
00182 case TYPE_NULL:
00183
00184 break;
00185 }
00186
00187 return *this;
00188 }
00189
00190 bool variant_iterator::operator==(const variant_iterator& that) const
00191 {
00192 if (type_ == TYPE_LIST)
00193 {
00194 if (that.type_ != TYPE_LIST)
00195 return false;
00196 return list_iterator_ == that.list_iterator_;
00197 } else if (type_ == TYPE_MAP)
00198 {
00199 if (that.type_ != TYPE_MAP)
00200 return false;
00201 return map_iterator_ == that.map_iterator_;
00202 } else if (type_ == TYPE_NULL && that.type_ == TYPE_NULL )
00203 return true;
00204 else
00205 return false;
00206 }
00207
00208 bool variant_iterator::operator!=(const variant_iterator& that) const
00209 {
00210 if (type_ == TYPE_LIST)
00211 {
00212 if (that.type_ != TYPE_LIST)
00213 return true;
00214 return list_iterator_ != that.list_iterator_;
00215 } else if (type_ == TYPE_MAP)
00216 {
00217 if (that.type_ != TYPE_MAP)
00218 return true;
00219 return map_iterator_ != that.map_iterator_;
00220 } else if (type_ == TYPE_NULL && that.type_ == TYPE_NULL )
00221 return false;
00222 else
00223 return true;
00224 }
00225
00226 struct variant_list {
00227 variant_list()
00228 : elements()
00229 , refcount(0)
00230 {
00231 }
00232
00233 std::vector<variant> elements;
00234 int refcount;
00235 };
00236
00237 struct variant_string {
00238 variant_string()
00239 : str()
00240 , refcount(0)
00241 {
00242 }
00243
00244 std::string str;
00245 int refcount;
00246 };
00247
00248 struct variant_map {
00249 variant_map()
00250 : elements()
00251 , refcount(0)
00252 {
00253 }
00254
00255 std::map<variant,variant> elements;
00256 int refcount;
00257 };
00258
00259 void variant::increment_refcount()
00260 {
00261 switch(type_) {
00262 case TYPE_LIST:
00263 ++list_->refcount;
00264 break;
00265 case TYPE_STRING:
00266 ++string_->refcount;
00267 break;
00268 case TYPE_MAP:
00269 ++map_->refcount;
00270 break;
00271 case TYPE_CALLABLE:
00272 intrusive_ptr_add_ref(callable_);
00273 break;
00274
00275
00276 case TYPE_NULL:
00277 case TYPE_DECIMAL:
00278 case TYPE_INT :
00279 break;
00280 }
00281 }
00282
00283 void variant::release()
00284 {
00285 switch(type_) {
00286 case TYPE_LIST:
00287 if(--list_->refcount == 0) {
00288 delete list_;
00289 }
00290 break;
00291 case TYPE_STRING:
00292 if(--string_->refcount == 0) {
00293 delete string_;
00294 }
00295 break;
00296 case TYPE_MAP:
00297 if(--map_->refcount == 0) {
00298 delete map_;
00299 }
00300 break;
00301 case TYPE_CALLABLE:
00302 intrusive_ptr_release(callable_);
00303 break;
00304
00305
00306 case TYPE_NULL:
00307 case TYPE_DECIMAL:
00308 case TYPE_INT :
00309 break;
00310 }
00311 }
00312
00313 variant::variant() : type_(TYPE_NULL), int_value_(0)
00314 {}
00315
00316 variant::variant(int n) : type_(TYPE_INT), int_value_(n)
00317 {}
00318
00319 variant::variant(int n, variant::DECIMAL_VARIANT_TYPE ) : type_(TYPE_DECIMAL), decimal_value_(n)
00320 {}
00321
00322 variant::variant(const game_logic::formula_callable* callable)
00323 : type_(TYPE_CALLABLE), callable_(callable)
00324 {
00325 assert(callable_);
00326 increment_refcount();
00327 }
00328
00329 variant::variant(std::vector<variant>* array)
00330 : type_(TYPE_LIST)
00331 {
00332 assert(array);
00333 list_ = new variant_list;
00334 list_->elements.swap(*array);
00335 increment_refcount();
00336 }
00337
00338 variant::variant(const std::string& str)
00339 : type_(TYPE_STRING)
00340 {
00341 string_ = new variant_string;
00342 string_->str = str;
00343 increment_refcount();
00344 }
00345
00346 variant::variant(std::map<variant,variant>* map)
00347 : type_(TYPE_MAP)
00348 {
00349 assert(map);
00350 map_ = new variant_map;
00351 map_->elements.swap(*map);
00352 increment_refcount();
00353 }
00354
00355 variant::variant(const variant& v)
00356 : type_(v.type_)
00357 {
00358 memcpy(this, &v, sizeof(v));
00359 increment_refcount();
00360 }
00361
00362 variant::~variant()
00363 {
00364 release();
00365 }
00366
00367 const variant& variant::operator=(const variant& v)
00368 {
00369 if(&v != this) {
00370 release();
00371 memcpy(this, &v, sizeof(v));
00372 increment_refcount();
00373 }
00374 return *this;
00375 }
00376
00377 const variant& variant::operator[](size_t n) const
00378 {
00379 if(type_ == TYPE_CALLABLE) {
00380 assert(n == 0);
00381 return *this;
00382 }
00383
00384 must_be(TYPE_LIST);
00385 assert(list_);
00386 if(n >= list_->elements.size()) {
00387 throw type_error("invalid index");
00388 }
00389
00390 return list_->elements[n];
00391 }
00392
00393 const variant& variant::operator[](const variant& v) const
00394 {
00395 if(type_ == TYPE_CALLABLE) {
00396 assert(v.as_int() == 0);
00397 return *this;
00398 }
00399
00400 if(type_ == TYPE_MAP) {
00401 assert(map_);
00402 std::map<variant,variant>::const_iterator i = map_->elements.find(v);
00403 if (i == map_->elements.end())
00404 {
00405 static variant null_variant;
00406 return null_variant;
00407 }
00408 return i->second;
00409 } else if(type_ == TYPE_LIST) {
00410 return operator[](v.as_int());
00411 } else {
00412 throw type_error((formatter() << "type error: "
00413 << " expected a list or a map but found "
00414 << variant_type_to_string(type_)
00415 << " (" << to_debug_string() << ")").str());
00416 }
00417 }
00418
00419 variant variant::get_keys() const
00420 {
00421 must_be(TYPE_MAP);
00422 assert(map_);
00423 std::vector<variant> tmp;
00424 for(std::map<variant,variant>::const_iterator i=map_->elements.begin(); i != map_->elements.end(); ++i) {
00425 tmp.push_back(i->first);
00426 }
00427 return variant(&tmp);
00428 }
00429
00430 variant variant::get_values() const
00431 {
00432 must_be(TYPE_MAP);
00433 assert(map_);
00434 std::vector<variant> tmp;
00435 for(std::map<variant,variant>::const_iterator i=map_->elements.begin(); i != map_->elements.end(); ++i) {
00436 tmp.push_back(i->second);
00437 }
00438 return variant(&tmp);
00439 }
00440
00441 variant_iterator variant::begin() const
00442 {
00443 if(type_ == TYPE_LIST)
00444 return variant_iterator( list_->elements.begin() );
00445
00446 if(type_ == TYPE_MAP)
00447 return variant_iterator( map_->elements.begin() );
00448
00449 return variant_iterator();
00450 }
00451 variant_iterator variant::end() const
00452 {
00453 if(type_ == TYPE_LIST)
00454 return variant_iterator( list_->elements.end() );
00455
00456 if(type_ == TYPE_MAP)
00457 return variant_iterator( map_->elements.end() );
00458
00459 return variant_iterator();
00460 }
00461
00462 bool variant::is_empty() const
00463 {
00464 if(type_ == TYPE_NULL) {
00465 return true;
00466 } else if (type_ == TYPE_LIST) {
00467 assert(list_);
00468 return list_->elements.empty();
00469 } else if (type_ == TYPE_MAP) {
00470 assert(map_);
00471 return map_->elements.empty();
00472 }
00473
00474 return false;
00475 }
00476
00477 size_t variant::num_elements() const
00478 {
00479 if(type_ == TYPE_CALLABLE) {
00480 return 1;
00481 }
00482
00483 if (type_ == TYPE_LIST) {
00484 assert(list_);
00485 return list_->elements.size();
00486 } else if (type_ == TYPE_MAP) {
00487 assert(map_);
00488 return map_->elements.size();
00489 } else {
00490 throw type_error((formatter() << "type error: "
00491 << " expected a list or a map but found "
00492 << variant_type_to_string(type_)
00493 << " (" << to_debug_string() << ")").str());
00494 }
00495 }
00496
00497 variant variant::get_member(const std::string& str) const
00498 {
00499 if(is_callable()) {
00500 return callable_->query_value(str);
00501 }
00502
00503 if(str == "self") {
00504 return *this;
00505 } else {
00506 return variant();
00507 }
00508 }
00509
00510 int variant::as_decimal() const
00511 {
00512 if( type_ == TYPE_DECIMAL) {
00513 return decimal_value_;
00514 } else if( type_ == TYPE_INT ) {
00515 return int_value_*1000;
00516 } else if( type_ == TYPE_NULL) {
00517 return 0;
00518 } else {
00519 throw type_error((formatter() << "type error: "
00520 << " expected integer or decimal but found "
00521 << variant_type_to_string(type_)
00522 << " (" << to_debug_string() << ")").str());
00523 }
00524 }
00525
00526 bool variant::as_bool() const
00527 {
00528 switch(type_) {
00529 case TYPE_NULL:
00530 return false;
00531 case TYPE_INT:
00532 return int_value_ != 0;
00533 case TYPE_DECIMAL:
00534 return decimal_value_ != 0;
00535 case TYPE_CALLABLE:
00536 return callable_ != NULL;
00537 case TYPE_LIST:
00538 return !list_->elements.empty();
00539 case TYPE_MAP:
00540 return !map_->elements.empty();
00541 case TYPE_STRING:
00542 return !string_->str.empty();
00543 default:
00544 assert(false);
00545 return false;
00546 }
00547 }
00548
00549 const std::string& variant::as_string() const
00550 {
00551 must_be(TYPE_STRING);
00552 assert(string_);
00553 return string_->str;
00554 }
00555
00556 variant variant::operator+(const variant& v) const
00557 {
00558 if(type_ == TYPE_LIST) {
00559 if(v.type_ == TYPE_LIST) {
00560 std::vector<variant> res;
00561 res.reserve(list_->elements.size() + v.list_->elements.size());
00562 for(size_t i = 0; i<list_->elements.size(); ++i) {
00563 const variant& var = list_->elements[i];
00564 res.push_back(var);
00565 }
00566
00567 for(size_t j = 0; j<v.list_->elements.size(); ++j) {
00568 const variant& var = v.list_->elements[j];
00569 res.push_back(var);
00570 }
00571
00572 return variant(&res);
00573 }
00574 }
00575 if(type_ == TYPE_MAP) {
00576 if(v.type_ == TYPE_MAP) {
00577 std::map<variant,variant> res(map_->elements);
00578
00579 for(std::map<variant,variant>::const_iterator i = v.map_->elements.begin(); i != v.map_->elements.end(); ++i) {
00580 res[i->first] = i->second;
00581 }
00582
00583 return variant(&res);
00584 }
00585 }
00586 if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) {
00587 return variant( as_decimal() + v.as_decimal() , DECIMAL_VARIANT);
00588 }
00589
00590 return variant(as_int() + v.as_int());
00591 }
00592
00593 variant variant::operator-(const variant& v) const
00594 {
00595 if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) {
00596 return variant( as_decimal() - v.as_decimal() , DECIMAL_VARIANT);
00597 }
00598
00599 return variant(as_int() - v.as_int());
00600 }
00601
00602 variant variant::operator*(const variant& v) const
00603 {
00604 if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) {
00605
00606 long long long_int = as_decimal();
00607
00608 long_int *= v.as_decimal();
00609
00610 long_int /= 100;
00611
00612 if( long_int%10 >= 5) {
00613 long_int /= 10;
00614 ++long_int;
00615 } else
00616 long_int/=10;
00617
00618 return variant( static_cast<int>(long_int) , variant::DECIMAL_VARIANT );
00619 }
00620
00621 return variant(as_int() * v.as_int());
00622 }
00623
00624 variant variant::operator/(const variant& v) const
00625 {
00626 if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) {
00627 int denominator = v.as_decimal();
00628
00629 if(denominator == 0) {
00630 throw type_error((formatter() << "divide by zero error").str());
00631 }
00632
00633 long long long_int = as_decimal();
00634
00635 long_int *= 10000;
00636
00637 long_int /= denominator;
00638
00639 if( long_int%10 >= 5) {
00640 long_int /= 10;
00641 ++long_int;
00642 } else
00643 long_int/=10;
00644
00645 return variant( static_cast<int>(long_int) , variant::DECIMAL_VARIANT);
00646 }
00647
00648
00649 const int numerator = as_int();
00650 const int denominator = v.as_int();
00651 if(denominator == 0) {
00652 throw type_error((formatter() << "divide by zero error").str());;
00653 }
00654
00655 return variant(numerator/denominator);
00656 }
00657
00658 variant variant::operator%(const variant& v) const
00659 {
00660 const int numerator = as_int();
00661 const int denominator = v.as_int();
00662 if(denominator == 0) {
00663 throw type_error((formatter() << "divide by zero error").str());
00664 }
00665
00666 return variant(numerator%denominator);
00667 }
00668
00669
00670 variant variant::operator^(const variant& v) const
00671 {
00672 if( type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL ) {
00673
00674 double res = pow( as_decimal()/1000.0 , v.as_decimal()/1000.0 );
00675
00676 res *= 1000;
00677 int i = static_cast<int>( res );
00678
00679 res -= i;
00680
00681 if( res > 0.5 )
00682 i++;
00683
00684 return variant( i , variant::DECIMAL_VARIANT);
00685 }
00686
00687 return variant(static_cast<int>(
00688 round_portable(pow(static_cast<double>(as_int()), v.as_int()))));
00689 }
00690
00691 variant variant::operator-() const
00692 {
00693 if( type_ == TYPE_DECIMAL)
00694 return variant( -decimal_value_, variant::DECIMAL_VARIANT );
00695
00696 return variant(-as_int());
00697 }
00698
00699 bool variant::operator==(const variant& v) const
00700 {
00701 if(type_ != v.type_) {
00702 if( type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL ) {
00703 return as_decimal() == v.as_decimal();
00704 }
00705
00706 return false;
00707 }
00708
00709 switch(type_) {
00710 case TYPE_NULL: {
00711 return v.is_null();
00712 }
00713
00714 case TYPE_STRING: {
00715 return string_->str == v.string_->str;
00716 }
00717
00718 case TYPE_INT: {
00719 return int_value_ == v.int_value_;
00720 }
00721
00722 case TYPE_DECIMAL: {
00723 return decimal_value_ == v.decimal_value_;
00724 }
00725
00726 case TYPE_LIST: {
00727 if(num_elements() != v.num_elements()) {
00728 return false;
00729 }
00730
00731 for(size_t n = 0; n != num_elements(); ++n) {
00732 if((*this)[n] != v[n]) {
00733 return false;
00734 }
00735 }
00736
00737 return true;
00738 }
00739
00740 case TYPE_MAP: {
00741 return map_->elements == v.map_->elements;
00742 }
00743
00744 case TYPE_CALLABLE: {
00745 return callable_->equals(v.callable_);
00746 }
00747 }
00748
00749 assert(false);
00750 return false;
00751 }
00752
00753 bool variant::operator!=(const variant& v) const
00754 {
00755 return !operator==(v);
00756 }
00757
00758 bool variant::operator<=(const variant& v) const
00759 {
00760 if(type_ != v.type_) {
00761 if( type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL ) {
00762 return as_decimal() <= v.as_decimal();
00763 }
00764
00765 return type_ < v.type_;
00766 }
00767
00768 switch(type_) {
00769 case TYPE_NULL: {
00770 return true;
00771 }
00772
00773 case TYPE_STRING: {
00774 return string_->str <= v.string_->str;
00775 }
00776
00777 case TYPE_INT: {
00778 return int_value_ <= v.int_value_;
00779 }
00780
00781 case TYPE_DECIMAL: {
00782 return decimal_value_ <= v.decimal_value_;
00783 }
00784
00785 case TYPE_LIST: {
00786 for(size_t n = 0; n != num_elements() && n != v.num_elements(); ++n) {
00787 if((*this)[n] < v[n]) {
00788 return true;
00789 } else if((*this)[n] > v[n]) {
00790 return false;
00791 }
00792 }
00793
00794 return num_elements() <= v.num_elements();
00795 }
00796
00797 case TYPE_MAP: {
00798 return map_->elements <= v.map_->elements;
00799 }
00800
00801 case TYPE_CALLABLE: {
00802 return !v.callable_->less(callable_);
00803 }
00804 }
00805
00806 assert(false);
00807 return false;
00808 }
00809
00810 bool variant::operator>=(const variant& v) const
00811 {
00812 return v <= *this;
00813 }
00814
00815 bool variant::operator<(const variant& v) const
00816 {
00817 return !(*this >= v);
00818 }
00819
00820 bool variant::operator>(const variant& v) const
00821 {
00822 return !(*this <= v);
00823 }
00824
00825 variant variant::list_elements_add(const variant& v) const
00826 {
00827 must_be(TYPE_LIST);
00828 v.must_be(TYPE_LIST);
00829
00830 if( num_elements() != v.num_elements() )
00831 throw type_error("Operator '.+' requires two lists of the same length");
00832
00833 std::vector< variant > res;
00834 res.reserve(num_elements());
00835
00836 for(size_t i = 0; i < num_elements(); ++i) {
00837 res.push_back( (*this)[i] + v[i] );
00838 }
00839
00840 return variant( &res );
00841 }
00842
00843 variant variant::list_elements_sub(const variant& v) const
00844 {
00845 must_be(TYPE_LIST);
00846 v.must_be(TYPE_LIST);
00847
00848 if( num_elements() != v.num_elements() )
00849 throw type_error("Operator '.-' requires two lists of the same length");
00850
00851 std::vector< variant > res;
00852 res.reserve(num_elements());
00853
00854 for(size_t i = 0; i < num_elements(); ++i) {
00855 res.push_back( (*this)[i] - v[i] );
00856 }
00857
00858 return variant( &res );
00859 }
00860
00861 variant variant::list_elements_mul(const variant& v) const
00862 {
00863 must_be(TYPE_LIST);
00864 v.must_be(TYPE_LIST);
00865
00866 if( num_elements() != v.num_elements() )
00867 throw type_error("Operator '.*' requires two lists of the same length");
00868
00869 std::vector< variant > res;
00870 res.reserve(num_elements());
00871
00872 for(size_t i = 0; i < num_elements(); ++i) {
00873 res.push_back( (*this)[i] * v[i] );
00874 }
00875
00876 return variant( &res );
00877 }
00878
00879 variant variant::list_elements_div(const variant& v) const
00880 {
00881 must_be(TYPE_LIST);
00882 v.must_be(TYPE_LIST);
00883
00884 if( num_elements() != v.num_elements() )
00885 throw type_error("Operator './' requires two lists of the same length");
00886
00887 std::vector< variant > res;
00888 res.reserve(num_elements());
00889
00890 for(size_t i = 0; i < num_elements(); ++i) {
00891 res.push_back( (*this)[i] / v[i] );
00892 }
00893
00894 return variant( &res );
00895 }
00896
00897 void variant::must_be(variant::TYPE t) const
00898 {
00899 if(type_ != t) {
00900 throw type_error((formatter() << "type error: " << " expected "
00901 << variant_type_to_string(t) << " but found "
00902 << variant_type_to_string(type_)
00903 << " (" << to_debug_string() << ")").str());
00904 }
00905 }
00906
00907 void variant::serialize_to_string(std::string& str) const
00908 {
00909 switch(type_) {
00910 case TYPE_NULL:
00911 str += "null()";
00912 case TYPE_INT:
00913 str += boost::lexical_cast<std::string>(int_value_);
00914 break;
00915 case TYPE_DECIMAL: {
00916 std::ostringstream s;
00917
00918 int fractional = decimal_value_ % 1000;
00919 int integer = (decimal_value_ - fractional) / 1000;
00920
00921 s << integer << ".";
00922
00923 fractional = abs(fractional);
00924
00925 if( fractional < 100) {
00926 if( fractional < 10)
00927 s << "00";
00928 else
00929 s << 0;
00930 }
00931
00932 s << fractional;
00933
00934 str += s.str();
00935 break;
00936 }
00937 case TYPE_CALLABLE:
00938 callable_->serialize(str);
00939 break;
00940 case TYPE_LIST: {
00941 str += "[";
00942 bool first_time = true;
00943 for(size_t i=0; i<list_->elements.size(); ++i) {
00944 const variant& var = list_->elements[i];
00945 if(!first_time) {
00946 str += ",";
00947 }
00948 first_time = false;
00949 var.serialize_to_string(str);
00950 }
00951 str += "]";
00952 break;
00953 }
00954 case TYPE_MAP: {
00955 str += "[";
00956 bool first_time = true;
00957 for(std::map<variant,variant>::const_iterator i=map_->elements.begin(); i != map_->elements.end(); ++i) {
00958 if(!first_time) {
00959 str += ",";
00960 }
00961 first_time = false;
00962 i->first.serialize_to_string(str);
00963 str += "->";
00964 i->second.serialize_to_string(str);
00965 }
00966 str += "]";
00967 break;
00968 }
00969 case TYPE_STRING:
00970 str += "'";
00971 str += string_->str;
00972 str += "'";
00973 break;
00974 default:
00975 assert(false);
00976 }
00977 }
00978
00979 void variant::serialize_from_string(const std::string& str)
00980 {
00981 try {
00982 *this = game_logic::formula(str).evaluate();
00983 } catch(...) {
00984 *this = variant(str);
00985 }
00986 }
00987
00988 int variant::refcount() const
00989 {
00990 switch(type_) {
00991 case TYPE_LIST:
00992 return list_->refcount;
00993 break;
00994 case TYPE_STRING:
00995 return string_->refcount;
00996 break;
00997 case TYPE_MAP:
00998 return map_->refcount;
00999 break;
01000 case TYPE_CALLABLE:
01001 return callable_->refcount();
01002 break;
01003 default:
01004 return -1;
01005 }
01006 }
01007
01008 std::string variant::string_cast() const
01009 {
01010 switch(type_) {
01011 case TYPE_NULL:
01012 return "0";
01013 case TYPE_INT:
01014 return boost::lexical_cast<std::string>(int_value_);
01015 case TYPE_DECIMAL: {
01016 std::ostringstream s;
01017
01018 int fractional = decimal_value_ % 1000;
01019 int integer = (decimal_value_ - fractional) / 1000;
01020
01021 s << integer << ".";
01022
01023 fractional = abs(fractional);
01024
01025 if( fractional < 100) {
01026 if( fractional < 10)
01027 s << "00";
01028 else
01029 s << 0;
01030 }
01031
01032 s << fractional;
01033
01034 return s.str();
01035 }
01036 case TYPE_CALLABLE:
01037 return "(object)";
01038 case TYPE_LIST: {
01039 std::string res = "";
01040 for(size_t i=0; i<list_->elements.size(); ++i) {
01041 const variant& var = list_->elements[i];
01042 if(!res.empty()) {
01043 res += ", ";
01044 }
01045
01046 res += var.string_cast();
01047 }
01048
01049 return res;
01050 }
01051 case TYPE_MAP: {
01052 std::string res = "";
01053 for(std::map<variant,variant>::const_iterator i=map_->elements.begin(); i != map_->elements.end(); ++i) {
01054 if(!res.empty()) {
01055 res += ",";
01056 }
01057 res += i->first.string_cast();
01058 res += "->";
01059 res += i->second.string_cast();
01060 }
01061 return res;
01062 }
01063
01064 case TYPE_STRING:
01065 return string_->str;
01066 default:
01067 assert(false);
01068 return "invalid";
01069 }
01070 }
01071
01072 std::string variant::to_debug_string(std::vector<const game_logic::formula_callable*>* seen, bool verbose) const
01073 {
01074 std::vector<const game_logic::formula_callable*> seen_stack;
01075 if(!seen) {
01076 seen = &seen_stack;
01077 }
01078
01079 std::ostringstream s;
01080 switch(type_) {
01081 case TYPE_NULL:
01082 s << "(null)";
01083 case TYPE_INT:
01084 s << int_value_;
01085 break;
01086 case TYPE_DECIMAL: {
01087 int fractional = decimal_value_ % 1000;
01088 int integer = (decimal_value_ - fractional) / 1000;
01089
01090 s << integer << ".";
01091
01092 fractional = abs(fractional);
01093
01094 if( fractional < 100) {
01095 if( fractional < 10)
01096 s << "00";
01097 else
01098 s << 0;
01099 }
01100
01101 s << fractional;
01102
01103 break;
01104 }
01105 case TYPE_LIST: {
01106 s << "[";
01107 for(size_t n = 0; n != num_elements(); ++n) {
01108 if(n != 0) {
01109 s << ", ";
01110 }
01111
01112 s << operator[](n).to_debug_string(seen, verbose);
01113 }
01114 s << "]";
01115 break;
01116 }
01117 case TYPE_CALLABLE: {
01118 s << "{";
01119 if(std::find(seen->begin(), seen->end(), callable_) == seen->end()) {
01120 if(!verbose)
01121 seen->push_back(callable_);
01122 std::vector<game_logic::formula_input> v = callable_->inputs();
01123 bool first = true;
01124 for(size_t i=0; i<v.size(); ++i) {
01125 const game_logic::formula_input& input = v[i];
01126 if(!first) {
01127 s << ", ";
01128 }
01129 first = false;
01130 s << input.name << " ";
01131 if(input.access == game_logic::FORMULA_READ_WRITE) {
01132 s << "(read-write) ";
01133 } else if(input.access == game_logic::FORMULA_WRITE_ONLY) {
01134 s << "(writeonly) ";
01135 }
01136
01137 s << "-> " << callable_->query_value(input.name).to_debug_string(seen, verbose);
01138 }
01139 } else {
01140 s << "...";
01141 }
01142 s << "}";
01143 break;
01144 }
01145 case TYPE_MAP: {
01146 s << "[";
01147 bool first_time = true;
01148 for(std::map<variant,variant>::const_iterator i=map_->elements.begin(); i != map_->elements.end(); ++i) {
01149 if(!first_time) {
01150 s << ",";
01151 }
01152 first_time = false;
01153 s << i->first.to_debug_string(seen, verbose);
01154 s << "->";
01155 s << i->second.to_debug_string(seen, verbose);
01156 }
01157 s << "]";
01158 break;
01159 }
01160 case TYPE_STRING: {
01161 s << "'" << string_->str << "'";
01162 break;
01163 }
01164 }
01165
01166 return s.str();
01167 }