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: }