001    /* This file was generated with JastAdd2 (http://jastadd.org) version 2.1.13-12-g880e696 */
002    package org.extendj.ast;
003    
004    import java.util.HashSet;
005    import java.io.File;
006    import java.util.Set;
007    import java.util.Collections;
008    import java.util.Collection;
009    import java.util.ArrayList;
010    import beaver.*;
011    import java.util.*;
012    import java.io.ByteArrayOutputStream;
013    import java.io.PrintStream;
014    import java.lang.reflect.InvocationTargetException;
015    import java.lang.reflect.Method;
016    import org.jastadd.util.*;
017    import java.util.zip.*;
018    import java.io.*;
019    import org.jastadd.util.PrettyPrintable;
020    import org.jastadd.util.PrettyPrinter;
021    import java.io.FileNotFoundException;
022    import java.io.BufferedInputStream;
023    import java.io.DataInputStream;
024    /**
025     * Java double-precision floating point literal.
026     * Can store any value representable as an
027     * IEEE 754 64-bit double-precision floating point number.
028     * @ast node
029     * @declaredat /home/jesper/git/extendj/java7/grammar/Literals.ast:67
030     * @production DoubleLiteral : {@link NumericLiteral};
031    
032     */
033    public class DoubleLiteral extends NumericLiteral implements Cloneable {
034      /**
035       * @aspect TypeCheck
036       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeCheck.jrag:678
037       */
038      public void typeCheck() {
039        if (!isZero() && constant().doubleValue() == 0.0f) {
040          errorf("It is an error for nonzero floating-point %s to round to zero", getLITERAL());
041        }
042        if (constant().doubleValue() == Double.NEGATIVE_INFINITY || constant().doubleValue() == Double.POSITIVE_INFINITY) {
043          errorf("the floating-point literal \"%s\" is too large", getLITERAL());
044        }
045      }
046      /**
047       * @aspect CodeGeneration
048       * @declaredat /home/jesper/git/extendj/java4/backend/CodeGeneration.jrag:130
049       */
050      public static void push(CodeGeneration gen, double value) {
051        if (value == 0) {
052          gen.emit(Bytecode.DCONST_0);
053        } else if (value == 1) {
054          gen.emit(Bytecode.DCONST_1);
055        } else {
056          int index = gen.constantPool().addConstant(value);
057          gen.emit(Bytecode.LDC2_W).add2(index);
058        }
059      }
060      /**
061       * @aspect CodeGeneration
062       * @declaredat /home/jesper/git/extendj/java4/backend/CodeGeneration.jrag:197
063       */
064      public void emitPushConstant(CodeGeneration gen) {
065        DoubleLiteral.push(gen, constant().doubleValue());
066      }
067      /**
068       * @declaredat ASTNode:1
069       */
070      public DoubleLiteral() {
071        super();
072      }
073      /**
074       * Initializes the child array to the correct size.
075       * Initializes List and Opt nta children.
076       * @apilevel internal
077       * @ast method
078       * @declaredat ASTNode:10
079       */
080      public void init$Children() {
081      }
082      /**
083       * @declaredat ASTNode:12
084       */
085      public DoubleLiteral(String p0) {
086        setLITERAL(p0);
087      }
088      /**
089       * @declaredat ASTNode:15
090       */
091      public DoubleLiteral(beaver.Symbol p0) {
092        setLITERAL(p0);
093      }
094      /**
095       * @apilevel low-level
096       * @declaredat ASTNode:21
097       */
098      protected int numChildren() {
099        return 0;
100      }
101      /**
102       * @apilevel internal
103       * @declaredat ASTNode:27
104       */
105      public boolean mayHaveRewrite() {
106        return true;
107      }
108      /**
109       * @apilevel internal
110       * @declaredat ASTNode:33
111       */
112      public void flushAttrCache() {
113        super.flushAttrCache();
114        type_reset();
115        isZero_reset();
116        constant_reset();
117      }
118      /**
119       * @apilevel internal
120       * @declaredat ASTNode:42
121       */
122      public void flushCollectionCache() {
123        super.flushCollectionCache();
124      }
125      /**
126       * @apilevel internal
127       * @declaredat ASTNode:48
128       */
129      public void flushRewriteCache() {
130        super.flushRewriteCache();
131      }
132      /**
133       * @apilevel internal
134       * @declaredat ASTNode:54
135       */
136      public DoubleLiteral clone() throws CloneNotSupportedException {
137        DoubleLiteral node = (DoubleLiteral) super.clone();
138        return node;
139      }
140      /**
141       * @apilevel internal
142       * @declaredat ASTNode:61
143       */
144      public DoubleLiteral copy() {
145        try {
146          DoubleLiteral node = (DoubleLiteral) clone();
147          node.parent = null;
148          if (children != null) {
149            node.children = (ASTNode[]) children.clone();
150          }
151          return node;
152        } catch (CloneNotSupportedException e) {
153          throw new Error("Error: clone not supported for " + getClass().getName());
154        }
155      }
156      /**
157       * Create a deep copy of the AST subtree at this node.
158       * The copy is dangling, i.e. has no parent.
159       * @return dangling copy of the subtree at this node
160       * @apilevel low-level
161       * @deprecated Please use treeCopy or treeCopyNoTransform instead
162       * @declaredat ASTNode:80
163       */
164      @Deprecated
165      public DoubleLiteral fullCopy() {
166        return treeCopyNoTransform();
167      }
168      /**
169       * Create a deep copy of the AST subtree at this node.
170       * The copy is dangling, i.e. has no parent.
171       * @return dangling copy of the subtree at this node
172       * @apilevel low-level
173       * @declaredat ASTNode:90
174       */
175      public DoubleLiteral treeCopyNoTransform() {
176        DoubleLiteral tree = (DoubleLiteral) copy();
177        if (children != null) {
178          for (int i = 0; i < children.length; ++i) {
179            ASTNode child = (ASTNode) children[i];
180            if (child != null) {
181              child = child.treeCopyNoTransform();
182              tree.setChild(child, i);
183            }
184          }
185        }
186        return tree;
187      }
188      /**
189       * Create a deep copy of the AST subtree at this node.
190       * The subtree of this node is traversed to trigger rewrites before copy.
191       * The copy is dangling, i.e. has no parent.
192       * @return dangling copy of the subtree at this node
193       * @apilevel low-level
194       * @declaredat ASTNode:110
195       */
196      public DoubleLiteral treeCopy() {
197        doFullTraversal();
198        return treeCopyNoTransform();
199      }
200      /**
201       * @apilevel internal
202       * @declaredat ASTNode:117
203       */
204      protected boolean is$Equal(ASTNode node) {
205        return super.is$Equal(node) && (tokenString_LITERAL == ((DoubleLiteral)node).tokenString_LITERAL);    
206      }
207      /**
208       * Replaces the lexeme LITERAL.
209       * @param value The new value for the lexeme LITERAL.
210       * @apilevel high-level
211       */
212      public void setLITERAL(String value) {
213        tokenString_LITERAL = value;
214      }
215      /**
216       * JastAdd-internal setter for lexeme LITERAL using the Beaver parser.
217       * @param symbol Symbol containing the new value for the lexeme LITERAL
218       * @apilevel internal
219       */
220      public void setLITERAL(beaver.Symbol symbol) {
221        if (symbol.value != null && !(symbol.value instanceof String))
222        throw new UnsupportedOperationException("setLITERAL is only valid for String lexemes");
223        tokenString_LITERAL = (String)symbol.value;
224        LITERALstart = symbol.getStart();
225        LITERALend = symbol.getEnd();
226      }
227      /**
228       * Retrieves the value for the lexeme LITERAL.
229       * @return The value for the lexeme LITERAL.
230       * @apilevel high-level
231       */
232      @ASTNodeAnnotation.Token(name="LITERAL")
233      public String getLITERAL() {
234        return tokenString_LITERAL != null ? tokenString_LITERAL : "";
235      }
236      /**
237       * Defer pretty printing to superclass.
238       * @aspect Java7Literals
239       * @declaredat /home/jesper/git/extendj/java7/frontend/Literals.jrag:138
240       */
241        public void prettyPrint(PrettyPrinter out) {
242        super.prettyPrint(out);
243      }
244      /**
245       * @apilevel internal
246       */
247      protected boolean type_computed = false;
248      /**
249       * @apilevel internal
250       */
251      protected TypeDecl type_value;
252      /**
253       * @apilevel internal
254       */
255      private void type_reset() {
256        type_computed = false;
257        type_value = null;
258      }
259      /**
260       * @attribute syn
261       * @aspect TypeAnalysis
262       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeAnalysis.jrag:302
263       */
264      @ASTNodeAnnotation.Attribute
265      public TypeDecl type() {
266        ASTNode$State state = state();
267        if (type_computed) {
268          return type_value;
269        }
270        boolean intermediate = state.INTERMEDIATE_VALUE;
271        state.INTERMEDIATE_VALUE = false;
272        int num = state.boundariesCrossed;
273        boolean isFinal = this.is$Final();
274        type_value = typeDouble();
275        if (isFinal && num == state().boundariesCrossed) {
276          type_computed = true;
277        } else {
278        }
279        state.INTERMEDIATE_VALUE |= intermediate;
280    
281        return type_value;
282      }
283      /**
284       * @apilevel internal
285       */
286      protected boolean isZero_computed = false;
287      /**
288       * @apilevel internal
289       */
290      protected boolean isZero_value;
291      /**
292       * @apilevel internal
293       */
294      private void isZero_reset() {
295        isZero_computed = false;
296      }
297      /**
298       * @return true if this floating point literal is equivalent to a zero literal
299       * @attribute syn
300       * @aspect Java7Literals
301       * @declaredat /home/jesper/git/extendj/java7/frontend/Literals.jrag:60
302       */
303      @ASTNodeAnnotation.Attribute
304      public boolean isZero() {
305        ASTNode$State state = state();
306        if (isZero_computed) {
307          return isZero_value;
308        }
309        boolean intermediate = state.INTERMEDIATE_VALUE;
310        state.INTERMEDIATE_VALUE = false;
311        int num = state.boundariesCrossed;
312        boolean isFinal = this.is$Final();
313        isZero_value = isZero_compute();
314        if (isFinal && num == state().boundariesCrossed) {
315          isZero_computed = true;
316        } else {
317        }
318        state.INTERMEDIATE_VALUE |= intermediate;
319    
320        return isZero_value;
321      }
322      /**
323       * @apilevel internal
324       */
325      private boolean isZero_compute() {
326          for (int i = 0; i < digits.length(); i++) {
327            char c = Character.toLowerCase(digits.charAt(i));
328            if (c == 'e' || c == 'p') {
329              break;
330            }
331            if (c != '0' && c != '.' && c != 'x') {
332              return false;
333            }
334          }
335          return true;
336        }
337      /**
338       * @apilevel internal
339       */
340      protected boolean constant_computed = false;
341      /**
342       * @apilevel internal
343       */
344      protected Constant constant_value;
345      /**
346       * @apilevel internal
347       */
348      private void constant_reset() {
349        constant_computed = false;
350        constant_value = null;
351      }
352      /**
353       * @attribute syn
354       * @aspect ConstantExpression
355       * @declaredat /home/jesper/git/extendj/java4/frontend/ConstantExpression.jrag:37
356       */
357      @ASTNodeAnnotation.Attribute
358      public Constant constant() {
359        ASTNode$State state = state();
360        if (constant_computed) {
361          return constant_value;
362        }
363        boolean intermediate = state.INTERMEDIATE_VALUE;
364        state.INTERMEDIATE_VALUE = false;
365        int num = state.boundariesCrossed;
366        boolean isFinal = this.is$Final();
367        constant_value = constant_compute();
368        if (isFinal && num == state().boundariesCrossed) {
369          constant_computed = true;
370        } else {
371        }
372        state.INTERMEDIATE_VALUE |= intermediate;
373    
374        return constant_value;
375      }
376      /**
377       * @apilevel internal
378       */
379      private Constant constant_compute() {
380          try {
381            return Constant.create(Double.parseDouble(getDigits()));
382          }
383          catch (NumberFormatException e) {
384            Constant c = Constant.create(0.0d);
385            c.error = true;
386            return c;
387          }
388        }
389      /**
390       * Utility attribute for literal rewriting.
391       * Any of the NumericLiteral subclasses have already
392       * been rewritten and/or parsed, and should not be
393       * rewritten again.
394       * 
395       * @return true if this literal is a "raw", not-yet-parsed NumericLiteral
396       * @attribute syn
397       * @aspect Java7Literals
398       * @declaredat /home/jesper/git/extendj/java7/frontend/Literals.jrag:373
399       */
400      @ASTNodeAnnotation.Attribute
401      public boolean needsRewrite() {
402        boolean needsRewrite_value = false;
403    
404        return needsRewrite_value;
405      }
406      /**
407       * @apilevel internal
408       */
409      public ASTNode rewriteTo() {
410        return super.rewriteTo();
411      }
412    }