type_info.cc

Go to the documentation of this file.
00001 /*!
00002         \file
00003         \brief Type informations.
00004         \author jaz
00005 */
00006 
00007 #include <lestes/lang/cplus/sem/ss_type.g.hh>
00008 #include <lestes/lang/cplus/sem/ss_type_builtin.g.hh>
00009 #include <lestes/md/types/tm_data_type.g.hh>
00010 #include <lestes/md/types/num_range.g.hh>
00011 #include <lestes/md/types/num_range_getter.g.hh>
00012 #include <lestes/md/types/type_info.g.hh>
00013 #include <lestes/md/types/ss_type2tm_type.g.hh>
00014 
00015 #include <regex.h>
00016 
00017 package(lestes);
00018 package(md);
00019 package(types);
00020 
00021 using namespace ::lestes::md::types;
00022 using namespace ::lestes::lang::cplus::sem;
00023 
00024 ptr<type_info> type_info::instance() {
00025         if ( !singleton_instance_get() ) {
00026                 singleton_instance_set(type_info::create());
00027         }
00028         return singleton_instance_get();
00029 }
00030 
00031 /*!
00032         \brief Returns ss_type corresponding to ptrdiff_t type.
00033 */
00034 ptr<ss_type> type_info::get_ptrdiff_t_type() {
00035         return ss_type_sint::instance();
00036 }
00037 
00038 
00039 /*!
00040         \brief Returns ss_type corresponding to size_t type.
00041 */
00042 ptr<ss_type> type_info::get_size_t_type() {
00043         return ss_type_uint::instance();
00044 }
00045 
00046 /*!
00047         \brief Tells whether a value is of given type.
00048         
00049         \param The value.
00050         \param The type.
00051         \return True if the value is of the type. False otherwise.
00052 */
00053 bool type_info::does_value_match_type(ucn_string value, ptr<ss_type> type) {
00054         lassert(type);
00055 
00056         //Get target type fro type.
00057         ptr<tm_data_type_base> tm_type = type->accept_ss_type2tm_type_gen_base(ss_type2tm_type::instance());
00058         
00059         //Non-basic types are not accepted.
00060         lassert(tm_type->kind_get()==tm_data_type_base::SIMPLE);
00061         
00062         //Get range for type.
00063         ptr<num_range> range = num_range_getter::instance()->get_range(tm_type);
00064         lassert(range);
00065         
00066         switch ( tm_type->id_get() ) {
00067                 case DT_INT_8P :
00068                 case DT_INT_8U :
00069                 case DT_INT_8S :
00070                 case DT_INT_16U :
00071                 case DT_INT_16S :
00072                 case DT_INT_32U :
00073                 case DT_INT_32S :{
00074                         //Get decimal representation.
00075                         lstring decimal_value = get_decimal_representation(value,tm_type);
00076                         
00077                         //Check number length.
00078                         ulint max_digits = range->digits_get();
00079                 
00080                         if ( decimal_value.length() > max_digits ) {
00081                                 //Number is too long. Too many digits.
00082                                 return false;
00083                         }
00084                         
00085                         /*
00086                                 Check if value is less than maximum value for type. 
00087                                 This can be done as string comparation, because length of the value
00088                                 is the same or shorter than length of maximum.
00089                         */
00090                         if ( decimal_value.length() == max_digits && decimal_value.compare(range->max_get())>0 ) {
00091                                 //Number is out of range.
00092                                 return false;
00093                         }
00094                         
00095                         //Check number format.
00096                         char* pattern = "^[0-9]+$";
00097                         
00098                         regex_t re;
00099                         lassert(regcomp(&re,pattern,REG_EXTENDED|REG_NOSUB)==0);
00100                         int status = regexec(&re,decimal_value.c_str(),(size_t)0,NULL,0);
00101                         regfree(&re);
00102                         
00103                         return (status==0);
00104                         
00105                 } break;                
00106                 
00107                 default:
00108                 break;
00109         }
00110         lassert(false);
00111         return false;
00112 }
00113 
00114 end_package(types);
00115 end_package(md);
00116 end_package(lestes);
00117 

Generated on Mon Feb 12 18:23:43 2007 for lestes by doxygen 1.5.1-20070107