Change symbtable_c -> use design pattern used by C++ standard library (STL)
authormjsousa
Fri, 26 Dec 2014 09:57:02 +0000
changeset 971 8aee27d46208
parent 970 0ede7ca157e2
child 972 bc90dd4bbf4f
Change symbtable_c -> use design pattern used by C++ standard library (STL)
absyntax_utils/absyntax_utils.cc
absyntax_utils/absyntax_utils.hh
absyntax_utils/search_base_type.cc
absyntax_utils/type_initial_value.cc
stage1_2/iec_bison.yy
stage1_2/stage1_2.cc
stage1_2/stage1_2_priv.hh
stage3/declaration_check.cc
stage3/lvalue_check.cc
stage3/remove_forward_dependencies.cc
stage3/remove_forward_dependencies.hh
stage4/generate_c/generate_c_il.cc
stage4/generate_c/generate_c_vardecl.cc
util/symtable.cc
util/symtable.hh
--- a/absyntax_utils/absyntax_utils.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/absyntax_utils/absyntax_utils.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -108,12 +108,10 @@
 dsymtable_c<function_declaration_c *, &null_symbol1> function_symtable;
 
 /* A symbol table with all globally declared functions block types... */
-function_block_declaration_c null_symbol2(NULL,NULL,NULL);
-symtable_c<function_block_declaration_c *, &null_symbol2> function_block_type_symtable;
+symtable_c<function_block_declaration_c *> function_block_type_symtable;
 
 /* A symbol table with all globally declared program types... */
-program_declaration_c null_symbol3(NULL,NULL,NULL);
-symtable_c<program_declaration_c *, &null_symbol3> program_type_symtable;
+symtable_c<program_declaration_c *> program_type_symtable;
 
 /* A symbol table with all user declared type definitions... */
 /* Note that function block types and program types have their
@@ -121,8 +119,7 @@
  *
  * The symbol_c * associated to the value will point to the data type declaration.
  */
-symbol_c null_symbol4;
-symtable_c<symbol_c *, &null_symbol4> type_symtable;
+symtable_c<symbol_c *> type_symtable;
 
 
 /***********************************************************************/
--- a/absyntax_utils/absyntax_utils.hh	Fri Dec 26 09:39:18 2014 +0000
+++ b/absyntax_utils/absyntax_utils.hh	Fri Dec 26 09:57:02 2014 +0000
@@ -61,12 +61,12 @@
 extern function_symtable_t function_symtable;
 
 /* A symbol table with all globally declared functions block types... */
-extern function_block_declaration_c null_symbol2;
-extern symtable_c<function_block_declaration_c *, &null_symbol2> function_block_type_symtable;
+typedef symtable_c<function_block_declaration_c *> function_block_type_symtable_t;
+extern  function_block_type_symtable_t function_block_type_symtable;
 
 /* A symbol table with all globally declared program types... */
-extern program_declaration_c null_symbol3;
-extern symtable_c<program_declaration_c *, &null_symbol3> program_type_symtable;
+typedef symtable_c<program_declaration_c *> program_type_symtable_t;
+extern  program_type_symtable_t program_type_symtable;
 
 /* A symbol table with all user declared type definitions... */
 /* Note that function block types and program types have their
@@ -74,8 +74,8 @@
  *
  * The symbol_c * associated to the value will point to the data type declaration.
  */
-extern symbol_c null_symbol4;
-extern symtable_c<symbol_c *, &null_symbol4> type_symtable;
+typedef symtable_c<symbol_c *> type_symtable_t;
+extern  type_symtable_t type_symtable;
 
 
 /***********************************************************************/
