Source Code Cross Referenced for NumberCompare.java in  » Scripting » Kawa » gnu » kawa » functions » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » Kawa » gnu.kawa.functions 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package gnu.kawa.functions;
002:
003:        import gnu.math.*;
004:        import gnu.mapping.*;
005:        import gnu.bytecode.*;
006:        import gnu.expr.*;
007:        import java.math.*;
008:
009:        /** This implements the numeric comparison relations: <, <=, etc. */
010:
011:        public class NumberCompare extends ProcedureN implements  CanInline,
012:                Inlineable {
013:            Language language;
014:
015:            // Return codes from Numeric.compare:
016:            static final int RESULT_GRT = 1;
017:            static final int RESULT_EQU = 0;
018:            static final int RESULT_LSS = -1;
019:            static final int RESULT_NAN = -2;
020:            static final int RESULT_NEQ = -3;
021:
022:            // One flag bit for each of the above RESULT_XXX codes:
023:            public static final int TRUE_IF_GRT = 1 << (RESULT_GRT + 3);
024:            public static final int TRUE_IF_EQU = 1 << (RESULT_EQU + 3);
025:            public static final int TRUE_IF_LSS = 1 << (RESULT_LSS + 3);
026:            public static final int TRUE_IF_NAN = 1 << (RESULT_NAN + 3);
027:            public static final int TRUE_IF_NEQ = 1 << (RESULT_NEQ + 3);
028:            int flags;
029:
030:            public int numArgs() {
031:                return (-1 << 12) | 2;
032:            }
033:
034:            public static boolean $Eq(Object arg1, Object arg2) {
035:                return apply2(TRUE_IF_EQU, arg1, arg2);
036:            }
037:
038:            public static boolean $Gr(Object arg1, Object arg2) {
039:                return apply2(TRUE_IF_GRT, arg1, arg2);
040:            }
041:
042:            public static boolean $Gr$Eq(Object arg1, Object arg2) {
043:                return apply2(TRUE_IF_GRT | TRUE_IF_EQU, arg1, arg2);
044:            }
045:
046:            public static boolean $Ls(Object arg1, Object arg2) {
047:                return apply2(TRUE_IF_LSS, arg1, arg2);
048:            }
049:
050:            public static boolean $Ls$Eq(Object arg1, Object arg2) {
051:                return apply2(TRUE_IF_LSS | TRUE_IF_EQU, arg1, arg2);
052:            }
053:
054:            public static boolean $Eq$V(Object arg1, Object arg2, Object arg3,
055:                    Object[] rest) {
056:                return ($Eq(arg1, arg2) && $Eq(arg2, arg3) && (rest.length == 0 || ($Eq(
057:                        arg3, rest[0]) && applyN(TRUE_IF_EQU, rest))));
058:            }
059:
060:            public static boolean $Gr$V(Object arg1, Object arg2, Object arg3,
061:                    Object[] rest) {
062:                return ($Gr(arg1, arg2) && $Gr(arg2, arg3) && (rest.length == 0 || ($Gr(
063:                        arg3, rest[0]) && applyN(TRUE_IF_GRT, rest))));
064:            }
065:
066:            public static boolean $Gr$Eq$V(Object arg1, Object arg2,
067:                    Object arg3, Object[] rest) {
068:                return ($Gr$Eq(arg1, arg2) && $Gr$Eq(arg2, arg3) && (rest.length == 0 || ($Gr$Eq(
069:                        arg3, rest[0]) && applyN(TRUE_IF_GRT | TRUE_IF_EQU,
070:                        rest))));
071:            }
072:
073:            public static boolean $Ls$V(Object arg1, Object arg2, Object arg3,
074:                    Object[] rest) {
075:                return ($Ls(arg1, arg2) && $Ls(arg2, arg3) && (rest.length == 0 || ($Ls(
076:                        arg3, rest[0]) && applyN(TRUE_IF_LSS, rest))));
077:            }
078:
079:            public static boolean $Ls$Eq$V(Object arg1, Object arg2,
080:                    Object arg3, Object[] rest) {
081:                return ($Ls$Eq(arg1, arg2) && $Ls$Eq(arg2, arg3) && (rest.length == 0 || ($Ls$Eq(
082:                        arg3, rest[0]) && applyN(TRUE_IF_LSS | TRUE_IF_EQU,
083:                        rest))));
084:            }
085:
086:            public static NumberCompare make(Language language, String name,
087:                    int flags) {
088:                NumberCompare proc = new NumberCompare();
089:                proc.language = language;
090:                proc.setName(name);
091:                proc.flags = flags;
092:                return proc;
093:            }
094:
095:            protected final Language getLanguage() {
096:                return language;
097:            }
098:
099:            public Object apply2(Object arg1, Object arg2) {
100:                return getLanguage().booleanObject(apply2(flags, arg1, arg2));
101:            }
102:
103:            static public boolean apply2(int flags, Object arg1, Object arg2) {
104:                return ((1 << (3 + compare(arg1, arg2, true))) & flags) != 0;
105:            }
106:
107:            public static boolean checkCompareCode(int code, int flags) {
108:                return ((1 << (3 + code)) & flags) != 0;
109:            }
110:
111:            static public boolean applyWithPromotion(int flags, Object arg1,
112:                    Object arg2) {
113:                return checkCompareCode(compare(arg1, arg2, false), flags);
114:            }
115:
116:            /** Compare two numbers.
117:             * @param exact true if we should compare exact/inexact numbers exactly
118:             *   (by converting the inexact number to exact), or inexactly (by
119:             *   "promoting" the exact to inexact) (as required for XQuery).
120:             * @return 1 if {@code arg1>arg2}; 0 if {@code arg1==arg2};
121:             * -1 if {@code arg1<arg2}; -2 if either is {@code NaN};
122:             * -3 if not comparable (either is not a number). */
123:            static public int compare(Object arg1, Object arg2, boolean exact) {
124:                int code1 = Arithmetic.classifyValue(arg1);
125:                int code2 = Arithmetic.classifyValue(arg2);
126:                return compare(arg1, code1, arg2, code2, exact);
127:            }
128:
129:            static public int compare(Object arg1, int code1, Object arg2,
130:                    int code2, boolean exact) {
131:                if (code1 < 0 || code2 < 0)
132:                    return -3;
133:                int code = code1 < code2 ? code2 : code1;
134:                int comp; // A Numeric.compare return code: -1, 0, 1, or rarely: -2, or -3.
135:                switch (code) {
136:                case Arithmetic.INT_CODE:
137:                    int i1 = Arithmetic.asInt(arg1);
138:                    int i2 = Arithmetic.asInt(arg2);
139:                    comp = i1 < i2 ? -1 : i1 > i2 ? 1 : 0;
140:                    break;
141:                case Arithmetic.LONG_CODE:
142:                    long l1 = Arithmetic.asLong(arg1);
143:                    long l2 = Arithmetic.asLong(arg2);
144:                    comp = l1 < l2 ? -1 : l1 > l2 ? 1 : 0;
145:                    break;
146:                case Arithmetic.BIGINTEGER_CODE:
147:                    BigInteger bi1 = Arithmetic.asBigInteger(arg1);
148:                    BigInteger bi2 = Arithmetic.asBigInteger(arg2);
149:                    comp = bi1.compareTo(bi2);
150:                    break;
151:                case Arithmetic.INTNUM_CODE:
152:                    comp = IntNum.compare(Arithmetic.asIntNum(arg1), Arithmetic
153:                            .asIntNum(arg2));
154:                    break;
155:                case Arithmetic.BIGDECIMAL_CODE:
156:                    BigDecimal bd1 = Arithmetic.asBigDecimal(arg1);
157:                    BigDecimal bd2 = Arithmetic.asBigDecimal(arg2);
158:                    comp = bd1.compareTo(bd2);
159:                    break;
160:                case Arithmetic.RATNUM_CODE:
161:                    comp = RatNum.compare(Arithmetic.asRatNum(arg1), Arithmetic
162:                            .asRatNum(arg2));
163:                    break;
164:                case Arithmetic.FLOAT_CODE:
165:                    if (!exact
166:                            || (code1 > Arithmetic.RATNUM_CODE && code2 > Arithmetic.RATNUM_CODE)) {
167:                        float f1 = Arithmetic.asFloat(arg1);
168:                        float f2 = Arithmetic.asFloat(arg2);
169:                        comp = f1 > f2 ? 1 : f1 < f2 ? -1 : f1 == f2 ? 0 : -2;
170:                        break;
171:                    }
172:                    // else fall through, to handle exact-inexact comparison
173:                case Arithmetic.DOUBLE_CODE:
174:                case Arithmetic.FLONUM_CODE:
175:                    if (!exact
176:                            || (code1 > Arithmetic.RATNUM_CODE && code2 > Arithmetic.RATNUM_CODE)) {
177:                        double d1 = Arithmetic.asDouble(arg1);
178:                        double d2 = Arithmetic.asDouble(arg2);
179:                        comp = d1 > d2 ? 1 : d1 < d2 ? -1 : d1 == d2 ? 0 : -2;
180:                        break;
181:                    }
182:                    // else fall through, to handle exact-inexact comparison
183:                default:
184:                    Numeric num1 = Arithmetic.asNumeric(arg1);
185:                    Numeric num2 = Arithmetic.asNumeric(arg2);
186:                    comp = ((Numeric) num1).compare(num2);
187:                }
188:                return comp;
189:            }
190:
191:            static boolean applyN(int flags, Object[] args) {
192:                //  if (args.length < 2)
193:                //  throw new WrongArguments(this.name(),2,"(< x1 x2 ...)");
194:                for (int i = 0; i < args.length - 1; i++) {
195:                    Object arg1 = args[i];
196:                    Object arg2 = args[i + 1];
197:                    if (!apply2(flags, arg1, arg2))
198:                        return false;
199:                }
200:                return true;
201:            }
202:
203:            public Object applyN(Object[] args) {
204:                //  if (args.length < 2)
205:                //  throw new WrongArguments(this.name(),2,"(< x1 x2 ...)");
206:                return getLanguage().booleanObject(applyN(flags, args));
207:            }
208:
209:            public Expression inline(ApplyExp exp, ExpWalker walker) {
210:                Expression folded = exp.inlineIfConstant(this , walker);
211:                if (folded != exp)
212:                    return folded;
213:                return exp;
214:            }
215:
216:            public void compile(ApplyExp exp, Compilation comp, Target target) {
217:                Expression[] args = exp.getArgs();
218:                if (args.length == 2) {
219:                    Expression arg0 = args[0];
220:                    Expression arg1 = args[1];
221:                    int kind0 = classify(arg0);
222:                    int kind1 = classify(arg1);
223:                    CodeAttr code = comp.getCode();
224:                    if (kind0 >= RealNum_KIND && kind1 >= RealNum_KIND
225:                    // Don't optimize if both operands are fractions.
226:                            && (kind0 != RealNum_KIND || kind1 != RealNum_KIND)) {
227:                        if (!(target instanceof  ConditionalTarget)) {
228:                            IfExp.compile(exp, QuoteExp.trueExp,
229:                                    QuoteExp.falseExp, comp, target);
230:                            return;
231:                        }
232:                        int mask = flags;
233:                        if (mask == TRUE_IF_NEQ)
234:                            mask = TRUE_IF_GRT | TRUE_IF_LSS;
235:                        if (kind0 >= IntNum_KIND && kind1 >= IntNum_KIND
236:                                && (kind0 < long_KIND || kind1 < long_KIND)) {
237:                            Type[] ctypes = new Type[2];
238:                            ctypes[0] = AddOp.typeIntNum;
239:                            if (kind1 >= long_KIND) {
240:                                ctypes[1] = Type.long_type;
241:                            } else if (kind0 >= long_KIND
242:                            // Simple check to avoid re-ordering side-effects.
243:                                    && (arg0 instanceof  QuoteExp
244:                                            || arg1 instanceof  QuoteExp
245:                                            || arg0 instanceof  ReferenceExp || arg1 instanceof  ReferenceExp)) {
246:                                ctypes[1] = Type.long_type;
247:                                args = new Expression[2];
248:                                args[0] = arg1;
249:                                args[1] = arg0;
250:                                if (mask != TRUE_IF_EQU
251:                                        && mask != TRUE_IF_GRT + TRUE_IF_LSS)
252:                                    mask ^= TRUE_IF_GRT | TRUE_IF_LSS;
253:                            } else
254:                                ctypes[1] = AddOp.typeIntNum;
255:                            Method cmeth = AddOp.typeIntNum.getDeclaredMethod(
256:                                    "compare", ctypes);
257:                            PrimProcedure compare = new PrimProcedure(cmeth);
258:                            arg0 = new ApplyExp(compare, args);
259:                            arg1 = new QuoteExp(IntNum.zero());
260:                            kind0 = kind1 = int_KIND;
261:                        }
262:                        Type commonType;
263:                        if (kind0 >= int_KIND && kind1 >= int_KIND)
264:                            commonType = Type.int_type;
265:                        else if (kind0 >= long_KIND && kind1 >= long_KIND)
266:                            commonType = Type.long_type;
267:                        else
268:                            commonType = Type.double_type;
269:                        StackTarget subTarget = new StackTarget(commonType);
270:                        ConditionalTarget ctarget = (ConditionalTarget) target;
271:
272:                        int opcode;
273:                        if (arg0 instanceof  QuoteExp
274:                                && !(arg1 instanceof  QuoteExp)) {
275:                            Expression tmp = arg1;
276:                            arg1 = arg0;
277:                            arg0 = tmp;
278:                            if (mask != TRUE_IF_EQU
279:                                    && mask != TRUE_IF_GRT + TRUE_IF_LSS)
280:                                mask ^= TRUE_IF_GRT | TRUE_IF_LSS;
281:                        }
282:                        Label label1 = ctarget.trueBranchComesFirst ? ctarget.ifFalse
283:                                : ctarget.ifTrue;
284:                        if (ctarget.trueBranchComesFirst)
285:                            mask ^= TRUE_IF_GRT | TRUE_IF_LSS | TRUE_IF_EQU;
286:                        switch (mask) {
287:                        case TRUE_IF_GRT:
288:                            opcode = 157 /*ifgt*/;
289:                            break;
290:                        case TRUE_IF_EQU:
291:                            opcode = 153 /*ifeq*/;
292:                            break;
293:                        case TRUE_IF_LSS:
294:                            opcode = 155 /*iflt*/;
295:                            break;
296:                        case TRUE_IF_GRT | TRUE_IF_LSS:
297:                            opcode = 154 /*ifne*/;
298:                            break;
299:                        case TRUE_IF_GRT | TRUE_IF_EQU:
300:                            opcode = 156 /*ifge*/;
301:                            break;
302:                        case TRUE_IF_LSS | TRUE_IF_EQU:
303:                            opcode = 158 /*ifle*/;
304:                            break;
305:                        default:
306:                            opcode = 0;
307:                        }
308:                        arg0.compile(comp, subTarget);
309:                        Object value;
310:                        if (kind0 >= int_KIND
311:                                && kind1 >= int_KIND
312:                                && arg1 instanceof  QuoteExp
313:                                && (value = ((QuoteExp) arg1).getValue()) instanceof  IntNum
314:                                && ((IntNum) value).isZero()) {
315:                            code.emitGotoIfCompare1(label1, opcode);
316:                        } else {
317:                            arg1.compile(comp, subTarget);
318:                            code.emitGotoIfCompare2(label1, opcode);
319:                        }
320:                        ctarget.emitGotoFirstBranch(code);
321:                        return;
322:                    }
323:                }
324:                ApplyExp.compile(exp, comp, target);
325:            }
326:
327:            // Return a code indicate type of number:
328:            private static final int Unknown_KIND = 0; // unknown or invalid type
329:            private static final int Number_KIND = 1; // java.lang.Number - not used
330:            private static final int Numeric_KIND = 2; // gnu.math.Numeric
331:            private static final int RealNum_KIND = 3; // exact or unknown real
332:            private static final int double_KIND = 4; // inexact real (double or DFloNum)
333:            private static final int IntNum_KIND = 5; // gnu.math.IntNum
334:            private static final int long_KIND = 6; // long
335:            private static final int int_KIND = 7; // int
336:
337:            static int classify(Expression exp) {
338:                Type type = exp.getType();
339:                int kind = classify(type);
340:                Object value;
341:                if (kind == IntNum_KIND
342:                        && exp instanceof  QuoteExp
343:                        && (value = ((QuoteExp) exp).getValue()) instanceof  IntNum) {
344:                    int ilength = ((IntNum) value).intLength();
345:                    if (ilength < 32)
346:                        return int_KIND;
347:                    if (ilength < 64)
348:                        return long_KIND;
349:                }
350:                return kind;
351:            }
352:
353:            static int classify(Type type) {
354:                if (type instanceof  PrimType) {
355:                    char sig = type.getSignature().charAt(0);
356:                    if (sig == 'V' || sig == 'Z' || sig == 'C')
357:                        return Unknown_KIND;
358:                    if (sig == 'D' || sig == 'F')
359:                        return double_KIND;
360:                    if (sig == 'J')
361:                        return long_KIND;
362:                    return int_KIND;
363:                }
364:                if (type.isSubtype(AddOp.typeIntNum))
365:                    return IntNum_KIND;
366:                if (type.isSubtype(AddOp.typeDFloNum))
367:                    return double_KIND;
368:                if (type.isSubtype(AddOp.typeRealNum))
369:                    return RealNum_KIND;
370:                if (type.isSubtype(AddOp.typeNumeric))
371:                    return Numeric_KIND;
372:                return Unknown_KIND;
373:            }
374:
375:            public Type getReturnType(Expression[] args) {
376:                return Compilation.scmBooleanType;
377:            }
378:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.