stage3/constant_folding.cc
changeset 601 683ae5444237
parent 600 f5d4e9f91513
child 602 456add88d64c
equal deleted inserted replaced
600:f5d4e9f91513 601:683ae5444237
   253 static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);}
   253 static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);}
   254 
   254 
   255 
   255 
   256 /* extract the value of an integer from an integer_c object !! */
   256 /* extract the value of an integer from an integer_c object !! */
   257 /* NOTE: it must ignore underscores! */
   257 /* NOTE: it must ignore underscores! */
   258 int64_t extract_int64_value(symbol_c *sym, int base, bool *overflow) {
   258 /* NOTE: To follow the basic structure used throughout the compiler's code, we should really be
   259   std::string str = "";
   259  * writing this as a visitor_c (and do away with the dynamic casts!), but since we only have 3 distinct 
   260   integer_c *integer;
   260  * symbol class types to handle, it is probably easier to read if we write it as a standard function... 
   261   char *endptr;
   261  */
   262   int64_t ret;
   262 int64_t extract_int64_value(symbol_c *sym, bool *overflow) {
   263 
   263   int64_t      ret;
   264   if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR;
   264   std::string  str = "";
   265   for(unsigned int i = 0; i < strlen(integer->value); i++)
   265   char        *endptr;
   266     if (integer->value[i] != '_')  str += integer->value[i];
   266   const char  *value;
       
   267   int          base;
       
   268   integer_c         *integer;
       
   269   hex_integer_c     *hex_integer;
       
   270   octal_integer_c   *octal_integer;
       
   271   binary_integer_c  *binary_integer;
       
   272 
       
   273    if       ((integer        = dynamic_cast<integer_c *>(sym))        != NULL) {value = integer       ->value + 0; base = 10;}
       
   274    else  if ((hex_integer    = dynamic_cast<hex_integer_c *>(sym))    != NULL) {value = hex_integer   ->value + 3; base = 16;}
       
   275    else  if ((octal_integer  = dynamic_cast<octal_integer_c *>(sym))  != NULL) {value = octal_integer ->value + 2; base =  8;}
       
   276    else  if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base =  2;}
       
   277    else  ERROR;
       
   278 
       
   279   for(unsigned int i = 0; i < strlen(value); i++)
       
   280     if (value[i] != '_')  str += value[i];
   267 
   281 
   268   errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
   282   errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
   269   ret = matiec_strtoint64((int64_t *)NULL, str.c_str(), &endptr, base);
   283   ret = matiec_strtoint64((int64_t *)NULL, str.c_str(), &endptr, base);
   270   if (overflow != NULL)
   284   if (overflow != NULL)
   271     *overflow = (errno == ERANGE);
   285     *overflow = (errno == ERANGE);
   273     ERROR;
   287     ERROR;
   274 
   288 
   275   return ret;
   289   return ret;
   276 }
   290 }
   277 
   291 
   278 uint64_t extract_uint64_value(symbol_c *sym, int base, bool *overflow) {
   292 
   279   std::string str = "";
   293 
   280   integer_c *integer;
   294 uint64_t extract_uint64_value(symbol_c *sym, bool *overflow) {
   281   char *endptr;
   295   uint64_t     ret;
   282   uint64_t ret;
   296   std::string  str = "";
   283   
   297   char        *endptr;
   284   if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR;
   298   const char  *value;
   285   for(unsigned int i = 0; i < strlen(integer->value); i++)
   299   int          base;
   286     if (integer->value[i] != '_')  str += integer->value[i];
   300   integer_c         *integer;
       
   301   hex_integer_c     *hex_integer;
       
   302   octal_integer_c   *octal_integer;
       
   303   binary_integer_c  *binary_integer;
       
   304 
       
   305    if       ((integer        = dynamic_cast<integer_c *>(sym))        != NULL) {value = integer       ->value + 0; base = 10;}
       
   306    else  if ((hex_integer    = dynamic_cast<hex_integer_c *>(sym))    != NULL) {value = hex_integer   ->value + 3; base = 16;}
       
   307    else  if ((octal_integer  = dynamic_cast<octal_integer_c *>(sym))  != NULL) {value = octal_integer ->value + 2; base =  8;}
       
   308    else  if ((binary_integer = dynamic_cast<binary_integer_c *>(sym)) != NULL) {value = binary_integer->value + 2; base =  2;}
       
   309    else  ERROR;
       
   310 
       
   311   for(unsigned int i = 0; i < strlen(value); i++)
       
   312     if (value[i] != '_')  str += value[i];
   287 
   313 
   288   errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
   314   errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
   289   ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, base);
   315   ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, base);
   290   if (overflow != NULL)
   316   if (overflow != NULL)
   291     *overflow = (errno == ERANGE);
   317     *overflow = (errno == ERANGE);
   571 }
   597 }
   572 
   598 
   573 
   599 
   574 void *constant_folding_c::visit(integer_c *symbol) {
   600 void *constant_folding_c::visit(integer_c *symbol) {
   575 	bool overflow;
   601 	bool overflow;
   576 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, 10, &overflow));
   602 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
   577 	if (overflow) SET_OVFLOW(int64, symbol);
   603 	if (overflow) SET_OVFLOW(int64, symbol);
   578 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 10, &overflow));
   604 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
   579 	if (overflow) SET_OVFLOW(uint64, symbol);
   605 	if (overflow) SET_OVFLOW(uint64, symbol);
   580 	return NULL;
   606 	return NULL;
   581 }
   607 }
   582 
   608 
   583 
   609 
   606 }
   632 }
   607 
   633 
   608 
   634 
   609 void *constant_folding_c::visit(binary_integer_c *symbol) {
   635 void *constant_folding_c::visit(binary_integer_c *symbol) {
   610 	bool overflow;
   636 	bool overflow;
   611 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol,  2, &overflow));
   637 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
   612 	if (overflow) SET_OVFLOW(int64, symbol);
   638 	if (overflow) SET_OVFLOW(int64, symbol);
   613 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol,  2, &overflow));
   639 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
   614 	if (overflow) SET_OVFLOW(uint64, symbol);
   640 	if (overflow) SET_OVFLOW(uint64, symbol);
   615 	return NULL;
   641 	return NULL;
   616 }
   642 }
   617 
   643 
   618 
   644 
   619 void *constant_folding_c::visit(octal_integer_c *symbol) {
   645 void *constant_folding_c::visit(octal_integer_c *symbol) {
   620 	bool overflow;
   646 	bool overflow;
   621 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol,  8, &overflow));
   647 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
   622 	if (overflow) SET_OVFLOW(int64, symbol);
   648 	if (overflow) SET_OVFLOW(int64, symbol);
   623 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol,  8, &overflow));
   649 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
   624 	if (overflow) SET_OVFLOW(uint64, symbol);
   650 	if (overflow) SET_OVFLOW(uint64, symbol);
   625 	return NULL;
   651 	return NULL;
   626 }
   652 }
   627 
   653 
   628 
   654 
   629 void *constant_folding_c::visit(hex_integer_c *symbol) {
   655 void *constant_folding_c::visit(hex_integer_c *symbol) {
   630 	bool overflow;
   656 	bool overflow;
   631 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, 16, &overflow));
   657 	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value (symbol, &overflow));
   632 	if (overflow) SET_OVFLOW(int64, symbol);
   658 	if (overflow) SET_OVFLOW(int64, symbol);
   633 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, 16, &overflow));
   659 	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
   634 	if (overflow) SET_OVFLOW(uint64, symbol);
   660 	if (overflow) SET_OVFLOW(uint64, symbol);
   635 	return NULL;
   661 	return NULL;
   636 }
   662 }
   637 
   663 
   638 
   664