Small code re-organization of how const values are stored in symbol_c (can now be accessed through member functions, instead of macros)
authormjsousa
Wed, 17 Dec 2014 13:46:36 +0000
changeset 965 c9eeb67ba939
parent 964 5f4dfe6670da
child 966 cd7fa00ad774
Small code re-organization of how const values are stored in symbol_c (can now be accessed through member functions, instead of macros)
absyntax/absyntax.cc
absyntax/absyntax.hh
absyntax_utils/debug_ast.cc
stage3/array_range_check.cc
stage3/constant_folding.cc
stage3/fill_candidate_datatypes.cc
stage4/generate_c/generate_c.cc
--- a/absyntax/absyntax.cc	Sun Dec 14 19:15:29 2014 +0000
+++ b/absyntax/absyntax.cc	Wed Dec 17 13:46:36 2014 +0000
@@ -44,6 +44,7 @@
 
 
 
+
 /* The base class of all symbols */
 symbol_c::symbol_c(
                    int first_line, int first_column, const char *ffile, long int first_order,
@@ -59,10 +60,6 @@
   this->parent       = NULL;
   this->datatype     = NULL;
   this->scope        = NULL;
-  this->const_value._real64.status   = cs_undefined;
-  this->const_value._int64.status    = cs_undefined;
-  this->const_value._uint64.status   = cs_undefined;
-  this->const_value._bool.status     = cs_undefined;
 }
 
 
--- a/absyntax/absyntax.hh	Sun Dec 14 19:15:29 2014 +0000
+++ b/absyntax/absyntax.hh	Wed Dec 17 13:46:36 2014 +0000
@@ -93,9 +93,50 @@
 
 
 
-
-
-
+/*** constant folding ***/
+/* During stage 3 (semantic analysis/checking) we will be doing constant folding.
+ * That algorithm will anotate the abstract syntax tree with the result of operations
+ * on literals (i.e. 44 + 55 will store the result 99).
+ * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT,
+ * or an ANY_BIT, we need to handle all possibilities, and determine the result of the
+ * operation assuming each type.
+ * For this reason, we have one entry for each possible type, with some expressions
+ * having more than one entry filled in!
+ */    
+class const_value_c {
+  public:
+    typedef enum { cs_undefined,   /* not defined/not yet evaluated --> const_value is not valid! */
+                   cs_non_const,   /* we have determined that expression is not a const value --> const_value is not valid! */
+                   cs_const_value, /* const value is valid */
+                   cs_overflow     /* result produced overflow or underflow --> const_value is not valid! */
+                 } const_status_t;
+ 
+    template<typename value_type> class const_value__ {
+      const_status_t status;  
+      value_type     value;
+      
+      public:
+      const_value__(void): status(cs_undefined), value(0) {};
+      
+      value_type get(void)              {return value;}
+      void       set(value_type value_) {status = cs_const_value; value = value_;}
+      void       set_overflow(void)     {status = cs_overflow   ;}
+      void       set_nonconst(void)     {status = cs_non_const  ;}
+      bool       is_valid    (void)     {return (status == cs_const_value);}
+      bool       is_overflow (void)     {return (status == cs_overflow   );}
+      bool       is_nonconst (void)     {return (status == cs_non_const  );}
+      bool       is_zero     (void)     {return (is_valid() && (get() == 0));}
+    };
+
+    const_value__< int64_t>  _int64; /* status is initialised to UNDEFINED */
+    const_value__<uint64_t> _uint64; /* status is initialised to UNDEFINED */
+    const_value__<real64_t> _real64; /* status is initialised to UNDEFINED */
+    const_value__<bool    >   _bool; /* status is initialised to UNDEFINED */
+    
+    /* default constructor and destructor */
+     const_value_c(void) {};
+    ~const_value_c(void) {};
+};
 
 
 
@@ -142,33 +183,8 @@
     symbol_c *scope;    
 
     /*** constant folding ***/
