Do constant propagation of configuration/resource variables, taking into account scope of variables.
authormjsousa
Fri, 26 Dec 2014 12:43:13 +0000
changeset 973 f86d5d6bb04e
parent 972 bc90dd4bbf4f
child 974 a47c2df5ae3d
Do constant propagation of configuration/resource variables, taking into account scope of variables.
stage3/constant_folding.cc
stage3/constant_folding.hh
util/symtable.cc
util/symtable.hh
--- a/stage3/constant_folding.cc	Fri Dec 26 10:09:27 2014 +0000
+++ b/stage3/constant_folding.cc	Fri Dec 26 12:43:13 2014 +0000
@@ -1390,10 +1390,12 @@
 // SYM_REF4(resource_declaration_c, resource_name, resource_type_name, global_var_declarations, resource_declaration, 
 //          enumvalue_symtable_t enumvalue_symtable; localvar_symbmap_t localvar_symbmap; localvar_symbvec_t localvar_symbvec;)
 void *constant_folding_c::visit(resource_declaration_c *symbol) {
-	values.clear(); /* Clear global map */
+	values.push(); /* Create inner scope */
 	/* Add initial value of all declared variables into Values map. */
 	function_pou_ = false;
-	return iterator_visitor_c::visit(symbol); // let the base iterator class handle the rest (basically iterate through the whole configuration and do the constant folding!
+	iterator_visitor_c::visit(symbol); // let the base iterator class handle the rest (basically iterate through the whole configuration and do the constant folding!
+	values.pop(); /* Delete inner scope */
+	return NULL;
 }
 
 
--- a/stage3/constant_folding.hh	Fri Dec 26 10:09:27 2014 +0000
+++ b/stage3/constant_folding.hh	Fri Dec 26 12:43:13 2014 +0000
@@ -41,6 +41,7 @@
 
 #include <vector>
 #include "../absyntax_utils/absyntax_utils.hh"
+#include "../util/symtable.hh"
 
 
 
@@ -68,7 +69,7 @@
     virtual ~constant_folding_c(void);
     int get_error_count();
     int handle_var_extern_global_pair(symbol_c *extern_var_name, symbol_c *extern_var_decl, symbol_c *global_var_name, symbol_c *global_var_decl);
-    typedef std::map <std::string, const_value_c> map_values_t;
+    typedef symtable_c<const_value_c> map_values_t;
   private:
     map_values_t values;
     void *handle_var_list_decl(symbol_c *var_list, symbol_c *type_decl);
--- a/util/symtable.cc	Fri Dec 26 10:09:27 2014 +0000
+++ b/util/symtable.cc	Fri Dec 26 12:43:13 2014 +0000
@@ -47,7 +47,7 @@
 
  /* clear all entries... */
 template<typename value_type>
-void symtable_c<value_type>::reset(void) {
+void symtable_c<value_type>::clear(void) {
   _base.clear();
 }
 
@@ -142,25 +142,47 @@
 
 
 template<typename value_type>
-typename symtable_c<value_type>::iterator symtable_c<value_type>::end(void) {return _base.end();}
+int symtable_c<value_type>::count(const       char *identifier_str) {return _base.count(identifier_str)+((inner_scope == NULL)?0:inner_scope->count(identifier_str));}
+template<typename value_type>
+int symtable_c<value_type>::count(const std::string identifier_str) {return _base.count(identifier_str)+((inner_scope == NULL)?0:inner_scope->count(identifier_str));}
+
+
+// in the operator[] we delegate to find(), since that method will also search in the inner scopes!
+template<typename value_type>
+typename symtable_c<value_type>::value_t symtable_c<value_type>::operator[] (const       char *identifier_str) {return find(identifier_str)->second;}
+template<typename value_type>
+typename symtable_c<value_type>::value_t symtable_c<value_type>::operator[] (const std::string identifier_str) {return find(identifier_str)->second;}
+
+
+template<typename value_type>
+typename symtable_c<value_type>::iterator symtable_c<value_type>::end  (void) {return _base.end  ();}
+
+template<typename value_type>
+typename symtable_c<value_type>::iterator symtable_c<value_type>::begin(void) {return _base.begin();}
 
 /* returns end() if not found! */
 template<typename value_type>
-typename symtable_c<value_type>::iterator symtable_c<value_type>::find(const char *identifier_str) {
-  if (inner_scope != NULL) {
-    iterator i = inner_scope->find(identifier_str);
-    if (i != inner_scope->end())  // NOTE: must use the end() value of the inner scope!
-      /* found in the lower level */
-      return i;
-  }
-
+typename symtable_c<value_type>::iterator symtable_c<value_type>::find(const       char *identifier_str) {
+  iterator i;
+  if ((inner_scope != NULL) && ((i = inner_scope->find(identifier_str)) != inner_scope->end()))  // NOTE: must use the end() value of the inner scope!
+      return i;  // found in the lower level
   /* if no lower level, or not found in lower level... */
   return _base.find(identifier_str);
 }
 
 
 template<typename value_type>
-typename symtable_c<value_type>::iterator symtable_c<value_type>::find(const symbol_c *symbol) {
+typename symtable_c<value_type>::iterator symtable_c<value_type>::find(const std::string identifier_str) {
+  iterator i;
+  if ((inner_scope != NULL) && ((i = inner_scope->find(identifier_str)) != inner_scope->end()))  // NOTE: must use the end() value of the inner scope!
+      return i;  // found in the lower level
+  /* if no lower level, or not found in lower level... */
+  return _base.find(identifier_str);
+}
+
+
+template<typename value_type>
+typename symtable_c<value_type>::iterator symtable_c<value_type>::find(const   symbol_c *symbol) {
   const token_c *name = dynamic_cast<const token_c *>(symbol);
   if (name == NULL)
     ERROR;
--- a/util/symtable.hh	Fri Dec 26 10:09:27 2014 +0000
+++ b/util/symtable.hh	Fri Dec 26 12:43:13 2014 +0000
@@ -81,7 +81,7 @@
   public:
     symtable_c(void);
 
-    void reset(void); /* clear all entries... */
+    void clear(void); /* clear all entries... */
 
     void push(void); /* create new inner scope */
     int  pop(void);  /* clear most inner scope */
@@ -91,10 +91,24 @@
     void insert(const char *identifier_str, value_t value); // insert a new (string,value) pair. Give an error if string already in map associated to different value!
     void insert(const symbol_c *symbol, value_t value);     // insert a new (string,value) pair. Give an error if string already in map associated to different value!
 
+    value_t operator[](const       char *identifier_str);
+    value_t operator[](const std::string identifier_str);
+ // value_t operator[](const   symbol_c *identifier    ); // not yet implemented
+   
+    /* Since symtable_c does not allow duplicates in each level, count() will return
+     *  - 0 : if not found in any level
+     *  - n : number of level containing that entry (max is current number of levels!)
+     */
+    int count(const       char *identifier_str);
+    int count(const std::string identifier_str);
+ // int count(const   symbol_c *identifier    ); // not yet implemented
+    
     /* Search for an entry. Will return end() if not found */
+    iterator               begin(void);
     iterator               end  (void);
-    iterator               find (const char     *identifier_str);
-    iterator               find (const symbol_c *symbol        );
+    iterator               find (const char       *identifier_str);
+    iterator               find (const std::string identifier_str);
+    iterator               find (const symbol_c   *symbol        );
 
 
   /* iterators ... */