128 /*********************/ |
205 /*********************/ |
129 /******************************/ |
206 /******************************/ |
130 /* B 1.2.1 - Numeric Literals */ |
207 /* B 1.2.1 - Numeric Literals */ |
131 /******************************/ |
208 /******************************/ |
132 void *constant_folding_c::visit(real_c *symbol) { |
209 void *constant_folding_c::visit(real_c *symbol) { |
133 MALLOC(symbol->const_value_real, real64_t); |
210 NEW_CVALUE(real64, symbol); |
134 *symbol->const_value_real = extract_real_value(symbol); |
211 SET_CVALUE(real64, symbol, extract_real_value(symbol)); |
135 |
|
136 return NULL; |
212 return NULL; |
137 } |
213 } |
138 |
214 |
139 |
215 |
140 void *constant_folding_c::visit(integer_c *symbol) { |
216 void *constant_folding_c::visit(integer_c *symbol) { |
141 int64_t *integer_value; |
217 NEW_CVALUE( int64, symbol); |
142 |
218 SET_CVALUE( int64, symbol, extract_integer_value(symbol)); |
143 integer_value = (int64_t *)malloc(sizeof(int64_t)); |
219 NEW_CVALUE(uint64, symbol); |
144 *integer_value = extract_integer_value(symbol); |
220 SET_CVALUE(uint64, symbol, extract_integer_value(symbol)); |
145 symbol->const_value_integer = integer_value; |
|
146 |
|
147 return NULL; |
221 return NULL; |
148 } |
222 } |
149 |
223 |
150 |
224 |
151 void *constant_folding_c::visit(neg_real_c *symbol) { |
225 void *constant_folding_c::visit(neg_real_c *symbol) { |
152 symbol->exp->accept(*this); |
226 symbol->exp->accept(*this); |
153 if (NULL == symbol->exp->const_value_real) |
227 if (!VALID_CVALUE(real64, symbol->exp)) |
154 ERROR; |
228 return NULL; |
155 symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t)); |
229 NEW_CVALUE(real64, symbol); |
156 *symbol->const_value_real = - *(symbol->exp->const_value_real); |
230 SET_CVALUE(real64, symbol, - GET_CVALUE( real64, symbol->exp)); |
157 return NULL; |
231 return NULL; |
158 } |
232 } |
159 |
233 |
160 |
234 /* | '-' integer {$$ = new neg_integer_c($2, locloc(@$));} */ |
161 void *constant_folding_c::visit(neg_integer_c *symbol) { |
235 void *constant_folding_c::visit(neg_integer_c *symbol) { |
162 int64_t *integer_value; |
236 symbol->exp->accept(*this); |
163 |
237 if (VALID_CVALUE(int64, symbol->exp)) { |
164 integer_value = (int64_t *)malloc(sizeof(int64_t)); |
238 NEW_CVALUE( int64, symbol); |
165 *integer_value = extract_integer_value(symbol); |
239 SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp)); |
166 symbol->const_value_integer = integer_value; |
240 } |
167 |
|
168 return NULL; |
241 return NULL; |
169 } |
242 } |
170 |
243 |
171 |
244 |
172 void *constant_folding_c::visit(binary_integer_c *symbol) { |
245 void *constant_folding_c::visit(binary_integer_c *symbol) { |
173 |
|
174 return NULL; |
246 return NULL; |
175 } |
247 } |
176 |
248 |
177 |
249 |
178 void *constant_folding_c::visit(octal_integer_c *symbol) { |
250 void *constant_folding_c::visit(octal_integer_c *symbol) { |
179 |
|
180 return NULL; |
251 return NULL; |
181 } |
252 } |
182 |
253 |
183 |
254 |
184 void *constant_folding_c::visit(hex_integer_c *symbol) { |
255 void *constant_folding_c::visit(hex_integer_c *symbol) { |
185 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
256 NEW_CVALUE( int64, symbol); |
186 *(symbol->const_value_integer) = extract_hex_value(symbol); |
257 SET_CVALUE( int64, symbol, extract_hex_value(symbol)); |
187 |
258 NEW_CVALUE(uint64, symbol); |
188 return NULL; |
259 SET_CVALUE(uint64, symbol, extract_hex_value(symbol)); |
189 } |
260 return NULL; |
190 |
261 } |
191 |
262 |
|
263 |
|
264 /* |
|
265 integer_literal: |
|
266 integer_type_name '#' signed_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
|
267 | integer_type_name '#' binary_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
|
268 | integer_type_name '#' octal_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
|
269 | integer_type_name '#' hex_integer {$$ = new integer_literal_c($1, $3, locloc(@$));} |
|
270 */ |
|
271 // SYM_REF2(integer_literal_c, type, value) |
192 void *constant_folding_c::visit(integer_literal_c *symbol) { |
272 void *constant_folding_c::visit(integer_literal_c *symbol) { |
193 symbol->value->accept(*this); |
273 symbol->value->accept(*this); |
194 if (NULL == symbol->value->const_value_integer) ERROR; |
274 if (VALID_CVALUE( int64, symbol->value)) { |
195 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
275 NEW_CVALUE( int64, symbol); |
196 *(symbol->const_value_integer) = *(symbol->value->const_value_integer); |
276 SET_CVALUE( int64, symbol, GET_CVALUE( int64, symbol->value)); |
197 |
277 } |
|
278 if (VALID_CVALUE(uint64, symbol->value)) { |
|
279 NEW_CVALUE(uint64, symbol); |
|
280 SET_CVALUE(uint64, symbol, GET_CVALUE(uint64, symbol->value)); |
|
281 } |
198 return NULL; |
282 return NULL; |
199 } |
283 } |
200 |
284 |
201 |
285 |
202 void *constant_folding_c::visit(real_literal_c *symbol) { |
286 void *constant_folding_c::visit(real_literal_c *symbol) { |
203 symbol->value->accept(*this); |
287 symbol->value->accept(*this); |
204 if (NULL == symbol->value->const_value_real) ERROR; |
288 if (VALID_CVALUE(real64, symbol->value)) { |
205 symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t)); |
289 NEW_CVALUE(real64, symbol); |
206 *symbol->const_value_real = *(symbol->value->const_value_real); |
290 SET_CVALUE(real64, symbol, GET_CVALUE(real64, symbol->value)); |
207 |
291 } |
208 return NULL; |
292 return NULL; |
209 } |
293 } |
210 |
294 |
211 |
295 |
212 void *constant_folding_c::visit(bit_string_literal_c *symbol) { |
296 void *constant_folding_c::visit(bit_string_literal_c *symbol) { |
213 |
|
214 return NULL; |
297 return NULL; |
215 } |
298 } |
216 |
299 |
217 |
300 |
218 void *constant_folding_c::visit(boolean_literal_c *symbol) { |
301 void *constant_folding_c::visit(boolean_literal_c *symbol) { |
219 symbol->value->accept(*this); |
302 symbol->value->accept(*this); |
220 if (NULL == symbol->value->const_value_bool) ERROR; |
303 if (VALID_CVALUE(bool, symbol->value)) { |
221 symbol->const_value_bool = (bool *)malloc(sizeof(bool)); |
304 NEW_CVALUE(bool, symbol); |
222 *(symbol->const_value_bool) = *(symbol->value->const_value_bool); |
305 SET_CVALUE(bool, symbol, GET_CVALUE( bool, symbol->value)); |
223 |
306 } |
224 return NULL; |
307 return NULL; |
225 } |
308 } |
226 |
309 |
227 |
310 |
228 void *constant_folding_c::visit(boolean_true_c *symbol) { |
311 void *constant_folding_c::visit(boolean_true_c *symbol) { |
229 symbol->const_value_bool = (bool *)malloc(sizeof(bool)); |
312 NEW_CVALUE(bool, symbol); |
230 *(symbol->const_value_bool) = true; |
313 SET_CVALUE(bool, symbol, true); |
231 |
|
232 return NULL; |
314 return NULL; |
233 } |
315 } |
234 |
316 |
235 |
317 |
236 void *constant_folding_c::visit(boolean_false_c *symbol) { |
318 void *constant_folding_c::visit(boolean_false_c *symbol) { |
237 symbol->const_value_bool = (bool *)malloc(sizeof(bool)); |
319 NEW_CVALUE(bool, symbol); |
238 *(symbol->const_value_bool) = false; |
320 SET_CVALUE(bool, symbol, false); |
239 |
321 return NULL; |
240 return NULL; |
322 } |
241 } |
|
242 |
|
243 |
323 |
244 |
324 |
245 /***************************************/ |
325 /***************************************/ |
246 /* B.3 - Language ST (Structured Text) */ |
326 /* B.3 - Language ST (Structured Text) */ |
247 /***************************************/ |
327 /***************************************/ |
249 /* B 3.1 - Expressions */ |
329 /* B 3.1 - Expressions */ |
250 /***********************/ |
330 /***********************/ |
251 void *constant_folding_c::visit(or_expression_c *symbol) { |
331 void *constant_folding_c::visit(or_expression_c *symbol) { |
252 symbol->l_exp->accept(*this); |
332 symbol->l_exp->accept(*this); |
253 symbol->r_exp->accept(*this); |
333 symbol->r_exp->accept(*this); |
254 if (DO_OPER(bool)) { |
334 DO_BIN_OPER(bool, ||); |
255 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
335 DO_BIN_OPER(uint64, | ); |
256 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) || *(symbol->r_exp->const_value_bool); |
|
257 } |
|
258 if (DO_OPER(integer)) { |
|
259 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
260 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) | *(symbol->r_exp->const_value_integer); |
|
261 } |
|
262 |
|
263 return NULL; |
336 return NULL; |
264 } |
337 } |
265 |
338 |
266 |
339 |
267 void *constant_folding_c::visit(xor_expression_c *symbol) { |
340 void *constant_folding_c::visit(xor_expression_c *symbol) { |
268 symbol->l_exp->accept(*this); |
341 symbol->l_exp->accept(*this); |
269 symbol->r_exp->accept(*this); |
342 symbol->r_exp->accept(*this); |
270 if (DO_OPER(integer)) { |
343 DO_BIN_OPER(bool, ^); |
271 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
344 DO_BIN_OPER(uint64, ^); |
272 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) ^ *(symbol->r_exp->const_value_integer); |
|
273 } |
|
274 |
|
275 return NULL; |
345 return NULL; |
276 } |
346 } |
277 |
347 |
278 |
348 |
279 void *constant_folding_c::visit(and_expression_c *symbol) { |
349 void *constant_folding_c::visit(and_expression_c *symbol) { |
280 symbol->l_exp->accept(*this); |
350 symbol->l_exp->accept(*this); |
281 symbol->r_exp->accept(*this); |
351 symbol->r_exp->accept(*this); |
282 if (DO_OPER(bool)) { |
352 DO_BIN_OPER(bool, &&); |
283 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
353 DO_BIN_OPER(uint64, & ); |
284 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) && *(symbol->r_exp->const_value_bool); |
|
285 } |
|
286 if (DO_OPER(integer)) { |
|
287 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
288 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) & *(symbol->r_exp->const_value_integer); |
|
289 } |
|
290 |
|
291 return NULL; |
354 return NULL; |
292 } |
355 } |
293 |
356 |
294 |
357 |
295 void *constant_folding_c::visit(equ_expression_c *symbol) { |
358 void *constant_folding_c::visit(equ_expression_c *symbol) { |
296 symbol->l_exp->accept(*this); |
359 symbol->l_exp->accept(*this); |
297 symbol->r_exp->accept(*this); |
360 symbol->r_exp->accept(*this); |
298 if (DO_OPER(bool)) { |
361 DO_BIN_OPER(bool, ==); |
299 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
362 DO_BIN_OPER(uint64, ==); |
300 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) == *(symbol->r_exp->const_value_bool); |
363 DO_BIN_OPER( int64, ==); |
301 } |
364 DO_BIN_OPER(real64, ==); |
302 if (DO_OPER(integer)) { |
|
303 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
304 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) == *(symbol->r_exp->const_value_integer); |
|
305 } |
|
306 if (DO_OPER(real)) { |
|
307 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
308 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) == *(symbol->r_exp->const_value_real); |
|
309 } |
|
310 |
|
311 return NULL; |
365 return NULL; |
312 } |
366 } |
313 |
367 |
314 |
368 |
315 void *constant_folding_c::visit(notequ_expression_c *symbol) { |
369 void *constant_folding_c::visit(notequ_expression_c *symbol) { |
316 symbol->l_exp->accept(*this); |
370 symbol->l_exp->accept(*this); |
317 symbol->r_exp->accept(*this); |
371 symbol->r_exp->accept(*this); |
318 if (DO_OPER(bool)) { |
372 DO_BIN_OPER(bool, !=); |
319 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
373 DO_BIN_OPER(uint64, !=); |
320 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_bool) != *(symbol->r_exp->const_value_bool); |
374 DO_BIN_OPER( int64, !=); |
321 } |
375 DO_BIN_OPER(real64, !=); |
322 if (DO_OPER(integer)) { |
|
323 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
324 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) != *(symbol->r_exp->const_value_integer); |
|
325 } |
|
326 if (DO_OPER(real)) { |
|
327 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
328 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) != *(symbol->r_exp->const_value_real); |
|
329 } |
|
330 |
|
331 return NULL; |
376 return NULL; |
332 } |
377 } |
333 |
378 |
334 |
379 |
335 void *constant_folding_c::visit(lt_expression_c *symbol) { |
380 void *constant_folding_c::visit(lt_expression_c *symbol) { |
336 symbol->l_exp->accept(*this); |
381 symbol->l_exp->accept(*this); |
337 symbol->r_exp->accept(*this); |
382 symbol->r_exp->accept(*this); |
338 if (DO_OPER(integer)) { |
383 DO_BIN_OPER(bool, <); |
339 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
384 DO_BIN_OPER(uint64, <); |
340 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) < *(symbol->r_exp->const_value_integer); |
385 DO_BIN_OPER( int64, <); |
341 } |
386 DO_BIN_OPER(real64, <); |
342 if (DO_OPER(real)) { |
|
343 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
344 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) < *(symbol->r_exp->const_value_real); |
|
345 } |
|
346 |
|
347 return NULL; |
387 return NULL; |
348 } |
388 } |
349 |
389 |
350 |
390 |
351 void *constant_folding_c::visit(gt_expression_c *symbol) { |
391 void *constant_folding_c::visit(gt_expression_c *symbol) { |
352 symbol->l_exp->accept(*this); |
392 symbol->l_exp->accept(*this); |
353 symbol->r_exp->accept(*this); |
393 symbol->r_exp->accept(*this); |
354 if (DO_OPER(integer)) { |
394 DO_BIN_OPER(bool, >); |
355 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
395 DO_BIN_OPER(uint64, >); |
356 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) > *(symbol->r_exp->const_value_integer); |
396 DO_BIN_OPER( int64, >); |
357 } |
397 DO_BIN_OPER(real64, >); |
358 if (DO_OPER(real)) { |
|
359 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
360 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) > *(symbol->r_exp->const_value_real); |
|
361 } |
|
362 |
|
363 return NULL; |
398 return NULL; |
364 } |
399 } |
365 |
400 |
366 |
401 |
367 void *constant_folding_c::visit(le_expression_c *symbol) { |
402 void *constant_folding_c::visit(le_expression_c *symbol) { |
368 symbol->l_exp->accept(*this); |
403 symbol->l_exp->accept(*this); |
369 symbol->r_exp->accept(*this); |
404 symbol->r_exp->accept(*this); |
370 if (DO_OPER(integer)) { |
405 DO_BIN_OPER(bool, <=); |
371 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
406 DO_BIN_OPER(uint64, <=); |
372 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) <= *(symbol->r_exp->const_value_integer); |
407 DO_BIN_OPER( int64, <=); |
373 } |
408 DO_BIN_OPER(real64, <=); |
374 if (DO_OPER(real)) { |
|
375 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
|
376 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) <= *(symbol->r_exp->const_value_real); |
|
377 } |
|
378 |
|
379 return NULL; |
409 return NULL; |
380 } |
410 } |
381 |
411 |
382 |
412 |
383 void *constant_folding_c::visit(ge_expression_c *symbol) { |
413 void *constant_folding_c::visit(ge_expression_c *symbol) { |
384 symbol->l_exp->accept(*this); |
414 symbol->l_exp->accept(*this); |
385 symbol->r_exp->accept(*this); |
415 symbol->r_exp->accept(*this); |
386 if (DO_OPER(integer)) { |
416 DO_BIN_OPER(bool, >=); |
387 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
417 DO_BIN_OPER(uint64, >=); |
388 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_integer) >= *(symbol->r_exp->const_value_integer); |
418 DO_BIN_OPER( int64, >=); |
389 } |
419 DO_BIN_OPER(real64, >=); |
390 if (DO_OPER(real)) { |
420 return NULL; |
391 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
421 } |
392 *(symbol->const_value_bool) = *(symbol->l_exp->const_value_real) >= *(symbol->r_exp->const_value_real); |
422 |
393 } |
423 |
394 |
424 #define CHECK_OVERFLOW_SUM(dtype)\ |
395 return NULL; |
425 if (VALID_CVALUE(dtype, symbol)) \ |
396 } |
426 if ((((std::numeric_limits< dtype##_t >::max() - GET_CVALUE(dtype, symbol->l_exp)) < (GET_CVALUE(dtype, symbol->r_exp))) ? 1 : 0) || \ |
397 |
427 (((std::numeric_limits< dtype##_t >::min() + GET_CVALUE(dtype, symbol->l_exp)) > (GET_CVALUE(dtype, symbol->r_exp))) ? 1 : 0)) \ |
398 |
428 SET_OVFLOW(dtype, symbol); |
|
429 #define CHECK_OVERFLOW_real64 \ |
|
430 if (VALID_CVALUE(real64, symbol)) \ |
|
431 /* NaN => underflow, overflow, number is a higher precision format, is a complex number (IEEE standard) */ \ |
|
432 if (isnan(GET_CVALUE(real64, symbol))) \ |
|
433 SET_OVFLOW(real64, symbol); |
399 void *constant_folding_c::visit(add_expression_c *symbol) { |
434 void *constant_folding_c::visit(add_expression_c *symbol) { |
400 symbol->l_exp->accept(*this); |
435 symbol->l_exp->accept(*this); |
401 symbol->r_exp->accept(*this); |
436 symbol->r_exp->accept(*this); |
402 if (DO_OPER(integer)) { |
437 DO_BIN_OPER(uint64, +); |
403 if (CHECK_OVERFLOW_SUM(*(symbol->l_exp->const_value_integer), *(symbol->r_exp->const_value_integer), int64_t)) |
438 DO_BIN_OPER( int64, +); |
404 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
439 DO_BIN_OPER(real64, +); |
405 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
440 CHECK_OVERFLOW_SUM(uint64); |
406 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) + *(symbol->r_exp->const_value_integer); |
441 CHECK_OVERFLOW_SUM( int64); |
407 } |
442 CHECK_OVERFLOW_real64; |
408 if (DO_OPER(real)) { |
443 return NULL; |
409 symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t)); |
444 } |
410 *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) + *(symbol->r_exp->const_value_real); |
445 |
411 /* |
446 |
412 * According to the IEEE standard, NaN value is used as: |
447 #define CHECK_OVERFLOW_SUB(dtype)\ |
413 * - representation of a number that has underflowed |
448 if (VALID_CVALUE(dtype, symbol)) \ |
414 * - representation of number that has overflowed |
449 if ((((std::numeric_limits< dtype##_t >::max() - GET_CVALUE(dtype, symbol->l_exp)) < (-GET_CVALUE(dtype, symbol->r_exp))) ? 1 : 0) || \ |
415 * - number is a higher precision format |
450 (((std::numeric_limits< dtype##_t >::min() + GET_CVALUE(dtype, symbol->l_exp)) > (-GET_CVALUE(dtype, symbol->r_exp))) ? 1 : 0)) \ |
416 * - A complex number |
451 SET_OVFLOW(dtype, symbol); |
417 */ |
|
418 if (isnan(*(symbol->const_value_real))) |
|
419 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
|
420 } |
|
421 |
|
422 return NULL; |
|
423 } |
|
424 |
|
425 |
|
426 void *constant_folding_c::visit(sub_expression_c *symbol) { |
452 void *constant_folding_c::visit(sub_expression_c *symbol) { |
427 symbol->l_exp->accept(*this); |
453 symbol->l_exp->accept(*this); |
428 symbol->r_exp->accept(*this); |
454 symbol->r_exp->accept(*this); |
429 if (DO_OPER(integer)) { |
455 DO_BIN_OPER(uint64, -); |
430 if (CHECK_OVERFLOW_SUB(*(symbol->l_exp->const_value_integer), *(symbol->r_exp->const_value_integer), int64_t)) |
456 DO_BIN_OPER( int64, -); |
431 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
457 DO_BIN_OPER(real64, -); |
432 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
458 CHECK_OVERFLOW_SUB(uint64); |
433 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) - *(symbol->r_exp->const_value_integer); |
459 CHECK_OVERFLOW_SUB( int64); |
434 } |
460 CHECK_OVERFLOW_real64; |
435 if (DO_OPER(real)) { |
461 return NULL; |
436 symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t)); |
462 } |
437 *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) - *(symbol->r_exp->const_value_real); |
463 |
438 /* |
464 |
439 * According to the IEEE standard, NaN value is used as: |
465 /* TODO!!! */ |
440 * - representation of a number that has underflowed |
466 #define CHECK_OVERFLOW_MUL(dtype)\ |
441 * - representation of number that has overflowed |
467 if (VALID_CVALUE(dtype, symbol)) \ |
442 * - number is a higher precision format |
468 if (false) \ |
443 * - A complex number |
469 SET_OVFLOW(dtype, symbol); |
444 */ |
|
445 if (isnan(*(symbol->const_value_real))) |
|
446 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
|
447 } |
|
448 |
|
449 return NULL; |
|
450 } |
|
451 |
|
452 |
|
453 void *constant_folding_c::visit(mul_expression_c *symbol) { |
470 void *constant_folding_c::visit(mul_expression_c *symbol) { |
454 symbol->l_exp->accept(*this); |
471 symbol->l_exp->accept(*this); |
455 symbol->r_exp->accept(*this); |
472 symbol->r_exp->accept(*this); |
456 if (DO_OPER(integer)) { |
473 DO_BIN_OPER(uint64, *); |
457 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
474 DO_BIN_OPER( int64, *); |
458 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) * *(symbol->r_exp->const_value_integer); |
475 DO_BIN_OPER(real64, *); |
459 } |
476 CHECK_OVERFLOW_MUL(uint64); |
460 if (DO_OPER(real)) { |
477 CHECK_OVERFLOW_MUL( int64); |
461 symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t)); |
478 CHECK_OVERFLOW_real64; |
462 *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) * *(symbol->r_exp->const_value_real); |
479 return NULL; |
463 /* |
480 } |
464 * According to the IEEE standard, NaN value is used as: |
481 |
465 * - representation of a number that has underflowed |
482 |
466 * - representation of number that has overflowed |
483 |
467 * - number is a higher precision format |
484 /* TODO!!! */ |
468 * - A complex number |
485 #define CHECK_OVERFLOW_DIV(dtype)\ |
469 */ |
486 if (VALID_CVALUE(dtype, symbol)) \ |
470 if (isnan(*(symbol->const_value_real))) |
487 if (false) \ |
471 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
488 SET_OVFLOW(dtype, symbol); |
472 } |
|
473 |
|
474 return NULL; |
|
475 } |
|
476 |
|
477 |
|
478 void *constant_folding_c::visit(div_expression_c *symbol) { |
489 void *constant_folding_c::visit(div_expression_c *symbol) { |
479 symbol->l_exp->accept(*this); |
490 symbol->l_exp->accept(*this); |
480 symbol->r_exp->accept(*this); |
491 symbol->r_exp->accept(*this); |
481 if (DO_OPER(integer)) { |
492 if (ISZERO_CVALUE(uint64, symbol->r_exp)) {NEW_CVALUE(uint64, symbol); SET_OVFLOW(uint64, symbol);} else {DO_BIN_OPER(uint64, /); CHECK_OVERFLOW_DIV(uint64)}; |
482 if (*(symbol->r_exp->const_value_integer) == 0) |
493 if (ISZERO_CVALUE( int64, symbol->r_exp)) {NEW_CVALUE( int64, symbol); SET_OVFLOW( int64, symbol);} else {DO_BIN_OPER( int64, /); CHECK_OVERFLOW_DIV( int64)}; |
483 STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression."); |
494 if (ISZERO_CVALUE(real64, symbol->r_exp)) {NEW_CVALUE(real64, symbol); SET_OVFLOW(real64, symbol);} else {DO_BIN_OPER(real64, /); CHECK_OVERFLOW_real64;}; |
484 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
495 return NULL; |
485 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) / *(symbol->r_exp->const_value_integer); |
496 } |
486 } |
497 |
487 if (DO_OPER(real)) { |
498 |
488 if (*(symbol->r_exp->const_value_real) == 0) |
499 /* TODO!!! */ |
489 STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression."); |
500 #define CHECK_OVERFLOW_MOD(dtype)\ |
490 symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t)); |
501 if (VALID_CVALUE(dtype, symbol)) \ |
491 *(symbol->const_value_real) = *(symbol->l_exp->const_value_real) / *(symbol->r_exp->const_value_real); |
502 if (false) \ |
492 /* |
503 SET_OVFLOW(dtype, symbol); |
493 * According to the IEEE standard, NaN value is used as: |
|
494 * - representation of a number that has underflowed |
|
495 * - representation of number that has overflowed |
|
496 * - number is a higher precision format |
|
497 * - A complex number |
|
498 */ |
|
499 if (isnan(*(symbol->const_value_real))) |
|
500 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
|
501 } |
|
502 |
|
503 return NULL; |
|
504 } |
|
505 |
|
506 |
|
507 void *constant_folding_c::visit(mod_expression_c *symbol) { |
504 void *constant_folding_c::visit(mod_expression_c *symbol) { |
508 symbol->l_exp->accept(*this); |
505 symbol->l_exp->accept(*this); |
509 symbol->r_exp->accept(*this); |
506 symbol->r_exp->accept(*this); |
510 if (DO_OPER(integer)) { |
507 if (ISZERO_CVALUE(uint64, symbol->r_exp)) {NEW_CVALUE(uint64, symbol); SET_OVFLOW(uint64, symbol);} else {DO_BIN_OPER(uint64, %); CHECK_OVERFLOW_MOD(uint64)}; |
511 if (*(symbol->r_exp->const_value_integer) == 0) |
508 if (ISZERO_CVALUE( int64, symbol->r_exp)) {NEW_CVALUE( int64, symbol); SET_OVFLOW( int64, symbol);} else {DO_BIN_OPER( int64, %); CHECK_OVERFLOW_MOD( int64)}; |
512 STAGE3_ERROR(0, symbol, symbol, "Division by zero in constant expression."); |
|
513 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
|
514 *(symbol->const_value_integer) = *(symbol->l_exp->const_value_integer) % *(symbol->r_exp->const_value_integer); |
|
515 |
|
516 } |
|
517 |
|
518 return NULL; |
509 return NULL; |
519 } |
510 } |
520 |
511 |
521 |
512 |
522 void *constant_folding_c::visit(power_expression_c *symbol) { |
513 void *constant_folding_c::visit(power_expression_c *symbol) { |
523 symbol->l_exp->accept(*this); |
514 symbol->l_exp->accept(*this); |
524 symbol->r_exp->accept(*this); |
515 symbol->r_exp->accept(*this); |
525 if ((NULL != symbol->l_exp->const_value_real) && (NULL != symbol->r_exp->const_value_integer)) { |
516 /* NOTE: If the const_value in symbol->r_exp is within the limits of both int64 and uint64, then we do both operations. |
526 symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t)); |
517 * That is OK, as the result should be identicial (we do create an unnecessary CVALUE variable, but who cares?). |
527 *(symbol->const_value_real) = pow(*(symbol->l_exp->const_value_real), *(symbol->r_exp->const_value_integer)); |
518 * If only one is valid, then that is the oper we will do! |
528 /* |
519 */ |
529 * According to the IEEE standard, NaN value is used as: |
520 if (VALID_CVALUE(real64, symbol->l_exp) && VALID_CVALUE( int64, symbol->r_exp)) { |
530 * - representation of a number that has underflowed |
521 NEW_CVALUE(real64, symbol); |
531 * - representation of number that has overflowed |
522 SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, symbol->l_exp), GET_CVALUE( int64, symbol->r_exp))); |
532 * - number is a higher precision format |
523 } |
533 * - A complex number |
524 if (VALID_CVALUE(real64, symbol->l_exp) && VALID_CVALUE(uint64, symbol->r_exp)) { |
534 */ |
525 NEW_CVALUE(real64, symbol); |
535 if (isnan(*(symbol->const_value_real))) |
526 SET_CVALUE(real64, symbol, pow(GET_CVALUE(real64, symbol->l_exp), GET_CVALUE(uint64, symbol->r_exp))); |
536 STAGE3_ERROR(0, symbol, symbol, "Overflow in constant expression."); |
527 } |
537 } |
528 CHECK_OVERFLOW_real64; |
538 |
529 return NULL; |
539 return NULL; |
530 } |
540 } |
531 |
541 |
532 |
542 |
533 /* TODO!!! */ |
|
534 #define CHECK_OVERFLOW_NEG(dtype)\ |
|
535 if (VALID_CVALUE(dtype, symbol)) \ |
|
536 if (false) \ |
|
537 SET_OVFLOW(dtype, symbol); |
543 void *constant_folding_c::visit(neg_expression_c *symbol) { |
538 void *constant_folding_c::visit(neg_expression_c *symbol) { |
544 symbol->exp->accept(*this); |
539 symbol->exp->accept(*this); |
545 if (NULL != symbol->exp->const_value_integer) { |
540 if (VALID_CVALUE( int64, symbol->exp)) { |
546 symbol->const_value_integer = (int64_t*) malloc(sizeof(int64_t)); |
541 NEW_CVALUE( int64, symbol); |
547 *(symbol->const_value_integer) = - *(symbol->exp->const_value_integer); |
542 SET_CVALUE( int64, symbol, - GET_CVALUE( int64, symbol->exp)); |
548 } |
543 } |
549 if (NULL != symbol->exp->const_value_real) { |
544 if (VALID_CVALUE(real64, symbol->exp)) { |
550 symbol->const_value_real = (real64_t*) malloc(sizeof(real64_t)); |
545 NEW_CVALUE(real64, symbol); |
551 *(symbol->const_value_real) = - *(symbol->exp->const_value_real); |
546 SET_CVALUE(real64, symbol, - GET_CVALUE(real64, symbol->exp)); |
552 } |
547 } |
|
548 CHECK_OVERFLOW_NEG( int64); |
|
549 CHECK_OVERFLOW_real64; |
553 return NULL; |
550 return NULL; |
554 } |
551 } |
555 |
552 |
556 |
553 |
557 |
554 |
558 void *constant_folding_c::visit(not_expression_c *symbol) { |
555 void *constant_folding_c::visit(not_expression_c *symbol) { |
559 symbol->exp->accept(*this); |
556 symbol->exp->accept(*this); |
560 if (NULL != symbol->exp->const_value_bool) { |
557 if (VALID_CVALUE( bool, symbol->exp)) { |
561 symbol->const_value_bool = (bool*) malloc(sizeof(bool)); |
558 NEW_CVALUE( bool, symbol); |
562 *(symbol->const_value_bool) = !*(symbol->exp->const_value_bool); |
559 SET_CVALUE( bool, symbol, ! GET_CVALUE( bool, symbol->exp)); |
563 } |
560 } |
564 |
561 if (VALID_CVALUE(uint64, symbol->exp)) { |
565 return NULL; |
562 NEW_CVALUE(uint64, symbol); |
566 } |
563 SET_CVALUE(uint64, symbol, ~ GET_CVALUE(uint64, symbol->exp)); |
567 |
564 } |
568 |
565 return NULL; |
569 |
566 } |
|
567 |
|
568 |