--- a/absyntax_utils/search_base_type.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/absyntax_utils/search_base_type.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -108,8 +108,6 @@
 
 
 void *search_base_type_c::handle_datatype_identifier(token_c *type_name) {
-  symbol_c *type_decl;
-
   this->current_basetype_name = type_name;
   /* if we have reached this point, it is because the current_basetype is not yet pointing to the base datatype we are looking for,
    * so we will be searching for the delcaration of the type named in type_name, which might be the base datatype (we search recursively!)
@@ -117,16 +115,16 @@
   this->current_basetype  = NULL; 
   
   /* look up the type declaration... */
-  type_decl = type_symtable.find_value(type_name);
-  if (type_decl != type_symtable.end_value())
-    return type_decl->accept(*this);
+  type_symtable_t::iterator iter1 = type_symtable.find(type_name);
+  if (iter1 != type_symtable.end())
+    return iter1->second->accept(*this); // iter1->second is the type_decl 
     
-  type_decl = function_block_type_symtable.find_value(type_name);
-  if (type_decl != function_block_type_symtable.end_value())
-    return type_decl->accept(*this);
+  function_block_type_symtable_t::iterator iter2  = function_block_type_symtable.find(type_name);
+  if (iter2 != function_block_type_symtable.end())
+    return iter2->second->accept(*this); // iter2->second is the type_decl 
   
   /* Type declaration not found!! */
-    ERROR;
+  ERROR;
     
   return NULL;
 }
--- a/absyntax_utils/type_initial_value.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/absyntax_utils/type_initial_value.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -117,15 +117,15 @@
 
 void *type_initial_value_c::handle_type_name(symbol_c *type_name) {
   /* look up the type declaration... */
-  symbol_c *type_decl = type_symtable.find_value(type_name);
+  type_symtable_t::iterator iter = type_symtable.find(type_name);
     /* Type declaration not found!! */
     /* NOTE: Variables declared out of function block 'data types',for eg:  VAR  timer: TON; END_VAR
      * do not have a default value, so (TON) will never be found in the type symbol table. This means 
      * we cannot simply consider this an error and abort, but must rather return a NULL.
      */
-  if (type_decl == type_symtable.end_value())   return NULL;
-
-  return type_decl->accept(*this);
+  if (iter == type_symtable.end())   return NULL;
+
+  return iter->second->accept(*this);  // iter->second is the type_decl
 }
 
 /* visitor for identifier_c should no longer be necessary. All references to derived datatypes are now stored in then          */
--- a/stage1_2/iec_bison.yy	Fri Dec 26 09:39:18 2014 +0000
+++ b/stage1_2/iec_bison.yy	Fri Dec 26 09:57:02 2014 +0000
@@ -8712,8 +8712,8 @@
 
   /* if by any chance the library is not complete, we now add the missing reserved keywords to the list!!!  */
   for(int i = 0; standard_function_block_names[i] != NULL; i++)
-    if (library_element_symtable.find_value(standard_function_block_names[i]) ==
-        library_element_symtable.end_value())
+    if (library_element_symtable.find(standard_function_block_names[i]) ==
+        library_element_symtable.end())
       library_element_symtable.insert(standard_function_block_names[i], standard_function_block_name_token);
 
   /* now parse the input file... */
--- a/stage1_2/stage1_2.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/stage1_2/stage1_2.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -135,15 +135,6 @@
 /* NOTE: only accessed indirectly by the lexical parser (flex)
  *       through the function get_identifier_token()
  */
-/* NOTE: BOGUS_TOKEN_ID is defined in the bison generated file iec_bison.hh.
- *       We need this constant defined before we can declare the symbol tables.
- *       However, we cannot #include "iec_bison.hh" in this file (stage1_2_priv.hh) directly
- *       because of the way bison ver. 3.2 is copying all declarations in the prologue
- *       of iec.y to the iec_bison.hh file (including an #include stage1_2_priv.hh).
- *       So, if we were to include "iec_bison.hh" here, we would get a circular include.
- *       All this means that whoever includes this file (stage1_2_priv.hh) will need
- *       to take care to first inlcude iec_bison.hh !!
- */ 
 /* A symbol table to store all the library elements */
 /* e.g.: <function_name , function_decl>
  *       <fb_name , fb_decl>
@@ -151,17 +142,17 @@
  *       <program_name , program_decl>
  *       <configuration_name , configuration_decl>
  */
-/* static */ symtable_c<int, BOGUS_TOKEN_ID> library_element_symtable;
+/* static */ library_element_symtable_t library_element_symtable;
 
 /* A symbol table to store the declared variables of
  * the function currently being parsed...
  */
