Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
authorMario de Sousa <msousa@fe.up.pt>
Fri, 15 Jun 2012 19:54:33 +0100
changeset 596 4efb11e44065
parent 595 c41975a290ce
child 597 7326a0658104
Add ERROR_MSG macro && move extract_XXX() functions to constant_folding.cc
absyntax/absyntax.cc
absyntax_utils/absyntax_utils.cc
absyntax_utils/absyntax_utils.hh
absyntax_utils/add_en_eno_param_decl.cc
absyntax_utils/array_dimension_iterator.cc
absyntax_utils/case_element_iterator.cc
absyntax_utils/function_call_iterator.cc
absyntax_utils/function_call_param_iterator.cc
absyntax_utils/function_param_iterator.cc
absyntax_utils/get_sizeof_datatype.cc
absyntax_utils/search_base_type.cc
absyntax_utils/search_constant_type.cc
absyntax_utils/spec_init_separator.cc
main.cc
stage1_2/iec_bison.yy
stage3/constant_folding.cc
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_vardecl.cc
stage4/generate_iec/generate_iec.cc
stage4/stage4.cc
util/dsymtable.cc
util/symtable.cc
--- a/absyntax/absyntax.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax/absyntax.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -40,12 +40,7 @@
 #include "absyntax.hh"
 //#include "../stage1_2/iec.hh" /* required for BOGUS_TOKEN_ID, etc... */
 #include "visitor.hh"
-
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
-
-#define ABORT(str) {printf("ERROR: %s\n", str); ERROR;}
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 
@@ -106,7 +101,7 @@
   n++;
   elements = (symbol_c **)realloc(elements, n * sizeof(symbol_c *));
   if (elements == NULL)
-    ABORT("Out of memory");
+    ERROR_MSG("Out of memory");
   elements[n - 1] = elem;
  
   if (elem == NULL)
--- a/absyntax_utils/absyntax_utils.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/absyntax_utils.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -50,13 +50,14 @@
 #include <typeinfo>
 #include <list>
 #include <strings.h>
-#include <string.h>  /* required for strlen() */
-#include <stdlib.h>  /* required for atoi() */
-#include <errno.h>   /* required for errno */
+// #include <string.h>  /* required for strlen() */
+// #include <stdlib.h>  /* required for atoi() */
+// #include <errno.h>   /* required for errno */
 
 #include "../util/symtable.hh"
 #include "../util/dsymtable.hh"
 #include "../absyntax/visitor.hh"
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 
@@ -67,9 +68,6 @@
 #define TRACE(classname)
 #endif
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
 
 
 /***********************************************************************/
@@ -98,135 +96,6 @@
 
 
 