-    /* During stage 3 (semantic analysis/checking) we will be doing constant folding.
-     * That algorithm will anotate the abstract syntax tree with the result of operations
-     * on literals (i.e. 44 + 55 will store the result 99).
-     * Since the same source code (e.g. 1 + 0) may actually be a BOOL or an ANY_INT,
-     * or an ANY_BIT, we need to handle all possibilities, and determine the result of the
-     * operation assuming each type.
-     * For this reason, we have one entry for each possible type, with some expressions
-     * having more than one entry filled in!
-     */
-    typedef enum { cs_undefined,   /* not defined/not yet evaluated --> const_value is not valid! */
-                   cs_non_const,   /* we have determined that expression is not a const value --> const_value is not valid! */
-                   cs_const_value, /* const value is valid */
-                   cs_overflow     /* result produced overflow or underflow --> const_value is not valid! */
-                 } const_status_t;
- 
-    typedef struct const_value_real64_s {const_status_t status;  real64_t  value;  const_value_real64_s (): status(cs_undefined), value(0.0)   {} } const_value_real64_t;
-    typedef struct const_value_int64_s  {const_status_t status;   int64_t  value;  const_value_int64_s  (): status(cs_undefined), value(0)     {} } const_value_int64_t;
-    typedef struct const_value_uint64_s {const_status_t status;  uint64_t  value;  const_value_uint64_s (): status(cs_undefined), value(0)     {} } const_value_uint64_t;
-    typedef struct const_value_bool_s   {const_status_t status;      bool  value;  const_value_bool_s   (): status(cs_undefined), value(false) {} } const_value_bool_t;
-
-    typedef struct {
-      const_value_real64_t _real64; /* status is initialised to UNDEFINED */
-      const_value_int64_t   _int64; /* status is initialised to UNDEFINED */
-      const_value_uint64_t _uint64; /* status is initialised to UNDEFINED */
-      const_value_bool_t     _bool; /* status is initialised to UNDEFINED */
-    } const_value_t;
-    const_value_t const_value;
+    /* If the symbol has a constant numerical value, this will be set to that value by constant_folding_c */
+    const_value_c const_value;
     
     /*** Enumeration datatype checking ***/    
     /* Not all symbols will contain the following anotations, which is why they are not declared here in symbol_c
--- a/absyntax_utils/debug_ast.cc	Sun Dec 14 19:15:29 2014 +0000
+++ b/absyntax_utils/debug_ast.cc	Wed Dec 17 13:46:36 2014 +0000
@@ -118,7 +118,7 @@
   fprintf(stderr, "}\t");         
   
   /* print the const values... */
-  fprintf(stderr, " constv{f=%f, i=%"PRId64", u=%"PRIu64", b=%d}\t", symbol->const_value._real64.value, symbol->const_value._int64.value, symbol->const_value._uint64.value, symbol->const_value._bool.value?1:0);
+  fprintf(stderr, " constv{f=%f, i=%"PRId64", u=%"PRIu64", b=%d}\t", symbol->const_value._real64.get(), symbol->const_value._int64.get(), symbol->const_value._uint64.get(), symbol->const_value._bool.get()?1:0);
   
 }
 
--- a/stage3/array_range_check.cc	Sun Dec 14 19:15:29 2014 +0000
+++ b/stage3/array_range_check.cc	Wed Dec 17 13:46:36 2014 +0000
@@ -68,8 +68,9 @@
     warning_found = true;                                                                                                   \
 }
 
-#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.value)
-#define VALID_CVALUE(dtype, symbol)           (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status)
+
+#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.get())
+#define VALID_CVALUE(dtype, symbol)           ((symbol)->const_value._##dtype.is_valid())
 
 /*  The cmp_unsigned_signed function compares two numbers u and s.
  *  It returns an integer indicating the relationship between the numbers:
--- a/stage3/constant_folding.cc	Sun Dec 14 19:15:29 2014 +0000
+++ b/stage3/constant_folding.cc	Wed Dec 17 13:46:36 2014 +0000
@@ -186,15 +186,16 @@
 
 
 
-#define SET_CVALUE(dtype, symbol, new_value) {((symbol)->const_value._##dtype.value) = new_value; ((symbol)->const_value._##dtype.status) = symbol_c::cs_const_value;}
-#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.value)
-#define SET_OVFLOW(dtype, symbol)             ((symbol)->const_value._##dtype.status) = symbol_c::cs_overflow
-#define SET_NONCONST(dtype, symbol)           ((symbol)->const_value._##dtype.status) = symbol_c::cs_non_const
-
-#define VALID_CVALUE(dtype, symbol)           (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status)
-#define IS_OVFLOW(dtype, symbol)              (symbol_c::cs_overflow    == (symbol)->const_value._##dtype.status)
-#define IS_NONCONST(dtype, symbol)            (symbol_c::cs_non_const   == (symbol)->const_value._##dtype.status)
-#define ISZERO_CVALUE(dtype, symbol)          ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0))
+#define SET_CVALUE(dtype, symbol, new_value)  ((symbol)->const_value._##dtype.set(new_value))
+#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.get())
+#define SET_OVFLOW(dtype, symbol)             ((symbol)->const_value._##dtype.set_overflow())
+#define SET_NONCONST(dtype, symbol)           ((symbol)->const_value._##dtype.set_nonconst())
+
+#define VALID_CVALUE(dtype, symbol)           ((symbol)->const_value._##dtype.is_valid())
+#define IS_OVFLOW(dtype, symbol)              ((symbol)->const_value._##dtype.is_overflow())
+#define IS_NONCONST(dtype, symbol)            ((symbol)->const_value._##dtype.is_nonconst())
+#define ISZERO_CVALUE(dtype, symbol)          ((symbol)->const_value._##dtype.is_zero())
+
 
 #define ISEQUAL_CVALUE(dtype, symbol1, symbol2) \
 	(VALID_CVALUE(dtype, symbol1) && VALID_CVALUE(dtype, symbol2) && (GET_CVALUE(dtype, symbol1) == GET_CVALUE(dtype, symbol2))) 
@@ -225,18 +226,16 @@
  * - constant * constant = non_const (if not equal)
  */
 #define COMPUTE_MEET_SEMILATTICE(dtype, c1, c2, resValue) {\
