/*
 * cccc_tok.h
 * definition of the token class interface for the cccc project
 *
 */

#ifndef __CCCC_TOK_H
#define __CCCC_TOK_H

#include <iostream.h>

// before we go into the token header file, the compiler must have seen 
// a definition for enum ANTLRTokenType
// there are three conflicting 'real' definitions, one in use by each parser
// if we have seen one of these, we do not need to worry, otherwise we
// must create a dummy one
// the three definitions are in the files Ctokens.h Jtokens.h and Atokens.h
#if !defined(Ctokens_h) && !defined(Jtokens_h) && !defined(Atokens_h)
enum ANTLRTokenType { DUMMY,DEFINITION };
#endif

#include "AToken.h"
#include "cccc.h"


/*
** the counts to be used - tcLAST must be last to ensure allocation
** of the correct size matrix within ANTLRToken.
** The token count is maintained, but is not used at present.
*/
enum TokenCount { tcCOMLINES, tcCODELINES, tcTOKENS, tcMCCABES_VG, tcLAST };

/*
** the class definition for ANTLRToken
** Note that the name ANTLRToken is required to be either a class or a typedef
** by the PCCTS support code
*/
class ANTLRToken : public ANTLRCommonToken {

  // Lexical counting is done by attaching running counts of each of the
  // interesting features to every token produced by the lexer
  // the parser calculates the counts for a particular region by taking
  // taking the differences of the counts for the first and last tokens
  // in the region's extent.

  // The running count array contains the running total of each count
  static int RunningCount[tcLAST];

  // The pending count array is used to gather counts as patterns are
  // recognized.  These counts are not added to the running count array
  // until after a 'real' token has been created from a pattern.  The 
  // effect of this deferral is to make the counts generated by leading
  // comments appear within the scope of the item which follows.  Deferral
  // does not appear to have any undesirable effects.
  static int PendingCount[tcLAST];

  // nesting levels are used to control resynchronisation
  static int RunningNesting;

  static int numAllocated;
  int CurrentCount[tcLAST];
  int CurrentNesting;
  friend ostream& operator << (ostream&,ANTLRToken&);
  friend class AST;
  friend class DLGLexer;
  void SetCounts();
  void CopyCounts(ANTLRToken& copyTok);
public:
  static int bCodeLine;

  ANTLRToken(ANTLRTokenType t, ANTLRChar *s);
  ANTLRToken(ANTLRToken& copyTok);
  ANTLRToken();
  ANTLRToken& operator=(ANTLRToken& copyTok);
  
  virtual ~ANTLRToken();

  virtual ANTLRAbstractToken *makeToken(
    ANTLRTokenType tt, ANTLRChar *txt, int line
  );

  friend void IncrementCount(TokenCount tc) { 
    DbgMsg(COUNTER,cerr,"Incrementing count ");
    DbgMsg(COUNTER,cerr,tc);
    DbgMsg(COUNTER,cerr,endl);
    PendingCount[tc]++; 
  }

  friend void IncrementNesting() { RunningNesting++; }
  friend void DecrementNesting() { RunningNesting--; }

  int getCount(TokenCount tc) { return CurrentCount[tc]; }
  int getNestingLevel() { return CurrentNesting; }
  void CountToken();
  char *getTokenTypeName();
  static void ZeroCounts() { 
    int i;
    for(i=0;i<tcLAST;i++) { RunningCount[i]=0; } 
    RunningNesting=0; 
  }
};

#define MY_TOK(t) ((ANTLRToken*)(t))
ostream& operator << (ostream&, ANTLRToken&);

extern ANTLRToken currentLexerToken;


#endif

 