-  /* To allow the compiler to be portable, we cannot assume that int64_t is mapped onto long long int,
-   * so we cannot call strtoll() and strtoull() in extract_int64() and extract_uint64().
-   *
-   * So, we create our own strtouint64() and strtoint64() functions.
-   * (We actually call them matiec_strtoint64() so they will not clash with any function
-   *  that may be added to the standard library in the future).
-   * We actually create several of each, and let the compiler choose which is the correct one,
-   * by having it resolve the call to the overloaded function. For the C++ compiler to be able
-   * to resolve this ambiguity, we need to add a dummy parameter to each function!
-   *
-   * TODO: support platforms in which int64_t is mapped onto int !! Is this really needed?
-   */
-static  int64_t matiec_strtoint64 (         long      int *dummy, const char *nptr, char **endptr, int base) {return strtol  (nptr, endptr, base);}
-static  int64_t matiec_strtoint64 (         long long int *dummy, const char *nptr, char **endptr, int base) {return strtoll (nptr, endptr, base);}
-  
-static uint64_t matiec_strtouint64(unsigned long      int *dummy, const char *nptr, char **endptr, int base) {return strtoul (nptr, endptr, base);}
-static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);}
-
-
-/* extract the value of an integer from an integer_c object !! */
-/* NOTE: it must ignore underscores! */
-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 ((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; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
-  ret = matiec_strtoint64((int64_t *)NULL, 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; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
-  ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, 10);
-  if (overflow != NULL)
-    *overflow = (errno == ERANGE);
-  if ((errno != 0) && (errno != ERANGE))
-    ERROR;
-
-  return ret;
-}
-
-
-/* extract the value of an hex integer from an hex_integer_c object !! */
-/* NOTE: it must ignore underscores! */
-uint64_t extract_hex_value(symbol_c *sym) {
-  std::string str = "";
-  char *endptr;
-  hex_integer_c * hex_integer;
-  uint64_t ret;
-
-  if ((hex_integer = dynamic_cast<hex_integer_c *>(sym)) == NULL) ERROR;
-  for(unsigned int i = 3; i < strlen(hex_integer->value); i++)
-    if (hex_integer->value[i] != '_') str += hex_integer->value[i];
-    
-  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
-  ret = strtoull(str.c_str(), &endptr, 16);
-  if (errno != 0) ERROR;
-
-  return ret;
-}
-
-
-/* extract the value of a real from an real_c object !! */
-/* NOTE: it must ignore underscores! */
-/* From iec_bison.yy
- *  real:
- *   real_token		{$$ = new real_c($1, locloc(@$));}
- * | fixed_point_token	{$$ = new real_c($1, locloc(@$));}
- *
- * From iec_flex.ll
- * {real}			{yylval.ID=strdup(yytext); return real_token;}
- * {fixed_point}		{yylval.ID=strdup(yytext); return fixed_point_token;}
- *
- * real		{integer}\.{integer}{exponent}
- * fixed_point		{integer}\.{integer}
- * exponent        [Ee]([+-]?){integer}
- * integer         {digit}((_?{digit})*)
- */
-real64_t extract_real_value(symbol_c *sym, bool *overflow) {
-  std::string str = "";
-  real_c * real_sym;
-  real64_t ret;
-
-  if ((real_sym = dynamic_cast<real_c *>(sym)) == NULL) ERROR;
-  for(unsigned int i = 0; i < strlen(real_sym->value); i++)
-    if (real_sym->value[i] != '_') str += real_sym->value[i];
-    
-  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
-  #if    (real64_t  == float)
-    ret = strtof(str.c_str(), NULL);
-  #elif  (real64_t  == double)
-    ret = strtod(str.c_str(), NULL);
-  #elif  (real64_t  == long_double)
-    ret = strtold(str.c_str(), NULL);
-  #else 
-    #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting!
-  #endif
-  if (overflow != NULL)
-    *overflow = (errno == ERANGE);
-  if ((errno != 0) && (errno != ERANGE)) 
-    ERROR;
-
-  return ret;
-}
-
-
-
 /***********************************************************************/
 /***********************************************************************/
 /***********************************************************************/
--- a/absyntax_utils/absyntax_utils.hh	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/absyntax_utils.hh	Fri Jun 15 19:54:33 2012 +0100
@@ -55,12 +55,6 @@
 /* returns 0 if the names are equal!! Case is ignored. */
 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 !! */
-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 = NULL);
-  
 /* A symbol table with all globally declared functions... */
 extern function_declaration_c null_symbol1;
 typedef dsymtable_c<function_declaration_c *, &null_symbol1> function_symtable_t;
--- a/absyntax_utils/add_en_eno_param_decl.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/add_en_eno_param_decl.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -44,6 +44,7 @@
 
 #include "add_en_eno_param_decl.hh"
 #include <strings.h>
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 // #define DEBUG
@@ -54,9 +55,6 @@
 #endif
 
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
 
 
 
