source: to-imperative/trunk/library/Convert/to_int.cc @ 767

Last change on this file since 767 was 767, checked in by orlov, 18 years ago
  • Some comments.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.2 KB
Line 
1// $Source$
2// $Revision: 767 $
3// $Date: 2003-05-27 12:11:02 +0000 (Tue, 27 May 2003) $
4// $Author: orlov $
5
6#include <rf_core.hh>
7
8namespace refal
9{
10
11using namespace rfrt;
12using namespace rftype;
13
14namespace Convert
15{
16
17RF_FUNC (To_m_Int, (RF_ARG e_Exp), (RF_RES s_Int))
18  uintptr_t len = 0;
19  int flag = 0;
20
21  Term* t = e_Exp.get_first();
22  //пропускаем произвольное количество пробелов, если
23  //последовательность термов Char
24  //
25  //FIXME: А если там не пробел, а \n, \r, \v, \t или что там ещё разрешено?
26  //И надо добавить соответствующие тесты.
27  //Кроме того, если уж есть функция is_not_space(), почему бы её здесь не
28  //использовать?
29  //
30  if (t->get_type() == type_char) {
31    for (; ;)
32      if (((Char*)t)->to_wchar_t() != ' ') {
33        break;
34      }
35      else t++;
36  }
37  //в переменную flag присваиваем -1, если перед последовательностью
38  //символов-чисел был знак '-', и 1, если перед последовательностью
39  //был знак '+'
40  //
41  if (t->get_type() == type_char) {
42    if (((Char*)t)->to_wchar_t() == '-') {
43      flag = -1; t++;
44    }
45    else
46    if (((Char*)t)->to_wchar_t() == '+') {
47      flag = 1; t++;
48    }
49  };
50  //функция is_number() проверяет, что терм типа Word является
51  //записью числа;
52  //наличие или отсутствие знаков '+' или '-' у термов типа Word проверяет
53  // так же функция is_number(),
54  //в переменную flag записывается соответствующее значение:
55  //-1, если знак '-', 1, если знак '+' и 0, если слово является числом
56  //и у него нет знака
57  //
58  //FIXME: не надо вызывать is_number() каждый раз по новой.  Надо либо доп.
59  //переменную использовать, либо switch.  Также очень неплохо вместо
60  //обозначения возвращаемых значений цифрами завести enum.
61  //
62  if ((t->get_type() == type_word) )
63    if (((Word*)t)->is_number() == -1)
64       flag = -1;
65    else
66    if(((Word*)t)->is_number() == 1)
67      flag = 1;
68    else
69    if(((Word*)t)->is_number() == 2)
70      flag = 0;
71    else 
72      retfail;
73   
74  if (t->get_type() == type_short_int ||t->get_type() == type_word ) {
75    t++;
76  }
77
78  //первый терм в выражении порверен, переходим к проверке
79  //следующих в цикле
80  //
81 
82  for (; t < e_Exp.get_last(); t++) {
83    //если терм типа Char, то необходимо проверить, является ли он
84    //символом-числом, если да, то его длина добавляется к длине
85    //выражения, которое будет построено из исходного
86    //
87    //FIXME: зачем два раза проверяется is_not_space()?
88    //
89    if (t->get_type() == type_char) { 
90
91      if (((Char*)t)->is_not_space()) {
92
93        if (((Char*)t)->is_digit()) { 
94
95          if (len > UINTPTR_MAX - 1)
96            RF_LIB_ERROR("Argument too large for conversion");
97          else {
98            len += 1;
99          }
100        }
101        else {
102          if (((Char*)t)->is_not_space()) 
103            retfail;
104          else
105            continue;   
106        }
107      }
108      //после символов-чисел допускается любое количество пробелов,
109      // не допускаются пробелы между символами-числами
110      //
111      //FIXME: зачем внутри цикла всё время присваиваем t = temp?  Зачем вообще
112      //нужна temp?
113      //Что будет, если очередной символ -- это " "?  Надо добавить
114      //соответствующий тест.
115      //
116      else { 
117        Term* temp = t;
118        while (temp->get_type()==type_char){
119          if (((Char*)temp)->is_not_space() == false){
120            temp++; t = temp;
121          }
122          else {
123            retfail;
124          }
125        }
126      }
127    } 
128    //для термов типа ShortInt не допускается появление отрицательных чисел
129    //внутри исходного выражения; если число положительное,
130    //то считается его длина и добавляется к длине выражения, которое будет
131    //построено из исходного
132    //
133    else
134      if (t->get_type() == type_short_int) {
135        if (((ShortInt*)t)->to_int() < 0)
136          retfail;
137        else {
138          size_t num_len = ((ShortInt*)t)->get_char_len();
139          if (len > UINTPTR_MAX - num_len)
140            RF_LIB_ERROR("Argument too large for conversion");
141          else
142            len += num_len; 
143        }
144      }
145    //для термов типа Word не допускается появление знаков '+' или '-'
146    //внутри исходного выражения;
147    //если слова являются правильной записью числа (допускается
148    //произвольное количество пробелов в начале и в конце слова,
149    //не допускаются пробелы внутри слова, что проверяет функция
150    //is_number(), то считается длина слова и добавляется к
151    //длине выражения, которое будет построено из исходного
152    //
153    //FIXME: что, если в начале слова идёт пробел, а у нас уже накоплены цифры?
154    //Аналогично с концом слова.
155    //
156    else
157      if (t->get_type() == type_word){
158        if (((Word*)t)->is_number() == 1 ||((Word*)t)->is_number() == -1 )
159          retfail;
160
161        size_t word_len = ((Word*)t)->get_len();
162
163        if (len > UINTPTR_MAX - word_len)
164          RF_LIB_ERROR("Argument too large for conversion");
165        else
166          len += word_len;
167      }
168    else
169      retfail;
170  };
171  //проверка, что длина выражения, которое может быть построено
172  //из исходного, не превышает максимальной длины числа ShortInt
173  //(в будущем если эта проверка не выполнится, будет построено число
174  //типа Int)
175  //
176  if (len >= ShortInt::max_len)
177    RF_LIB_ERROR("Argument too large for conversion");
178 
179  //посторение выражения, содержащего число, из исходного выражения
180  s_Int = ShortInt::create_expr(e_Exp, flag);
181 
182RF_END
183}
184}
185 
Note: See TracBrowser for help on using the repository browser.