123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /* $Header$ */
- /* Symbol handling */
- #include <alloc.h>
- #include <out.h>
- #include <stb.h>
- #include <assert.h>
- #include "position.h"
- #include "file.h"
- #include "idf.h"
- #include "type.h"
- #include "symbol.h"
- #include "scope.h"
- #include "tree.h"
- #include "operator.h"
- p_symbol currfile;
- p_symbol
- NewSymbol(s, scope, class, nam)
- char *s;
- register p_scope scope;
- struct outname *nam;
- {
- register p_symbol sym;
-
- sym = new_symbol();
- sym->sy_idf = str2idf(s, 0);
- sym->sy_scope = scope;
- sym->sy_prev_sc = scope->sc_symbs;
- scope->sc_symbs = sym;
- sym->sy_next = sym->sy_idf->id_def;
- sym->sy_idf->id_def = sym;
- sym->sy_class = class;
- switch(class) {
- case MODULE:
- case PROC:
- case FUNCTION:
- case VAR:
- case REGVAR:
- case LOCVAR:
- case VARPAR:
- sym->sy_name.nm_value = nam->on_valu;
- break;
- default:
- break;
- }
- return sym;
- }
- /* Lookup a definition for 'id' in scope 'scope' with class in the 'class'
- bitset.
- */
- p_symbol
- Lookup(id, scope, class)
- struct idf *id;
- p_scope scope;
- int class;
- {
- register p_symbol p = id ? id->id_def : 0;
- while (p) {
- if (p->sy_scope == scope && (p->sy_class & class)) {
- return p;
- }
- p = p->sy_next;
- }
- return (p_symbol) 0;
- }
- /* Lookup a definition for 'id' with class in the 'class' bitset,
- starting in scope 'sc' and also looking in enclosing scopes.
- */
- p_symbol
- Lookfromscope(id, class, sc)
- register struct idf *id;
- int class;
- register p_scope sc;
- {
- if (! id) return (p_symbol) 0;
- while (sc) {
- register p_symbol sym = id->id_def;
- while (sym) {
- if (sym->sy_scope == sc && (sym->sy_class & class)) {
- return sym;
- }
- sym = sym->sy_next;
- }
- sc = sc->sc_static_encl;
- }
- return (p_symbol) 0;
- }
- /* Lookup a definition for 'id' with class in the 'class' bitset,
- starting in scope 'CurrentScope' and also looking in enclosing scopes.
- */
- p_symbol
- Lookfor(id, class)
- register struct idf *id;
- int class;
- {
- return Lookfromscope(id, class, CurrentScope);
- }
- extern char *strrindex();
- p_symbol
- add_file(s)
- char *s;
- {
- register p_symbol sym = NewSymbol(s,
- PervasiveScope,
- FILESYM,
- (struct outname *) 0);
- register char *p;
- sym->sy_file = new_file();
- sym->sy_file->f_sym = sym;
- p = strrindex(s, '.');
- if (p) {
- char c = *p;
- p_symbol sym1;
- *p = 0;
- sym1 = NewSymbol(Salloc(s, (unsigned) strlen(s)+1),
- PervasiveScope,
- FILELINK,
- (struct outname *) 0);
- *p = c;
- sym1->sy_filelink = sym;
- }
- return sym;
- }
- /* Determine if the OP_SELECT tree indicated by 'p' could lead to scope 'sc'.
- */
- static int
- consistent(p, sc)
- p_tree p;
- p_scope sc;
- {
- p_tree arg;
- p_symbol sym;
- assert(p->t_oper == OP_SELECT);
- sc = sc->sc_static_encl;
- if (!sc) return 0;
- p = p->t_args[0];
- switch(p->t_oper) {
- case OP_NAME:
- sym = Lookfromscope(p->t_idf, FILELINK|FILESYM|PROC|MODULE, sc);
- return sym != 0;
- case OP_SELECT:
- arg = p->t_args[1];
- sym = Lookfromscope(arg->t_idf, FILELINK|FILESYM|PROC|MODULE, sc);
- if (sym == 0) return 0;
- return consistent(p, sym->sy_scope);
- default:
- assert(0);
- }
- return 0; /* notreached? */
- }
- /* Try to find the name referred to in the node indicated by 'p', and
- try to be just a little bit intelligent about it.
- */
- p_symbol
- identify(p, class_set)
- p_tree p;
- int class_set;
- {
- p_symbol sym = 0;
- register p_symbol s;
- p_tree arg;
- switch(p->t_oper) {
- case OP_NAME:
- if (! p->t_sc) p->t_sc = CurrentScope;
- sym = Lookfromscope(p->t_idf, class_set, p->t_sc);
- if (sym) {
- /* Found it. */
- break;
- }
- /* We could not find it using scope p->t_sc; now we try to identify
- it using class_set. If this results in only one definition, we
- take this one.
- */
- s = p->t_idf->id_def;
- while (s) {
- if (s->sy_class & class_set) {
- if (sym) {
- error("could not identify \"%s\"", p->t_str);
- sym = 0;
- break;
- }
- sym = s;
- }
- s = s->sy_next;
- }
- if (!sym && !s) {
- error("could not find \"%s\"", p->t_str);
- }
- break;
- case OP_SELECT:
- arg = p->t_args[1];
- assert(arg->t_oper == OP_NAME);
- s = arg->t_idf->id_def;
- sym = 0;
- while (s) {
- if ((s->sy_class & class_set) && consistent(p, s->sy_scope)) {
- if (sym) {
- error("could not identify \"%s\"", arg->t_str);
- sym = 0;
- }
- sym = s;
- }
- s = s->sy_next;
- }
- if (!sym && !s) {
- error("could not find \"%s\"", arg->t_str);
- }
- break;
- default:
- assert(0);
- }
- return sym;
- }
|