Changeset 911


Ignore:
Timestamp:
Jun 30, 2003, 9:39:02 PM (18 years ago)
Author:
luba
Message:
  • To_m_Int function is corrected
File:
1 edited

Legend:

Unmodified
Added
Removed
  • to-imperative/trunk/library/Convert/to_int.cc

    r870 r911  
    1414namespace Convert
    1515{
    16 
    1716RF_FUNC (To_m_Int, (RF_ARG e_Exp), (RF_RES s_Int))
    1817  Term* t = e_Exp.get_first();
    19   Term* p = e_Exp.get_last();
    2018
    21   //строка-результат
     19  pxx::WString s;
     20  for (; t < e_Exp.get_last(); t++)
     21    s = s + pxx::WString(*t);
     22
     23  bool was_zero = false;
     24  bool prev_sym = false;
     25  bool prev_space = false;
     26
     27  bool flag = false;
     28
     29  uintptr_t len = 0;
     30  uintptr_t len_max = ShortInt::max_len;
     31  size_t i = 0;
     32  size_t str_len = s.get_length();
     33
     34  //пропустить все пробелы в начале;
     35  //если строка состоит из одних пробелов, то fail;
    2236  //
    23   pxx::WString str;
    24  
    25   //вспомогательная строка, получающаяся из каждого терма
     37  for (; i < s.get_length(); i++) {
     38    if (s[i] == ' ') {
     39      if (i == str_len - 1) retfail;
     40    }
     41    else
     42      break;
     43  }
     44  //проверяем, все ли символы в строке допустимы:
     45   //если рассматриваемый символ - цифра, а до этого встречались пробелы,
     46  //то fail;
     47  //если символ не равен 0, то запоминаем, что был символ и учитываем его
     48  //длину;
     49  //если символ равен 0, то, если до этого символы были, надо посчитать его
     50  //длину и запомнить, что был символ и он равен 0;
     51  //если встретили 0, а до этого были пробелы, то fail;
     52  //если строка состоит только из 0, то запомнить, что был символ 0;
     53  //если строка закончилась, а символов-цифр не было, то fail;
     54  //если встретился какой-либо символ, не цифра и не знак, то fail;
    2655  //
    27   pxx::WString s;
    28 
    29   //позиция первого непробела во вспомогательной строке s
     56  //если символ оказался знаком '+' или '-', то проверить, не было ли
     57  //символов до того, если были, то fail;
    3058  //
    31   size_t k = 0;
    32   //позиция первой ненулевой цифры во вспомогательной строке s
     59  //если символ - пробел, запомнить, что был пробел
    3360  //
    34   size_t j = 0;
    35   //длина вспомогательной строки s
    36   //
    37   size_t len = 0;
    38   //текущая длина строки-результата str
    39   //
    40   size_t length = 0;
    41   bool found = false;
    42   bool space = false;
    43   bool sign = false;
    44   bool digit = false;
    45 
    46   //если нашли цифру или знак, то выходим из цикла, чтобы обработать
    47   //эти и следующие символы,
    48   //если знак был '-' и терм был типа Char, добавляем его к строке-результату;
    49   //пробелы, предшествующие всем символам, пропускаем;
    50   //если ничего, кроме пробелов в выражении не встречается, то $fail;
    51   //
    52   for (; t < p; t++) {
    53     s = WString(*t);
    54     len = s.get_length();
    55     for (size_t i = 0; i < len; i++) {
    56       if (s[i] == '+' ) {
    57         found = true; sign = true; k = i; break;
     61  for ( ; i < str_len; i++) {
     62    if (iswdigit(s[i])) {
     63      if(prev_space)
     64          retfail;
     65      else {
     66      if (s[i] != '0'){
     67        len++;
     68        prev_sym = true;
    5869      }
    5970      else
    60       if (s[i] == '-') {
    61         if (t->get_type() == type_char) {
    62           str = str + s; length++; k = i;
    63         }
    64         found = true; sign = true;
    65         break;
     71      if (was_zero && prev_space)
     72        retfail;
     73      else
     74      if (prev_sym){
     75        len++;
     76        was_zero = true;
     77        prev_sym = true;
    6678      }
    6779      else
    68       if (iswdigit(s[i])) {
    69         found = true; k = i; break;
     80      if (i == str_len - 1) {
     81        len++;
     82        prev_sym = true;
    7083      }
    71       else
    72       if (s[i] != ' ') retfail;
    73     }
    74     if (found) break;
    75     else
    76     if (t == p - 1) retfail;
    77   }
    78 
    79   //начинаем просмотр очередного терма с той позиции, на которой нашли
    80   //цифру или знак;
    81   //ищем первую цифру, не равную 0, если нашли, то выходим из цикла ее
    82   //обрабатывать,
    83   //если выражение состоит только из 0, то выходим из
    84   //функции со значением результата, равным 0,
    85   //пропускаем первый знак '+' или '-', если терм типа Char,
    86   //и не допускаем появления еще каких-либо знаков;
    87   //если встретили не цифру, а что-либо еще, то $fail;
    88   //
    89   for (; t < p; t++) {
    90     s = WString(*t);
    91     len = s.get_length();
    92     for (; k < len; k++) {
    93       if (sign) {
    94         sign = false; continue;
    95       }
    96       else
    97       if (iswdigit(s[k])) {
    98         if (s[k] != '0') {
    99           digit = true;
    100           j = k;
    101           break;
    102         }
    103       }
    104       else retfail;
    105     }
    106     if (digit) break;
    107     else
    108     if (t == p - 1)
    109         s_Int = ShortInt::create_expr(0);
    110     else k = 0;
    111   }
    112 
    113   //начинаем просмотр очередного терма с той позиции, на которой нашли
    114   //ненулевую цифру;
    115   //если строка, полученная из терма, закончилась, добавляем ее к результату
    116   //и переходим к следующему терму;
    117   //выходим из цикла, если встретили пробел, добавив к результату
    118   //вспомогательную строку;
    119   //если встретили не цифру, то $fail;
    120   //
    121   for (; t < p; t++) {
    122     s = WString(*t);
    123     len = s.get_length();
    124     for (; j < len; j++) {
    125       if (s[j] == ' ') {
    126         str = str + s; space = true; length += len; break;
    127       }
    128       else
    129       if (!iswdigit(s[j])) retfail;
    130       else
    131       if (j == len - 1) {
    132         str = str + s; length += len;
    13384      }
    13485    }
    135     if (space) break;
    136     else
    137       j = 0;
     86      else
     87      if ((s[i] == '+' || s[i] == '-'))
     88        if (flag || prev_sym)
     89          retfail;
     90        else {
     91          len++;
     92          flag = true;
     93        }
     94      else
     95      if (s[i] == ' ') {
     96        prev_space = true;
     97        continue;
     98      }
     99      else
     100        retfail;
     101
     102  if (i == str_len - 1)
     103    if (prev_sym == false)
     104      retfail;
    138105  }
    139 
    140   //начинаем просмотр терма с той позиции, где нашли пробел;
    141   //если встретили что-то еще, то $fail;
     106  //проверка, что длина не больше, чем len_max
    142107  //
    143   for (; t < p; t++) {
    144     s = WString(*t);
    145     len = s.get_length();
    146     for (; j < len; j++) {
    147       if (s[j] != ' ')
    148         retfail;
    149     }
    150     j = 0;
    151   }   
    152   //создаем выражение из полученной строки
    153   //если длина его не превышает ShortInt::max_len
    154   //
    155   if (length < ShortInt::max_len) {
    156     s_Int = ShortInt::create_expr(str);
    157   }
    158   else
     108  if (len >= len_max)
    159109    RF_LIB_ERROR("Argument too large for conversion");
    160 
     110 
     111   s_Int = ShortInt::create_expr(s);
     112 
    161113RF_END
    162114}
    163 }
     115 }
    164116 
Note: See TracChangeset for help on using the changeset viewer.