-/* static */ symtable_c<int, BOGUS_TOKEN_ID> variable_name_symtable;
+/* static */ variable_name_symtable_t   variable_name_symtable;
 
 /* A symbol table to store the declared direct variables of
  * the function currently being parsed...
  */
-/* static */ symtable_c<int, BOGUS_TOKEN_ID> direct_variable_symtable;
+/* static */ direct_variable_symtable_t direct_variable_symtable;
 
 /* Function only called from within flex!
  *
@@ -173,12 +164,16 @@
  */
 int get_identifier_token(const char *identifier_str) {
 //  std::cout << "get_identifier_token(" << identifier_str << "): \n";
-  int token_id;
-
-  if ((token_id = variable_name_symtable.find_value(identifier_str)) == variable_name_symtable.end_value())
-    if ((token_id = library_element_symtable.find_value(identifier_str)) == library_element_symtable.end_value())
-      return identifier_token;
-  return token_id;
+  variable_name_symtable_t  ::iterator iter1;
+  library_element_symtable_t::iterator iter2;
+
+  if ((iter1 = variable_name_symtable.find(identifier_str)) != variable_name_symtable.end())
+    return iter1->second;
+    
+  if ((iter2 = library_element_symtable.find(identifier_str)) != library_element_symtable.end())
+    return iter2->second;
+  
+  return identifier_token;
 }
 
 /* Function only called from within flex!
@@ -188,11 +183,12 @@
  * symbol found.
  */
 int get_direct_variable_token(const char *direct_variable_str) {
-  int token_id;
-
-  if ((token_id = direct_variable_symtable.find_value(direct_variable_str)) == direct_variable_symtable.end_value())
-    return direct_variable_token;
-  return token_id;
+  direct_variable_symtable_t::iterator iter;
+
+  if ((iter = direct_variable_symtable.find(direct_variable_str)) != direct_variable_symtable.end())
+    return iter->second;
+
+  return direct_variable_token;
 }
 
 /************************/
--- a/stage1_2/stage1_2_priv.hh	Fri Dec 26 09:39:18 2014 +0000
+++ b/stage1_2/stage1_2_priv.hh	Fri Dec 26 09:57:02 2014 +0000
@@ -200,15 +200,6 @@
  *
  *       In essence, they are a data passing mechanism between Bison and Flex.
  */
-/* NOTE: BOGUS_TOKEN_ID is defined in the bison generated file iec_bison.hh.
- *       We need this constant defined before we can declare the symbol tables.
- *       However, we cannot #include "iec_bison.hh" in this file (stage1_2_priv.hh) directly
- *       because of the way bison ver. 2.3 is copying all declarations in the prologue
- *       of iec.y to the iec_bison.hh file (including an #include stage1_2_priv.hh).
- *       So, if we were to include "iec_bison.hh" here, we would get a circular include.
- *       All this means that whoever includes this file (stage1_2_priv.hh) will need
- *       to take care to first inlcude iec_bison.hh !!
- */ 
 /* A symbol table to store all the library elements */
 /* e.g.: <function_name , function_decl>
  *       <fb_name , fb_decl>
@@ -216,17 +207,20 @@
  *       <program_name , program_decl>
  *       <configuration_name , configuration_decl>
  */
-extern symtable_c<int, BOGUS_TOKEN_ID> library_element_symtable;
+typedef symtable_c<int>             library_element_symtable_t;
+extern  library_element_symtable_t  library_element_symtable;
 
 /* A symbol table to store the declared variables of
  * the function currently being parsed...
  */
-extern symtable_c<int, BOGUS_TOKEN_ID> variable_name_symtable;
+typedef symtable_c<int>             variable_name_symtable_t;
+extern  variable_name_symtable_t    variable_name_symtable;
 
 /* A symbol table to store the declared direct variables of
  * the function currently being parsed...
  */