--- a/absyntax_utils/array_dimension_iterator.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/array_dimension_iterator.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -49,6 +49,7 @@
 
 
 #include "array_dimension_iterator.hh"
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 //#define DEBUG
@@ -59,9 +60,6 @@
 #endif
 
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
 
 void* array_dimension_iterator_c::iterate_list(list_c *list) {
   void *res;
--- a/absyntax_utils/case_element_iterator.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/case_element_iterator.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -49,6 +49,7 @@
 
 
 #include "case_element_iterator.hh"
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 //#define DEBUG
@@ -59,9 +60,6 @@
 #endif
 
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
 
 
 void* case_element_iterator_c::handle_case_element(symbol_c *case_element) {
--- a/absyntax_utils/function_call_iterator.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/function_call_iterator.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -45,6 +45,7 @@
 
 
 #include "function_call_iterator.hh"
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 //#define DEBUG
@@ -54,10 +55,6 @@
 #define TRACE(classname)
 #endif
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
-
 
 
 
--- a/absyntax_utils/function_call_param_iterator.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/function_call_param_iterator.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -48,6 +48,7 @@
 
 #include "function_call_param_iterator.hh"
 #include <strings.h>
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 //#define DEBUG
@@ -57,9 +58,6 @@
 #define TRACE(classname)
 #endif
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
 
 
 
--- a/absyntax_utils/function_param_iterator.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/function_param_iterator.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -54,6 +54,7 @@
 #include <strings.h>
 #include <limits> // required for std::numeric_limits< XXX >::max()
 #include <errno.h> // required for errno
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 //#define DEBUG
 #ifdef DEBUG
@@ -63,11 +64,6 @@
 #endif
 
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
-
-
 
 
 
--- a/absyntax_utils/get_sizeof_datatype.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/get_sizeof_datatype.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -82,10 +82,8 @@
 #include <stdint.h>  // get definition of uint64_t and UINT64_MAX
 #include <errno.h>
 
-
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
+
 
 
 /* This class is a singleton.
--- a/absyntax_utils/search_base_type.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/search_base_type.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -46,10 +46,7 @@
  * we may have FB instances declared of a specific FB type.
  */
 #include "absyntax_utils.hh"
-
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 
--- a/absyntax_utils/search_constant_type.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/search_constant_type.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -44,11 +44,9 @@
 #include "../util/symtable.hh"
 #include "search_constant_type.hh"
 #include "absyntax_utils.hh"
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
 
 symbol_c *search_constant_type_c::get_type(symbol_c *constant) {
   return (symbol_c *)constant->accept(*this);
--- a/absyntax_utils/spec_init_separator.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/absyntax_utils/spec_init_separator.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -37,6 +37,8 @@
  */
 
 #include "spec_init_separator.hh"
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
+
 
 //#define DEBUG
 #ifdef DEBUG
@@ -45,9 +47,6 @@
 #define TRACE(classname)
 #endif
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
 
 
 spec_init_sperator_c *spec_init_sperator_c::get_class_instance(void) {
--- a/main.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/main.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -80,11 +80,23 @@
 #define HGVERSION ""
 #endif
 
-#define ERROR          error_exit(__FILE__,__LINE__)
-void error_exit(const char *file_name, int line_no) {
-  std::cerr << "\nInternal compiler error in file " << file_name
-            << " at line " << line_no << "\n";
-//   if (msg != NULL) std::cerr << message << "\n\n";
+#include "main.hh"  // symbol_c type
+#include <stdarg.h> // required for va_start(), va_list
+
+void error_exit(const char *file_name, int line_no, const char *errmsg, ...) {
+  va_list argptr;
+  va_start(argptr, errmsg); /* second argument is last fixed pamater of error_exit() */
+
+  fprintf(stderr, "\nInternal compiler error in file %s at line %d", file_name, line_no);
+  if (errmsg != NULL) {
+    fprintf(stderr, ": ");
+    vfprintf(stderr, errmsg, argptr);
+  } else {
+    fprintf(stderr, ".");
+  }
+  fprintf(stderr, "\n");
+  va_end(argptr);
+    
   exit(EXIT_FAILURE);
 }
 
--- a/stage1_2/iec_bison.yy	Thu Jun 14 17:50:37 2012 +0100
+++ b/stage1_2/iec_bison.yy	Fri Jun 15 19:54:33 2012 +0100
@@ -161,10 +161,7 @@
          while (0)
 
 
-/* A macro for printing out internal parser errors... */
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 
--- a/stage3/constant_folding.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/stage3/constant_folding.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -121,6 +121,13 @@
 #include <math.h> /* required for pow function, and HUGE_VAL, HUGE_VALF, HUGE_VALL */
 #include <stdlib.h> /* required for malloc() */
 
+
+#include <string.h>  /* required for strlen() */
+// #include <stdlib.h>  /* required for atoi() */
+#include <errno.h>   /* required for errno */
+
+
+
 #define __STDC_LIMIT_MACROS /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
 #include <stdint.h>         /* required for UINT64_MAX, INT64_MAX, INT64_MIN, ... */
 
@@ -217,6 +224,156 @@
 
 
 
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***            convert string to numerical value                    ***/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+
+
+
+  /* To allow the compiler to be portable, we cannot assume that int64_t is mapped onto long long int,
+   * so we cannot call strtoll() and strtoull() in extract_int64() and extract_uint64().
+   *
+   * So, we create our own strtouint64() and strtoint64() functions.
+   * (We actually call them matiec_strtoint64() so they will not clash with any function
+   *  that may be added to the standard library in the future).
+   * We actually create several of each, and let the compiler choose which is the correct one,
+   * by having it resolve the call to the overloaded function. For the C++ compiler to be able
+   * to resolve this ambiguity, we need to add a dummy parameter to each function!
+   *
+   * TODO: support platforms in which int64_t is mapped onto int !! Is this really needed?
+   */
+static  int64_t matiec_strtoint64 (         long      int *dummy, const char *nptr, char **endptr, int base) {return strtol  (nptr, endptr, base);}
+static  int64_t matiec_strtoint64 (         long long int *dummy, const char *nptr, char **endptr, int base) {return strtoll (nptr, endptr, base);}
+  
+static uint64_t matiec_strtouint64(unsigned long      int *dummy, const char *nptr, char **endptr, int base) {return strtoul (nptr, endptr, base);}
+static uint64_t matiec_strtouint64(unsigned long long int *dummy, const char *nptr, char **endptr, int base) {return strtoull(nptr, endptr, base);}
+
+
+/* extract the value of an integer from an integer_c object !! */
+/* NOTE: it must ignore underscores! */
+int64_t extract_int64_value(symbol_c *sym, bool *overflow) {
+  std::string str = "";
+  integer_c *integer;
+  char *endptr;
+  int64_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; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
+  ret = matiec_strtoint64((int64_t *)NULL, 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; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
+  ret = matiec_strtouint64((uint64_t *)NULL, str.c_str(), &endptr, 10);
+  if (overflow != NULL)
+    *overflow = (errno == ERANGE);
+  if ((errno != 0) && (errno != ERANGE))
+    ERROR;
+
+  return ret;
+}
+
+
+
+/* extract the value of an hex integer from an hex_integer_c object !! */
+/* NOTE: it must ignore underscores! */
+uint64_t extract_hex_value(symbol_c *sym) {
+  std::string str = "";
+  char *endptr;
+  hex_integer_c * hex_integer;
+  uint64_t ret;
+
+  if ((hex_integer = dynamic_cast<hex_integer_c *>(sym)) == NULL) ERROR;
+  for(unsigned int i = 3; i < strlen(hex_integer->value); i++)
+    if (hex_integer->value[i] != '_') str += hex_integer->value[i];
+    
+  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
+  ret = strtoull(str.c_str(), &endptr, 16);
+  if (errno != 0) ERROR;
+
+  return ret;
+}
+
+
+/* extract the value of a real from an real_c object !! */
+/* NOTE: it must ignore underscores! */
+/* From iec_bison.yy
+ *  real:
+ *   real_token		{$$ = new real_c($1, locloc(@$));}
+ * | fixed_point_token	{$$ = new real_c($1, locloc(@$));}
+ *
+ * From iec_flex.ll
+ * {real}			{yylval.ID=strdup(yytext); return real_token;}
+ * {fixed_point}		{yylval.ID=strdup(yytext); return fixed_point_token;}
+ *
+ * real		{integer}\.{integer}{exponent}
+ * fixed_point		{integer}\.{integer}
+ * exponent        [Ee]([+-]?){integer}
+ * integer         {digit}((_?{digit})*)
+ */
+real64_t extract_real_value(symbol_c *sym, bool *overflow) {
+  std::string str = "";
+  real_c * real_sym;
+  real64_t ret;
+
+  if ((real_sym = dynamic_cast<real_c *>(sym)) == NULL) ERROR;
+  for(unsigned int i = 0; i < strlen(real_sym->value); i++)
+    if (real_sym->value[i] != '_') str += real_sym->value[i];
+    
+  errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
+  #if    (real64_t  == float)
+    ret = strtof(str.c_str(), NULL);
+  #elif  (real64_t  == double)
+    ret = strtod(str.c_str(), NULL);
+  #elif  (real64_t  == long_double)
+    ret = strtold(str.c_str(), NULL);
+  #else 
+    #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting!
+  #endif
+  if (overflow != NULL)
+    *overflow = (errno == ERANGE);
+  if ((errno != 0) && (errno != ERANGE)) 
+    ERROR;
+
+  return ret;
+}
+
+
+
+
+
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***        Functions to check for overflow situation                ***/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+
+
 /* NOTE:
  *   Most of the conditions to detect overflows on signed and unsigned integer operations were adapted from
  *   https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow?showComments=false
@@ -383,7 +540,13 @@
 
 
 
-
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
+/***        The constant_folding_c                                   ***/
+/***********************************************************************/
+/***********************************************************************/
+/***********************************************************************/
 
 
 
--- a/stage4/generate_c/generate_c.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/stage4/generate_c/generate_c.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -36,6 +36,7 @@
 #include "../../util/dsymtable.hh"
 #include "../../absyntax/visitor.hh"
 #include "../../absyntax_utils/absyntax_utils.hh"
+#include "../../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 #include "../stage4.hh"
 
@@ -46,9 +47,6 @@
 #define TRACE(classname)
 #endif
 
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
 
 
 #define STAGE4_ERROR(symbol1, symbol2, ...) {stage4err("while generating C code", symbol1, symbol2, __VA_ARGS__); exit(EXIT_FAILURE);}
--- a/stage4/generate_c/generate_c_vardecl.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/stage4/generate_c/generate_c_vardecl.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -265,28 +265,37 @@
     /* integer '(' [array_initial_element] ')' */
     /* array_initial_element may be NULL ! */
     void *visit(array_initial_elements_c *symbol) {
-      unsigned long long int initial_element_number;
+      unsigned long long int initial_element_count;
+ 
+      /* This code assumes that unsigned long long int is >= uint64_t */
+      if (std::numeric_limits< uint64_t >::max() > std::numeric_limits< unsigned long long int >::max()) 
+	ERROR_MSG("Assertion (sizeof(uint64_t) > sizeof(unsigned long long int)) failed! Compiler cannot execute correctly on the current platform!");
       
       switch (current_mode) {
         case initializationvalue_am:
-          initial_element_number = extract_int64_value(symbol->integer);
+          if      (VALID_CVALUE( int64, symbol->integer) && (GET_CVALUE( int64, symbol->integer) >= 0))
+            initial_element_count = GET_CVALUE( int64, symbol->integer);
+          else if (VALID_CVALUE(uint64, symbol->integer))
+            initial_element_count = GET_CVALUE(uint64, symbol->integer);
+          else ERROR;
+     
           if (current_initialization_count < defined_values_count) {
             unsigned long long int temp_element_number = 0;
             unsigned long long int diff = defined_values_count - current_initialization_count;
-            if (diff <= initial_element_number)
-              temp_element_number = initial_element_number - diff;
-            current_initialization_count += initial_element_number - 1;
-            initial_element_number = temp_element_number;
-            if (initial_element_number > 0) {
+            if (diff <= initial_element_count)
+              temp_element_number = initial_element_count - diff;
+            current_initialization_count += initial_element_count - 1;
+            initial_element_count = temp_element_number;
+            if (initial_element_count > 0) {
               defined_values_count++;
               s4o.print(",");
             }
           }
           else
-            current_initialization_count += initial_element_number - 1;
-          if (defined_values_count + initial_element_number > array_size)
+            current_initialization_count += initial_element_count - 1;
+          if (defined_values_count + initial_element_count > array_size)
             ERROR;
-          for (unsigned long long int i = 0; i < initial_element_number; i++) {
+          for (unsigned long long int i = 0; i < initial_element_count; i++) {
             if (i > 0)
               s4o.print(",");
             if (symbol->array_initial_element != NULL) {
@@ -296,8 +305,8 @@
               array_default_value->accept(*this);
             }
           }
-          if (initial_element_number > 1)
-            defined_values_count += initial_element_number - 1;
+          if (initial_element_count > 1)
+            defined_values_count += initial_element_count - 1;
           break;
         default:
           break;
--- a/stage4/generate_iec/generate_iec.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/stage4/generate_iec/generate_iec.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -57,12 +57,10 @@
 #include "generate_iec.hh"
 
 #include "../stage4.hh"
-
-
-
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
+#include "../../main.hh" // required for ERROR() and ERROR_MSG() macros.
+
+
+
 
 
 
--- a/stage4/stage4.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/stage4/stage4.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -46,11 +46,9 @@
 #include <stdlib.h>
 
 #include "stage4.hh"
-
-
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
+
+
 
 
 #define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
@@ -61,10 +59,12 @@
     va_list argptr;
     va_start(argptr, errmsg); /* second argument is last fixed pamater of stage4err() */
 
-    fprintf(stderr, "%s:%d-%d..%d-%d: error %s: ",
-            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,
-                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column,
-            stage4_generator_id);
+    if ((symbol1 != NULL) && (symbol2 != NULL))
+      fprintf(stderr, "%s:%d-%d..%d-%d: ",
+              FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,
+                                                   LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);
+
+    fprintf(stderr, "error %s: ", stage4_generator_id);
     vfprintf(stderr, errmsg, argptr);
     fprintf(stderr, "\n");
     // error_count++;
--- a/util/dsymtable.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/util/dsymtable.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -33,14 +33,10 @@
 
 #include <iostream>
 #include "symtable.hh"
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 
-/* A macro for printing out internal parser errors... */
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
-
 
 
 
--- a/util/symtable.cc	Thu Jun 14 17:50:37 2012 +0100
+++ b/util/symtable.cc	Fri Jun 15 19:54:33 2012 +0100
@@ -34,14 +34,10 @@
 
 #include <iostream>
 #include "symtable.hh"
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
 
 
 
-/* A macro for printing out internal parser errors... */
-#define ERROR error_exit(__FILE__,__LINE__)
-/* function defined in main.cc */
-extern void error_exit(const char *file_name, int line_no);
-