Changeset 911
- Timestamp:
- Jun 30, 2003, 9:39:02 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
to-imperative/trunk/library/Convert/to_int.cc
r870 r911 14 14 namespace Convert 15 15 { 16 17 16 RF_FUNC (To_m_Int, (RF_ARG e_Exp), (RF_RES s_Int)) 18 17 Term* t = e_Exp.get_first(); 19 Term* p = e_Exp.get_last();20 18 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; 22 36 // 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; 26 55 // 27 pxx::WString s; 28 29 //позиция первого непробела во вспомогательной строке s 56 //если символ оказался знаком '+' или '-', то проверить, не было ли 57 //символов до того, если были, то fail; 30 58 // 31 size_t k = 0; 32 //позиция первой ненулевой цифры во вспомогательной строке s 59 //если символ - пробел, запомнить, что был пробел 33 60 // 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; 58 69 } 59 70 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; 66 78 } 67 79 else 68 if (iswdigit(s[i])) { 69 found = true; k = i; break; 80 if (i == str_len - 1) { 81 len++; 82 prev_sym = true; 70 83 } 71 else72 if (s[i] != ' ') retfail;73 }74 if (found) break;75 else76 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 else97 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 else108 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 else129 if (!iswdigit(s[j])) retfail;130 else131 if (j == len - 1) {132 str = str + s; length += len;133 84 } 134 85 } 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; 138 105 } 139 140 //начинаем просмотр терма с той позиции, где нашли пробел; 141 //если встретили что-то еще, то $fail; 106 //проверка, что длина не больше, чем len_max 142 107 // 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) 159 109 RF_LIB_ERROR("Argument too large for conversion"); 160 110 111 s_Int = ShortInt::create_expr(s); 112 161 113 RF_END 162 114 } 163 }115 } 164 116
Note: See TracChangeset
for help on using the changeset viewer.