#include #include "nmtbl.h" #include "token.h" #include "trnod.h" #include "util.h" //============================================================================= // Global data structures: // Ring where all global variables are entered b_ring b_ring::global_b_ring(b_ring::global); // Current ring (record or procedure body) b_ring *b_ring::curr_b_ring = &b_ring::global_b_ring; b_ring *b_ring::top_b_ring = &b_ring::global_b_ring; rename_item* rename_item::list; void symbol::translate(token* t) { if( path != NULL) { t->set_trans(dprintf("%s%s", path, out_name->text)); } else { t->set_trans(out_name->text); } } // Constructor for ring b_ring::b_ring(int scope) { b_ring::scope = scope; outer = NULL; inherite = NULL; syms = NULL; with = NULL; } // Search for an entry at one level of binding ring symbol* b_ring::shallow_search(token* t) { nm_entry* nm = t->name; for (symbol* vr = syms; vr != NULL; vr = vr->next) { if (vr->in_name == nm) { return vr->tag != symbol::s_dummy ? vr : (symbol*)0; } } return NULL; } // Search for an entry in this binding ring symbol* b_ring::search(token* t) { nm_entry* nm = t->name; for (b_ring* scope = this; scope != NULL; scope = scope->outer) { for (b_ring* br = scope; br != NULL; br = br->inherite) { for (symbol* vr = br->syms; vr != NULL; vr = vr->next) { if (vr->in_name == nm) { return vr->tag != symbol::s_dummy ? vr : (symbol*)0; } } } } return NULL; } void b_ring::make_unique(symbol* sym) { symbol *sp, **spp; int version = 0; check_loop: // for (spp = &top_b_ring->syms; (sp = *spp) != NULL; spp = &sp->next) { for (spp = &global_b_ring.syms; (sp = *spp) != NULL; spp = &sp->next) { if (sp->out_name == sym->out_name) { char buf[256]; sprintf(buf, "%s%d", sym->in_name->text, ++version); sym->out_name = nm_entry::add(buf, TKN_IDENT); goto check_loop; } } if (scope != global) { *spp = sp = new symbol; // this symbol will never be found sp->ring = top_b_ring; sp->next = NULL; sp->type = NULL; sp->in_name = sym->in_name; sp->out_name = sym->out_name; sp->tag = symbol::s_dummy; sp->tag = 0; } } // Create variable block and add it to this binding ring symbol* b_ring::add(nm_entry* in_name, nm_entry* out_name, int tag, tpexpr* type) { symbol *sym = new symbol; sym->in_name = in_name; sym->out_name = out_name; sym->flags = 0; sym->tag = tag; sym->type = type; sym->path = NULL; sym->ring = this; if (compile_system_library) { sym->out_name = rename_item::rename(sym->out_name); sym->flags |= symbol::f_syslib; } else { while (sym->out_name->flags & nm_entry::macro) { sym->out_name = nm_entry::add(dprintf("%s_", sym->out_name->text), TKN_IDENT); } } if (scope != record && (tag == symbol::s_proc || tag == symbol::s_type || scope == global)) { make_unique(sym); } sym->next = syms; syms = sym; return sym; } void b_ring::make_vars_static() { for (symbol *sym = syms; sym != NULL; sym = sym->next) { if ((sym->flags & (symbol::f_exported|symbol::f_val_param|symbol::f_var_param)) == symbol::f_exported) { sym->flags |= symbol::f_static; sym->ring->make_unique(sym); } } }