symtable.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include <string.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "symtable.h"
  5. #include "dd_dynamic_array.h"
  6. // number of entries on each symtable
  7. #define SYMMAX 100
  8. #define symtable_index(table, index) ((table << 16) | index)
  9. // symtable
  10. struct symtable {
  11. struct entry entry[SYMMAX];
  12. int lastentry;
  13. int parent;
  14. int index;
  15. } *symtable;
  16. struct dd_dynamic_array symtable_array;
  17. int current_symtable;
  18. /* init
  19. * allocate memory
  20. * no symbols inside
  21. */
  22. int symtable_init() {
  23. // init symtable and its index
  24. symtable = 0;
  25. current_symtable = -1;
  26. // init symtable array and push the first table
  27. dd_da_init(&symtable_array, sizeof(struct symtable));
  28. symtable_push();
  29. /* everything OK */
  30. return 1;
  31. }
  32. // lookup on a single table
  33. int lookup_table(char s[], struct symtable *t) {
  34. for (int i = 0; i <= t->lastentry; i++) {
  35. if (strcmp(t->entry[i].lexptr, s) == 0) {
  36. return i;
  37. }
  38. }
  39. return -1;
  40. }
  41. // find symbol, and return its index
  42. int lookup(char s[]) {
  43. struct symtable *csymtable = symtable;
  44. while (csymtable) {
  45. int index = lookup_table(s, csymtable);
  46. if (index >= 0) {
  47. return symtable_index(csymtable->index, index);
  48. }
  49. csymtable = dd_da_get(&symtable_array, csymtable->parent);
  50. }
  51. /* symbol not found */
  52. return -1;
  53. }
  54. // insert new symbol
  55. int symtable_insert(char s[], int tok) {
  56. // entry to be returned
  57. struct entry *symentry;
  58. // entry already in sym table - return it
  59. int index = lookup(s);
  60. if (index >= 0) {
  61. return index;
  62. }
  63. // make sure sym table has space
  64. if (symtable->lastentry +1 >= SYMMAX) {
  65. printf("symbol table full");
  66. return -1;
  67. }
  68. // sym table about to get a new symbol - prepare it
  69. int len;
  70. len = strlen(s);
  71. // entry's index
  72. symtable->lastentry++;
  73. // create new entry
  74. symentry = &symtable->entry[symtable->lastentry];
  75. symentry->token = tok;
  76. symentry->lexptr = malloc(sizeof(char) *len +1);
  77. symentry->value = 0;
  78. strcpy(symentry->lexptr, s);
  79. return symtable_index(current_symtable, symtable->lastentry);
  80. }
  81. // clean current system table and all it's parents
  82. void symtable_clean() {
  83. dd_da_free(&symtable_array);
  84. }
  85. // print symbol table
  86. void symtable_print() {
  87. for (int i = 0; i < symtable_array.elements; i++) {
  88. printf("symtable %d\n", i);
  89. struct symtable *s = dd_da_get(&symtable_array, i);
  90. for (int i = 0; i <= s->lastentry; i++) {
  91. printf("\t%s | token: %d\n", s->entry[i].lexptr, s->entry[i].token);
  92. }
  93. if (s->parent >= 0) printf("parent: %d\n", s->parent);
  94. else printf("parent: none\n");
  95. printf("end symtable:\n");
  96. }
  97. }
  98. // get entry from index
  99. struct entry *symtable_entryat(int index) {
  100. int symindex = index >> 16;
  101. index = 0xFF & index;
  102. struct symtable *t = dd_da_get(&symtable_array, symindex);
  103. /* index is within array's bounds - return entry at index */
  104. if (index >= 0 && index <= t->lastentry) {
  105. return &t->entry[index];
  106. }
  107. /* index is outside array's bounds - return null pointer */
  108. return 0;
  109. } // entryat
  110. /* push a new table-scope
  111. */
  112. void symtable_push() {
  113. // new table
  114. struct symtable table;
  115. table.lastentry = -1;
  116. table.parent = -1;
  117. table.index = symtable_array.elements;
  118. // add new table to array and refresh pointers
  119. dd_da_add(&symtable_array, &table);
  120. if (symtable) symtable = dd_da_get(&symtable_array, current_symtable);
  121. current_symtable = symtable_array.elements-1;
  122. struct symtable *t = dd_da_get(&symtable_array, symtable_array.elements-1);
  123. if (!t) {
  124. printf("error getting symtable\n");
  125. return;
  126. }
  127. if (symtable) {
  128. t->parent = symtable->index;
  129. }
  130. symtable = t;
  131. }
  132. void symtable_pop() {
  133. if (symtable->parent >= 0) {
  134. symtable = dd_da_get(&symtable_array, symtable->parent);
  135. current_symtable = symtable->index;
  136. }
  137. }