int current_scope = -1; // -1 is global scope

// given that C has four scopes: function, file, block, and function prototype - it's
// quite probably that this scheme is insufficient for true C.  Seems to work for my
// cut down version though.

#define BLOCK_EXTERNALS 0
#define BLOCK_PROCFN 1
#define BLOCK_COMPOUND 2
#define BLOCK_LOOP 3
#define BLOCK_IF 4
#define BLOCK_CASE 5

void push_scope(int here) // 'here' is an AST_Scope(block, parent block, type)
{
  current_scope = here;
}

void pop_scope(void) {
  current_scope = rightchild(current_scope);
}

// build a set of links back through each AST_Scope
void build_block_scope(int p, int parent_AST_Scope, int this_blocks_AST_Scope)
{
  int i;
  int disp;
  int this;

  if ((p == -1) || (astop(p) == -1)) return;

  if (astop(p) == AST_Scope) {

    // leftchild = this (following) code block
    // rightchild = AST_Scope of parent block - plugged here...
    // 1st extra field is for type of block

    rightchild(p) = this_blocks_AST_Scope;
    build_block_scope(leftchild(p), this_blocks_AST_Scope /* is now the parent */, p /* is now this_block's AST_Scope */);

  } else {
    // recursively search for more compound-statement blocks (really AST_Scopes) throughout the code:
    disp = op[astop(p)-AST_BASE].Display_Children;
    this = 1<<(children(p)-1);
    for (i = 0; i < children(p); i++) {
      if ((nthchild(p, i) != -1) && (disp&this)) {
        build_block_scope(nthchild(p, i), parent_AST_Scope, this_blocks_AST_Scope);
      }
      this = this>>1;
    }
  }
}