-extern symtable_c<int, BOGUS_TOKEN_ID> direct_variable_symtable;
+typedef symtable_c<int>             direct_variable_symtable_t;
+extern  direct_variable_symtable_t  direct_variable_symtable;
 
 /* Function only called from within flex!
  *
--- a/stage3/declaration_check.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/stage3/declaration_check.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -178,11 +178,11 @@
      * Note too that we must also check the datatypes of external and global variables!! 
      */
     void *visit(fb_spec_init_c *symbol) {
-      symbol_c *fb_decl = function_block_type_symtable.find_value(symbol->function_block_type_name);
+      function_block_type_symtable_t::iterator iter = function_block_type_symtable.find(symbol->function_block_type_name);
       /* stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable. */
-      if (fb_decl == function_block_type_symtable.end_value())
+      if (iter == function_block_type_symtable.end())
         ERROR;
-      fb_decl->accept(*this);
+      iter->second->accept(*this); // iter->second is a fb_decl
       return NULL;
     }
     
@@ -309,12 +309,18 @@
 
 /*  PROGRAM [RETAIN | NON_RETAIN] program_name [WITH task_name] ':' program_type_name ['(' prog_conf_elements ')'] */
 void *declaration_check_c::visit(program_configuration_c *symbol) {
-  symbol_c *p_decl = program_type_symtable.find_value(symbol->program_type_name);
-  if (p_decl == program_type_symtable.end_value())
-    p_decl = function_block_type_symtable.find_value(symbol->program_type_name);
-  if (p_decl == function_block_type_symtable.end_value())
+  symbol_c *p_decl = NULL;
+  program_type_symtable_t       ::iterator iter_p = program_type_symtable       .find(symbol->program_type_name);
+  function_block_type_symtable_t::iterator iter_f = function_block_type_symtable.find(symbol->program_type_name);
+
+  if  (iter_p != program_type_symtable       .end())  p_decl = iter_p->second;
+  if  (iter_f != function_block_type_symtable.end())  p_decl = iter_f->second;
+  
+  if ((iter_f != function_block_type_symtable.end()) && (iter_p != program_type_symtable.end())) 
+    ERROR;  // Should never occur! stage1_2 guarantees that the same identifier cannot be re-used.
+  if ((iter_f == function_block_type_symtable.end()) && (iter_p == program_type_symtable.end())) 
     ERROR;  // Should never occur! stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable.
-  
+
   check_extern_c check_extern(current_pou_decl, current_resource_decl);
   p_decl->accept(check_extern);
   return NULL;
--- a/stage3/lvalue_check.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/stage3/lvalue_check.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -132,8 +132,9 @@
 	 *       So, as soon as we find one record/structure element that is not a FB, no other record/structure element
 	 *       will be of FB type, which means we can quit this check!
 	 */
-	function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(basetype_id);
-	if (function_block_type_symtable.end_value() == fb_decl) return;
+	function_block_type_symtable_t::iterator iter = function_block_type_symtable.find(basetype_id);
+	if (function_block_type_symtable.end() == iter) return;
+	function_block_declaration_c *fb_decl = iter->second;
 
 	while (NULL != (struct_elem = decompose_lvalue.get_next())) {
 		search_var_instance_decl_c   fb_search_var_instance_decl(fb_decl);
@@ -146,8 +147,10 @@
 		type_decl   = fb_search_var_instance_decl.get_decl(struct_elem);
 		basetype_id = search_base_type_c::get_basetype_id(type_decl);
 		if (NULL == basetype_id) return; /* same comment as above... */
-		fb_decl = function_block_type_symtable.find_value(basetype_id);
-		if (function_block_type_symtable.end_value() == fb_decl) return; /* same comment as above... */
+
+		iter = function_block_type_symtable.find(basetype_id);
+		if (function_block_type_symtable.end() == iter) return; /* same comment as above... */
+		fb_decl = iter->second;  
 	}
 }
 
--- a/stage3/remove_forward_dependencies.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/stage3/remove_forward_dependencies.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -108,7 +108,7 @@
   /*******************************************/
   // return NULL if the symbol is already in the declared_identifiers symbol table, otherwise return the missing symbol!
   void *visit(            poutype_identifier_c *symbol)
-    {if (declared_identifiers->find_value(symbol) != declared_identifiers->end_value()) return NULL; else return symbol;}
+    {if (declared_identifiers->find(symbol) != declared_identifiers->end()) return NULL; else return symbol;}
 };   /* class find_forward_dependencies_c */
 
 
