/*
 * PUBLIC DOMAIN PCCTS-BASED C++ GRAMMAR (cplusplus.g, stat.g, expr.g)
 *
 * Authors: Sumana Srinivasan, NeXT Inc.;            sumana_srinivasan@next.com
 *          Terence Parr, Parr Research Corporation; parrt@parr-research.com
 *          Russell Quong, Purdue University;        quong@ecn.purdue.edu
 *
 * VERSION 1.1
 *
 * SOFTWARE RIGHTS
 *
 * This file is a part of the ANTLR-based C++ grammar and is free
 * software.  We do not reserve any LEGAL rights to its use or
 * distribution, but you may NOT claim ownership or authorship of this
 * grammar or support code.  An individual or company may otherwise do
 * whatever they wish with the grammar distributed herewith including the
 * incorporation of the grammar or the output generated by ANTLR into
 * commerical software.  You may redistribute in source or binary form
 * without payment of royalties to us as long as this header remains
 * in all source distributions.
 *
 * We encourage users to develop parsers/tools using this grammar.
 * In return, we ask that credit is given to us for developing this
 * grammar.  By "credit", we mean that if you incorporate our grammar or
 * the generated code into one of your programs (commercial product,
 * research project, or otherwise) that you acknowledge this fact in the
 * documentation, research report, etc....  In addition, you should say nice
 * things about us at every opportunity.
 *
 * As long as these guidelines are kept, we expect to continue enhancing
 * this grammar.  Feel free to send us enhancements, fixes, bug reports,
 * suggestions, or general words of encouragement at parrt@parr-research.com.
 *
 * NeXT Computer Inc.
 * 900 Chesapeake Dr.
 * Redwood City, CA 94555
 * 12/02/1994
 *
 * Restructured for public consumption by Terence Parr late February, 1995.
 *
 * Requires PCCTS 1.32b4 or higher to get past ANTLR.
 *
 * DISCLAIMER: we make no guarantees that this grammar works, makes sense,
 *             or can be used to do anything useful.
 */
/* 1999-2004 Version 3.0 July 2004
 * Modified by David Wigg at London South Bank University for CPP_parser.g
 */
/* 2004-2005 Version 3.1 November 2005
 * Modified by David Wigg at London South Bank University for CPP_parser.g
 *
 * See MyReadMe.txt for further information
 *
 * This file is best viewed in courier font with tabs set to 4 spaces
 *
 * See NotesScopes.txt for information about storing symbol names within scope
 *levels
 *
 * Symbols names are stored in lists selected by hashing
 *
 * Symbols are also chained in lists for each scope level,
 *	[0] = template scope	Note: Not used at present
 *	[1] = external scope	Note: These symbols (types) are never deleted.
 *"std" is allocated this scope in CPPParser::init()
 *	[2+]= function/variable scopes	Note: These symbol references are
 *deleted when they go out of scope.
 */

extern "C" {
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
}
#include "Dictionary.hpp"

/* Hashing function described in                   */
/* "Fast Hashing of Variable-Length Text Strings," */
/* by Peter K. Pearson, CACM, June 1990. */
/* Table from p. 678.*/
/* Pseudorandom Permutation of the Integers 0 through 255: */
unsigned char Dictionary::randomNumbers[] = {
    1,   14,  110, 25,  97,  174, 132, 119, 138, 170, 125, 118, 27,  233, 140,
    51,  87,  197, 177, 107, 234, 169, 56,  68,  30,  7,   173, 73,  188, 40,
    36,  65,  49,  213, 104, 190, 57,  211, 148, 223, 48,  115, 15,  2,   67,
    186, 210, 28,  12,  181, 103, 70,  22,  58,  75,  78,  183, 167, 238, 157,
    124, 147, 172, 144, 176, 161, 141, 86,  60,  66,  128, 83,  156, 241, 79,
    46,  168, 198, 41,  254, 178, 85,  253, 237, 250, 154, 133, 88,  35,  206,
    95,  116, 252, 192, 54,  221, 102, 218, 255, 240, 82,  106, 158, 201, 61,
    3,   89,  9,   42,  155, 159, 93,  166, 80,  50,  34,  175, 195, 100, 99,
    26,  150, 16,  145, 4,   33,  8,   189, 121, 64,  77,  72,  208, 245, 130,
    122, 143, 55,  105, 134, 29,  164, 185, 194, 193, 239, 101, 242, 5,   171,
    126, 11,  74,  59,  137, 228, 108, 191, 232, 139, 6,   24,  81,  20,  127,
    17,  91,  92,  251, 151, 225, 207, 21,  98,  113, 112, 84,  226, 18,  214,
    199, 187, 13,  32,  94,  220, 224, 212, 247, 204, 196, 43,  249, 236, 45,
    244, 111, 182, 153, 136, 129, 90,  217, 202, 19,  165, 231, 71,  230, 142,
    96,  227, 62,  179, 246, 114, 162, 53,  160, 215, 205, 180, 47,  109, 44,
    38,  31,  149, 135, 0,   216, 52,  63,  23,  37,  69,  39,  117, 146, 184,
    163, 200, 222, 235, 248, 243, 219, 10,  152, 131, 123, 229, 203, 76,  120,
    209};

