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