347 /***********************************************************************/ |
347 /***********************************************************************/ |
348 |
348 |
349 #define MILLISECOND 1000000 |
349 #define MILLISECOND 1000000 |
350 #define SECOND 1000 * MILLISECOND |
350 #define SECOND 1000 * MILLISECOND |
351 |
351 |
352 /* A helper class that knows how to generate code for both the IL and ST languages... */ |
352 unsigned long long calculate_time(symbol_c *symbol) { |
353 class calculate_time_c: public iterator_visitor_c { |
353 if (NULL == symbol) return 0; |
354 private: |
|
355 unsigned long long time; |
|
356 float current_value; |
|
357 |
354 |
358 public: |
355 interval_c *interval = dynamic_cast<interval_c *>(symbol); |
359 calculate_time_c(void){time = 0;}; |
356 duration_c *duration = dynamic_cast<duration_c *>(symbol); |
360 |
|
361 unsigned long long get_time(void) {return time;}; |
|
362 |
|
363 /* NOTE: we should really remove this function, and replace it with extract_integer_value() (in absyntax_utils.h) |
|
364 * but right now I don't want to spend time checking if this change will introduce some conversion bug |
|
365 * since it returns a long long, and not a float! |
|
366 */ |
|
367 void *get_integer_value(token_c *token) { |
|
368 std::string str = ""; |
|
369 for (unsigned int i = 0; i < strlen(token->value); i++) |
|
370 if (token->value[i] != '_') |
|
371 str += token->value[i]; |
|
372 current_value = atof(str.c_str()); |
|
373 return NULL; |
|
374 } |
|
375 |
|
376 /* NOTE: this function is incomplete, as it should also be removing '_' inserted into the literal, |
|
377 * but we leave it for now. |
|
378 * In truth, we should really have an extract_real_value() in absyntax_util.h !!! |
|
379 */ |
|
380 void *get_float_value(token_c *token) { |
|
381 current_value = atof(token->value); |
|
382 return NULL; |
|
383 } |
|
384 |
|
385 /******************************/ |
|
386 /* B 1.2.1 - Numeric Literals */ |
|
387 /******************************/ |
|
388 |
|
389 void *visit(integer_c *symbol) {return get_integer_value(symbol);} |
|
390 |
|
391 /************************/ |
|
392 /* B 1.2.3.1 - Duration */ |
|
393 /************************/ |
|
394 |
357 |
|
358 if ((NULL == interval) && (NULL == duration)) ERROR; |
|
359 |
|
360 if (NULL != duration) { |
395 /* SYM_REF2(duration_c, neg, interval) */ |
361 /* SYM_REF2(duration_c, neg, interval) */ |
396 void *visit(duration_c *symbol) { |
362 if (duration->neg != NULL) |
397 if (symbol->neg != NULL) |
363 {STAGE4_ERROR(duration, duration, "Negative TIME literals are not currently supported"); ERROR;} |
398 {STAGE4_ERROR(symbol, symbol, "Negative TIME literals are not currently supported"); ERROR;} |
364 return calculate_time(duration->interval); |
399 symbol->interval->accept(*this); |
365 } |
400 return NULL; |
366 |
401 } |
367 if (NULL != interval) { |
402 |
|
403 /* SYM_TOKEN(fixed_point_c) */ |
|
404 void *visit(fixed_point_c *symbol) {return get_float_value(symbol);} |
|
405 |
|
406 |
|
407 /* SYM_REF5(interval_c, days, hours, minutes, seconds, milliseconds) */ |
368 /* SYM_REF5(interval_c, days, hours, minutes, seconds, milliseconds) */ |
408 void *visit(interval_c *symbol) { |
369 unsigned long long int time_ull = 0; |
409 current_value = 0; |
370 long double time_ld = 0; |
410 if (NULL != symbol->milliseconds) symbol->milliseconds->accept(*this); |
371 /* |
411 time += (unsigned long long)(current_value * MILLISECOND); |
372 const unsigned long long int MILLISECOND = 1000000; |
|
373 const unsigned long long int SECOND = 1000 * MILLISECOND |
|
374 */ |
|
375 |
|
376 if (NULL != interval->milliseconds) { |
|
377 if (VALID_CVALUE( int64, interval->milliseconds) && GET_CVALUE( int64, interval->milliseconds) < 0) ERROR; // interval elements should always be positive! |
|
378 if (VALID_CVALUE( int64, interval->milliseconds)) time_ull += GET_CVALUE( int64, interval->milliseconds) * MILLISECOND; |
|
379 else if (VALID_CVALUE(uint64, interval->milliseconds)) time_ull += GET_CVALUE(uint64, interval->milliseconds) * MILLISECOND; |
|
380 else if (VALID_CVALUE(real64, interval->milliseconds)) time_ld += GET_CVALUE(real64, interval->milliseconds) * MILLISECOND; |
|
381 else ERROR; // if (NULL != interval->milliseconds) is true, then it must have a valid constant value! |
|
382 } |
412 |
383 |
413 current_value = 0; |
384 if (NULL != interval->seconds ) { |
414 if (NULL != symbol->seconds) symbol->seconds->accept(*this); |
385 if (VALID_CVALUE( int64, interval->seconds ) && GET_CVALUE( int64, interval->seconds ) < 0) ERROR; // interval elements should always be positive! |
415 time += (unsigned long long)(current_value * SECOND); |
386 if (VALID_CVALUE( int64, interval->seconds )) time_ull += GET_CVALUE( int64, interval->seconds ) * SECOND; |
416 |
387 else if (VALID_CVALUE(uint64, interval->seconds )) time_ull += GET_CVALUE(uint64, interval->seconds ) * SECOND; |
417 current_value = 0; |
388 else if (VALID_CVALUE(real64, interval->seconds )) time_ld += GET_CVALUE(real64, interval->seconds ) * SECOND; |
418 if (NULL != symbol->minutes) symbol->minutes->accept(*this); |
389 else ERROR; // if (NULL != interval->seconds) is true, then it must have a valid constant value! |
419 time += (unsigned long long)(current_value * 60 * SECOND); |
390 } |
420 |
391 |
421 current_value = 0; |
392 if (NULL != interval->minutes ) { |
422 if (NULL != symbol->hours) symbol->hours->accept(*this); |
393 if (VALID_CVALUE( int64, interval->minutes ) && GET_CVALUE( int64, interval->minutes ) < 0) ERROR; // interval elements should always be positive! |
423 time += (unsigned long long)(current_value * 60 * 60 * SECOND); |
394 if (VALID_CVALUE( int64, interval->minutes )) time_ull += GET_CVALUE( int64, interval->minutes ) * SECOND * 60; |
424 |
395 else if (VALID_CVALUE(uint64, interval->minutes )) time_ull += GET_CVALUE(uint64, interval->minutes ) * SECOND * 60; |
425 current_value = 0; |
396 else if (VALID_CVALUE(real64, interval->minutes )) time_ld += GET_CVALUE(real64, interval->minutes ) * SECOND * 60; |
426 if (NULL != symbol->days) symbol->days->accept(*this); |
397 else ERROR; // if (NULL != interval->minutes) is true, then it must have a valid constant value! |
427 time += (unsigned long long)(current_value * 60 * 60 * 24 * SECOND); |
398 } |
428 |
399 |
429 return NULL; |
400 if (NULL != interval->hours ) { |
430 } |
401 if (VALID_CVALUE( int64, interval->hours ) && GET_CVALUE( int64, interval->hours ) < 0) ERROR; // interval elements should always be positive! |
|
402 if (VALID_CVALUE( int64, interval->hours )) time_ull += GET_CVALUE( int64, interval->hours ) * SECOND * 60 * 60; |
|
403 else if (VALID_CVALUE(uint64, interval->hours )) time_ull += GET_CVALUE(uint64, interval->hours ) * SECOND * 60 * 60; |
|
404 else if (VALID_CVALUE(real64, interval->hours )) time_ld += GET_CVALUE(real64, interval->hours ) * SECOND * 60 * 60; |
|
405 else ERROR; // if (NULL != interval->hours) is true, then it must have a valid constant value! |
|
406 } |
|
407 |
|
408 if (NULL != interval->days ) { |
|
409 if (VALID_CVALUE( int64, interval->days ) && GET_CVALUE( int64, interval->days ) < 0) ERROR; // interval elements should always be positive! |
|
410 if (VALID_CVALUE( int64, interval->days )) time_ull += GET_CVALUE( int64, interval->days ) * SECOND * 60 * 60 * 24; |
|
411 else if (VALID_CVALUE(uint64, interval->days )) time_ull += GET_CVALUE(uint64, interval->days ) * SECOND * 60 * 60 * 24; |
|
412 else if (VALID_CVALUE(real64, interval->days )) time_ld += GET_CVALUE(real64, interval->days ) * SECOND * 60 * 60 * 24; |
|
413 else ERROR; // if (NULL != interval->days) is true, then it must have a valid constant value! |
|
414 } |
|
415 |
|
416 time_ull += time_ld; |
|
417 return time_ull; |
|
418 }; |
|
419 ERROR; // should never reach this point! |
|
420 return 0; // humour the compiler! |
431 }; |
421 }; |
432 |
422 |
433 /***********************************************************************/ |
423 /***********************************************************************/ |
434 /***********************************************************************/ |
424 /***********************************************************************/ |
435 /***********************************************************************/ |
425 /***********************************************************************/ |