Changeset 572

Show
Ignore:
Timestamp:
06/27/08 13:27:32 (5 months ago)
Author:
weyrick
Message:

start some cleanup and organization

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/rphp/runtime/CMakeLists.txt

    r565 r572  
    22 
    33FIND_PACKAGE(Boost REQUIRED) 
     4FIND_PACKAGE(ICU) 
    45 
    56cmake_minimum_required(VERSION 2.6) 
    6 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ) 
     7set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/../cmake/modules ) 
    78 
    89include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${Boost_INCLUDE_DIRS}) 
     
    1213) 
    1314 
    14 add_executable( rphp ${SRC_FILES} ) 
    15  
     15add_executable( var-test ${SRC_FILES} ) 
  • trunk/rphp/runtime/var-test.cpp

    r571 r572  
    22/* 
    33 
    4 playing around with boost::variant, to see if it's suitable to store php val
     4driver for testing pvar
    55 
    66*/ 
    77 
     8#include "rphp_runtime.h" 
     9#include "unicode/ustream.h" // ostream API for UnicodeString 
    810#include "boost/variant.hpp" 
    9 #include "boost/lexical_cast.hpp" 
    1011#include <iostream> 
    11 #include <typeinfo> 
    12  
    13 // just a demo class, we'd also have php_object 
    14 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 bool 
    33 // as an enum. note that php integers are type long 
    34 // we also use in to decide if this value is NULL. unfortunately a null value would evaluate 
    35 // to true (in c++, since it's non 0). can we do this better? 
    36  
    37 namespace RPHP { 
    38     enum p3state 
    39     { 
    40         False, 
    41         True, 
    42         Null 
    43     }; 
    44 } 
    45  
    46  
    47 // this would be the typedef for a generic php variable in our runtime 
    48 typedef boost::variant< RPHP::p3state, long, double, std::string, php_hash> pvar; 
    49  
    50 // used for determining type at runtime 
    51 typedef enum { PVAR_NULL, PVAR_BOOL, PVAR_LONG, PVAR_DOUBLE, PVAR_STRING, PVAR_HASH } pvartype; 
    5212 
    5313// generic visitor which can be applied to any pvar 
     
    5616{ 
    5717public: 
    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) { 
    6121            std::cout << "i see a null" << std::endl; 
    6222        } 
     
    6727    } 
    6828 
    69     int operator()(const long &i) const 
    70     { 
     29    int operator()(const long &i) const { 
    7130        std::cout << "i see a long" << std::endl; 
    7231        return i; 
    7332    } 
    7433 
    75     int operator()(const double &i) const 
    76     { 
     34    int operator()(const double &i) const { 
    7735        std::cout << "i see a float" << std::endl; 
    7836        return 0; 
    7937    } 
    8038 
    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; 
    8441        return str.length(); 
    8542    } 
    8643 
    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 { 
    8950        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; 
    9056        return 0; 
    9157    } 
     
    9359}; 
    9460 
    95 // a visitor for determining type 
    96 class type_checker : public boost::static_visitor<int> 
    97 { 
    98 public: 
    99     pvartype operator()(const long &i) const 
    100     { 
    101         return PVAR_LONG; 
    102     } 
    103  
    104     pvartype operator()(const double &i) const 
    105     { 
    106         return PVAR_DOUBLE; 
    107     } 
    108  
    109     pvartype operator()(const std::string &str) const 
    110     { 
    111         return PVAR_STRING; 
    112     } 
    113  
    114     pvartype operator()(const php_hash &h) const 
    115     { 
    116         return PVAR_HASH; 
    117     } 
    118  
    119     pvartype operator()(const RPHP::p3state &h) const 
    120     { 
    121         (h == RPHP::Null) ? PVAR_NULL : PVAR_BOOL; 
    122     } 
    123  
    124 }; 
    125  
    126 // a visitor for converting to a num 
    127 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) const 
    143   { 
    144         // nothing, already numeric 
    145   } 
    146  
    147   void operator()(const php_hash &h) const 
    148   { 
    149         var = (long)h.getSize(); 
    150   } 
    151  
    152     void operator()(const RPHP::p3state &h) const 
    153   { 
    154         (h == RPHP::True) ? var = 1l : var = 0l; 
    155   } 
    156  
    157   void operator()(const long &a) const { 
    158         // Do nothing - already correct type 
    159   } 
    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 pvars 
    174 // php hashes would concat, otherwise convert to number 
    175 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 add 
    187         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  
    19861// driver 
    19962int main() 
    20063{ 
    201     pvar u,t,r; 
     64    rphp::pvar u,t,r; 
    20265 
    203     // string 
    204     u = "hello world there"
     66    // binary string 
     67    u = rphp::bstring("hello world there")
    20568 
    20669    std::cout << u << std::endl; 
    20770    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 
    20878 
    20979    // long 
     
    22090 
    22191    // bool 
    222     u = RPHP::True; 
     92    u = rphp::True; 
    22393 
    22494    std::cout << u << std::endl; 
    22595    result = boost::apply_visitor( my_visitor(), u ); 
    22696 
    227     if (boost::get<RPHP::p3state>(u) == RPHP::True) { 
     97    if (rphp::pvar_getVal_bool(u) == rphp::True) { 
    22898        std::cout << "the bool was true" << std::endl; 
    22999    } 
    230100 
    231101    // null 
    232     u = RPHP::Null; 
     102    u = rphp::Null; 
    233103 
    234104    std::cout << u << std::endl; 
     
    236106 
    237107    // php hash 
    238     php_hash h(5); 
     108    rphp::php_hash h(5); 
    239109    std::cout << h; 
    240110    u = h; 
     
    246116 
    247117    // type checking? 
    248     int pt = boost::apply_visitor( type_checker(), u ); 
     118    int pt = rphp::pvar_getType(u); 
    249119    switch (pt) { 
    250     case PVAR_HASH: 
     120    case rphp::PVAR_HASH: 
    251121        std::cout << "found a hash" << std::endl; 
    252122        break; 
    253     case PVAR_DOUBLE: 
     123    case rphp::PVAR_DOUBLE: 
    254124        std::cout << "found a float" << std::endl; 
    255125        break; 
     
    257127        std::cout << "woops, what type was it?" << std::endl; 
    258128    } 
    259     // RTTI: output is ugly, it also might not be available everywhere 
    260     std::cout << typeid( u ).name() << std::endl; 
    261129 
    262130    //// 
     
    264132    // type conversion 
    265133    std::cout << "type conversion:" << std::endl; 
    266     u = "55"
     134    u = std::string("55")
    267135    boost::apply_visitor( my_visitor(), u ); 
    268     boost::apply_visitor( convert_to_num_visitor(u), u ); 
     136    rphp::pvar_convertToNumber(u); 
    269137    boost::apply_visitor( my_visitor(), u ); 
    270138    std::cout << "final: " << u << std::endl; 
    271139 
    272140    // operators 
    273      
     141 
    274142    // 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")
    277145    r = pvar_add(u, t); 
    278146    std::cout << "number add: " << r << std::endl;