Changeset 572
- Timestamp:
- 06/27/08 13:27:32 (5 months ago)
- Files:
-
- trunk/rphp/cmake/modules/FindICU.cmake (added)
- trunk/rphp/runtime/CMakeLists.txt (modified) (2 diffs)
- trunk/rphp/runtime/rphp_hash.h (added)
- trunk/rphp/runtime/rphp_object.h (added)
- trunk/rphp/runtime/rphp_pvar.h (added)
- trunk/rphp/runtime/rphp_runtime.h (added)
- trunk/rphp/runtime/rphp_types.h (added)
- trunk/rphp/runtime/var-test.cpp (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/rphp/runtime/CMakeLists.txt
r565 r572 2 2 3 3 FIND_PACKAGE(Boost REQUIRED) 4 FIND_PACKAGE(ICU) 4 5 5 6 cmake_minimum_required(VERSION 2.6) 6 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/ cmake/modules )7 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../cmake/modules ) 7 8 8 9 include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${Boost_INCLUDE_DIRS}) … … 12 13 ) 13 14 14 add_executable( rphp ${SRC_FILES} ) 15 15 add_executable( var-test ${SRC_FILES} ) trunk/rphp/runtime/var-test.cpp
r571 r572 2 2 /* 3 3 4 playing around with boost::variant, to see if it's suitable to store php vals4 driver for testing pvars 5 5 6 6 */ 7 7 8 #include "rphp_runtime.h" 9 #include "unicode/ustream.h" // ostream API for UnicodeString 8 10 #include "boost/variant.hpp" 9 #include "boost/lexical_cast.hpp"10 11 #include <iostream> 11 #include <typeinfo>12 13 // just a demo class, we'd also have php_object14 class php_hash {15 private:16 int size;17 public:18 php_hash(int sizevar) : size(sizevar) { }19 20 php_hash(const php_hash& h) {21 size = h.size;22 }23 int getSize() const { return size; }24 25 };26 27 std::ostream& operator << (std::ostream& os, const php_hash& h)28 {29 return os << "php_hash" << std::endl;30 }31 32 // using the c++ bool as a type seems to cause problems, so we implement php bool33 // as an enum. note that php integers are type long34 // we also use in to decide if this value is NULL. unfortunately a null value would evaluate35 // to true (in c++, since it's non 0). can we do this better?36 37 namespace RPHP {38 enum p3state39 {40 False,41 True,42 Null43 };44 }45 46 47 // this would be the typedef for a generic php variable in our runtime48 typedef boost::variant< RPHP::p3state, long, double, std::string, php_hash> pvar;49 50 // used for determining type at runtime51 typedef enum { PVAR_NULL, PVAR_BOOL, PVAR_LONG, PVAR_DOUBLE, PVAR_STRING, PVAR_HASH } pvartype;52 12 53 13 // generic visitor which can be applied to any pvar … … 56 16 { 57 17 public: 58 int operator()(const RPHP::p3state &i) const 59 {60 if (i == RPHP::Null) {18 19 int operator()(const rphp::p3state &i) const { 20 if (i == rphp::Null) { 61 21 std::cout << "i see a null" << std::endl; 62 22 } … … 67 27 } 68 28 69 int operator()(const long &i) const 70 { 29 int operator()(const long &i) const { 71 30 std::cout << "i see a long" << std::endl; 72 31 return i; 73 32 } 74 33 75 int operator()(const double &i) const 76 { 34 int operator()(const double &i) const { 77 35 std::cout << "i see a float" << std::endl; 78 36 return 0; 79 37 } 80 38 81 int operator()(const std::string &str) const 82 { 83 std::cout << "i see a string" << std::endl; 39 int operator()(const rphp::bstring &str) const { 40 std::cout << "i see a binary string" << std::endl; 84 41 return str.length(); 85 42 } 86 43 87 int operator()(const php_hash &h) const 88 { 44 int operator()(const rphp::ustring &str) const { 45 std::cout << "i see a unicode string" << std::endl; 46 return str.length(); 47 } 48 49 int operator()(const rphp::php_hash &h) const { 89 50 std::cout << "i see a php_hash" << std::endl; 51 return 0; 52 } 53 54 int operator()(const rphp::php_object &h) const { 55 std::cout << "i see a php_object" << std::endl; 90 56 return 0; 91 57 } … … 93 59 }; 94 60 95 // a visitor for determining type96 class type_checker : public boost::static_visitor<int>97 {98 public:99 pvartype operator()(const long &i) const100 {101 return PVAR_LONG;102 }103 104 pvartype operator()(const double &i) const105 {106 return PVAR_DOUBLE;107 }108 109 pvartype operator()(const std::string &str) const110 {111 return PVAR_STRING;112 }113 114 pvartype operator()(const php_hash &h) const115 {116 return PVAR_HASH;117 }118 119 pvartype operator()(const RPHP::p3state &h) const120 {121 (h == RPHP::Null) ? PVAR_NULL : PVAR_BOOL;122 }123 124 };125 126 // a visitor for converting to a num127 class convert_to_num_visitor : public boost::static_visitor<>128 {129 protected:130 pvar &var;131 public:132 convert_to_num_visitor(pvar &v) : var(v) {}133 134 void operator()(const std::string &a) const {135 try {136 var = boost::lexical_cast<long>(a);137 } catch(boost::bad_lexical_cast &) {138 var = 0l;139 }140 }141 142 void operator()(const double &i) const143 {144 // nothing, already numeric145 }146 147 void operator()(const php_hash &h) const148 {149 var = (long)h.getSize();150 }151 152 void operator()(const RPHP::p3state &h) const153 {154 (h == RPHP::True) ? var = 1l : var = 0l;155 }156 157 void operator()(const long &a) const {158 // Do nothing - already correct type159 }160 };161 162 163 // non destructive cast (makes a copy)164 pvar pvar_cast_to_number(const pvar p) {165 166 pvar r = p;167 boost::apply_visitor( convert_to_num_visitor(r), r );168 return r;169 170 }171 172 173 // define operators for working with pvars174 // php hashes would concat, otherwise convert to number175 pvar pvar_add (const pvar lhs, const pvar rhs)176 {177 pvar l,r,result;178 179 int lhs_type = boost::apply_visitor( type_checker(), lhs );180 int rhs_type = boost::apply_visitor( type_checker(), rhs );181 if ( (lhs_type == PVAR_HASH) && (rhs_type == PVAR_HASH) ) {182 std::cout << "fixme: concat hashes" << std::endl;183 result = 0l;184 }185 else {186 // convert to number, then add187 l = pvar_cast_to_number(lhs);188 std::cout << "pvar_add: l is " << l << std::endl;189 r = pvar_cast_to_number(rhs);190 std::cout << "pvar_add: r is " << r << std::endl;191 result = boost::get<long>(l) + boost::get<long>(r);192 std::cout << "pvar_add: result is " << result << std::endl;193 }194 195 return result;196 }197 198 61 // driver 199 62 int main() 200 63 { 201 pvar u,t,r;64 rphp::pvar u,t,r; 202 65 203 // string204 u = "hello world there";66 // binary string 67 u = rphp::bstring("hello world there"); 205 68 206 69 std::cout << u << std::endl; 207 70 int result = boost::apply_visitor( my_visitor(), u ); 71 72 // unicode string 73 u = rphp::ustring("hello world there -- unicode style"); 74 75 std::cout << u << std::endl; 76 result = boost::apply_visitor( my_visitor(), u ); 77 208 78 209 79 // long … … 220 90 221 91 // bool 222 u = RPHP::True;92 u = rphp::True; 223 93 224 94 std::cout << u << std::endl; 225 95 result = boost::apply_visitor( my_visitor(), u ); 226 96 227 if ( boost::get<RPHP::p3state>(u) == RPHP::True) {97 if (rphp::pvar_getVal_bool(u) == rphp::True) { 228 98 std::cout << "the bool was true" << std::endl; 229 99 } 230 100 231 101 // null 232 u = RPHP::Null;102 u = rphp::Null; 233 103 234 104 std::cout << u << std::endl; … … 236 106 237 107 // php hash 238 php_hash h(5);108 rphp::php_hash h(5); 239 109 std::cout << h; 240 110 u = h; … … 246 116 247 117 // type checking? 248 int pt = boost::apply_visitor( type_checker(), u);118 int pt = rphp::pvar_getType(u); 249 119 switch (pt) { 250 case PVAR_HASH:120 case rphp::PVAR_HASH: 251 121 std::cout << "found a hash" << std::endl; 252 122 break; 253 case PVAR_DOUBLE:123 case rphp::PVAR_DOUBLE: 254 124 std::cout << "found a float" << std::endl; 255 125 break; … … 257 127 std::cout << "woops, what type was it?" << std::endl; 258 128 } 259 // RTTI: output is ugly, it also might not be available everywhere260 std::cout << typeid( u ).name() << std::endl;261 129 262 130 //// … … 264 132 // type conversion 265 133 std::cout << "type conversion:" << std::endl; 266 u = "55";134 u = std::string("55"); 267 135 boost::apply_visitor( my_visitor(), u ); 268 boost::apply_visitor( convert_to_num_visitor(u), u);136 rphp::pvar_convertToNumber(u); 269 137 boost::apply_visitor( my_visitor(), u ); 270 138 std::cout << "final: " << u << std::endl; 271 139 272 140 // operators 273 141 274 142 // try adding a long and a numeric string 275 u = 10l; 276 t = "20";143 u = 10l; // NOTE: this is a long. int's turn into p3state (bool/null) 144 t = std::string("20"); 277 145 r = pvar_add(u, t); 278 146 std::cout << "number add: " << r << std::endl;
