1 package gnu.kawa.functions; 2 import gnu.math.*; 3 import gnu.mapping.*; 4 import gnu.expr.*; 5 import gnu.bytecode.*; 6 7 11 12 public class DivideOp extends ProcedureN implements CanInline 13 { 14 17 boolean asInteger; 18 19 public static final DivideOp $Sl = new DivideOp("/"); 20 public static final DivideOp idiv = new DivideOp("idiv"); 21 static { idiv.asInteger = true; } 22 23 public DivideOp(String name) 24 { 25 super(name); 26 } 27 28 public Object applyN (Object [] args) 29 { 30 Numeric result; 31 int i = 0; 32 if (args.length == 1) 33 result = IntNum.one (); 34 else 35 result = (Numeric) (args[i++]); 36 for (; i < args.length; i++) 37 result = result.div (args[i]); 38 if (asInteger) 39 result = ((RealNum) result).toExactInt(Numeric.TRUNCATE); 40 return result; 41 } 42 43 public Expression inline (ApplyExp exp, ExpWalker walker) 44 { 45 Expression folded = exp.inlineIfConstant(this, walker); 46 if (folded != exp) 47 return folded; 48 if (asInteger) 49 return exp; 50 Expression[] args = exp.getArgs(); 51 if (args.length > 2) 52 return AddOp.pairwise(this, exp.getFunction(), args, walker); 53 if (args.length == 2) 54 { 55 Type type0 = args[0].getType(); 56 Type type1 = args[1].getType(); 57 int kind0 = AddOp.classify(type0); 58 int kind1 = AddOp.classify(type1); 59 if ((kind0 == 4 || type0.isSubtype(typeRatNum)) 60 && (kind1 == 4 || type1.isSubtype(typeRatNum))) 61 return new ApplyExp(typeRatNum.getDeclaredMethod("divide", 2), 62 args); 63 if (kind0 >= 3 && kind1 >= 3) 64 { 65 Expression opt = AddOp.primInline(108, exp); 66 if (opt != exp) 67 return opt; 68 } 69 if (kind0 >= 2 && kind1 >= 2) 70 return new ApplyExp(AddOp.typeRealNum.getDeclaredMethod("divide", 2), 71 args); 72 } 73 return exp; 74 } 75 76 static ClassType typeRatNum = ClassType.make("gnu.math.RatNum"); 77 } 78 | Popular Tags |