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

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