Fix extract_integer_value.
authorManuele Conti <conti.ma@alice.it>
Tue, 12 Jun 2012 22:32:09 +0200
changeset 587 1ecf916cc397
parent 586 b602f0459f17
child 588 3d72d09bd40f
Fix extract_integer_value.
Now we handle signed and unsigned in different mode.
(Thanks to Andreas)
absyntax_utils/absyntax_utils.cc
absyntax_utils/absyntax_utils.hh
absyntax_utils/function_param_iterator.cc
stage3/constant_folding.cc
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_typedecl.cc
stage4/generate_c/generate_c_vardecl.cc
--- a/absyntax_utils/absyntax_utils.cc	Tue Jun 12 17:15:24 2012 +0100
+++ b/absyntax_utils/absyntax_utils.cc	Tue Jun 12 22:32:09 2012 +0200
@@ -99,21 +99,51 @@
 
 /* extract the value of an integer from an integer_c object !! */
 /* NOTE: it must ignore underscores! */
-long long extract_integer_value(symbol_c *sym) {
+int64_t extract_int64_value(symbol_c *sym, bool *overflow) {
   std::string str = "";
   integer_c *integer;
   neg_integer_c * neg_integer;
+  char *endptr;
+  int64_t ret;
 
   if ((neg_integer = dynamic_cast<neg_integer_c *>(sym)) != NULL)
-    return - extract_integer_value(neg_integer->exp);
-  
+    return - extract_int64_value(neg_integer->exp, overflow);
+
   if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR;
 
   for(unsigned int i = 0; i < strlen(integer->value); i++)
     if (integer->value[i] != '_')  str += integer->value[i];
 
-  /* return atoi(str.c_str()); */
-  return atoll(str.c_str());
+  errno = 0;
+  ret = strtoll(str.c_str(), &endptr, 10);
+  if (overflow != NULL)
+    *overflow = (errno == ERANGE);
+  if ((errno != 0) && (errno != ERANGE))
+    ERROR;
+
+  return ret;
+}
+
+uint64_t extract_uint64_value(symbol_c *sym, bool *overflow) {
+  std::string str = "";
+  integer_c *integer;
+  neg_integer_c * neg_integer;
+  char *endptr;
+  uint64_t ret;
+  
+  if ((integer = dynamic_cast<integer_c *>(sym)) == NULL) ERROR;
+
+  for(unsigned int i = 0; i < strlen(integer->value); i++)
+    if (integer->value[i] != '_')  str += integer->value[i];
+
+  errno = 0;
+  ret = strtoull(str.c_str(), &endptr, 10);
+  if (overflow != NULL)
+    *overflow = (errno == ERANGE);
+  if ((errno != 0) && (errno != ERANGE))
+    ERROR;
+
+  return ret;
 }
 
 
@@ -153,9 +183,8 @@
  * exponent        [Ee]([+-]?){integer}
  * integer         {digit}((_?{digit})*)
  */
-real64_t extract_real_value(symbol_c *sym, bool *overflow = NULL) {
+real64_t extract_real_value(symbol_c *sym, bool *overflow) {
   std::string str = "";
-  char *endptr;
   real_c * real_sym;
   real64_t ret;
 
--- a/absyntax_utils/absyntax_utils.hh	Tue Jun 12 17:15:24 2012 +0100
+++ b/absyntax_utils/absyntax_utils.hh	Tue Jun 12 22:32:09 2012 +0200
@@ -56,9 +56,10 @@
 int compare_identifiers(symbol_c *ident1, symbol_c *ident2);
 
 /* extract the value of an integer/hex_integer/real from an integer_c/hex_integer_c/real_c symbol !! */
-long long extract_integer_value(symbol_c *sym);
+int64_t   extract_int64_value  (symbol_c *sym, bool *overflow = NULL);
+int64_t   extract_uint64_value (symbol_c *sym, bool *overflow = NULL);
 uint64_t  extract_hex_value    (symbol_c *sym);
-real64_t  extract_real_value   (symbol_c *sym, bool *overflow);
+real64_t  extract_real_value   (symbol_c *sym, bool *overflow = NULL);
   
 /* A symbol table with all globally declared functions... */
 extern function_declaration_c null_symbol1;
--- a/absyntax_utils/function_param_iterator.cc	Tue Jun 12 17:15:24 2012 +0100
+++ b/absyntax_utils/function_param_iterator.cc	Tue Jun 12 22:32:09 2012 +0200
@@ -130,7 +130,7 @@
         if (extensible_parameter != NULL) {
           sym = extensible_parameter->var_name;
           current_param_is_extensible = true;
-          _first_extensible_param_index = extract_integer_value(extensible_parameter->first_index);
+          _first_extensible_param_index = extract_int64_value(extensible_parameter->first_index);
         }
         identifier_c *variable_name = dynamic_cast<identifier_c *>(sym);
         if (variable_name == NULL) ERROR;
@@ -167,7 +167,7 @@
       if (extensible_parameter != NULL) {
         var_name = extensible_parameter->var_name;
         current_param_is_extensible = true;
-        _first_extensible_param_index = extract_integer_value(extensible_parameter->first_index);
+        _first_extensible_param_index = extract_int64_value(extensible_parameter->first_index);
       }
       identifier_c *variable_name = dynamic_cast<identifier_c *>(var_name);
       if (variable_name == NULL) ERROR;
@@ -265,7 +265,7 @@
   if (extensible_parameter != NULL) {
     sym = extensible_parameter->var_name;
     current_param_is_extensible = true;
-    _first_extensible_param_index = extract_integer_value(extensible_parameter->first_index);
+    _first_extensible_param_index = extract_int64_value(extensible_parameter->first_index);
     current_extensible_param_index = _first_extensible_param_index;
   }
   identifier = dynamic_cast<identifier_c *>(sym);
--- a/stage3/constant_folding.cc	Tue Jun 12 17:15:24 2012 +0100
+++ b/stage3/constant_folding.cc	Tue Jun 12 22:32:09 2012 +0200
@@ -431,8 +431,9 @@
 
 
 void *constant_folding_c::visit(integer_c *symbol) {
-	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_integer_value(symbol));
-	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_integer_value(symbol));
+	bool overflow;
+	NEW_CVALUE( int64, symbol);	SET_CVALUE( int64, symbol, extract_int64_value(symbol, &overflow));
+	NEW_CVALUE(uint64, symbol);	SET_CVALUE(uint64, symbol, extract_uint64_value(symbol, &overflow));
 	return NULL;
 }
 
--- a/stage4/generate_c/generate_c.cc	Tue Jun 12 17:15:24 2012 +0100
+++ b/stage4/generate_c/generate_c.cc	Tue Jun 12 22:32:09 2012 +0200
@@ -782,7 +782,7 @@
     /*  signed_integer DOTDOT signed_integer */
     //SYM_REF2(subrange_c, lower_limit, upper_limit)
     void *visit(subrange_c *symbol) {
-      int dimension = extract_integer_value(symbol->upper_limit) - extract_integer_value(symbol->lower_limit) + 1;
+      int dimension = extract_int64_value(symbol->upper_limit) - extract_int64_value(symbol->lower_limit) + 1;
       switch (current_mode) {
         case arrayname_im:
           current_array_name += "_";
--- a/stage4/generate_c/generate_c_typedecl.cc	Tue Jun 12 17:15:24 2012 +0100
+++ b/stage4/generate_c/generate_c_typedecl.cc	Tue Jun 12 22:32:09 2012 +0200
@@ -255,7 +255,7 @@
     case array_td:
       if (current_basetypedeclaration == arraysubrange_bd) {
         s4o_incl.print("[");
-        dimension = extract_integer_value(symbol->upper_limit) - extract_integer_value(symbol->lower_limit) + 1;
+        dimension = extract_int64_value(symbol->upper_limit) - extract_int64_value(symbol->lower_limit) + 1;
         print_integer_incl(dimension);
         s4o_incl.print("]");
       }
--- a/stage4/generate_c/generate_c_vardecl.cc	Tue Jun 12 17:15:24 2012 +0100
+++ b/stage4/generate_c/generate_c_vardecl.cc	Tue Jun 12 22:32:09 2012 +0200
@@ -211,7 +211,7 @@
     /*  signed_integer DOTDOT signed_integer */
     //SYM_REF2(subrange_c, lower_limit, upper_limit)
     void *visit(subrange_c *symbol) {
-      int dimension = extract_integer_value(symbol->upper_limit) - extract_integer_value(symbol->lower_limit) + 1;
+      int dimension = extract_int64_value(symbol->upper_limit) - extract_int64_value(symbol->lower_limit) + 1;
       switch (current_mode) {
         case arraysize_am:
           array_size *= dimension;
@@ -264,7 +264,7 @@
       
       switch (current_mode) {
         case initializationvalue_am:
-          initial_element_number = extract_integer_value(symbol->integer);
+          initial_element_number = extract_int64_value(symbol->integer);
           if (current_initialization_count < defined_values_count) {
             int temp_element_number = 0;
             int diff = defined_values_count - current_initialization_count;
@@ -1407,7 +1407,7 @@
 /*  signed_integer DOTDOT signed_integer */
 //SYM_REF2(subrange_c, lower_limit, upper_limit)
 void *visit(subrange_c *symbol) {
-  long long dimension = extract_integer_value(symbol->upper_limit) - extract_integer_value(symbol->lower_limit) + 1;
+  long long dimension = extract_int64_value(symbol->upper_limit) - extract_int64_value(symbol->lower_limit) + 1;
   s4o.print("_");
   print_integer(dimension);
   return NULL;