/*
 * This function creates a hashtable and then appropriately attaches it to its parent,
 * whose identifier is given to us in the form of its identifier (parent_lvl, parent_sibno)
 */
  symhashtable_t *make_insert_hashtable(symhashtable_t  *root, int lvl, int sibno, int parent_lvl, int parent_sibno) {
    symhashtable_t *hashtable, *parent_hashtable, *temp;

    hashtable = create_symhashtable(HASHSIZE);
    assert(hashtable != NULL);

    parent_hashtable = find_hashtable(root, parent_lvl, parent_sibno);  //parent must have been created
    assert(parent_hashtable != NULL);

    // Fill the appropriate values for our hash table.
    hashtable->parent = parent_hashtable;
    hashtable->level = lvl;
    hashtable->sibno = sibno;

    //insert as rightmost child of parent
    if(parent_hashtable->child != NULL) {
      for(temp = parent_hashtable->child ; temp->rightsib != NULL; temp = temp->rightsib) {
        ;}
        temp->rightsib = hashtable;
    }
    else {
      parent_hashtable->child = hashtable;
    }

    return hashtable;
  }
/* Create an empty symbol table. */
 symboltable_t  *create_symboltable() {
  symboltable_t *symtab = calloc(sizeof(symboltable_t),1);
  assert(symtab);

  symhashtable_t *hashtable=create_symhashtable(HASHSIZE);
  assert(hashtable != NULL);
  hashtable->level = 0;
  hashtable->name = "0";

  symhashtable_t *collection = create_symhashtable(HASHSIZE);
  assert(collection != NULL);
  symtab->literal_collection = collection;

  symtab->root = hashtable;
  symtab->leaf = hashtable;
  return symtab;
}
/* Create an empty symbol table. */
symboltable_t *create_symboltable() {
  symboltable_t *symtab = calloc(1, sizeof(symboltable_t));
  assert(symtab);

  symhashtable_t *hashtable=create_symhashtable(HASHSIZE);
  hashtable->level = 0;
  hashtable->name = "0";

  symtab->root = hashtable;
  symtab->leaf = hashtable;
  return symtab;
}
/* 
 * Enter a new scope. 
 * Creates a new symhashtable at the next level and appropriate place.
 *
 */
void enter_scope(symboltable_t *symtab, ast_node definer) {
  assert(symtab);
  assert(symtab->leaf);

  symhashtable_t *curr = symtab->leaf;
  symhashtable_t *next = create_symhashtable(HASHSIZE); 
  symhashtable_t *it;

  int sibno = 0;

  levels[curr->level]++;

  // Set up the symhashtable with the correct basic values
  next->name = create_name(); // WRITE THE NAMING PROTOCOL
  next->level = curr->level + 1;
  next->declaring_func = definer;

  // Create a new symhashtable at the right place
  if (symtab->leaf->child) {
    it = symtab->leaf->child;
    sibno++;
    
    // Iterate until you find the rightmost child
    while (it->rightsib) {
      it = it->rightsib;
      sibno++;
    }
    
    // Set the new symhashtable as the rightmost child
    it->rightsib = next;
    next->sibno = sibno;
  } else {
    symtab->leaf->child = next;
    next->sibno = sibno;
  }

  // Set links for new node
  next->parent = symtab->leaf;
  next->child = NULL;
  next->rightsib = NULL;

  // Update the symboltable's leaf value
  symtab->leaf = next;

}