43 * as their data type is undefined (e.g. the datat type of '30' |
43 * as their data type is undefined (e.g. the datat type of '30' |
44 * could be 'INT' or 'SINT' or 'LINT' or 'USINT' or ... |
44 * could be 'INT' or 'SINT' or 'LINT' or 'USINT' or ... |
45 * NOTE: for base 10 numeric literals, any number taking up more than 64 bits |
45 * NOTE: for base 10 numeric literals, any number taking up more than 64 bits |
46 * will only return a bitsize of 1024! |
46 * will only return a bitsize of 1024! |
47 * |
47 * |
48 * For numeric literals, we return the minimum number of bits |
48 * NOTE: The code that does the following has been commented out, since we no longer need it! |
49 * required to store the value. |
49 * It has been superceded by the constant_folding.cc class. |
|
50 * // For numeric literals, we return the minimum number of bits |
|
51 * // required to store the value. |
50 * |
52 * |
51 * E.g. TYPE new_int_t : INT; END_TYPE; |
53 * E.g. TYPE new_int_t : INT; END_TYPE; |
52 * TYPE new_int2_t : INT = 2; END_TYPE; |
54 * TYPE new_int2_t : INT = 2; END_TYPE; |
53 * TYPE new_subr_t : INT (4..5); END_TYPE; |
55 * TYPE new_subr_t : INT (4..5); END_TYPE; |
54 * |
56 * |
55 * sizeof(SINT) -> 8 |
57 * sizeof(SINT) -> 8 |
56 * sizeof(INT) -> 16 |
58 * sizeof(INT) -> 16 |
57 * sizeof(DINT) -> 32 |
59 * sizeof(DINT) -> 32 |
58 * sizeof(LINT) -> 64 |
60 * sizeof(LINT) -> 64 |
59 * |
61 * |
60 * sizeof('1') -> 1 |
62 * NOTE: The code that does the following has been commented out, since we no longer need it! |
61 * sizeof('015') -> 4 # Leading zeros are ignored! |
63 * It has been superceded by the constant_folding.cc class. |
62 * sizeof('0') -> 1 # This is a special case! Even the value 0 needs at least 1 bit to store! |
64 * // sizeof('1') -> 1 |
63 * sizeof('16') -> 5 |
65 * // sizeof('015') -> 4 # Leading zeros are ignored! |
64 * sizeof('2#00101') -> 3 |
66 * // sizeof('0') -> 1 # This is a special case! Even the value 0 needs at least 1 bit to store! |
65 * sizeof('8#334') -> 9 |
67 * // sizeof('16') -> 5 |
66 * sizeof('16#2A') -> 8 |
68 * // sizeof('2#00101') -> 3 |
67 * |
69 * // sizeof('8#334') -> 9 |
68 * sizeof('7.4') -> 32 # all real literals return 32 bits, the size of a 'REAL' |
70 * // sizeof('16#2A') -> 8 |
69 * # TODO: study IEC 60559 for the range of values that may be |
71 * |
70 * # stored in a REAL (basic single width floating point format) |
72 * // sizeof('7.4') -> 32 # all real literals return 32 bits, the size of a 'REAL' |
71 * # and in a LREAL (basic double width floating point format) |
73 * // # TODO: study IEC 60559 for the range of values that may be |
72 * # and see if some real literals need to return 64 instead! |
74 * // # stored in a REAL (basic single width floating point format) |
|
75 * // # and in a LREAL (basic double width floating point format) |
|
76 * // # and see if some real literals need to return 64 instead! |
73 */ |
77 */ |
74 |
78 |
75 #include "get_sizeof_datatype.hh" |
79 #include "get_sizeof_datatype.hh" |
76 |
80 |
77 #include <stdlib.h> |
81 #include <stdlib.h> |
78 #include <string.h> |
82 #include <string.h> |
79 #include <limits.h> // get definition of ULLONG_MAX |
83 #include <limits.h> // get definition of ULLONG_MAX |
80 /* tell stdint.h we want the definition of UINT64_MAX */ |
84 #include <errno.h> |
81 #define __STDC_LIMIT_MACROS |
85 |
82 #include <stdint.h> // get definition of uint64_t and UINT64_MAX |
86 #include "../main.hh" // required for ERROR() and ERROR_MSG() macros, and uint64_t and UINT64_MAX |
83 |
87 |
84 |
|
85 #define ERROR error_exit(__FILE__,__LINE__) |
|
86 /* function defined in main.cc */ |
|
87 extern void error_exit(const char *file_name, int line_no); |
|
88 |
88 |
89 |
89 |
90 /* This class is a singleton. |
90 /* This class is a singleton. |
91 * So we need a pointer to the singe instance... |
91 * So we need a pointer to the singe instance... |
92 */ |
92 */ |
156 */ |
155 */ |
157 |
156 |
158 /* NOTE: all integer_c and real_c tokens will always be positive (i.e. no leading '-') |
157 /* NOTE: all integer_c and real_c tokens will always be positive (i.e. no leading '-') |
159 * due to the way the source code is parsed by iec.flex. |
158 * due to the way the source code is parsed by iec.flex. |
160 */ |
159 */ |
|
160 |
|
161 /* |
|
162 * IEC6113-3 and C++ use IEC 60559 to rappresent floating point data types |
|
163 * REAL => float => single precision 32 bit |
|
164 * LREAL => double => double precision 64 bit |
|
165 * ????? => long double => quadruple precision 128 bit |
|
166 */ |
161 void *get_sizeof_datatype_c::visit(real_c *symbol) { |
167 void *get_sizeof_datatype_c::visit(real_c *symbol) { |
162 return _encode_int(32); |
168 char *endp; |
|
169 long double ld_test; |
|
170 double d_test; |
|
171 float f_test; |
|
172 |
|
173 /* copy the original string, but leave out any underscores... */ |
|
174 char *sval, *oval; |
|
175 const char *pval; |
|
176 oval = sval = (char *)malloc(strlen(symbol->value)+1); |
|
177 if (NULL == sval) ERROR; |
|
178 |
|
179 for (pval = symbol->value, sval = oval; *pval != '\0'; pval++) { |
|
180 if ('_' != *pval) {*sval = *pval; sval++;} |
|
181 } |
|
182 *sval = '\0'; |
|
183 |
|
184 sval = oval; |
|
185 if ('\0' == *sval) ERROR; |
|
186 |
|
187 /* now do the conversion using the new string... */ |
|
188 f_test = strtof(sval, &endp); |
|
189 if (*endp != '\0') ERROR; |
|
190 if (ERANGE != errno) { |
|
191 /* No overflow/underflow! => It fits in a float! */ |
|
192 free(oval); |
|
193 return _encode_int(32); |
|
194 } |
|
195 |
|
196 d_test = strtod(sval, &endp); |
|
197 if (*endp != '\0') ERROR; |
|
198 if (ERANGE != errno) { |
|
199 /* No overflow/underflow! => It fits in a double! */ |
|
200 free(oval); |
|
201 return _encode_int(64); |
|
202 } |
|
203 |
|
204 ld_test = strtold(sval, &endp); |
|
205 if (*endp != '\0') ERROR; |
|
206 if (ERANGE != errno) { |
|
207 /* No overflow/underflow! => It fits in a long double! */ |
|
208 free(oval); |
|
209 return _encode_int(128); |
|
210 } |
|
211 |
|
212 free(oval); |
|
213 return _encode_int(65535); /* a very large number!!! */ |
163 } |
214 } |
164 |
215 |
165 void *get_sizeof_datatype_c::visit(neg_real_c *symbol) { |
216 void *get_sizeof_datatype_c::visit(neg_real_c *symbol) { |
166 return symbol->exp->accept(*this); |
217 return symbol->exp->accept(*this); |
167 } |
218 } |
280 for (bitsize = 0; '\0' != *sval; sval++) { |
331 for (bitsize = 0; '\0' != *sval; sval++) { |
281 /* consistency check: make sure we only have binary digits! */ |
332 /* consistency check: make sure we only have binary digits! */ |
282 if (('0' != *sval) && ('1' != *sval) && ('_' != *sval)) |
333 if (('0' != *sval) && ('1' != *sval) && ('_' != *sval)) |
283 ERROR; |
334 ERROR; |
284 |
335 |
285 if ('_' != *sval) bitsize ++; /* 1 bits per binary digit */ |
336 if ('_' != *sval) bitsize++; /* 1 bits per binary digit */ |
286 } |
337 } |
287 |
338 |
288 /* special case... if (value == 0) <=> (bitsize == 0), return bit size of 1 ! */ |
339 /* special case... if (value == 0) <=> (bitsize == 0), return bit size of 1 ! */ |
289 if (0 == bitsize) bitsize = 1; |
340 if (0 == bitsize) bitsize = 1; |
290 |
341 |
362 /* special case... if (value == 0) <=> (bitsize == 0), return bit size of 1 ! */ |
413 /* special case... if (value == 0) <=> (bitsize == 0), return bit size of 1 ! */ |
363 if (0 == bitsize) bitsize = 1; |
414 if (0 == bitsize) bitsize = 1; |
364 |
415 |
365 return _encode_int(bitsize); |
416 return _encode_int(bitsize); |
366 } |
417 } |
367 |
418 #endif |
368 |
419 |
369 /***********************************/ |
420 /***********************************/ |
370 /* B 1.3.1 - Elementary Data Types */ |
421 /* B 1.3.1 - Elementary Data Types */ |
371 /***********************************/ |
422 /***********************************/ |
372 // void *get_sizeof_datatype_c::visit(time_type_name_c *symbol) {return _encode_int(0); } |
423 // void *get_sizeof_datatype_c::visit(time_type_name_c *symbol) {return _encode_int(0); } |