KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > compiler > BinOpExpr


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: BinOpExpr.java,v 1.11 2004/02/16 22:24:29 minchau Exp $
18  */

19
20 package org.apache.xalan.xsltc.compiler;
21
22 import org.apache.bcel.generic.InstructionList;
23 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
24 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
25 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
26 import org.apache.xalan.xsltc.compiler.util.MethodType;
27 import org.apache.xalan.xsltc.compiler.util.Type;
28 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
29
30 /**
31  * @author Jacek Ambroziak
32  * @author Santiago Pericas-Geertsen
33  */

34 final class BinOpExpr extends Expression {
35     public static final int PLUS = 0;
36     public static final int MINUS = 1;
37     public static final int TIMES = 2;
38     public static final int DIV = 3;
39     public static final int MOD = 4;
40     
41     private static final String JavaDoc[] Ops = {
42     "+", "-", "*", "/", "%"
43     };
44
45     private int _op;
46     private Expression _left, _right;
47     
48     public BinOpExpr(int op, Expression left, Expression right) {
49     _op = op;
50     (_left = left).setParent(this);
51     (_right = right).setParent(this);
52     }
53
54     /**
55      * Returns true if this expressions contains a call to position(). This is
56      * needed for context changes in node steps containing multiple predicates.
57      */

58     public boolean hasPositionCall() {
59     if (_left.hasPositionCall()) return true;
60     if (_right.hasPositionCall()) return true;
61     return false;
62     }
63
64     /**
65      * Returns true if this expressions contains a call to last()
66      */

67     public boolean hasLastCall() {
68             return (_left.hasLastCall() || _right.hasLastCall());
69     }
70     
71     public void setParser(Parser parser) {
72     super.setParser(parser);
73     _left.setParser(parser);
74     _right.setParser(parser);
75     }
76     
77     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
78     final Type tleft = _left.typeCheck(stable);
79     final Type tright = _right.typeCheck(stable);
80     final MethodType ptype = lookupPrimop(stable, Ops[_op],
81                           new MethodType(Type.Void,
82                                  tleft, tright));
83     if (ptype != null) {
84         final Type arg1 = (Type) ptype.argsType().elementAt(0);
85         if (!arg1.identicalTo(tleft)) {
86         _left = new CastExpr(_left, arg1);
87         }
88         final Type arg2 = (Type) ptype.argsType().elementAt(1);
89         if (!arg2.identicalTo(tright)) {
90         _right = new CastExpr(_right, arg1);
91         }
92         return _type = ptype.resultType();
93     }
94     throw new TypeCheckError(this);
95     }
96
97     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
98     final InstructionList il = methodGen.getInstructionList();
99
100     _left.translate(classGen, methodGen);
101     _right.translate(classGen, methodGen);
102
103     switch (_op) {
104     case PLUS:
105         il.append(_type.ADD());
106         break;
107     case MINUS:
108         il.append(_type.SUB());
109         break;
110     case TIMES:
111         il.append(_type.MUL());
112         break;
113     case DIV:
114         il.append(_type.DIV());
115         break;
116     case MOD:
117         il.append(_type.REM());
118         break;
119     default:
120         ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_BINARY_OP_ERR, this);
121         getParser().reportError(Constants.ERROR, msg);
122     }
123     }
124
125     public String JavaDoc toString() {
126     return Ops[_op] + '(' + _left + ", " + _right + ')';
127     }
128 }
129
Popular Tags