1 #include <stdio.h>
2
3 #include "nmtbl.h"
4 #include "token.h"
5 #include "trnod.h"
6 #include "util.h"
7
8 //=============================================================================
9 // Global data structures:
10
11 // Ring where all global variables are entered
12 b_ring b_ring::global_b_ring(b_ring::global);
13
14 // Current ring (record or procedure body)
15 b_ring *b_ring::curr_b_ring = &b_ring::global_b_ring;
16
17 b_ring *b_ring::top_b_ring = &b_ring::global_b_ring;
18
19 rename_item* rename_item::list;
20
translate(token * t)21 void symbol::translate(token* t)
22 {
23 if( path != NULL) {
24 t->set_trans(dprintf("%s%s", path, out_name->text));
25 } else {
26 t->set_trans(out_name->text);
27 }
28 }
29
30 // Constructor for ring
b_ring(int scope)31 b_ring::b_ring(int scope) {
32 b_ring::scope = scope;
33 outer = NULL;
34 inherite = NULL;
35 syms = NULL;
36 with = NULL;
37 }
38
39 // Search for an entry at one level of binding ring
shallow_search(token * t)40 symbol* b_ring::shallow_search(token* t)
41 {
42 nm_entry* nm = t->name;
43 for (symbol* vr = syms; vr != NULL; vr = vr->next) {
44 if (vr->in_name == nm) {
45 return vr->tag != symbol::s_dummy ? vr : (symbol*)0;
46 }
47 }
48 return NULL;
49 }
50
find_scope(b_ring * type)51 bool b_ring::find_scope(b_ring* type)
52 {
53 for (b_ring* scope = this; scope != NULL; scope = scope->outer) {
54 if (type == scope) {
55 return true;
56 }
57 }
58 return false;
59 }
60
61 // Search for an entry in this binding ring
search(token * t)62 symbol* b_ring::search(token* t)
63 {
64 nm_entry* nm = t->name;
65
66 for (b_ring* scope = this; scope != NULL; scope = scope->outer) {
67 for (b_ring* br = scope; br != NULL; br = br->inherite) {
68 for (symbol* vr = br->syms; vr != NULL; vr = vr->next) {
69 if (vr->in_name == nm) {
70 return vr->tag != symbol::s_dummy ? vr : (symbol*)0;
71 }
72 }
73 }
74 }
75 return NULL;
76 }
77
make_unique(symbol * sym)78 void b_ring::make_unique(symbol* sym)
79 {
80 symbol *sp, **spp;
81 int version = 0;
82
83 check_loop:
84 // for (spp = &top_b_ring->syms; (sp = *spp) != NULL; spp = &sp->next) {
85 for (spp = &global_b_ring.syms; (sp = *spp) != NULL; spp = &sp->next) {
86 if (sp->out_name == sym->out_name) {
87 char buf[256];
88 sprintf(buf, "%s%d", sym->in_name->text, ++version);
89 sym->out_name = nm_entry::add(buf, TKN_IDENT);
90 goto check_loop;
91 }
92 }
93 if (scope != global) {
94 *spp = sp = new symbol; // this symbol will never be found
95 sp->ring = top_b_ring;
96 sp->next = NULL;
97 sp->type = NULL;
98 sp->in_name = sym->in_name;
99 sp->out_name = sym->out_name;
100 sp->tag = symbol::s_dummy;
101 sp->tag = 0;
102 }
103 }
104
105 // Create variable block and add it to this binding ring
add(nm_entry * in_name,nm_entry * out_name,int tag,tpexpr * type)106 symbol* b_ring::add(nm_entry* in_name, nm_entry* out_name, int tag, tpexpr* type)
107 {
108 symbol *sym = new symbol;
109 sym->in_name = in_name;
110 sym->out_name = out_name;
111 sym->flags = 0;
112 sym->tag = tag;
113 sym->type = type;
114 sym->path = NULL;
115 sym->ring = this;
116
117 if (compile_system_library) {
118 sym->out_name = rename_item::rename(sym->out_name);
119 sym->flags |= symbol::f_syslib;
120 } else {
121 while (sym->out_name->flags & nm_entry::macro) {
122 sym->out_name = nm_entry::add(dprintf("%s_", sym->out_name->text),
123 TKN_IDENT);
124 }
125 }
126
127 if (scope != record &&
128 (tag == symbol::s_proc || tag == symbol::s_type || scope == global))
129 {
130 make_unique(sym);
131 }
132 sym->next = syms;
133 syms = sym;
134
135 return sym;
136 }
137
make_vars_static()138 void b_ring::make_vars_static()
139 {
140 for (symbol *sym = syms; sym != NULL; sym = sym->next) {
141 if ((sym->flags & (symbol::f_exported|symbol::f_val_param|symbol::f_var_param))
142 == symbol::f_exported)
143 {
144 sym->flags |= symbol::f_static;
145 sym->ring->make_unique(sym);
146 }
147 }
148 }
149
150
151
152