-		if (( c1._##dtype.value  != c2._##dtype.value && c2._##dtype.status == symbol_c::cs_const_value &&\
-              c1._##dtype.status == symbol_c::cs_const_value) ||\
-		    ( c1._##dtype.status == symbol_c::cs_non_const && c2._##dtype.status == symbol_c::cs_const_value ) ||\
-		    ( c2._##dtype.status == symbol_c::cs_non_const && c1._##dtype.status == symbol_c::cs_const_value  )) {\
-			resValue._##dtype.status = symbol_c::cs_non_const;\
+		if (( c1._##dtype.get()  != c2._##dtype.get() && c2._##dtype.is_valid() && c1._##dtype.is_valid()) ||\
+		    ( c1._##dtype.is_nonconst() && c2._##dtype.is_valid() ) ||\
+		    ( c2._##dtype.is_nonconst() && c1._##dtype.is_valid() )) {\
+			resValue._##dtype.set_nonconst();\
 		} else {\
-			resValue._##dtype.status = symbol_c::cs_const_value;\
-			resValue._##dtype.value  = c1._##dtype.value;\
+			resValue._##dtype.set(c1._##dtype.get());\
 		}\
 }
 
-typedef std::map <std::string, symbol_c::const_value_t> map_values_t;
+typedef std::map <std::string, const_value_c> map_values_t;
 
 static map_values_t values;
 
@@ -734,11 +733,11 @@
 	itr = m1.begin();
 	for ( ; itr != m1.end(); ++itr) {
 		std::string name = itr->first;
-		symbol_c::const_value_t value;
+		const_value_c value;
 
 		if (m2.count(name) > 0) {
-			symbol_c::const_value_t c1 = itr->second;
-			symbol_c::const_value_t c2 = m2[name];
+			const_value_c c1 = itr->second;
+			const_value_c c2 = m2[name];
 			COMPUTE_MEET_SEMILATTICE (real64, c1, c2, value);
 			COMPUTE_MEET_SEMILATTICE (uint64, c1, c2, value);
 			COMPUTE_MEET_SEMILATTICE ( int64, c1, c2, value);
@@ -1581,7 +1580,7 @@
 	symbol->beg_expression->accept(*this);
 	symbol->end_expression->accept(*this);
 	varName =  get_var_name_c::get_name(symbol->control_variable)->value;
-	values[varName]._int64.status = symbol_c::cs_non_const;
+	values[varName]._int64.status = const_value_c::cs_non_const;
 
 	/* Optimize dead code */
 	if (NULL != symbol->by_expression) {
--- a/stage3/fill_candidate_datatypes.cc	Sun Dec 14 19:15:29 2014 +0000
+++ b/stage3/fill_candidate_datatypes.cc	Wed Dec 17 13:46:36 2014 +0000
@@ -68,11 +68,10 @@
 #include <string.h>
 #include <strings.h>
 
-#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.value)
-#define VALID_CVALUE(dtype, symbol)           (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status)
-#define IS_OVERFLOW(dtype, symbol)            (symbol_c::cs_overflow == (symbol)->const_value._##dtype.status)
-
-
+
+#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.get())
+#define VALID_CVALUE(dtype, symbol)           ((symbol)->const_value._##dtype.is_valid())
+#define IS_OVERFLOW(dtype, symbol)            ((symbol)->const_value._##dtype.is_overflow())
 
 
 /* set to 1 to see debug info during execution */
--- a/stage4/generate_c/generate_c.cc	Sun Dec 14 19:15:29 2014 +0000
+++ b/stage4/generate_c/generate_c.cc	Wed Dec 17 13:46:36 2014 +0000
@@ -53,8 +53,8 @@
 
 
 /* Macros to access the constant value of each expression (if it exists) from the annotation introduced to the symbol_c object by constant_folding_c in stage3! */
-#define VALID_CVALUE(dtype, symbol)           (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status)
-#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.value) 
+#define VALID_CVALUE(dtype, symbol)           ((symbol)->const_value._##dtype.is_valid())
+#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.get())