KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > kawa > functions > DivideOp


1 package gnu.kawa.functions;
2 import gnu.math.*;
3 import gnu.mapping.*;
4 import gnu.expr.*;
5 import gnu.bytecode.*;
6
7 /**
8  * Implement the Scheme standard function "/".
9  * @author Per Bothner
10  */

11
12 public class DivideOp extends ProcedureN implements CanInline
13 {
14   /** True if result shoudl be cast to integer.
15    * Basically a hack (that should be generalized) for XQuery's
16    * idiv operator. */

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 JavaDoc name)
24   {
25     super(name);
26   }
27
28   public Object JavaDoc applyN (Object JavaDoc[] 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