|
|
1.1 root 1: # include <stdio.h>
2: # include "constants.h"
3: # include "globals.h"
4: # include <sccs.h>
5:
6: SCCSID(@(#)cvar.c 8.1 12/31/84)
7:
8: /*
9: ** CVAR -- routines to manipulate the c variable trees
10: **
11: ** C variable trees are binary trees of cvar structs,
12: ** with the c_left < c_right with respect to c_id.
13: */
14: /*
15: ** DECL_CVAR -- Declare a C variable
16: **
17: ** Parameters:
18: ** name -- identifier string (makes its own copy for the tree)
19: ** type
20: ** indir_level -- level of indirection of declaration
21: ** (- 1 if string)
22: ** block_level -- 0 - global, else local var
23: **
24: ** Returns:
25: ** none
26: **
27: ** Side Effects:
28: ** allocates a cvar node, and a copy of name, may put a node
29: ** in a cvar tree (if not previously declared).
30: **
31: ** Called By:
32: ** the c_variable productions of the parser [grammar.y]
33: */
34:
35:
36: decl_cvar(name, type, indir_level, block_level)
37: char *name;
38: int type;
39: int indir_level;
40: int block_level;
41: {
42: register struct cvar *bad_node;
43: struct cvar *dec_var();
44:
45: if (bad_node = dec_var(name, type, indir_level, block_level,
46: &C_locals, &C_globals))
47: {
48: yysemerr("re-declared identifier", bad_node->c_id);
49: xfree(bad_node->c_id);
50: xfree(bad_node);
51: }
52: }
53:
54: /*
55: ** DECL_FIELD -- Declare a structures field
56: **
57: ** Same as decl_cvar() for fields within C records (structs).
58: ** NOTE : if a !0 is returned from dec_var() (i.e. the field
59: ** was already declared) the storage for that node is freed
60: ** but no error has been comitted, as fields may be re-declared.
61: */
62:
63: decl_field(name, type, indir_level, block_level)
64: char *name;
65: int type;
66: int indir_level;
67: int block_level;
68: {
69: register struct cvar *bad_node;
70: struct cvar *dec_var();
71:
72: if (bad_node = dec_var(name, type, indir_level, block_level,
73: &F_locals, &F_globals))
74: {
75: xfree(bad_node->c_id);
76: xfree(bad_node);
77: }
78: }
79: /*
80: ** DEC_VAR -- declare a C var or field.
81: **
82: ** Parameters:
83: ** same as decl_cvar() & decl_field plus
84: ** the local and global tree variables.
85: **
86: ** Returns:
87: ** 0 -- successful
88: ** other -- cvar node pointer that couldn't be entered
89: ** to tree
90: */
91:
92: struct cvar *
93: dec_var(name, type, indir_level, block_level, local_tree, global_tree)
94: char *name;
95: int type, indir_level, block_level;
96: struct cvar **local_tree, **global_tree;
97: {
98: register struct cvar *cvarp;
99: register i;
100: char *salloc();
101:
102: cvarp = (struct cvar *)nalloc(sizeof *cvarp);
103: if (!cvarp)
104: {
105: yysemerr("unable to allocate space for a variable", name);
106: return (0);
107: }
108: if (!(cvarp->c_id = salloc(name)))
109: {
110: yysemerr("no space for variable name", name);
111: xfree(cvarp);
112: return (0);
113: }
114: cvarp->c_type = type;
115: cvarp->c_indir = indir_level;
116: cvarp->c_left = cvarp->c_right = 0;
117: i = c_enter(cvarp, block_level > 0 ? local_tree : global_tree);
118: return (i ? 0 : cvarp);
119: }
120: /*
121: ** C_ENTER -- Enter a cvar node in a cvar tree
122: **
123: ** Parameters:
124: ** node -- the cvar node to insert
125: ** root -- a pointer to the root pointer
126: **
127: ** Returns:
128: ** 1 -- if successful
129: ** 0 -- otherwise (node of same name existed
130: **
131: ** Side Effects:
132: ** If a node of that name didn't exist one is inserted
133: **
134: ** Called By:
135: ** dec_var()
136: */
137:
138: c_enter(node, root)
139: struct cvar *node;
140: struct cvar **root;
141: {
142: register char *name;
143: register struct cvar *n, *r;
144:
145: r = *root;
146: n = node;
147: name = n->c_id;
148: if (!r)
149: {
150: *root = n;
151: return (1);
152: }
153: for (;;)
154: {
155: switch (scompare(name, 0, r->c_id, 0))
156: {
157:
158: case -1 :
159: if (!r->c_left)
160: {
161: r->c_left = n;
162: return (1);
163: }
164: r = r->c_left;
165: break;
166:
167: case 0 :
168: yysemerr("identifier re-declared", name);
169: xfree(name);
170: xfree(n);
171: return (0);
172:
173: case 1 :
174: if (!r->c_right)
175: {
176: r->c_right = n;
177: return (1);
178: }
179: r = r->c_right;
180: break;
181: }
182: }
183: }
184:
185:
186: /*
187: ** GET_VAR -- get a cvar node from a local_tree, global_tree pair
188: ** searching first through the local then the global.
189: **
190: ** Parameters:
191: ** id -- c_id key
192: ** local_tree -- first tree
193: ** global_tree -- secomd tree to search
194: **
195: ** Returns:
196: ** 0 -- if no node by that name
197: ** otherwise -- pointer to the node
198: */
199:
200:
201: struct cvar *get_var(id, local_tree, global_tree)
202: char *id;
203: struct cvar *local_tree, *global_tree;
204: {
205: register char *name;
206: register struct cvar *tree, *node;
207: char flag;
208:
209: flag = 0;
210: name = id;
211: tree = local_tree;
212: for ( ; ; )
213: {
214: for (node = tree; node; )
215: {
216: switch (scompare(name, 0, node->c_id, 0))
217: {
218:
219: case -1 :
220: if (!node->c_left)
221: break;
222: else
223: node = node->c_left;
224: continue;
225:
226: case 0 :
227: return (node);
228:
229: case 1 :
230: if (!node->c_right)
231: break;
232: else
233: node = node->c_right;
234: continue;
235: }
236: break;
237: }
238: if (!flag)
239: {
240: flag += 1;
241: tree = global_tree;
242: }
243: else
244: return (0);
245: }
246: }
247: /*
248: ** GETCVAR -- get the cvar node for a given identifier
249: ** Looks first in C_locals, then in C_globals.
250: **
251: ** Parameters:
252: ** id -- name of cvar to look for
253: **
254: ** Returns:
255: ** adress of cvar node if found
256: ** 0 -- otherwise
257: **
258: ** Requires:
259: ** C_locals & C_globals -- to search them
260: */
261:
262: struct cvar *
263: getcvar(id)
264: char *id;
265: {
266: return (get_var(id, C_locals, C_globals));
267: }
268:
269: /*
270: ** GETFIELD -- Same as getcvar() for structure fields
271: */
272:
273: struct cvar *
274: getfield(id)
275: char *id;
276: {
277: return (get_var(id, F_locals, F_globals));
278: }
279:
280:
281: /*
282: ** FREECVAR & F_CVAR -- Free up storage in a cvar tree
283: **
284: ** Freecvar calls f_cvar to free storage for a tree, then
285: ** 0's out the root pointer passed it.
286: */
287:
288: freecvar(rootp)
289: struct cvar **rootp;
290: {
291: f_cvar(*rootp);
292: *rootp = 0;
293: }
294:
295: f_cvar(root)
296: struct cvar *root;
297: {
298: if (root)
299: {
300: f_cvar(root->c_left);
301: f_cvar(root->c_right);
302: xfree(root->c_id);
303: xfree(root);
304: }
305: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.