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

Last change on this file since 772 was 772, checked in by luba, 18 years ago
  • Processing of spaces in words is corrected;
  • comments are added;
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.8 KB
Line 
1// $Source$
2// $Revision: 772 $
3// $Date: 2003-05-28 05:14:15 +0000 (Wed, 28 May 2003) $
4// $Author: luba $
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  //Eсли там не пробел, а \n, \r, \v, \t или не символ-число,
25  // то выдать сообщение об ошибке
26  //
27  if (t->get_type() == type_char) {
28    for (; ;)
29      if (((Char*)t)->is_not_space()) {
30        break;
31      }
32      else t++;
33  }
34  //в переменную flag присваиваем -1, если перед последовательностью
35  //символов-чисел был знак '-', и 1, если перед последовательностью
36  //был знак '+'
37  //
38  if (t->get_type() == type_char) {
39    if (((Char*)t)->to_wchar_t() == '-') {
40      flag = -1; t++;
41    }
42    else
43    if (((Char*)t)->to_wchar_t() == '+') {
44      flag = 1; t++;
45    }
46  };
47  //функция is_number() проверяет, что терм типа Word является
48  //записью числа;
49  //наличие или отсутствие знаков '+' или '-' у термов типа Word проверяет
50  // так же функция is_number(),
51  //в переменную flag записывается соответствующее значение:
52  //-1, если знак '-', 1, если знак '+' и 0, если слово является числом
53  //и у него нет знака
54  //
55  if ((t->get_type() == type_word) ) {
56    int res_is_number = ((Word*)t)->is_number();
57    if (res_is_number == minus)
58       flag = -1;
59    else
60    if(res_is_number == plus)
61      flag = 1;
62    else
63    if(res_is_number == positive_number)
64      flag = 0;
65    else 
66      retfail;
67  }
68  if (t->get_type() == type_short_int ||t->get_type() == type_word ) {
69    t++;
70  }
71
72  //первый терм в выражении порверен, переходим к проверке
73  //следующих в цикле
74  //
75 
76  for (; t < e_Exp.get_last(); t++) {
77    //если терм типа Char, то необходимо проверить, является ли он
78    //символом-числом, если да, то его длина добавляется к длине
79    //выражения, которое будет построено из исходного
80    //
81    if (t->get_type() == type_char) { 
82
83      if (((Char*)t)->is_not_space()) {
84
85        if (((Char*)t)->is_digit()) { 
86
87          if (len > UINTPTR_MAX - 1)
88            RF_LIB_ERROR("Argument too large for conversion");
89          else {
90            len += 1;
91          }
92        }
93        else 
94          retfail;
95      }
96      //после символов-чисел допускается любое количество пробелов,
97      // не допускаются пробелы между символами-числами
98      //
99      else { 
100        t++;
101        while (t->get_type()==type_char){
102          if (((Char*)t)->is_not_space() == false){
103            t++;
104          }
105          else {
106            retfail;
107          }
108        }
109      }
110    } 
111    //для термов типа ShortInt не допускается появление отрицательных чисел
112    //внутри исходного выражения; если число положительное,
113    //то считается его длина и добавляется к длине выражения, которое будет
114    //построено из исходного
115    //
116    else
117      if (t->get_type() == type_short_int) {
118        if (((ShortInt*)t)->to_int() < 0)
119          retfail;
120        else {
121          size_t num_len = ((ShortInt*)t)->get_char_len();
122          if (len > UINTPTR_MAX - num_len)
123            RF_LIB_ERROR("Argument too large for conversion");
124          else
125            len += num_len; 
126        }
127      }
128    //для термов типа Word не допускается появление знаков '+' или '-'
129    //внутри исходного выражения;
130    //если слова являются правильной записью числа (допускается
131    //произвольное количество пробелов в начале и в конце слова,
132    //не допускаются пробелы внутри слова, что проверяет функция
133    //is_number(), то считается длина слова и добавляется к
134    //длине выражения, которое будет построено из исходного
135    //
136    else
137      if (t->get_type() == type_word){
138        if (((Word*)t)->is_number() == plus ||
139            ((Word*)t)->is_number() == minus )
140          retfail;
141        //не допускаются пробелы в начале слова, если слово не первое в
142        //выражении
143        //
144        if ( ((Word*)t)->has_space() == 1 )
145          retfail;
146        //не допускаются пробелы в конце слова, если оно не последнее
147        //в выражении
148        //
149        if ( (((Word*)t)->has_space() == 2) && (t != e_Exp.get_last()) )
150          retfail;
151
152        size_t word_len = ((Word*)t)->get_len();
153
154        if (len > UINTPTR_MAX - word_len)
155          RF_LIB_ERROR("Argument too large for conversion");
156        else
157          len += word_len;
158      }
159    else
160      retfail;
161  };
162  //проверка, что длина выражения, которое может быть построено
163  //из исходного, не превышает максимальной длины числа ShortInt
164  //(в будущем если эта проверка не выполнится, будет построено число
165  //типа Int)
166  //
167  if (len >= ShortInt::max_len)
168    RF_LIB_ERROR("Argument too large for conversion");
169 
170  //посторение выражения, содержащего число, из исходного выражения
171  s_Int = ShortInt::create_expr(e_Exp, flag);
172 
173RF_END
174}
175}
176 
Note: See TracBrowser for help on using the repository browser.