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

Defined functions

c_enter defined in line 180; used 1 times
dec_var defined in line 130; used 3 times
decl_cvar defined in line 70; used 1 times
decl_field defined in line 99; used 1 times
f_cvar defined in line 358; used 3 times
freecvar defined in line 351; used 6 times
get_var defined in line 246; used 3 times
getfield defined in line 330; used 2 times
Last modified: 1995-04-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3195
Valid CSS Valid XHTML 1.0 Strict