|
|
1.1 ! root 1: # include <stdio.h> ! 2: # include "constants.h" ! 3: # include "globals.h" ! 4: # include <sccs.h> ! 5: ! 6: SCCSID(@(#)cvar.c 7.1 2/5/81) ! 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.