1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import org.apache.bcel.generic.BranchInstruction; 23 import org.apache.bcel.generic.ConstantPoolGen; 24 import org.apache.bcel.generic.INVOKESTATIC; 25 import org.apache.bcel.generic.InstructionList; 26 import org.apache.bcel.generic.PUSH; 27 import org.apache.xalan.xsltc.compiler.util.BooleanType; 28 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 29 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 30 import org.apache.xalan.xsltc.compiler.util.IntType; 31 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 32 import org.apache.xalan.xsltc.compiler.util.MethodType; 33 import org.apache.xalan.xsltc.compiler.util.NodeSetType; 34 import org.apache.xalan.xsltc.compiler.util.NodeType; 35 import org.apache.xalan.xsltc.compiler.util.RealType; 36 import org.apache.xalan.xsltc.compiler.util.ReferenceType; 37 import org.apache.xalan.xsltc.compiler.util.ResultTreeType; 38 import org.apache.xalan.xsltc.compiler.util.Type; 39 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 40 import org.apache.xalan.xsltc.runtime.Operators; 41 42 46 final class RelationalExpr extends Expression implements Operators { 47 private int _op; 48 private Expression _left, _right; 49 50 public RelationalExpr(int op, Expression left, Expression right) { 51 _op = op; 52 (_left = left).setParent(this); 53 (_right = right).setParent(this); 54 } 55 56 public void setParser(Parser parser) { 57 super.setParser(parser); 58 _left.setParser(parser); 59 _right.setParser(parser); 60 } 61 62 66 public boolean hasPositionCall() { 67 if (_left.hasPositionCall()) return true; 68 if (_right.hasPositionCall()) return true; 69 return false; 70 } 71 72 75 public boolean hasLastCall() { 76 return (_left.hasLastCall() || _right.hasLastCall()); 77 } 78 79 public boolean hasReferenceArgs() { 80 return _left.getType() instanceof ReferenceType || 81 _right.getType() instanceof ReferenceType; 82 } 83 84 public boolean hasNodeArgs() { 85 return _left.getType() instanceof NodeType || 86 _right.getType() instanceof NodeType; 87 } 88 89 public boolean hasNodeSetArgs() { 90 return _left.getType() instanceof NodeSetType || 91 _right.getType() instanceof NodeSetType; 92 } 93 94 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 95 Type tleft = _left.typeCheck(stable); 96 Type tright = _right.typeCheck(stable); 97 98 if (tleft instanceof ResultTreeType && 100 tright instanceof ResultTreeType ) 101 { 102 _right = new CastExpr(_right, Type.Real); 103 _left = new CastExpr(_left, Type.Real); 104 return _type = Type.Boolean; 105 } 106 107 if (hasReferenceArgs()) { 109 Type type = null; 110 Type typeL = null; 111 Type typeR = null; 112 if (tleft instanceof ReferenceType) { 113 if (_left instanceof VariableRefBase) { 114 VariableRefBase ref = (VariableRefBase)_left; 115 VariableBase var = ref.getVariable(); 116 typeL = var.getType(); 117 } 118 } 119 if (tright instanceof ReferenceType) { 120 if (_right instanceof VariableRefBase) { 121 VariableRefBase ref = (VariableRefBase)_right; 122 VariableBase var = ref.getVariable(); 123 typeR = var.getType(); 124 } 125 } 126 if (typeL == null) 128 type = typeR; 129 else if (typeR == null) 130 type = typeL; 131 else { 132 type = Type.Real; 133 } 134 if (type == null) type = Type.Real; 135 136 _right = new CastExpr(_right, type); 137 _left = new CastExpr(_left, type); 138 return _type = Type.Boolean; 139 } 140 141 if (hasNodeSetArgs()) { 142 if (tright instanceof NodeSetType) { 144 final Expression temp = _right; _right = _left; _left = temp; 145 _op = (_op == Operators.GT) ? Operators.LT : 146 (_op == Operators.LT) ? Operators.GT : 147 (_op == Operators.GE) ? Operators.LE : Operators.GE; 148 tright = _right.getType(); 149 } 150 151 if (tright instanceof NodeType) { 153 _right = new CastExpr(_right, Type.NodeSet); 154 } 155 if (tright instanceof IntType) { 157 _right = new CastExpr(_right, Type.Real); 158 } 159 if (tright instanceof ResultTreeType) { 161 _right = new CastExpr(_right, Type.String); 162 } 163 return _type = Type.Boolean; 164 } 165 166 if (hasNodeArgs()) { 168 if (tleft instanceof BooleanType) { 169 _right = new CastExpr(_right, Type.Boolean); 170 tright = Type.Boolean; 171 } 172 if (tright instanceof BooleanType) { 173 _left = new CastExpr(_left, Type.Boolean); 174 tleft = Type.Boolean; 175 } 176 } 177 178 MethodType ptype = lookupPrimop(stable, Operators.names[_op], 180 new MethodType(Type.Void, 181 tleft, tright)); 182 183 if (ptype != null) { 184 Type arg1 = (Type) ptype.argsType().elementAt(0); 185 if (!arg1.identicalTo(tleft)) { 186 _left = new CastExpr(_left, arg1); 187 } 188 Type arg2 = (Type) ptype.argsType().elementAt(1); 189 if (!arg2.identicalTo(tright)) { 190 _right = new CastExpr(_right, arg1); 191 } 192 return _type = ptype.resultType(); 193 } 194 throw new TypeCheckError(this); 195 } 196 197 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 198 if (hasNodeSetArgs() || hasReferenceArgs()) { 199 final ConstantPoolGen cpg = classGen.getConstantPool(); 200 final InstructionList il = methodGen.getInstructionList(); 201 202 _left.translate(classGen, methodGen); 204 _left.startIterator(classGen, methodGen); 205 _right.translate(classGen, methodGen); 206 _right.startIterator(classGen, methodGen); 207 208 il.append(new PUSH(cpg, _op)); 209 il.append(methodGen.loadDOM()); 210 211 int index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "compare", 212 "(" 213 + _left.getType().toSignature() 214 + _right.getType().toSignature() 215 + "I" 216 + DOM_INTF_SIG 217 + ")Z"); 218 il.append(new INVOKESTATIC(index)); 219 } 220 else { 221 translateDesynthesized(classGen, methodGen); 222 synthesize(classGen, methodGen); 223 } 224 } 225 226 public void translateDesynthesized(ClassGenerator classGen, 227 MethodGenerator methodGen) { 228 if (hasNodeSetArgs() || hasReferenceArgs()) { 229 translate(classGen, methodGen); 230 desynthesize(classGen, methodGen); 231 } 232 else { 233 BranchInstruction bi = null; 234 final InstructionList il = methodGen.getInstructionList(); 235 236 _left.translate(classGen, methodGen); 237 _right.translate(classGen, methodGen); 238 239 241 boolean tozero = false; 242 Type tleft = _left.getType(); 243 244 if (tleft instanceof RealType) { 245 il.append(tleft.CMP(_op == LT || _op == LE)); 246 tleft = Type.Int; 247 tozero = true; 248 } 249 250 switch (_op) { 251 case LT: 252 bi = tleft.GE(tozero); 253 break; 254 255 case GT: 256 bi = tleft.LE(tozero); 257 break; 258 259 case LE: 260 bi = tleft.GT(tozero); 261 break; 262 263 case GE: 264 bi = tleft.LT(tozero); 265 break; 266 267 default: 268 ErrorMsg msg = new ErrorMsg(ErrorMsg.ILLEGAL_RELAT_OP_ERR,this); 269 getParser().reportError(Constants.FATAL, msg); 270 } 271 272 _falseList.add(il.append(bi)); } 274 } 275 276 public String toString() { 277 return Operators.names[_op] + '(' + _left + ", " + _right + ')'; 278 } 279 } 280 | Popular Tags |