@@ -194,7 +194,7 @@
   if ((search2 != NULL) && (search2->accept(*find_forward_dependencies) != NULL)) return NULL; // A forward depency has not yet been satisfied. Wait for a later iteration to try again!
   if ((search3 != NULL) && (search3->accept(*find_forward_dependencies) != NULL)) return NULL; // A forward depency has not yet been satisfied. Wait for a later iteration to try again!
   /* no forward dependencies found => insert into new AST, and add to the 'defined identifiers' and 'inserted symbol' lists */
-  if (declared_identifiers.find_value(name) == declared_identifiers.end_value())
+  if (declared_identifiers.find(name) == declared_identifiers.end())
       declared_identifiers.insert(name, NULL);  // only add if not yet in the symbol table (an overloaded version of this same POU could have been inderted previously!)
   inserted_symbols.insert(symbol);
   new_tree->add_element(current_code_generation_pragma);  
--- a/stage3/remove_forward_dependencies.hh	Fri Dec 26 09:39:18 2014 +0000
+++ b/stage3/remove_forward_dependencies.hh	Fri Dec 26 09:57:02 2014 +0000
@@ -52,8 +52,7 @@
 
 
 class   find_forward_dependencies_c;
-extern  symbol_c remove_forward_dependencies_c_null_symbol;
-typedef symtable_c<symbol_c *, &remove_forward_dependencies_c_null_symbol> identifiers_symbtable_t;
+typedef symtable_c<symbol_c *> identifiers_symbtable_t;
 
 
 
--- a/stage4/generate_c/generate_c_il.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/stage4/generate_c/generate_c_il.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -1067,9 +1067,9 @@
   if (function_block_type_name == NULL) ERROR;
 
   /* Now find the declaration of the function block type being called... */
-  function_block_declaration_c *fb_decl = function_block_type_symtable.find_value(function_block_type_name);
-    /* should never occur. The function block type being called MUST be in the symtable... */
-  if (fb_decl == function_block_type_symtable.end_value()) ERROR;
+  function_block_type_symtable_t::iterator iter = function_block_type_symtable.find(function_block_type_name);
+  if (iter == function_block_type_symtable.end()) ERROR; // The function block type being called MUST be in the symtable.
+  function_block_declaration_c *fb_decl = iter->second;
 
   /* loop through each function block parameter, find the value we should pass
    * to it, and then output the c equivalent...
--- a/stage4/generate_c/generate_c_vardecl.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/stage4/generate_c/generate_c_vardecl.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -144,13 +144,13 @@
     }
     
     void *visit(identifier_c *type_name) {
-      symbol_c *type_decl;
+      type_symtable_t::iterator iter = type_symtable.end();
       switch (current_mode) {
         case arraysize_am:
           /* look up the type declaration... */
-          type_decl = type_symtable.find_value(type_name);
-          if (type_decl == type_symtable.end_value())   ERROR;  // Type declaration not found!!
-          type_decl->accept(*this);
+          iter = type_symtable.find(type_name);
+          if (iter == type_symtable.end())   ERROR;  // Type declaration not found!!
+          iter->second->accept(*this);  // iter->second is a type_decl
           break;
         default:
           print_token(type_name);
