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     * @ast node
026     * @declaredat /home/jesper/git/extendj/java4/grammar/Java.ast:172
027     * @production RelationalExpr : {@link Binary};
028    
029     */
030    public abstract class RelationalExpr extends Binary implements Cloneable {
031      /**
032       * @aspect TypeCheck
033       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeCheck.jrag:240
034       */
035      public void typeCheck() {
036        if (!getLeftOperand().type().isNumericType()) {
037          errorf("%s is not numeric", getLeftOperand().type().typeName());
038        }
039        if (!getRightOperand().type().isNumericType()) {
040          errorf("%s is not numeric", getRightOperand().type().typeName());
041        }
042      }
043      /**
044       * @aspect CreateBCode
045       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1046
046       */
047      public void createBCode(CodeGeneration gen) { emitBooleanCondition(gen); }
048      /**
049       * @aspect CreateBCode
050       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1196
051       */
052      public void branchTrue(CodeGeneration gen, int target) {
053        // branch when true
054        if (isConstant()) {
055          if (isTrue()) {
056            gen.emitGoto(target);
057            //gen.GOTO(target);
058          }
059        } else {
060          TypeDecl type = getLeftOperand().type();
061          if (type.isNumericType()) {
062            type = binaryNumericPromotedType();
063            getLeftOperand().createBCode(gen);
064            getLeftOperand().type().emitCastTo(gen, type); // Binary numeric promotion
065            getRightOperand().createBCode(gen);
066            getRightOperand().type().emitCastTo(gen, type); // Binary numeric promotion
067          } else {
068            getLeftOperand().createBCode(gen);
069            getRightOperand().createBCode(gen);
070          }
071          compareBranch(gen, target, type);
072        }
073      }
074      /**
075       * @aspect CreateBCode
076       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1311
077       */
078      public void branchFalse(CodeGeneration gen, int target) {
079        // branch when false
080        if (isConstant()) {
081          if (isFalse()) {
082            gen.emitGoto(target);
083            //gen.GOTO(target);
084          }
085        } else {
086          TypeDecl type = getLeftOperand().type();
087          if (type.isNumericType()) {
088            type = binaryNumericPromotedType();
089            getLeftOperand().createBCode(gen);
090            getLeftOperand().type().emitCastTo(gen, type); // Binary numeric promotion
091            getRightOperand().createBCode(gen);
092            getRightOperand().type().emitCastTo(gen, type); // Binary numeric promotion
093          } else {
094            getLeftOperand().createBCode(gen);
095            getRightOperand().createBCode(gen);
096          }
097          compareNotBranch(gen, target, type);
098        }
099      }
100      /**
101       * @aspect CreateBCode
102       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1334
103       */
104      public void compareBranch(CodeGeneration gen, int label, TypeDecl typeDecl) {
105        throw new Error("compareBranch not implemented for " + getClass().getName());
106      }
107      /**
108       * @aspect CreateBCode
109       * @declaredat /home/jesper/git/extendj/java4/backend/CreateBCode.jrag:1344
110       */
111      public void compareNotBranch(CodeGeneration gen, int label, TypeDecl typeDecl) {
112        throw new Error("compareNotBranch not implemented for " + getClass().getName());
113      }
114      /**
115       * @declaredat ASTNode:1
116       */
117      public RelationalExpr() {
118        super();
119      }
120      /**
121       * Initializes the child array to the correct size.
122       * Initializes List and Opt nta children.
123       * @apilevel internal
124       * @ast method
125       * @declaredat ASTNode:10
126       */
127      public void init$Children() {
128        children = new ASTNode[2];
129      }
130      /**
131       * @declaredat ASTNode:13
132       */
133      public RelationalExpr(Expr p0, Expr p1) {
134        setChild(p0, 0);
135        setChild(p1, 1);
136      }
137      /**
138       * @apilevel low-level
139       * @declaredat ASTNode:20
140       */
141      protected int numChildren() {
142        return 2;
143      }
144      /**
145       * @apilevel internal
146       * @declaredat ASTNode:26
147       */
148      public boolean mayHaveRewrite() {
149        return false;
150      }
151      /**
152       * @apilevel internal
153       * @declaredat ASTNode:32
154       */
155      public void flushAttrCache() {
156        super.flushAttrCache();
157        type_reset();
158      }
159      /**
160       * @apilevel internal
161       * @declaredat ASTNode:39
162       */
163      public void flushCollectionCache() {
164        super.flushCollectionCache();
165      }
166      /**
167       * @apilevel internal
168       * @declaredat ASTNode:45
169       */
170      public void flushRewriteCache() {
171        super.flushRewriteCache();
172      }
173      /**
174       * @apilevel internal
175       * @declaredat ASTNode:51
176       */
177      public RelationalExpr clone() throws CloneNotSupportedException {
178        RelationalExpr node = (RelationalExpr) super.clone();
179        return node;
180      }
181      /**
182       * Create a deep copy of the AST subtree at this node.
183       * The copy is dangling, i.e. has no parent.
184       * @return dangling copy of the subtree at this node
185       * @apilevel low-level
186       * @deprecated Please use treeCopy or treeCopyNoTransform instead
187       * @declaredat ASTNode:62
188       */
189      @Deprecated
190      public abstract RelationalExpr fullCopy();
191      /**
192       * Create a deep copy of the AST subtree at this node.
193       * The copy is dangling, i.e. has no parent.
194       * @return dangling copy of the subtree at this node
195       * @apilevel low-level
196       * @declaredat ASTNode:70
197       */
198      public abstract RelationalExpr treeCopyNoTransform();
199      /**
200       * Create a deep copy of the AST subtree at this node.
201       * The subtree of this node is traversed to trigger rewrites before copy.
202       * The copy is dangling, i.e. has no parent.
203       * @return dangling copy of the subtree at this node
204       * @apilevel low-level
205       * @declaredat ASTNode:78
206       */
207      public abstract RelationalExpr treeCopy();
208      /**
209       * Replaces the LeftOperand child.
210       * @param node The new node to replace the LeftOperand child.
211       * @apilevel high-level
212       */
213      public void setLeftOperand(Expr node) {
214        setChild(node, 0);
215      }
216      /**
217       * Retrieves the LeftOperand child.
218       * @return The current node used as the LeftOperand child.
219       * @apilevel high-level
220       */
221      @ASTNodeAnnotation.Child(name="LeftOperand")
222      public Expr getLeftOperand() {
223        return (Expr) getChild(0);
224      }
225      /**
226       * Retrieves the LeftOperand child.
227       * <p><em>This method does not invoke AST transformations.</em></p>
228       * @return The current node used as the LeftOperand child.
229       * @apilevel low-level
230       */
231      public Expr getLeftOperandNoTransform() {
232        return (Expr) getChildNoTransform(0);
233      }
234      /**
235       * Replaces the RightOperand child.
236       * @param node The new node to replace the RightOperand child.
237       * @apilevel high-level
238       */
239      public void setRightOperand(Expr node) {
240        setChild(node, 1);
241      }
242      /**
243       * Retrieves the RightOperand child.
244       * @return The current node used as the RightOperand child.
245       * @apilevel high-level
246       */
247      @ASTNodeAnnotation.Child(name="RightOperand")
248      public Expr getRightOperand() {
249        return (Expr) getChild(1);
250      }
251      /**
252       * Retrieves the RightOperand child.
253       * <p><em>This method does not invoke AST transformations.</em></p>
254       * @return The current node used as the RightOperand child.
255       * @apilevel low-level
256       */
257      public Expr getRightOperandNoTransform() {
258        return (Expr) getChildNoTransform(1);
259      }
260      /**
261       * @apilevel internal
262       */
263      protected boolean type_computed = false;
264      /**
265       * @apilevel internal
266       */
267      protected TypeDecl type_value;
268      /**
269       * @apilevel internal
270       */
271      private void type_reset() {
272        type_computed = false;
273        type_value = null;
274      }
275      /**
276       * @attribute syn
277       * @aspect TypeAnalysis
278       * @declaredat /home/jesper/git/extendj/java4/frontend/TypeAnalysis.jrag:302
279       */
280      @ASTNodeAnnotation.Attribute
281      public TypeDecl type() {
282        ASTNode$State state = state();
283        if (type_computed) {
284          return type_value;
285        }
286        boolean intermediate = state.INTERMEDIATE_VALUE;
287        state.INTERMEDIATE_VALUE = false;
288        int num = state.boundariesCrossed;
289        boolean isFinal = this.is$Final();
290        type_value = typeBoolean();
291        if (isFinal && num == state().boundariesCrossed) {
292          type_computed = true;
293        } else {
294        }
295        state.INTERMEDIATE_VALUE |= intermediate;
296    
297        return type_value;
298      }
299      /**
300       * @apilevel internal
301       */
302      public ASTNode rewriteTo() {
303        return super.rewriteTo();
304      }
305    }