Small code re-organization of how const values are stored in symbol_c (can now be accessed through member functions, instead of macros)
--- 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())