001    /* Copyright 2000, 2001, Compaq Computer Corporation */
002    
003    package javafe.ast;
004    //@ model import javafe.parser.TagConstants;
005    
006    /** <CODE>_SpecialParserInterface</CODE> is not a class that should be
007    used by general clients of the <CODE>javafe.ast</CODE> package.  It
008    holds a number of routines and constants used by the
009    <CODE>javafe.parser</CODE> package that we want to hide from other,
010    more general clients of <CODE>javafe.ast</CODE>.
011    
012    <CODE>_SpecialParserInterface</CODE> serves two purposes:
013    
014    <UL>
015    
016    <LI> It defines two constants, <CODE>DUMMYLOC</CODE> and
017    <CODE>IDENT</CODE> common to both packages, breaking what would
018    otherwise be a mutual recursion between the two packages.  This lets
019    <CODE>javafe.ast</CODE> be completely independent of
020    <CODE>javafe.parser</CODE>.
021    
022    <P> <LI> It defines a "friend" interface to the
023    <CODE>Identifier</CODE> class, allowing the scanner to have a
024    specialized interface to <CODE>Identifier</CODE> without exposing that
025    interface to more general clients.
026    
027    </UL>
028    
029    <P> The "friend" interface to <CODE>Identifier</CODE> exposed by
030    <CODE>_SpecialParserInterface</CODE> includes a extra integer field of
031    <CODE>Identifier</CODE> objects used to hold token types.  For most
032    instances of <CODE>Identifier</CODE>, this hidden field holds the
033    value <CODE>IDENT</CODE>, the token code for identifiers.  However,
034    for an <CODE>Identifier</CODE> object associated with a keyword, the
035    hidden field holds the token type for the keyword.  During its
036    initialization, the scanner class interns all keywords and uses the
037    <CODE>_SpecialParserInterface.setTokenType</CODE> to write the
038    appropriate token-type values into the hidden fields of the resulting
039    <CODE>Identifier</CODE> objects.  Note that no synchronization is done
040    by <CODE>_SpecialParserInterface</CODE> when reading and writing these
041    fields.
042    
043    */
044    
045    
046    public abstract class _SpecialParserInterface {
047    
048        /**
049         * Return the hidden "token type" field of <CODE>id</CODE>.
050         *
051         * The token code will be one that does not require a
052         * non-null auxVal (cf. Token.auxVal).
053         */
054        //@ ensures \result != TagConstants.BOOLEANLIT;
055        //@ ensures \result != TagConstants.INTLIT;
056        //@ ensures \result != TagConstants.LONGLIT;
057        //@ ensures \result != TagConstants.FLOATLIT;
058        //@ ensures \result != TagConstants.DOUBLELIT;
059        //@ ensures \result != TagConstants.STRINGLIT;
060        //@ ensures \result != TagConstants.CHARLIT;
061        //@ ensures \result != TagConstants.LEXICALPRAGMA;
062        //@ ensures \result != TagConstants.MODIFIERPRAGMA;
063        //@ ensures \result != TagConstants.STMTPRAGMA;
064        //@ ensures \result != TagConstants.TYPEDECLELEMPRAGMA;
065        //@ ensures \result != TagConstants.TYPEMODIFIERPRAGMA;
066        public static int getTokenType(/*@ non_null @*/ Identifier id) {
067            return id.tokenType;
068        }
069    
070    
071        /**
072         * Set the hidden "token type" field of <CODE>id</CODE>.
073         *
074         * The token code must be one that does not require a
075         * non-null auxVal (cf. Token.auxVal).
076         */
077        //@ requires tokenType != TagConstants.BOOLEANLIT;
078        //@ requires tokenType != TagConstants.INTLIT;
079        //@ requires tokenType != TagConstants.LONGLIT;
080        //@ requires tokenType != TagConstants.FLOATLIT;
081        //@ requires tokenType != TagConstants.DOUBLELIT;
082        //@ requires tokenType != TagConstants.STRINGLIT;
083        //@ requires tokenType != TagConstants.CHARLIT;
084        //@ requires tokenType != TagConstants.LEXICALPRAGMA;
085        //@ requires tokenType != TagConstants.MODIFIERPRAGMA;
086        //@ requires tokenType != TagConstants.STMTPRAGMA;
087        //@ requires tokenType != TagConstants.TYPEDECLELEMPRAGMA;
088        //@ requires tokenType != TagConstants.TYPEMODIFIERPRAGMA;
089        public static void setTokenType(/*@ non_null @*/ Identifier id,
090                                        int tokenType) {
091            id.tokenType = tokenType;
092        }
093    
094    
095      /** Intern a sequence of characters with a pre-computed hashcode.
096    
097        <BR> Requires: <CODE>hashcode = hash(text, textlen)</CODE> 
098    
099        <P> Ensures: returns the <CODE>Identifier</CODE> instance
100        associated with the symbol consisting of the first
101        <CODE>textlen</CODE> characters of <CODE>text</CODE>. */
102    
103      //@ requires text != null;
104      //@ requires 0 <= textlen && textlen <= text.length;
105      //@ ensures \result != null;
106      public static Identifier intern(char[] text, int textlen, int hashcode) {
107        return Identifier.intern(text, textlen, hashcode);
108      }
109    
110      /** Constant used for hashing.  The hash function used to hash a
111        <i>n</i>-character identifier <code>idn</code> is to sum
112        <code>HC</code>^<i>(n-(i+1))</i><code>*idn[</code><i>i</i><code>]</code>.
113        Note that this is the same hash function used by Java 1.1 for
114        hashing <code>String</code> objects.  */
115      public static final int HC = Identifier.HC;
116    
117      /** Return the hash code used by <CODE>Identifier</CODE> for a given
118        sequence of characters. */
119    
120      //@ requires text != null;
121      //@ requires 0 <= textlen && textlen < text.length;
122      public static int hash(char[] text, int textlen)
123      { return Identifier.hash(text, textlen); }
124    }