1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import org.apache.bcel.generic.GOTO; 23 import org.apache.bcel.generic.InstructionHandle; 24 import org.apache.bcel.generic.InstructionList; 25 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 26 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 27 import org.apache.xalan.xsltc.compiler.util.MethodType; 28 import org.apache.xalan.xsltc.compiler.util.Type; 29 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 30 31 36 final class LogicalExpr extends Expression { 37 38 public static final int OR = 0; 39 public static final int AND = 1; 40 41 private final int _op; private Expression _left; private Expression _right; 45 private static final String [] Ops = { "or", "and" }; 46 47 53 public LogicalExpr(int op, Expression left, Expression right) { 54 _op = op; 55 (_left = left).setParent(this); 56 (_right = right).setParent(this); 57 } 58 59 63 public boolean hasPositionCall() { 64 return (_left.hasPositionCall() || _right.hasPositionCall()); 65 } 66 67 70 public boolean hasLastCall() { 71 return (_left.hasLastCall() || _right.hasLastCall()); 72 } 73 74 79 public Object evaluateAtCompileTime() { 80 final Object leftb = _left.evaluateAtCompileTime(); 81 final Object rightb = _right.evaluateAtCompileTime(); 82 83 if (leftb == null || rightb == null) { 85 return null; 86 } 87 88 if (_op == AND) { 89 return (leftb == Boolean.TRUE && rightb == Boolean.TRUE) ? 90 Boolean.TRUE : Boolean.FALSE; 91 } 92 else { 93 return (leftb == Boolean.TRUE || rightb == Boolean.TRUE) ? 94 Boolean.TRUE : Boolean.FALSE; 95 } 96 } 97 98 102 public int getOp() { 103 return(_op); 104 } 105 106 110 public void setParser(Parser parser) { 111 super.setParser(parser); 112 _left.setParser(parser); 113 _right.setParser(parser); 114 } 115 116 119 public String toString() { 120 return Ops[_op] + '(' + _left + ", " + _right + ')'; 121 } 122 123 126 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 127 Type tleft = _left.typeCheck(stable); 129 Type tright = _right.typeCheck(stable); 130 131 MethodType wantType = new MethodType(Type.Void, tleft, tright); 133 MethodType haveType = lookupPrimop(stable, Ops[_op], wantType); 134 135 if (haveType != null) { 137 Type arg1 = (Type)haveType.argsType().elementAt(0); 139 if (!arg1.identicalTo(tleft)) 140 _left = new CastExpr(_left, arg1); 141 Type arg2 = (Type) haveType.argsType().elementAt(1); 143 if (!arg2.identicalTo(tright)) 144 _right = new CastExpr(_right, arg1); 145 return _type = haveType.resultType(); 147 } 148 throw new TypeCheckError(this); 149 } 150 151 154 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 155 translateDesynthesized(classGen, methodGen); 156 synthesize(classGen, methodGen); 157 } 158 159 162 public void translateDesynthesized(ClassGenerator classGen, 163 MethodGenerator methodGen) { 164 165 final InstructionList il = methodGen.getInstructionList(); 166 final SyntaxTreeNode parent = getParent(); 167 168 if (_op == AND) { 170 171 _left.translateDesynthesized(classGen, methodGen); 173 174 InstructionHandle middle = il.append(NOP); 176 177 _right.translateDesynthesized(classGen, methodGen); 179 180 InstructionHandle after = il.append(NOP); 182 183 _falseList.append(_right._falseList.append(_left._falseList)); 185 186 if ((_left instanceof LogicalExpr) && 189 (((LogicalExpr)_left).getOp() == OR)) { 190 _left.backPatchTrueList(middle); 191 } 192 else if (_left instanceof NotCall) { 193 _left.backPatchTrueList(middle); 194 } 195 else { 196 _trueList.append(_left._trueList); 197 } 198 199 if ((_right instanceof LogicalExpr) && 202 (((LogicalExpr)_right).getOp() == OR)) { 203 _right.backPatchTrueList(after); 204 } 205 else if (_right instanceof NotCall) { 206 _right.backPatchTrueList(after); 207 } 208 else { 209 _trueList.append(_right._trueList); 210 } 211 } 212 else { 214 _left.translateDesynthesized(classGen, methodGen); 216 217 InstructionHandle ih = il.append(new GOTO(null)); 220 221 _right.translateDesynthesized(classGen, methodGen); 223 224 _left._trueList.backPatch(ih); 225 _left._falseList.backPatch(ih.getNext()); 226 227 _falseList.append(_right._falseList); 228 _trueList.add(ih).append(_right._trueList); 229 } 230 } 231 } 232 | Popular Tags |