001    // -*- mode: java -*-
002    /* Copyright 2000, 2001, Compaq Computer Corporation */
003    
004    /* IF THIS IS A JAVA FILE, DO NOT EDIT IT!  
005    
006       Most Java files in this directory which are part of the Javafe AST
007       are automatically generated using the astgen comment (see
008       ESCTools/Javafe/astgen) from the input file 'hierarchy.h'.  If you
009       wish to modify AST classes or introduce new ones, modify
010       'hierarchy.j.'
011     */
012    
013    package javafe.ast;
014    
015    import javafe.util.Assert;
016    import javafe.util.Location;
017    import javafe.util.ErrorSet;
018    
019    // Convention: unless otherwise noted, integer fields named "loc" refer
020    // to the location of the first character of the syntactic unit
021    
022    
023    /**
024     * Represents a Literal.
025     *
026     * <p> The tag of a LiteralExpr should be one of the *LIT (eg INTLIT)
027     * constants defined in TagConstants.  The value fields is a
028     * Character/String/Long/Double/Boolean/null, as appropriate.
029     */
030    
031    public class LiteralExpr extends Expr
032    {
033      //@ invariant isValidTag(tag);
034      public int tag;
035    
036    
037      //@ invariant isValidValue(tag, value);
038      public Object value;
039    
040    
041      final
042      public int loc;
043    
044      public final int getTag() { return this.tag; }
045    
046      private void postCheck() {
047        Assert.notFalse(isValidTag(tag));
048        Assert.notFalse(isValidValue(tag, value));
049      }
050      //@ public represents startLoc <- loc;
051      public /*@ pure @*/ int getStartLoc() { return loc; }
052      //@ also public normal_behavior
053      //@ ensures \result == loc;
054      public /*@ pure @*/ int getEndLoc() { return loc; }
055    
056      static public LiteralExpr cast(LiteralExpr lit, int t) {
057            if (!(lit.value instanceof Number)) return lit;
058            Number num = (Number)lit.value;
059            if (t == TagConstants.BYTELIT) {
060                return LiteralExpr.make(t,new Integer(num.byteValue()),lit.getStartLoc());
061            } else if (t == TagConstants.SHORTLIT) {
062                return LiteralExpr.make(t,new Short(num.shortValue()),lit.getStartLoc());
063            } else if (t == TagConstants.INTLIT) {
064                return LiteralExpr.make(t,new Integer(num.intValue()),lit.getStartLoc());
065            } else if (t == TagConstants.LONGLIT) {
066                return LiteralExpr.make(t,new Long(num.longValue()),lit.getStartLoc());
067            } else if (t == TagConstants.FLOATLIT) {
068                return LiteralExpr.make(t,new Float(num.floatValue()),lit.getStartLoc());
069            } else if (t == TagConstants.DOUBLELIT) {
070                return LiteralExpr.make(t,new Double(num.doubleValue()),lit.getStartLoc());
071            } else return lit;
072            // FIXME - what about casts to character values ???
073      }
074    
075      // Note: Java does not actually have byte and short literals.
076      // We include them here because we pre-compute literals that have been
077      // cast to other types, e.g. (short)0, as a literal of the target type
078      // FIXME - short and byte are included for completeness, but I'm not sure they actually ever get used that way
079    
080         /*@ ensures \result <==> tag==TagConstants.NULLLIT    ||
081           @                      tag==TagConstants.BOOLEANLIT ||
082           @                      tag==TagConstants.BYTELIT    ||
083           @                      tag==TagConstants.SHORTLIT   ||
084           @                      tag==TagConstants.CHARLIT    ||
085           @                      tag==TagConstants.INTLIT     ||
086           @                      tag==TagConstants.LONGLIT    ||
087           @                      tag==TagConstants.FLOATLIT   ||
088           @                      tag==TagConstants.DOUBLELIT  ||
089           @                      tag==TagConstants.STRINGLIT;
090           @*/
091          public static boolean isValidTag(int tag)
092          {
093              return tag==TagConstants.NULLLIT    ||
094                     tag==TagConstants.BOOLEANLIT ||
095                     tag==TagConstants.BYTELIT    ||
096                     tag==TagConstants.SHORTLIT   ||
097                     tag==TagConstants.CHARLIT    ||
098                     tag==TagConstants.INTLIT     ||
099                     tag==TagConstants.LONGLIT    ||
100                     tag==TagConstants.FLOATLIT   ||
101                     tag==TagConstants.DOUBLELIT  ||
102                     tag==TagConstants.STRINGLIT;
103          }
104         /*@ requires isValidTag(tag);
105           @ ensures \result <==> (tag==TagConstants.NULLLIT    ==> value == null) &&
106           @                      (tag==TagConstants.BOOLEANLIT ==> value instanceof Boolean) &&
107           @                      (tag==TagConstants.BYTELIT    ==> value instanceof Byte) &&
108           @                      (tag==TagConstants.SHORTLIT   ==> value instanceof Short) &&
109           @                      (tag==TagConstants.CHARLIT    ==> value instanceof Integer) &&
110           @                      (tag==TagConstants.INTLIT     ==> value instanceof Integer) &&
111           @                      (tag==TagConstants.LONGLIT    ==> value instanceof Long) &&
112           @                      (tag==TagConstants.FLOATLIT   ==> value instanceof Float) &&
113           @                      (tag==TagConstants.DOUBLELIT  ==> value instanceof Double) &&
114           @                      (tag==TagConstants.STRINGLIT  ==> value instanceof String);
115           @*/
116          public static boolean isValidValue(int tag, Object value)
117          {
118              if (tag == TagConstants.NULLLIT)    return value == null;
119              if (tag == TagConstants.BOOLEANLIT) return value instanceof Boolean;
120              if (tag == TagConstants.BYTELIT)    return value instanceof Byte;
121              if (tag == TagConstants.SHORTLIT)   return value instanceof Short;
122              if (tag == TagConstants.CHARLIT)    return value instanceof Integer;
123              if (tag == TagConstants.INTLIT)     return value instanceof Integer;
124              if (tag == TagConstants.LONGLIT)    return value instanceof Long;
125              if (tag == TagConstants.FLOATLIT)   return value instanceof Float;
126              if (tag == TagConstants.DOUBLELIT)  return value instanceof Double;
127              if (tag == TagConstants.STRINGLIT)  return value instanceof String;
128              return false; //should be unreachable
129          } 
130    
131      //@ requires isValidTag(tag);
132      //@ requires isValidValue(tag, value);
133      //@ requires loc != javafe.util.Location.NULL;
134      public static /*@non_null*/ LiteralExpr make(int tag, Object value, int loc) {
135         LiteralExpr result = new LiteralExpr(tag,value,loc);
136         return result;
137      }
138    
139      //@ requires isValidTag(tag);
140      //@ requires isValidValue(tag, value);
141      public static /*@non_null*/ LiteralExpr makeNonSyntax(int tag, Object value) {
142         LiteralExpr result = new LiteralExpr(tag,value,Location.NULL);
143         return result;
144      }
145    
146      public /*@ non_null @*/ String getInfoNewTree(){
147              return (value==null ? "null" : value.toString());
148      }
149    
150    
151    // Generated boilerplate constructors:
152    
153      //@ ensures this.tag == tag;
154      //@ ensures this.value == value;
155      //@ ensures this.loc == loc;
156      protected LiteralExpr(int tag, Object value, int loc) {
157         super();
158         this.tag = tag;
159         this.value = value;
160         this.loc = loc;
161      }
162    
163    // Generated boilerplate methods:
164    
165      public final int childCount() {
166         return 1;
167      }
168    
169      public final Object childAt(int index) {
170              /*throws IndexOutOfBoundsException*/
171         if (index < 0)
172            throw new IndexOutOfBoundsException("AST child index " + index);
173         int indexPre = index;
174    
175         int sz;
176    
177         if (index == 0) return this.value;
178         else index--;
179    
180         throw new IndexOutOfBoundsException("AST child index " + indexPre);
181      }   //@ nowarn Exception;
182    
183      public final /*@non_null*/String toString() {
184         return "[LiteralExpr"
185            + " tag = " + this.tag
186            + " value = " + this.value
187            + " loc = " + this.loc
188            + "]";
189      }
190    
191      public final void accept(Visitor v) { v.visitLiteralExpr(this); }
192    
193      public final Object accept(VisitorArgResult v, Object o) {return v.visitLiteralExpr(this, o); }
194    
195      public void check() {
196         super.check();
197         postCheck();
198      }
199    
200    }