@@ -557,15 +557,14 @@
     }
 
     void *visit(identifier_c *type_name) {
-      symbol_c *type_decl;
+      type_symtable_t::iterator iter = type_symtable.end();
       switch (current_mode) {
         case initdefault_sm:
           /* look up the type declaration... */
-          type_decl = type_symtable.find_value(type_name);
-          if (type_decl == type_symtable.end_value())
-            /* Type declaration not found!! */
-            ERROR;
-          type_decl->accept(*this);
+          iter = type_symtable.find(type_name);
+          if (iter == type_symtable.end())
+            ERROR; // Type declaration not found!!
+          iter->second->accept(*this); // iter->second is a type_decl
           break;
         default:
           print_token(type_name);
@@ -575,15 +574,14 @@
     }
     
     void *visit(derived_datatype_identifier_c *type_name) {
-      symbol_c *type_decl;
+      type_symtable_t::iterator iter = type_symtable.end();
       switch (current_mode) {
         case initdefault_sm:
           /* look up the type declaration... */
-          type_decl = type_symtable.find_value(type_name);
-          if (type_decl == type_symtable.end_value())
-            /* Type declaration not found!! */
-            ERROR;
-          type_decl->accept(*this);
+          iter = type_symtable.find(type_name);
+          if (iter == type_symtable.end())
+            ERROR; // Type declaration not found!!
+          iter->second->accept(*this); // iter->second is a type_decl
           break;
         default:
           print_token(type_name);
@@ -2523,11 +2521,9 @@
 private:
   /* a helper function to the program_configuration_c visitor... */
   void program_constructor_call(program_configuration_c *symbol) {
-  program_declaration_c *p_decl = program_type_symtable.find_value(symbol->program_type_name);
-
-  if (p_decl == program_type_symtable.end_value())
-    /* should never occur. The program being called MUST be in the symtable... */
-    ERROR;
+  program_type_symtable_t::iterator iter = program_type_symtable.find(symbol->program_type_name);
+  if (iter == program_type_symtable.end()) ERROR; // The program being called MUST be in the symtable.
+  program_declaration_c *p_decl = iter->second;
 
   symbol->program_name->accept(*this);
   s4o.print("(");
--- a/util/symtable.cc	Fri Dec 26 09:39:18 2014 +0000
+++ b/util/symtable.cc	Fri Dec 26 09:57:02 2014 +0000
@@ -41,19 +41,19 @@
 
 
 
-template<typename value_type, value_type null_value>
-symtable_c<value_type, null_value>::symtable_c(void) {inner_scope = NULL;}
+template<typename value_type>
+symtable_c<value_type>::symtable_c(void) {inner_scope = NULL;}
 
 
  /* clear all entries... */
-template<typename value_type, value_type null_value>
-void symtable_c<value_type, null_value>::reset(void) {
+template<typename value_type>
+void symtable_c<value_type>::reset(void) {
   _base.clear();
 }
 
  /* create new inner scope */
-template<typename value_type, value_type null_value>
-void symtable_c<value_type, null_value>::push(void) {
+template<typename value_type>
+void symtable_c<value_type>::push(void) {
   if (inner_scope != NULL) {
     inner_scope->push();
   } else {
@@ -64,8 +64,8 @@
   /* clear most inner scope */
   /* returns 1 if this is the inner most scope	*/
   /*         0 otherwise			*/
-template<typename value_type, value_type null_value>
-int symtable_c<value_type, null_value>::pop(void) {
+template<typename value_type>
+int symtable_c<value_type>::pop(void) {
   if (inner_scope != NULL) {
     if (inner_scope->pop() == 1) {
       delete inner_scope;
@@ -78,8 +78,8 @@
   }
 }
 
-template<typename value_type, value_type null_value>
-void symtable_c<value_type, null_value>::set(const symbol_c *symbol, value_t new_value) {
+template<typename value_type>
+void symtable_c<value_type>::set(const symbol_c *symbol, value_t new_value) {
   if (inner_scope != NULL) {
     inner_scope->set(symbol, new_value);
     return;
@@ -92,8 +92,8 @@
 }
 
 
-template<typename value_type, value_type null_value>
-void symtable_c<value_type, null_value>::set(const char *identifier_str, value_t new_value) {
+template<typename value_type>
+void symtable_c<value_type>::set(const char *identifier_str, value_t new_value) {
   if (inner_scope != NULL) {
     inner_scope->set(identifier_str, new_value);
     return;
@@ -108,8 +108,8 @@
   _base[identifier_str] = new_value;
 }
 
-template<typename value_type, value_type null_value>
-void symtable_c<value_type, null_value>::insert(const char *identifier_str, value_t new_value) {
+template<typename value_type>
+void symtable_c<value_type>::insert(const char *identifier_str, value_t new_value) {
   if (inner_scope != NULL) {
     inner_scope->insert(identifier_str, new_value);
     return;
@@ -125,8 +125,8 @@
   if (!res.second) {ERROR;} /* unknown error inserting new identifier */
 }
 
-template<typename value_type, value_type null_value>
-void symtable_c<value_type, null_value>::insert(const symbol_c *symbol, value_t new_value) {
+template<typename value_type>
+void symtable_c<value_type>::insert(const symbol_c *symbol, value_t new_value) {
 /*
 // not required...
   if (inner_scope != NULL) {
@@ -141,39 +141,37 @@
 }
 
 
+template<typename value_type>
+typename symtable_c<value_type>::iterator symtable_c<value_type>::end(void) {return _base.end();}
 
-/* returns null_value if not found! */
-template<typename value_type, value_type null_value>
-value_type symtable_c<value_type, null_value>::find_value(const char *identifier_str) {
+/* 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) {
-    value_t token = inner_scope->find_value(identifier_str);
-    if (token != null_value)
+    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 token;
+      return i;
   }
 
   /* if no lower level, or not found in lower level... */
-  iterator i = _base.find(identifier_str);
-
-  if (i == _base.end())
-    return null_value;
-  else
-    return i->second;
+  return _base.find(identifier_str);
 }
 
 
-template<typename value_type, value_type null_value>
-value_type symtable_c<value_type, null_value>::find_value(const symbol_c *symbol) {
+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;
-  return find_value(name->value);
+  return find(name->value);
 }
 
 
+
 /* debuging function... */
-template<typename value_type, value_type null_value>
-void symtable_c<value_type, null_value>::print(void) {
+template<typename value_type>
+void symtable_c<value_type>::print(void) {
   for(iterator i = _base.begin();
       i != _base.end();
       i++)
@@ -192,4 +190,3 @@
 
 
 
-
--- a/util/symtable.hh	Fri Dec 26 09:39:18 2014 +0000
+++ b/util/symtable.hh	Fri Dec 26 09:57:02 2014 +0000
@@ -42,7 +42,7 @@
 
 
 
-template<typename value_type, value_type null_value> class symtable_c {
+template<typename value_type> class symtable_c {
   /* Case insensitive string compare copied from
    * "The C++ Programming Language" - 3rd Edition
    * by Bjarne Stroustrup, ISBN 0201889544.
@@ -86,30 +86,30 @@
     void push(void); /* create new inner scope */
     int  pop(void);  /* clear most inner scope */
 
-    void set(const char *identifier_str, value_t value);
-    void set(const symbol_c *symbol, value_t value);
-    void insert(const char *identifier_str, value_t value);
-    void insert(const symbol_c *symbol, value_t value);
+    void set(const char *identifier_str, value_t value);    // Will change value associated to string if already in map. Will create new entry if string not in map.
+    void set(const symbol_c *symbol, value_t value);        // Will change value associated to string if already in map. Will create new entry if string not in map.
+    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!
 
-    /* Search for an entry. Will return end_value() if not found */
-    value_t end_value(void) {return null_value;}
-    value_t find_value(const char *identifier_str);
-    value_t find_value(const symbol_c *symbol);
+    /* Search for an entry. Will return end() if not found */
+    iterator               end  (void);
+    iterator               find (const char     *identifier_str);
+    iterator               find (const symbol_c *symbol        );
 
 
   /* iterators ... */
   /* NOTE: These member functions are incorrect, as the returned iterator will not iterate through the inner_scopes!! */
   /*       We simply comment it all out, as they are not currently needed!                                            */
   #if 0
-    iterator               find (const char *identifier_str) {return _base.find(identifier_str);}
-    iterator               begin()                           {return _base.begin();}
-    const_iterator         begin()  const                    {return _base.begin();}
-    iterator               end()                             {return _base.end();}
-    const_iterator         end()    const                    {return _base.end();}
-    reverse_iterator       rbegin()                          {return _base.rbegin();}
-    const_reverse_iterator rbegin() const                    {return _base.rbegin();}
-    reverse_iterator       rend()                            {return _base.rend();}
-    const_reverse_iterator rend()   const                    {return _base.rend();}
+    iterator               find (const char *identifier_str)
+    iterator               begin()                          
+    const_iterator         begin()  const                   
+    iterator               end()                            
+    const_iterator         end()    const                   
+    reverse_iterator       rbegin()                         
+    const_reverse_iterator rbegin() const                   
+    reverse_iterator       rend()                           
+    const_reverse_iterator rend()   const                   
   #endif
     /* debuging function... */
     void print(void);