symbol.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /* $Header$ */
  2. /* Symbol handling */
  3. #include <alloc.h>
  4. #include <out.h>
  5. #include <stb.h>
  6. #include <assert.h>
  7. #include "position.h"
  8. #include "file.h"
  9. #include "idf.h"
  10. #include "type.h"
  11. #include "symbol.h"
  12. #include "scope.h"
  13. #include "tree.h"
  14. #include "operator.h"
  15. p_symbol currfile;
  16. p_symbol
  17. NewSymbol(s, scope, class, nam)
  18. char *s;
  19. register p_scope scope;
  20. struct outname *nam;
  21. {
  22. register p_symbol sym;
  23. sym = new_symbol();
  24. sym->sy_idf = str2idf(s, 0);
  25. sym->sy_scope = scope;
  26. sym->sy_prev_sc = scope->sc_symbs;
  27. scope->sc_symbs = sym;
  28. sym->sy_next = sym->sy_idf->id_def;
  29. sym->sy_idf->id_def = sym;
  30. sym->sy_class = class;
  31. switch(class) {
  32. case MODULE:
  33. case PROC:
  34. case FUNCTION:
  35. case VAR:
  36. case REGVAR:
  37. case LOCVAR:
  38. case VARPAR:
  39. sym->sy_name.nm_value = nam->on_valu;
  40. break;
  41. default:
  42. break;
  43. }
  44. return sym;
  45. }
  46. /* Lookup a definition for 'id' in scope 'scope' with class in the 'class'
  47. bitset.
  48. */
  49. p_symbol
  50. Lookup(id, scope, class)
  51. struct idf *id;
  52. p_scope scope;
  53. int class;
  54. {
  55. register p_symbol p = id ? id->id_def : 0;
  56. while (p) {
  57. if (p->sy_scope == scope && (p->sy_class & class)) {
  58. return p;
  59. }
  60. p = p->sy_next;
  61. }
  62. return (p_symbol) 0;
  63. }
  64. /* Lookup a definition for 'id' with class in the 'class' bitset,
  65. starting in scope 'sc' and also looking in enclosing scopes.
  66. */
  67. p_symbol
  68. Lookfromscope(id, class, sc)
  69. register struct idf *id;
  70. int class;
  71. register p_scope sc;
  72. {
  73. if (! id) return (p_symbol) 0;
  74. while (sc) {
  75. register p_symbol sym = id->id_def;
  76. while (sym) {
  77. if (sym->sy_scope == sc && (sym->sy_class & class)) {
  78. return sym;
  79. }
  80. sym = sym->sy_next;
  81. }
  82. sc = sc->sc_static_encl;
  83. }
  84. return (p_symbol) 0;
  85. }
  86. /* Lookup a definition for 'id' with class in the 'class' bitset,
  87. starting in scope 'CurrentScope' and also looking in enclosing scopes.
  88. */
  89. p_symbol
  90. Lookfor(id, class)
  91. register struct idf *id;
  92. int class;
  93. {
  94. return Lookfromscope(id, class, CurrentScope);
  95. }
  96. extern char *strrindex();
  97. p_symbol
  98. add_file(s)
  99. char *s;
  100. {
  101. register p_symbol sym = NewSymbol(s,
  102. PervasiveScope,
  103. FILESYM,
  104. (struct outname *) 0);
  105. register char *p;
  106. sym->sy_file = new_file();
  107. sym->sy_file->f_sym = sym;
  108. p = strrindex(s, '.');
  109. if (p) {
  110. char c = *p;
  111. p_symbol sym1;
  112. *p = 0;
  113. sym1 = NewSymbol(Salloc(s, (unsigned) strlen(s)+1),
  114. PervasiveScope,
  115. FILELINK,
  116. (struct outname *) 0);
  117. *p = c;
  118. sym1->sy_filelink = sym;
  119. }
  120. return sym;
  121. }
  122. /* Determine if the OP_SELECT tree indicated by 'p' could lead to scope 'sc'.
  123. */
  124. static int
  125. consistent(p, sc)
  126. p_tree p;
  127. p_scope sc;
  128. {
  129. p_tree arg;
  130. p_symbol sym;
  131. assert(p->t_oper == OP_SELECT);
  132. sc = sc->sc_static_encl;
  133. if (!sc) return 0;
  134. p = p->t_args[0];
  135. switch(p->t_oper) {
  136. case OP_NAME:
  137. sym = Lookfromscope(p->t_idf, FILELINK|FILESYM|PROC|MODULE, sc);
  138. return sym != 0;
  139. case OP_SELECT:
  140. arg = p->t_args[1];
  141. sym = Lookfromscope(arg->t_idf, FILELINK|FILESYM|PROC|MODULE, sc);
  142. if (sym == 0) return 0;
  143. return consistent(p, sym->sy_scope);
  144. default:
  145. assert(0);
  146. }
  147. return 0; /* notreached? */
  148. }
  149. /* Try to find the name referred to in the node indicated by 'p', and
  150. try to be just a little bit intelligent about it.
  151. */
  152. p_symbol
  153. identify(p, class_set)
  154. p_tree p;
  155. int class_set;
  156. {
  157. p_symbol sym = 0;
  158. register p_symbol s;
  159. p_tree arg;
  160. switch(p->t_oper) {
  161. case OP_NAME:
  162. if (! p->t_sc) p->t_sc = CurrentScope;
  163. sym = Lookfromscope(p->t_idf, class_set, p->t_sc);
  164. if (sym) {
  165. /* Found it. */
  166. break;
  167. }
  168. /* We could not find it using scope p->t_sc; now we try to identify
  169. it using class_set. If this results in only one definition, we
  170. take this one.
  171. */
  172. s = p->t_idf->id_def;
  173. while (s) {
  174. if (s->sy_class & class_set) {
  175. if (sym) {
  176. error("could not identify \"%s\"", p->t_str);
  177. sym = 0;
  178. break;
  179. }
  180. sym = s;
  181. }
  182. s = s->sy_next;
  183. }
  184. if (!sym && !s) {
  185. error("could not find \"%s\"", p->t_str);
  186. }
  187. break;
  188. case OP_SELECT:
  189. arg = p->t_args[1];
  190. assert(arg->t_oper == OP_NAME);
  191. s = arg->t_idf->id_def;
  192. sym = 0;
  193. while (s) {
  194. if ((s->sy_class & class_set) && consistent(p, s->sy_scope)) {
  195. if (sym) {
  196. error("could not identify \"%s\"", arg->t_str);
  197. sym = 0;
  198. }
  199. sym = s;
  200. }
  201. s = s->sy_next;
  202. }
  203. if (!sym && !s) {
  204. error("could not find \"%s\"", arg->t_str);
  205. }
  206. break;
  207. default:
  208. assert(0);
  209. }
  210. return sym;
  211. }