1 16 19 20 package org.apache.xalan.xsltc.compiler; 21 22 import java.util.Vector ; 23 24 import org.apache.bcel.generic.BranchHandle; 25 import org.apache.bcel.generic.ConstantPoolGen; 26 import org.apache.bcel.generic.GOTO_W; 27 import org.apache.bcel.generic.IFEQ; 28 import org.apache.bcel.generic.InstructionHandle; 29 import org.apache.bcel.generic.InstructionList; 30 import org.apache.xalan.xsltc.compiler.util.BooleanType; 31 import org.apache.xalan.xsltc.compiler.util.ClassGenerator; 32 import org.apache.xalan.xsltc.compiler.util.ErrorMsg; 33 import org.apache.xalan.xsltc.compiler.util.MethodGenerator; 34 import org.apache.xalan.xsltc.compiler.util.MethodType; 35 import org.apache.xalan.xsltc.compiler.util.NodeSetType; 36 import org.apache.xalan.xsltc.compiler.util.Type; 37 import org.apache.xalan.xsltc.compiler.util.TypeCheckError; 38 39 45 abstract class Expression extends SyntaxTreeNode { 46 50 protected Type _type; 51 52 55 protected FlowList _trueList = new FlowList(); 56 57 60 protected FlowList _falseList = new FlowList(); 61 62 public Type getType() { 63 return _type; 64 } 65 66 public abstract String toString(); 67 68 public boolean hasPositionCall() { 69 return false; } 71 72 public boolean hasLastCall() { 73 return false; 74 } 75 76 81 public Object evaluateAtCompileTime() { 82 return null; 83 } 84 85 88 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 89 return typeCheckContents(stable); 90 } 91 92 95 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 96 ErrorMsg msg = new ErrorMsg(ErrorMsg.NOT_IMPLEMENTED_ERR, 97 getClass(), this); 98 getParser().reportError(FATAL, msg); 99 } 100 101 105 public final InstructionList compile(ClassGenerator classGen, 106 MethodGenerator methodGen) { 107 final InstructionList result, save = methodGen.getInstructionList(); 108 methodGen.setInstructionList(result = new InstructionList()); 109 translate(classGen, methodGen); 110 methodGen.setInstructionList(save); 111 return result; 112 } 113 114 117 public void translateDesynthesized(ClassGenerator classGen, 118 MethodGenerator methodGen) { 119 translate(classGen, methodGen); 120 if (_type instanceof BooleanType) { 121 desynthesize(classGen, methodGen); 122 } 123 } 124 125 129 public void startIterator(ClassGenerator classGen, 130 MethodGenerator methodGen) { 131 if (_type instanceof NodeSetType == false) { 133 return; 134 } 135 136 Expression expr = this; 138 if (expr instanceof CastExpr) { 139 expr = ((CastExpr) expr).getExpr(); 140 } 141 if (expr instanceof VariableRefBase == false) { 142 final InstructionList il = methodGen.getInstructionList(); 143 il.append(methodGen.loadContextNode()); 144 il.append(methodGen.setStartNode()); 145 } 146 } 147 148 153 public void synthesize(ClassGenerator classGen, MethodGenerator methodGen) { 154 final ConstantPoolGen cpg = classGen.getConstantPool(); 155 final InstructionList il = methodGen.getInstructionList(); 156 _trueList.backPatch(il.append(ICONST_1)); 157 final BranchHandle truec = il.append(new GOTO_W(null)); 158 _falseList.backPatch(il.append(ICONST_0)); 159 truec.setTarget(il.append(NOP)); 160 } 161 162 public void desynthesize(ClassGenerator classGen, 163 MethodGenerator methodGen) { 164 final InstructionList il = methodGen.getInstructionList(); 165 _falseList.add(il.append(new IFEQ(null))); 166 } 167 168 public FlowList getFalseList() { 169 return _falseList; 170 } 171 172 public FlowList getTrueList() { 173 return _trueList; 174 } 175 176 public void backPatchFalseList(InstructionHandle ih) { 177 _falseList.backPatch(ih); 178 } 179 180 public void backPatchTrueList(InstructionHandle ih) { 181 _trueList.backPatch(ih); 182 } 183 184 191 public MethodType lookupPrimop(SymbolTable stable, String op, 192 MethodType ctype) { 193 MethodType result = null; 194 final Vector primop = stable.lookupPrimop(op); 195 if (primop != null) { 196 final int n = primop.size(); 197 int minDistance = Integer.MAX_VALUE; 198 for (int i = 0; i < n; i++) { 199 final MethodType ptype = (MethodType) primop.elementAt(i); 200 if (ptype.argsCount() != ctype.argsCount()) { 202 continue; 203 } 204 205 if (result == null) { 207 result = ptype; } 209 210 final int distance = ctype.distanceTo(ptype); 212 if (distance < minDistance) { 213 minDistance = distance; 214 result = ptype; 215 } 216 } 217 } 218 return result; 219 } 220 } 221 | Popular Tags |