1 
2 // -*- C++ -*-
3 // Binding rings (lists actually)
4 #ifndef __BRING_H__
5 #define __BRING_H__
6 
7 #include "main.h"
8 
9 class b_ring;
10 class tpexpr;
11 
12 // Element of binding contour: variable, type or label
13 class symbol : public heap_object {
14   public:
15     symbol	*next;
16     nm_entry 	*in_name;
17     nm_entry    *out_name;
18     char        *path;     // path to component in structure
19     b_ring	*ring;
20     enum {
21       s_var,    // variable
22       s_ref,    // reference
23       s_const,  // constant
24       s_type,   // type
25       s_proc,   // procedure
26       s_label,  // label
27       s_dummy   // dummy symbol, used only to preserve name in namespace
28     };
29     int		tag;
30 
31     enum {
32         f_used 		= 0x01, //
33 	f_defined	= 0x02, //
34         f_val_param     = 0x04, // variable is parameter passed by values
35         f_var_param     = 0x08, // variable is VAR parameter passsed b
36 	f_exported      = 0x10, // variable is accessed by nexted function
37 	f_static        = 0x20, // variable is static
38 	f_syslib        = 0x40, // symbol from system library
39 	f_const         = 0x80, // integer constant is stored in "value"
40 	f_lvalue        = 0x100 // variable is used as lvalue
41     };
42     int	        flags;
43     int         value;
44     tpexpr	*type;
45 
46     void translate(token* t);
47 };
48 
49 // Binding contour
50 class b_ring {
51   public:
52     b_ring(int scope);
53 
54     b_ring	*outer;
55     b_ring	*inherite;
56     symbol	*syms;
57     symbol      *with; // WITH variable for RECORD ring
58 
59 
60     // Kinds of binding contours
61     enum {
62 	block, record, proc, global
63     };
64 
65     int    scope;
66 
67     static b_ring global_b_ring;
68     static b_ring *curr_b_ring;
69     static b_ring *top_b_ring;
70 
push(b_ring * r)71     static void push(b_ring* r) {
72         /*
73         if (r->outer != NULL) {
74             r = new b_ring(r->scope);
75         }
76         */
77         r->outer = curr_b_ring;
78         curr_b_ring = r;
79     }
80 
pop()81     static b_ring* pop() {
82 	b_ring* top = curr_b_ring;
83         curr_b_ring = curr_b_ring->outer;
84         top->outer = NULL;
85 	return top;
86     }
87 
88     symbol* search(token* t);
89     symbol* shallow_search(token* t);
90     symbol* add(nm_entry* in_name, nm_entry* out_name, int tag, tpexpr* type);
add(nm_entry * in_name,int tag,tpexpr * type)91     symbol* add(nm_entry* in_name, int tag, tpexpr* type) {
92         return add(in_name, in_name, tag, type);
93     }
search_cur(token * t)94     static symbol* search_cur(token* t) { return curr_b_ring->search(t); }
add_cur(token * t,int tag,tpexpr * type)95     static symbol* add_cur(token* t, int tag, tpexpr* type) {
96         return
97           curr_b_ring->add(t->name,
98 			   (strcmp(t->name->text, t->out_text) == 0)
99 			    ? t->name : nm_entry::add(t->out_text, TKN_IDENT),
100 			   tag, type);
101     }
add_cur(nm_entry * in_nm,nm_entry * out_nm,int tag,tpexpr * type)102     static symbol* add_cur(nm_entry* in_nm, nm_entry* out_nm,
103 			   int tag, tpexpr* type)
104       { return curr_b_ring->add(in_nm, out_nm, tag, type); }
105 
add_cur(nm_entry * nm,int tag,tpexpr * type)106     static symbol* add_cur(nm_entry* nm, int tag, tpexpr* type)
107       { return curr_b_ring->add(nm, tag, type); }
108 
109     bool find_scope(b_ring* type);
110 
111     void make_unique(symbol* s);
112     void make_vars_static();
113 };
114 
115 class rename_item {
116   protected:
117     static rename_item* list;
118 
119     rename_item* next;
120     nm_entry*    nm_old;
121     nm_entry*    nm_new;
122 
123   public:
add(nm_entry * nm_new,nm_entry * nm_old)124     static void add(nm_entry *nm_new, nm_entry *nm_old) {
125 	rename_item* item = new rename_item;
126 	item->nm_new = nm_new;
127 	item->nm_old = nm_old;
128 	item->next = list;
129 	list = item;
130     }
rename(nm_entry * name)131     static nm_entry* rename(nm_entry* name) {
132 	for (rename_item *item = list; item != NULL; item = item->next) {
133 	    if (item->nm_old == name) return item->nm_new;
134 	}
135 	return name;
136     }
137 };
138 
139 #endif
140