1 16 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 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 [] 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 58 public boolean hasPositionCall() { 59 if (_left.hasPositionCall()) return true; 60 if (_right.hasPositionCall()) return true; 61 return false; 62 } 63 64 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 toString() { 126 return Ops[_op] + '(' + _left + ", " + _right + ')'; 127 } 128 } 129 | Popular Tags |