char *Dictionary::strings = NULL;
char *Dictionary::strp = NULL;
unsigned Dictionary::strsize = 0;

Dictionary::Dictionary(int nb, int ns, int nc) {
  int i;

  // allocate buckets for names
  bucket = new DictEntry *[nb];
  if (bucket == NULL) panic((const char *)"can't alloc buckets");

  // Initialize buckets for names
  nbuckets = nb;
  for (i = 0; i < nb; i++) bucket[i] = NULL;

  // allocate a scope list for the start of each scope list
  scope = new DictEntry *[ns];
  if (scope == NULL) panic("can't alloc scopes");

  // allocate an endScope list for the end of each scope list
  endScope = new DictEntry *[ns];
  if (endScope == NULL) panic("can't alloc endScope");

  // Initialize scopes and endscopes
  nscopes = ns;
  for (i = 0; i < ns; i++) {
    scope[i] = NULL;
    endScope[i] = NULL;
  }

  currentScope = 0;

  strsize = nc;
  strings = new char[nc];
  strp = strings;
}

Dictionary::~Dictionary() {
  delete[] bucket;
  delete[] scope;
  delete[] endScope;
  nbuckets = nscopes = 0;
  currentScope = -1;
}

/* Hashing function described in                   */
/* "Fast Hashing of Variable-Length Text Strings," */
/* by Peter K. Pearson, CACM, June 1990.           */
int Dictionary::hash(const char *string) {
  int hash1 = 0;
  int hash2 = 0;
  int length = 0;
  int r = 0;

  while (*string != 0) {
    length++;
    /* Hash function is XOR of successive characters randomized by
     * the hash table.
     */
    hash1 ^= randomNumbers[static_cast<int>(*string++)];
    if (*string != 0) hash2 ^= randomNumbers[static_cast<int>(*string++)];
  }
  r = (hash1 << 8) | hash2;
  return r;
}

/* Return ptr to 1st entry found in table under key
 * (return NULL if none found).
 */
DictEntry *Dictionary::lookup(const char *key, CPPSymbol::ObjectType tp) {
  // tp is type to be looked for
  // Default, 0, is to look for any symbol irrespective of type
  // Each new DictEntry is stored at start of its list so most
  // recent additions are reached first
  // DictEntry *q;
  CPPSymbol *q;
  // int scope = getCurrentScopeIndex();
  // if(sc != -1)
  //		scope = sc;

  int h = hash(key) % nbuckets;
  q = (CPPSymbol *)bucket[h];

  for (; q != NULL; q = (CPPSymbol *)q->getNext()) {
    // printf("Dictionary.cpp lookup symbol %s in scope %d current scope %d\n",
    //	q->getKey(),q->this_scope,getCurrentScopeIndex());
    if (h != q->getHashCode()) {
      fprintf(stderr,
              "dictionary.cpp lookup, h not equal to q->getHashCode() for %s\n",
              key);
    }

    if (h == q->getHashCode() && strcmp(key, q->getKey()) == 0) {
      if (tp == 0) {  // Search for first matching symbol
        return q;
      } else {
        CPPSymbol::ObjectType type = q->getType();
        if (tp == CPPSymbol::otTypename)  // Search for first type name
        {
          if (type == CPPSymbol::otTypedef || type == CPPSymbol::otEnum ||
              type == CPPSymbol::otClass || type == CPPSymbol::otStruct ||
              type == CPPSymbol::otUnion) {
            return q;
          }
        } else if (tp ==
                   CPPSymbol::otNonTypename)  // Search for first non type name
        {
          if (type == CPPSymbol::otVariable || type == CPPSymbol::otFunction) {
            return q;
          }
        } else if (type == tp) {  // Search for first symbol with specific type
          return q;
        } else {
          return NULL;
        }
      }
    }
  }
  return NULL;
}

void Dictionary::define(const char *key, DictEntry *entry) {
  defineInScope(key, entry, currentScope);
}

void Dictionary::defineInScope(const char *key, DictEntry *entry, int sc) {
  int h = hash(key) % nbuckets;  // July 2005, nbuckets = 4001 See CPP_parser.g
  // printf("Dictionary.cpp defineInScope key %s hash(key) %d bucket %d scope
  // %d\n",
  //	key,hash(key),h,sc);
  entry->this_scope = sc;
  entry->setKey(strdup(key));  // Make a local copy of key
  entry->setHashCode(h);
  entry->setNext(bucket[h]);  // Set next pointer to current entry in bucket
  bucket[h] = entry;          // Replace current entry in bucket
  if (endScope[sc] == NULL) {
    scope[sc] = endScope[sc] = entry;
  } else {
    endScope[sc]->setScope(entry);
    endScope[sc] = entry;
  }
}

