symtab.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * (C) Mike van Emmerik
  3. * These could probably be replaced by functions from libg++
  4. */
  5. /* * * * * * * * * * * * * * * * * * * * * * * * * * * *\
  6. * *
  7. * S y m b o l t a b l e F u n c t i o n s *
  8. * *
  9. \* * * * * * * * * * * * * * * * * * * * * * * * * * * */
  10. /* This file implements a symbol table with a symbolic name, a symbol value
  11. (uint16_t), and a procedure number. Two tables are maintained, to be able to
  12. look up by name or by value. Pointers are used for the duplicated symbolic
  13. name to save space. Both tables have the same structure.
  14. The hash tables automatically expand when they get 90% full; they are
  15. never compressed. Expanding the tables could take some time, since about
  16. half of the entries have to be moved on average.
  17. Linear probing is used, due to the difficulty of implementing (e.g.)
  18. quadratic probing with a variable table size.
  19. */
  20. #include <cstdio>
  21. #include <cassert>
  22. #include <cstdlib>
  23. #include <cstring>
  24. #include <unordered_map>
  25. #include "dcc.h"
  26. #include "symtab.h"
  27. #define TABLESIZE 16 /* Number of entries added each expansion */
  28. /* Probably has to be a power of 2 */
  29. #define STRTABSIZE 256 /* Size string table is inc'd by */
  30. using namespace std;
  31. static char *pStrTab; /* Pointer to the current string table */
  32. static int strTabNext; /* Next free index into pStrTab */
  33. namespace std
  34. {
  35. template<>
  36. struct hash<SYMTABLE> : public unary_function<const SYMTABLE &,size_t>
  37. {
  38. size_t operator()(const SYMTABLE & key) const
  39. {
  40. uint16_t h = 0;
  41. h = (uint16_t)(key.symOff ^ (key.symOff >> 8));
  42. return h;
  43. }
  44. };
  45. }
  46. static tableType curTableType; /* Which table is current */
  47. struct TABLEINFO_TYPE
  48. {
  49. TABLEINFO_TYPE()
  50. {
  51. symTab=valTab=0;
  52. }
  53. //void deleteVal(uint32_t symOff, Function *symProc, boolT bSymToo);
  54. void create(tableType type);
  55. void destroy();
  56. private:
  57. SYMTABLE *symTab; /* Pointer to the symbol hashed table */
  58. SYMTABLE *valTab; /* Pointer to the value hashed table */
  59. uint16_t numEntry; /* Number of entries in this table */
  60. uint16_t tableSize;/* Size of the table (entries) */
  61. unordered_map<string,SYMTABLE> z;
  62. unordered_map<SYMTABLE,string> z2;
  63. };
  64. static TABLEINFO_TYPE tableInfo[NUM_TABLE_TYPES]; /* Array of info about tables */
  65. static TABLEINFO_TYPE currentTabInfo;
  66. /* Create a new symbol table. Returns "handle" */
  67. void TABLEINFO_TYPE::create(tableType type)
  68. {
  69. switch(type)
  70. {
  71. case Comment:
  72. numEntry = 0;
  73. tableSize = TABLESIZE;
  74. valTab = new SYMTABLE [TABLESIZE];
  75. symTab = 0;
  76. break;
  77. case Label:
  78. currentTabInfo.numEntry = 0;
  79. currentTabInfo.tableSize = TABLESIZE;
  80. currentTabInfo.symTab = new SYMTABLE [TABLESIZE];
  81. currentTabInfo.valTab = new SYMTABLE [TABLESIZE];
  82. break;
  83. }
  84. }
  85. void createSymTables(void)
  86. {
  87. /* Initilise the comment table */
  88. /* NB - there is no symbol hashed comment table */
  89. currentTabInfo.create(Comment);
  90. tableInfo[Comment] = currentTabInfo;
  91. /* Initialise the label table */
  92. currentTabInfo.create(Label);
  93. tableInfo[Label] = currentTabInfo;
  94. curTableType = Label;
  95. /* Now the string table */
  96. strTabNext = 0;
  97. pStrTab = new char[STRTABSIZE];
  98. curTableType = Label;
  99. }
  100. void selectTable(tableType tt)
  101. {
  102. if (curTableType == tt)
  103. return; /* Nothing to do */
  104. currentTabInfo = tableInfo[tt];
  105. curTableType = tt;
  106. }
  107. void TABLEINFO_TYPE::destroy()
  108. {
  109. delete [] symTab; // The symbol hashed label table
  110. delete [] valTab; // And the value hashed label table
  111. }
  112. void destroySymTables(void)
  113. {
  114. selectTable(Label);
  115. currentTabInfo.destroy();
  116. selectTable(Comment);
  117. currentTabInfo.destroy();
  118. }
  119. /* Using the value, read the symbolic name */
  120. boolT readVal(std::ostringstream &/*symName*/, uint32_t /*symOff*/, Function * /*symProc*/)
  121. {
  122. return false; // no symbolic names for now
  123. }
  124. /* Updates the type of the symbol in the symbol table. The size is updated
  125. * if necessary (0 means no update necessary). */
  126. void SYMTAB::updateSymType (uint32_t symbol,const TypeContainer &tc)
  127. {
  128. auto iter=findByLabel(symbol);
  129. if(iter==end())
  130. return;
  131. iter->type = tc.m_type;
  132. if (tc.m_size != 0)
  133. iter->size = tc.m_size;
  134. }
  135. /* Creates an entry in the global symbol table (symtab) if the variable
  136. * is not there yet. If it is part of the symtab, the size of the variable
  137. * is checked and updated if the old size was less than the new size (ie.
  138. * the maximum size is always saved). */
  139. //TODO: SYMTAB::updateGlobSym should be renamed to insertOrUpdateSym
  140. SYM * SYMTAB::updateGlobSym (uint32_t operand, int size, uint16_t duFlag,bool &inserted_new)
  141. {
  142. /* Check for symbol in symbol table */
  143. auto iter = findByLabel(operand);
  144. if(iter!=end())
  145. {
  146. if(iter->size<size)
  147. iter->size = size;
  148. inserted_new=false;
  149. return &(*iter);
  150. }
  151. /* New symbol, not in symbol table */
  152. SYM v;
  153. char buf[32]={};
  154. sprintf (buf, "var%05X", operand);
  155. v.name = buf;
  156. v.label = operand;
  157. v.size = size;
  158. v.type = TypeContainer::defaultTypeForSize(size);
  159. if (duFlag == eDuVal::USE) /* must already have init value */
  160. {
  161. v.duVal.use =1; // USEVAL;
  162. v.duVal.val =1;
  163. }
  164. else
  165. {
  166. v.duVal.setFlags(duFlag);
  167. }
  168. push_back(v);
  169. inserted_new=true;
  170. return (&back());
  171. }
  172. //template<> class SymbolTableCommon<SYM>;
  173. //template<> class SymbolTableCommon<STKSYM>;