util/symtable.cc
changeset 0 fb772792efd1
child 279 c0453b7f99df
equal deleted inserted replaced
-1:000000000000 0:fb772792efd1
       
     1 /*
       
     2  * (c) 2003 Mario de Sousa
       
     3  *
       
     4  * Offered to the public under the terms of the GNU General Public License
       
     5  * as published by the Free Software Foundation; either version 2 of the
       
     6  * License, or (at your option) any later version.
       
     7  *
       
     8  * This program is distributed in the hope that it will be useful, but
       
     9  * WITHOUT ANY WARRANTY; without even the implied warranty of
       
    10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
       
    11  * Public License for more details.
       
    12  *
       
    13  * This code is made available on the understanding that it will not be
       
    14  * used in safety-critical situations without a full and competent review.
       
    15  */
       
    16 
       
    17 /*
       
    18  * An IEC 61131-3 IL and ST compiler.
       
    19  *
       
    20  * Based on the
       
    21  * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
       
    22  *
       
    23  */
       
    24 
       
    25 
       
    26 /*
       
    27  * A generic symbol table.
       
    28  *
       
    29  * This is used to create symbol tables such as a list of
       
    30  * variables currently in scope, etc...
       
    31  * Note that the list of previously defined funstions uses the
       
    32  * dsymtable_c instead, as it requires the table to store duplicate values.
       
    33  */
       
    34 
       
    35 
       
    36 #include <iostream>
       
    37 #include "symtable.hh"
       
    38 
       
    39 
       
    40 
       
    41 /* A macro for printing out internal parser errors... */
       
    42 #define ERROR error_exit(__FILE__,__LINE__)
       
    43 /* function defined in main.cc */
       
    44 extern void error_exit(const char *file_name, int line_no);
       
    45 
       
    46 
       
    47 
       
    48 
       
    49 template<typename value_type, value_type null_value>
       
    50 symtable_c<value_type, null_value>::symtable_c(void) {inner_scope = NULL;}
       
    51 
       
    52 
       
    53  /* clear all entries... */
       
    54 template<typename value_type, value_type null_value>
       
    55 void symtable_c<value_type, null_value>::reset(void) {
       
    56   _base.clear();
       
    57 }
       
    58 
       
    59  /* create new inner scope */
       
    60 template<typename value_type, value_type null_value>
       
    61 void symtable_c<value_type, null_value>::push(void) {
       
    62   if (inner_scope != NULL) {
       
    63     inner_scope->push();
       
    64   } else {
       
    65     inner_scope = new symtable_c();
       
    66   }
       
    67 }
       
    68 
       
    69   /* clear most inner scope */
       
    70   /* returns 1 if this is the inner most scope	*/
       
    71   /*         0 otherwise			*/
       
    72 template<typename value_type, value_type null_value>
       
    73 int symtable_c<value_type, null_value>::pop(void) {
       
    74   if (inner_scope != NULL) {
       
    75     if (inner_scope->pop() == 1) {
       
    76       delete inner_scope;
       
    77       inner_scope = NULL;
       
    78     }
       
    79     return 0;
       
    80   } else {
       
    81     _base.clear();
       
    82     return 1;
       
    83   }
       
    84 }
       
    85 
       
    86 template<typename value_type, value_type null_value>
       
    87 void symtable_c<value_type, null_value>::set(const symbol_c *symbol, value_t new_value) {
       
    88   if (inner_scope != NULL) {
       
    89     inner_scope->set(symbol, new_value);
       
    90     return;
       
    91   }
       
    92 
       
    93   const token_c *name = dynamic_cast<const token_c *>(symbol);
       
    94   if (name == NULL)
       
    95     ERROR;
       
    96   set(name->value, new_value);
       
    97 }
       
    98 
       
    99 
       
   100 template<typename value_type, value_type null_value>
       
   101 void symtable_c<value_type, null_value>::set(const char *identifier_str, value_t new_value) {
       
   102   if (inner_scope != NULL) {
       
   103     inner_scope->set(identifier_str, new_value);
       
   104     return;
       
   105   }
       
   106 
       
   107   // std::cout << "set_identifier(" << identifier_str << "): \n";
       
   108   iterator i = _base.find(identifier_str);
       
   109   if (i == _base.end())
       
   110     /* identifier not already in map! */
       
   111     ERROR;
       
   112 
       
   113   _base[identifier_str] = new_value;
       
   114 }
       
   115 
       
   116 template<typename value_type, value_type null_value>
       
   117 void symtable_c<value_type, null_value>::insert(const char *identifier_str, value_t new_value) {
       
   118   if (inner_scope != NULL) {
       
   119     inner_scope->insert(identifier_str, new_value);
       
   120     return;
       
   121   }
       
   122 
       
   123   // std::cout << "store_identifier(" << identifier_str << "): \n";
       
   124   std::pair<const char *, value_t> new_element(identifier_str, new_value);
       
   125   std::pair<iterator, bool> res = _base.insert(new_element);
       
   126   if (!res.second)
       
   127     /* error inserting new identifier... */
       
   128     /* identifier already in map?        */
       
   129     ERROR;
       
   130 }
       
   131 
       
   132 template<typename value_type, value_type null_value>
       
   133 void symtable_c<value_type, null_value>::insert(const symbol_c *symbol, value_t new_value) {
       
   134 /*
       
   135 // not required...
       
   136   if (inner_scope != NULL) {
       
   137     inner_scope->insert(symbol, new_value);
       
   138     return;
       
   139   }
       
   140 */
       
   141   const token_c *name = dynamic_cast<const token_c *>(symbol);
       
   142   if (name == NULL)
       
   143     ERROR;
       
   144   insert(name->value, new_value);
       
   145 }
       
   146 
       
   147 
       
   148 
       
   149 /* returns null_value if not found! */
       
   150 template<typename value_type, value_type null_value>
       
   151 value_type symtable_c<value_type, null_value>::find_value(const char *identifier_str) {
       
   152   if (inner_scope != NULL) {
       
   153     value_t token = inner_scope->find_value(identifier_str);
       
   154     if (token != null_value)
       
   155       /* found in the lower level */
       
   156       return token;
       
   157   }
       
   158 
       
   159   /* if no lower level, or not found in lower level... */
       
   160   iterator i = _base.find(identifier_str);
       
   161 
       
   162   if (i == _base.end())
       
   163     return null_value;
       
   164   else
       
   165     return i->second;
       
   166 }
       
   167 
       
   168 
       
   169 template<typename value_type, value_type null_value>
       
   170 value_type symtable_c<value_type, null_value>::find_value(const symbol_c *symbol) {
       
   171   const token_c *name = dynamic_cast<const token_c *>(symbol);
       
   172   if (name == NULL)
       
   173     ERROR;
       
   174   return find_value(name->value);
       
   175 }
       
   176 
       
   177 
       
   178 /* debuging function... */
       
   179 template<typename value_type, value_type null_value>
       
   180 void symtable_c<value_type, null_value>::print(void) {
       
   181   for(iterator i = _base.begin();
       
   182       i != _base.end();
       
   183       i++)
       
   184     std::cout << i->second << ":" << i->first << "\n";
       
   185   std::cout << "=====================\n";
       
   186 
       
   187   if (inner_scope != NULL) {
       
   188     inner_scope->print();
       
   189   }
       
   190 }
       
   191 
       
   192 
       
   193 
       
   194 
       
   195 
       
   196 
       
   197 
       
   198 
       
   199