int Dictionary::getCurrentScopeIndex() { return currentScope; }

DictEntry *Dictionary::getCurrentScope() {
  if (currentScope < 0 || currentScope > nscopes) {
    panic("getCurrentScope: no scope");
  }
  return scope[currentScope];
}

void Dictionary::saveScope() {
  // Advance scope number (for included scope)
  if (currentScope < nscopes) currentScope++;
  /*
  if ( currentScope>=nscopes )
    panic( "saveScope: overflow" );
  */
  // printf("Dictionary saveScope entered. Scope now %d\n",currentScope);
}

void Dictionary::restoreScope() {
  // Reduce scope number for next highest scope
  // if ( currentScope==0 )
  //  panic( "restoreScope: underflow" );
  if (currentScope > 0) currentScope--;
  // printf("Dictionary restoreScope entered. Scope now %d\n",currentScope);
}

/*	This unlinks all entries from the Dictionary that are members
 *	of the current scope.  The scope level is not restored to the previous
 *	scope however. This requires use of restoreScope() above
 */
DictEntry *Dictionary::removeScope(int sc) {
  DictEntry *de, *r;
  if (sc == -1) {  // removeScope() without parameter value defaults sc to -1
    sc = currentScope;
  }
  for (de = scope[sc]; de != NULL; de = de->getNextInScope()) {
    remove(de);
  }
  r = scope[sc];
  scope[sc] = endScope[sc] = NULL;
  return r;
}

//	Remove this dictEntry from its bucket by unlinking it
DictEntry *Dictionary::remove(DictEntry *de) {
  DictEntry *prev, *curr;
  if (de == NULL) panic("Dictionary.cpp remove: NULL ptr");
  int h = hash(de->getKey()) % nbuckets;  // Find pointer to bucket
  for (prev = NULL, curr = bucket[h]; curr != NULL;
       prev = curr, curr = curr->getNext()) {
    if (de == curr) {
      if (prev == NULL) {
        bucket[h] = de->getNext();
      } else {
        prev->setNext(de->getNext());
      }
      de->setNext(NULL);
      return de;
    }
  }
  return NULL;  // should never get here...
}

/*	Lookup the object referred to by 'key' and then physically remove
 *	it from the Dictionary.  Return the object referred to by the key.
 *	If more than one definition is found for 'key', then only the
 *	first one is removed.  Return NULL if not found.
 *  Note: DW 12/06/03 Probably not used
 */
DictEntry *Dictionary::remove(char *key) {
  DictEntry *q, *prev;

  int h = hash(key) % nbuckets;
  for (prev = NULL, q = bucket[h]; q != NULL; prev = q, q = q->getNext()) {
    if (h == q->getHashCode() && strcmp(key, q->getKey()) == 0) {
      if (prev == NULL) {
        bucket[h] = q->getNext();
      } else {
        prev->setNext(q->getNext());
      }
      q->setNext(NULL);
      return q;
    }
  }
  return NULL;  // should never get here, but make compiler happy
}

void Dictionary::dumpScope(FILE *f, int sc) {
  DictEntry *s;

  if (sc == -1) {  // dumpScope() without parameter value defaults sc to -1
    sc = currentScope;
  }
  for (s = scope[sc]; s != NULL; s = s->getNextInScope()) {
    dumpSymbol(f, s);
  }
}

// This is overridden in CPPDictionary.hpp
void Dictionary::dumpSymbol(FILE *f, DictEntry *de) {
  fprintf(f, "%s\n", de->getKey());
}

// Diagnostic function
// Contents of first 10 scopes printed
void Dictionary::dumpScopes() {
  DictEntry *dictEntry;
  int i;

  printf("Scopes");
  for (i = 0; i < 10; i++) {
    printf("     %d     ", i);
  }
  printf("\n");
  printf(" first");
  for (i = 0; i < 10; i++) {
    if (scope[i] != NULL) {
      dictEntry = scope[i];
      printf("%10s ", dictEntry->getKey());
    } else {
      printf("           ");
    }
  }
  printf("\n");
  printf(" last ");
  for (i = 0; i < 10; i++) {
    if (endScope[i] != NULL) {
      dictEntry = endScope[i];
      printf("%10s ", dictEntry->getKey());
    } else {
      printf("           ");
    }
  }
  printf("\n");
}

/* Add a string to the string table and return a pointer to it.
 * Bump the pointer into the string table to next avail position.
 */
char *Dictionary::strdup(const char *s) {
  char *start = strp;
  if (s == NULL) panic("strdup: NULL string");
  if (start + strlen(s) + 1 > &(strings[strsize - 2])) {
    panic("string table overflow");
  }
  while (*s != '\0') {
    *strp++ = *s++;
  }
  *strp++ = '\0';
  return start;
}

void Dictionary::panic(const char *err) {
  fprintf(stdout, "Dictionary panic: %s\n", err);
  exit(-1);
}
