Source Code Cross Referenced for Primitive.java in  » Scripting » beanshell » bsh » 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 » beanshell » bsh 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*****************************************************************************
0002:         *                                                                           *
0003:         *  This file is part of the BeanShell Java Scripting distribution.          *
0004:         *  Documentation and updates may be found at http://www.beanshell.org/      *
0005:         *                                                                           *
0006:         *  Sun Public License Notice:                                               *
0007:         *                                                                           *
0008:         *  The contents of this file are subject to the Sun Public License Version  *
0009:         *  1.0 (the "License"); you may not use this file except in compliance with *
0010:         *  the License. A copy of the License is available at http://www.sun.com    * 
0011:         *                                                                           *
0012:         *  The Original Code is BeanShell. The Initial Developer of the Original    *
0013:         *  Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright     *
0014:         *  (C) 2000.  All Rights Reserved.                                          *
0015:         *                                                                           *
0016:         *  GNU Public License Notice:                                               *
0017:         *                                                                           *
0018:         *  Alternatively, the contents of this file may be used under the terms of  *
0019:         *  the GNU Lesser General Public License (the "LGPL"), in which case the    *
0020:         *  provisions of LGPL are applicable instead of those above. If you wish to *
0021:         *  allow use of your version of this file only under the  terms of the LGPL *
0022:         *  and not to allow others to use your version of this file under the SPL,  *
0023:         *  indicate your decision by deleting the provisions above and replace      *
0024:         *  them with the notice and other provisions required by the LGPL.  If you  *
0025:         *  do not delete the provisions above, a recipient may use your version of  *
0026:         *  this file under either the SPL or the LGPL.                              *
0027:         *                                                                           *
0028:         *  Patrick Niemeyer (pat@pat.net)                                           *
0029:         *  Author of Learning Java, O'Reilly & Associates                           *
0030:         *  http://www.pat.net/~pat/                                                 *
0031:         *                                                                           *
0032:         *****************************************************************************/package bsh;
0033:
0034:        import java.util.Hashtable;
0035:
0036:        /**
0037:         * <p>Wrapper for primitive types in Bsh.  This is package public because it 
0038:         * is used in the implementation of some bsh commands.</p>
0039:         *
0040:         * <p>See the note in LHS.java about wrapping objects.</p>
0041:         * 
0042:         * @author Pat Niemeyer
0043:         * @author Daniel Leuck
0044:         */
0045:        public final class Primitive implements  ParserConstants,
0046:                java.io.Serializable {
0047:            /*
0048:            Note: this class is final because we may test == Primitive.class in places.
0049:            If we need to change that search for those tests.
0050:             */
0051:
0052:            /*
0053:            static Hashtable primitiveToWrapper = new Hashtable();
0054:            static Hashtable wrapperToPrimitive = new Hashtable();
0055:            static {
0056:            	primitiveToWrapper.put( Boolean.TYPE, Boolean.class );
0057:            	primitiveToWrapper.put( Byte.TYPE, Byte.class );
0058:            	primitiveToWrapper.put( Short.TYPE, Short.class );
0059:            	primitiveToWrapper.put( Character.TYPE, Character.class );
0060:            	primitiveToWrapper.put( Integer.TYPE, Integer.class );
0061:            	primitiveToWrapper.put( Long.TYPE, Long.class );
0062:            	primitiveToWrapper.put( Float.TYPE, Float.class );
0063:            	primitiveToWrapper.put( Double.TYPE, Double.class );
0064:            	wrapperToPrimitive.put( Boolean.class, Boolean.TYPE );
0065:            	wrapperToPrimitive.put( Byte.class, Byte.TYPE );
0066:            	wrapperToPrimitive.put( Short.class, Short.TYPE );
0067:            	wrapperToPrimitive.put( Character.class, Character.TYPE );
0068:            	wrapperToPrimitive.put( Integer.class, Integer.TYPE );
0069:            	wrapperToPrimitive.put( Long.class, Long.TYPE );
0070:            	wrapperToPrimitive.put( Float.class, Float.TYPE );
0071:            	wrapperToPrimitive.put( Double.class, Double.TYPE );
0072:            }
0073:             */
0074:            static Hashtable wrapperMap = new Hashtable();
0075:            static {
0076:                wrapperMap.put(Boolean.TYPE, Boolean.class);
0077:                wrapperMap.put(Byte.TYPE, Byte.class);
0078:                wrapperMap.put(Short.TYPE, Short.class);
0079:                wrapperMap.put(Character.TYPE, Character.class);
0080:                wrapperMap.put(Integer.TYPE, Integer.class);
0081:                wrapperMap.put(Long.TYPE, Long.class);
0082:                wrapperMap.put(Float.TYPE, Float.class);
0083:                wrapperMap.put(Double.TYPE, Double.class);
0084:                wrapperMap.put(Boolean.class, Boolean.TYPE);
0085:                wrapperMap.put(Byte.class, Byte.TYPE);
0086:                wrapperMap.put(Short.class, Short.TYPE);
0087:                wrapperMap.put(Character.class, Character.TYPE);
0088:                wrapperMap.put(Integer.class, Integer.TYPE);
0089:                wrapperMap.put(Long.class, Long.TYPE);
0090:                wrapperMap.put(Float.class, Float.TYPE);
0091:                wrapperMap.put(Double.class, Double.TYPE);
0092:            }
0093:
0094:            /** The primitive value stored in its java.lang wrapper class */
0095:            private Object value;
0096:
0097:            private static class Special implements  java.io.Serializable {
0098:                private Special() {
0099:                }
0100:
0101:                public static final Special NULL_VALUE = new Special();
0102:                public static final Special VOID_TYPE = new Special();
0103:            }
0104:
0105:            /*
0106:                NULL means "no value".
0107:                This ia a placeholder for primitive null value.
0108:             */
0109:            public static final Primitive NULL = new Primitive(
0110:                    Special.NULL_VALUE);
0111:
0112:            public static Primitive TRUE = new Primitive(true);
0113:            public static Primitive FALSE = new Primitive(false);
0114:
0115:            /**
0116:                VOID means "no type".
0117:                Strictly speaking, this makes no sense here.  But for practical
0118:                reasons we'll consider the lack of a type to be a special value.
0119:             */
0120:            public static final Primitive VOID = new Primitive(
0121:                    Special.VOID_TYPE);
0122:
0123:            // private to prevent invocation with param that isn't a primitive-wrapper
0124:            public Primitive(Object value) {
0125:                if (value == null)
0126:                    throw new InterpreterError(
0127:                            "Use Primitve.NULL instead of Primitive(null)");
0128:
0129:                if (value != Special.NULL_VALUE && value != Special.VOID_TYPE
0130:                        && !isWrapperType(value.getClass()))
0131:                    throw new InterpreterError("Not a wrapper type: "
0132:                            + value.getClass());
0133:
0134:                this .value = value;
0135:            }
0136:
0137:            public Primitive(boolean value) {
0138:                this (value ? Boolean.TRUE : Boolean.FALSE);
0139:            }
0140:
0141:            public Primitive(byte value) {
0142:                this (new Byte(value));
0143:            }
0144:
0145:            public Primitive(short value) {
0146:                this (new Short(value));
0147:            }
0148:
0149:            public Primitive(char value) {
0150:                this (new Character(value));
0151:            }
0152:
0153:            public Primitive(int value) {
0154:                this (new Integer(value));
0155:            }
0156:
0157:            public Primitive(long value) {
0158:                this (new Long(value));
0159:            }
0160:
0161:            public Primitive(float value) {
0162:                this (new Float(value));
0163:            }
0164:
0165:            public Primitive(double value) {
0166:                this (new Double(value));
0167:            }
0168:
0169:            /**
0170:            	Return the primitive value stored in its java.lang wrapper class
0171:             */
0172:            public Object getValue() {
0173:                if (value == Special.NULL_VALUE)
0174:                    return null;
0175:                else if (value == Special.VOID_TYPE)
0176:                    throw new InterpreterError("attempt to unwrap void type");
0177:                else
0178:                    return value;
0179:            }
0180:
0181:            public String toString() {
0182:                if (value == Special.NULL_VALUE)
0183:                    return "null";
0184:                else if (value == Special.VOID_TYPE)
0185:                    return "void";
0186:                else
0187:                    return value.toString();
0188:            }
0189:
0190:            /**
0191:            	Get the corresponding Java primitive TYPE class for this Primitive.
0192:            	@return the primitive TYPE class type of the value or Void.TYPE for
0193:            	Primitive.VOID or null value for type of Primitive.NULL
0194:             */
0195:            public Class getType() {
0196:                if (this  == Primitive.VOID)
0197:                    return Void.TYPE;
0198:
0199:                // NULL return null as type... we currently use null type to indicate 
0200:                // loose typing throughout bsh.
0201:                if (this  == Primitive.NULL)
0202:                    return null;
0203:
0204:                return unboxType(value.getClass());
0205:            }
0206:
0207:            /**
0208:            	Perform a binary operation on two Primitives or wrapper types.
0209:            	If both original args were Primitives return a Primitive result
0210:            	else it was mixed (wrapper/primitive) return the wrapper type.
0211:            	The exception is for boolean operations where we will return the 
0212:            	primitive type either way.
0213:             */
0214:            public static Object binaryOperation(Object obj1, Object obj2,
0215:                    int kind) throws UtilEvalError {
0216:                // special primitive types
0217:                if (obj1 == NULL || obj2 == NULL)
0218:                    throw new UtilEvalError(
0219:                            "Null value or 'null' literal in binary operation");
0220:                if (obj1 == VOID || obj2 == VOID)
0221:                    throw new UtilEvalError(
0222:                            "Undefined variable, class, or 'void' literal in binary operation");
0223:
0224:                // keep track of the original types
0225:                Class lhsOrgType = obj1.getClass();
0226:                Class rhsOrgType = obj2.getClass();
0227:
0228:                // Unwrap primitives
0229:                if (obj1 instanceof  Primitive)
0230:                    obj1 = ((Primitive) obj1).getValue();
0231:                if (obj2 instanceof  Primitive)
0232:                    obj2 = ((Primitive) obj2).getValue();
0233:
0234:                Object[] operands = promotePrimitives(obj1, obj2);
0235:                Object lhs = operands[0];
0236:                Object rhs = operands[1];
0237:
0238:                if (lhs.getClass() != rhs.getClass())
0239:                    throw new UtilEvalError("Type mismatch in operator.  "
0240:                            + lhs.getClass() + " cannot be used with "
0241:                            + rhs.getClass());
0242:
0243:                Object result;
0244:                try {
0245:                    result = binaryOperationImpl(lhs, rhs, kind);
0246:                } catch (ArithmeticException e) {
0247:                    throw new UtilTargetError(
0248:                            "Arithemetic Exception in binary op", e);
0249:                }
0250:
0251:                if (result instanceof  Boolean)
0252:                    return ((Boolean) result).booleanValue() ? Primitive.TRUE
0253:                            : Primitive.FALSE;
0254:                // If both original args were Primitives return a Primitive result
0255:                // else it was mixed (wrapper/primitive) return the wrapper type
0256:                // Exception is for boolean result, return the primitive
0257:                else if ((lhsOrgType == Primitive.class && rhsOrgType == Primitive.class))
0258:                    return new Primitive(result);
0259:                else
0260:                    return result;
0261:            }
0262:
0263:            static Object binaryOperationImpl(Object lhs, Object rhs, int kind)
0264:                    throws UtilEvalError {
0265:                if (lhs instanceof  Boolean)
0266:                    return booleanBinaryOperation((Boolean) lhs, (Boolean) rhs,
0267:                            kind);
0268:                else if (lhs instanceof  Integer)
0269:                    return intBinaryOperation((Integer) lhs, (Integer) rhs,
0270:                            kind);
0271:                else if (lhs instanceof  Long)
0272:                    return longBinaryOperation((Long) lhs, (Long) rhs, kind);
0273:                else if (lhs instanceof  Float)
0274:                    return floatBinaryOperation((Float) lhs, (Float) rhs, kind);
0275:                else if (lhs instanceof  Double)
0276:                    return doubleBinaryOperation((Double) lhs, (Double) rhs,
0277:                            kind);
0278:                else
0279:                    throw new UtilEvalError("Invalid types in binary operator");
0280:            }
0281:
0282:            static Boolean booleanBinaryOperation(Boolean B1, Boolean B2,
0283:                    int kind) {
0284:                boolean lhs = B1.booleanValue();
0285:                boolean rhs = B2.booleanValue();
0286:
0287:                switch (kind) {
0288:                case EQ:
0289:                    return lhs == rhs ? Boolean.TRUE : Boolean.FALSE;
0290:
0291:                case NE:
0292:                    return lhs != rhs ? Boolean.TRUE : Boolean.FALSE;
0293:
0294:                case BOOL_OR:
0295:                case BOOL_ORX:
0296:                    return lhs || rhs ? Boolean.TRUE : Boolean.FALSE;
0297:
0298:                case BOOL_AND:
0299:                case BOOL_ANDX:
0300:                    return lhs && rhs ? Boolean.TRUE : Boolean.FALSE;
0301:
0302:                default:
0303:                    throw new InterpreterError("unimplemented binary operator");
0304:                }
0305:            }
0306:
0307:            // returns Object covering both Long and Boolean return types
0308:            static Object longBinaryOperation(Long L1, Long L2, int kind) {
0309:                long lhs = L1.longValue();
0310:                long rhs = L2.longValue();
0311:
0312:                switch (kind) {
0313:                // boolean
0314:                case LT:
0315:                case LTX:
0316:                    return lhs < rhs ? Boolean.TRUE : Boolean.FALSE;
0317:
0318:                case GT:
0319:                case GTX:
0320:                    return lhs > rhs ? Boolean.TRUE : Boolean.FALSE;
0321:
0322:                case EQ:
0323:                    return lhs == rhs ? Boolean.TRUE : Boolean.FALSE;
0324:
0325:                case LE:
0326:                case LEX:
0327:                    return lhs <= rhs ? Boolean.TRUE : Boolean.FALSE;
0328:
0329:                case GE:
0330:                case GEX:
0331:                    return lhs >= rhs ? Boolean.TRUE : Boolean.FALSE;
0332:
0333:                case NE:
0334:                    return lhs != rhs ? Boolean.TRUE : Boolean.FALSE;
0335:
0336:                    // arithmetic
0337:                case PLUS:
0338:                    return new Long(lhs + rhs);
0339:
0340:                case MINUS:
0341:                    return new Long(lhs - rhs);
0342:
0343:                case STAR:
0344:                    return new Long(lhs * rhs);
0345:
0346:                case SLASH:
0347:                    return new Long(lhs / rhs);
0348:
0349:                case MOD:
0350:                    return new Long(lhs % rhs);
0351:
0352:                    // bitwise
0353:                case LSHIFT:
0354:                case LSHIFTX:
0355:                    return new Long(lhs << rhs);
0356:
0357:                case RSIGNEDSHIFT:
0358:                case RSIGNEDSHIFTX:
0359:                    return new Long(lhs >> rhs);
0360:
0361:                case RUNSIGNEDSHIFT:
0362:                case RUNSIGNEDSHIFTX:
0363:                    return new Long(lhs >>> rhs);
0364:
0365:                case BIT_AND:
0366:                case BIT_ANDX:
0367:                    return new Long(lhs & rhs);
0368:
0369:                case BIT_OR:
0370:                case BIT_ORX:
0371:                    return new Long(lhs | rhs);
0372:
0373:                case XOR:
0374:                    return new Long(lhs ^ rhs);
0375:
0376:                default:
0377:                    throw new InterpreterError(
0378:                            "Unimplemented binary long operator");
0379:                }
0380:            }
0381:
0382:            // returns Object covering both Integer and Boolean return types
0383:            static Object intBinaryOperation(Integer I1, Integer I2, int kind) {
0384:                int lhs = I1.intValue();
0385:                int rhs = I2.intValue();
0386:
0387:                switch (kind) {
0388:                // boolean
0389:                case LT:
0390:                case LTX:
0391:                    return lhs < rhs ? Boolean.TRUE : Boolean.FALSE;
0392:
0393:                case GT:
0394:                case GTX:
0395:                    return lhs > rhs ? Boolean.TRUE : Boolean.FALSE;
0396:
0397:                case EQ:
0398:                    return lhs == rhs ? Boolean.TRUE : Boolean.FALSE;
0399:
0400:                case LE:
0401:                case LEX:
0402:                    return lhs <= rhs ? Boolean.TRUE : Boolean.FALSE;
0403:
0404:                case GE:
0405:                case GEX:
0406:                    return lhs >= rhs ? Boolean.TRUE : Boolean.FALSE;
0407:
0408:                case NE:
0409:                    return lhs != rhs ? Boolean.TRUE : Boolean.FALSE;
0410:
0411:                    // arithmetic
0412:                case PLUS:
0413:                    return new Integer(lhs + rhs);
0414:
0415:                case MINUS:
0416:                    return new Integer(lhs - rhs);
0417:
0418:                case STAR:
0419:                    return new Integer(lhs * rhs);
0420:
0421:                case SLASH:
0422:                    return new Integer(lhs / rhs);
0423:
0424:                case MOD:
0425:                    return new Integer(lhs % rhs);
0426:
0427:                    // bitwise
0428:                case LSHIFT:
0429:                case LSHIFTX:
0430:                    return new Integer(lhs << rhs);
0431:
0432:                case RSIGNEDSHIFT:
0433:                case RSIGNEDSHIFTX:
0434:                    return new Integer(lhs >> rhs);
0435:
0436:                case RUNSIGNEDSHIFT:
0437:                case RUNSIGNEDSHIFTX:
0438:                    return new Integer(lhs >>> rhs);
0439:
0440:                case BIT_AND:
0441:                case BIT_ANDX:
0442:                    return new Integer(lhs & rhs);
0443:
0444:                case BIT_OR:
0445:                case BIT_ORX:
0446:                    return new Integer(lhs | rhs);
0447:
0448:                case XOR:
0449:                    return new Integer(lhs ^ rhs);
0450:
0451:                default:
0452:                    throw new InterpreterError(
0453:                            "Unimplemented binary integer operator");
0454:                }
0455:            }
0456:
0457:            // returns Object covering both Double and Boolean return types
0458:            static Object doubleBinaryOperation(Double D1, Double D2, int kind)
0459:                    throws UtilEvalError {
0460:                double lhs = D1.doubleValue();
0461:                double rhs = D2.doubleValue();
0462:
0463:                switch (kind) {
0464:                // boolean
0465:                case LT:
0466:                case LTX:
0467:                    return lhs < rhs ? Boolean.TRUE : Boolean.FALSE;
0468:
0469:                case GT:
0470:                case GTX:
0471:                    return lhs > rhs ? Boolean.TRUE : Boolean.FALSE;
0472:
0473:                case EQ:
0474:                    return lhs == rhs ? Boolean.TRUE : Boolean.FALSE;
0475:
0476:                case LE:
0477:                case LEX:
0478:                    return lhs <= rhs ? Boolean.TRUE : Boolean.FALSE;
0479:
0480:                case GE:
0481:                case GEX:
0482:                    return lhs >= rhs ? Boolean.TRUE : Boolean.FALSE;
0483:
0484:                case NE:
0485:                    return lhs != rhs ? Boolean.TRUE : Boolean.FALSE;
0486:
0487:                    // arithmetic
0488:                case PLUS:
0489:                    return new Double(lhs + rhs);
0490:
0491:                case MINUS:
0492:                    return new Double(lhs - rhs);
0493:
0494:                case STAR:
0495:                    return new Double(lhs * rhs);
0496:
0497:                case SLASH:
0498:                    return new Double(lhs / rhs);
0499:
0500:                case MOD:
0501:                    return new Double(lhs % rhs);
0502:
0503:                    // can't shift floating-point values
0504:                case LSHIFT:
0505:                case LSHIFTX:
0506:                case RSIGNEDSHIFT:
0507:                case RSIGNEDSHIFTX:
0508:                case RUNSIGNEDSHIFT:
0509:                case RUNSIGNEDSHIFTX:
0510:                    throw new UtilEvalError("Can't shift doubles");
0511:
0512:                default:
0513:                    throw new InterpreterError(
0514:                            "Unimplemented binary double operator");
0515:                }
0516:            }
0517:
0518:            // returns Object covering both Long and Boolean return types
0519:            static Object floatBinaryOperation(Float F1, Float F2, int kind)
0520:                    throws UtilEvalError {
0521:                float lhs = F1.floatValue();
0522:                float rhs = F2.floatValue();
0523:
0524:                switch (kind) {
0525:                // boolean
0526:                case LT:
0527:                case LTX:
0528:                    return lhs < rhs ? Boolean.TRUE : Boolean.FALSE;
0529:
0530:                case GT:
0531:                case GTX:
0532:                    return lhs > rhs ? Boolean.TRUE : Boolean.FALSE;
0533:
0534:                case EQ:
0535:                    return lhs == rhs ? Boolean.TRUE : Boolean.FALSE;
0536:
0537:                case LE:
0538:                case LEX:
0539:                    return lhs <= rhs ? Boolean.TRUE : Boolean.FALSE;
0540:
0541:                case GE:
0542:                case GEX:
0543:                    return lhs >= rhs ? Boolean.TRUE : Boolean.FALSE;
0544:
0545:                case NE:
0546:                    return lhs != rhs ? Boolean.TRUE : Boolean.FALSE;
0547:
0548:                    // arithmetic
0549:                case PLUS:
0550:                    return new Float(lhs + rhs);
0551:
0552:                case MINUS:
0553:                    return new Float(lhs - rhs);
0554:
0555:                case STAR:
0556:                    return new Float(lhs * rhs);
0557:
0558:                case SLASH:
0559:                    return new Float(lhs / rhs);
0560:
0561:                case MOD:
0562:                    return new Float(lhs % rhs);
0563:
0564:                    // can't shift floats
0565:                case LSHIFT:
0566:                case LSHIFTX:
0567:                case RSIGNEDSHIFT:
0568:                case RSIGNEDSHIFTX:
0569:                case RUNSIGNEDSHIFT:
0570:                case RUNSIGNEDSHIFTX:
0571:                    throw new UtilEvalError("Can't shift floats ");
0572:
0573:                default:
0574:                    throw new InterpreterError(
0575:                            "Unimplemented binary float operator");
0576:                }
0577:            }
0578:
0579:            /**
0580:            	Promote primitive wrapper type to to Integer wrapper type
0581:             */
0582:            static Object promoteToInteger(Object wrapper) {
0583:                if (wrapper instanceof  Character)
0584:                    return new Integer(((Character) wrapper).charValue());
0585:                else if ((wrapper instanceof  Byte)
0586:                        || (wrapper instanceof  Short))
0587:                    return new Integer(((Number) wrapper).intValue());
0588:
0589:                return wrapper;
0590:            }
0591:
0592:            /**
0593:            	Promote the pair of primitives to the maximum type of the two.
0594:            	e.g. [int,long]->[long,long]
0595:             */
0596:            static Object[] promotePrimitives(Object lhs, Object rhs) {
0597:                lhs = promoteToInteger(lhs);
0598:                rhs = promoteToInteger(rhs);
0599:
0600:                if ((lhs instanceof  Number) && (rhs instanceof  Number)) {
0601:                    Number lnum = (Number) lhs;
0602:                    Number rnum = (Number) rhs;
0603:
0604:                    boolean b;
0605:
0606:                    if ((b = (lnum instanceof  Double))
0607:                            || (rnum instanceof  Double)) {
0608:                        if (b)
0609:                            rhs = new Double(rnum.doubleValue());
0610:                        else
0611:                            lhs = new Double(lnum.doubleValue());
0612:                    } else if ((b = (lnum instanceof  Float))
0613:                            || (rnum instanceof  Float)) {
0614:                        if (b)
0615:                            rhs = new Float(rnum.floatValue());
0616:                        else
0617:                            lhs = new Float(lnum.floatValue());
0618:                    } else if ((b = (lnum instanceof  Long))
0619:                            || (rnum instanceof  Long)) {
0620:                        if (b)
0621:                            rhs = new Long(rnum.longValue());
0622:                        else
0623:                            lhs = new Long(lnum.longValue());
0624:                    }
0625:                }
0626:
0627:                return new Object[] { lhs, rhs };
0628:            }
0629:
0630:            public static Primitive unaryOperation(Primitive val, int kind)
0631:                    throws UtilEvalError {
0632:                if (val == NULL)
0633:                    throw new UtilEvalError(
0634:                            "illegal use of null object or 'null' literal");
0635:                if (val == VOID)
0636:                    throw new UtilEvalError(
0637:                            "illegal use of undefined object or 'void' literal");
0638:
0639:                Class operandType = val.getType();
0640:                Object operand = promoteToInteger(val.getValue());
0641:
0642:                if (operand instanceof  Boolean)
0643:                    return booleanUnaryOperation((Boolean) operand, kind) ? Primitive.TRUE
0644:                            : Primitive.FALSE;
0645:                else if (operand instanceof  Integer) {
0646:                    int result = intUnaryOperation((Integer) operand, kind);
0647:
0648:                    // ++ and -- must be cast back the original type
0649:                    if (kind == INCR || kind == DECR) {
0650:                        if (operandType == Byte.TYPE)
0651:                            return new Primitive((byte) result);
0652:                        if (operandType == Short.TYPE)
0653:                            return new Primitive((short) result);
0654:                        if (operandType == Character.TYPE)
0655:                            return new Primitive((char) result);
0656:                    }
0657:
0658:                    return new Primitive(result);
0659:                } else if (operand instanceof  Long)
0660:                    return new Primitive(longUnaryOperation((Long) operand,
0661:                            kind));
0662:                else if (operand instanceof  Float)
0663:                    return new Primitive(floatUnaryOperation((Float) operand,
0664:                            kind));
0665:                else if (operand instanceof  Double)
0666:                    return new Primitive(doubleUnaryOperation((Double) operand,
0667:                            kind));
0668:                else
0669:                    throw new InterpreterError(
0670:                            "An error occurred.  Please call technical support.");
0671:            }
0672:
0673:            static boolean booleanUnaryOperation(Boolean B, int kind)
0674:                    throws UtilEvalError {
0675:                boolean operand = B.booleanValue();
0676:                switch (kind) {
0677:                case BANG:
0678:                    return !operand;
0679:                default:
0680:                    throw new UtilEvalError(
0681:                            "Operator inappropriate for boolean");
0682:                }
0683:            }
0684:
0685:            static int intUnaryOperation(Integer I, int kind) {
0686:                int operand = I.intValue();
0687:
0688:                switch (kind) {
0689:                case PLUS:
0690:                    return operand;
0691:                case MINUS:
0692:                    return -operand;
0693:                case TILDE:
0694:                    return ~operand;
0695:                case INCR:
0696:                    return operand + 1;
0697:                case DECR:
0698:                    return operand - 1;
0699:                default:
0700:                    throw new InterpreterError("bad integer unaryOperation");
0701:                }
0702:            }
0703:
0704:            static long longUnaryOperation(Long L, int kind) {
0705:                long operand = L.longValue();
0706:
0707:                switch (kind) {
0708:                case PLUS:
0709:                    return operand;
0710:                case MINUS:
0711:                    return -operand;
0712:                case TILDE:
0713:                    return ~operand;
0714:                case INCR:
0715:                    return operand + 1;
0716:                case DECR:
0717:                    return operand - 1;
0718:                default:
0719:                    throw new InterpreterError("bad long unaryOperation");
0720:                }
0721:            }
0722:
0723:            static float floatUnaryOperation(Float F, int kind) {
0724:                float operand = F.floatValue();
0725:
0726:                switch (kind) {
0727:                case PLUS:
0728:                    return operand;
0729:                case MINUS:
0730:                    return -operand;
0731:                default:
0732:                    throw new InterpreterError("bad float unaryOperation");
0733:                }
0734:            }
0735:
0736:            static double doubleUnaryOperation(Double D, int kind) {
0737:                double operand = D.doubleValue();
0738:
0739:                switch (kind) {
0740:                case PLUS:
0741:                    return operand;
0742:                case MINUS:
0743:                    return -operand;
0744:                default:
0745:                    throw new InterpreterError("bad double unaryOperation");
0746:                }
0747:            }
0748:
0749:            public int intValue() throws UtilEvalError {
0750:                if (value instanceof  Number)
0751:                    return ((Number) value).intValue();
0752:                else
0753:                    throw new UtilEvalError("Primitive not a number");
0754:            }
0755:
0756:            public boolean booleanValue() throws UtilEvalError {
0757:                if (value instanceof  Boolean)
0758:                    return ((Boolean) value).booleanValue();
0759:                else
0760:                    throw new UtilEvalError("Primitive not a boolean");
0761:            }
0762:
0763:            /**
0764:            	Determine if this primitive is a numeric type.
0765:            	i.e. not boolean, null, or void (but including char)
0766:             */
0767:            public boolean isNumber() {
0768:                return (!(value instanceof  Boolean) && !(this  == NULL) && !(this  == VOID));
0769:            }
0770:
0771:            public Number numberValue() throws UtilEvalError {
0772:                Object value = this .value;
0773:
0774:                // Promote character to Number type for these purposes
0775:                if (value instanceof  Character)
0776:                    value = new Integer(((Character) value).charValue());
0777:
0778:                if (value instanceof  Number)
0779:                    return (Number) value;
0780:                else
0781:                    throw new UtilEvalError("Primitive not a number");
0782:            }
0783:
0784:            /**
0785:            	Primitives compare equal with other Primitives containing an equal
0786:            	wrapped value.
0787:             */
0788:            public boolean equals(Object obj) {
0789:                if (obj instanceof  Primitive)
0790:                    return ((Primitive) obj).value.equals(this .value);
0791:                else
0792:                    return false;
0793:            }
0794:
0795:            /**
0796:            	The hash of the Primitive is tied to the hash of the wrapped value but
0797:            	shifted so that they are not the same.
0798:             */
0799:            public int hashCode() {
0800:                return this .value.hashCode() * 21; // arbitrary
0801:            }
0802:
0803:            /**
0804:            	Unwrap primitive values and map voids to nulls.
0805:            	Non Primitive types remain unchanged.
0806:
0807:            	@param obj object type which may be bsh.Primitive
0808:            	@return corresponding "normal" Java type, "unwrapping" 
0809:            		any bsh.Primitive types to their wrapper types.
0810:             */
0811:            public static Object unwrap(Object obj) {
0812:                // map voids to nulls for the outside world
0813:                if (obj == Primitive.VOID)
0814:                    return null;
0815:
0816:                // unwrap primitives
0817:                if (obj instanceof  Primitive)
0818:                    return ((Primitive) obj).getValue();
0819:                else
0820:                    return obj;
0821:            }
0822:
0823:            /*
0824:                Unwrap Primitive wrappers to their java.lang wrapper values.
0825:            	e.g. Primitive(42) becomes Integer(42)
0826:            	@see #unwrap( Object )
0827:             */
0828:            public static Object[] unwrap(Object[] args) {
0829:                Object[] oa = new Object[args.length];
0830:                for (int i = 0; i < args.length; i++)
0831:                    oa[i] = unwrap(args[i]);
0832:                return oa;
0833:            }
0834:
0835:            /*
0836:             */
0837:            public static Object[] wrap(Object[] args, Class[] paramTypes) {
0838:                if (args == null)
0839:                    return null;
0840:
0841:                Object[] oa = new Object[args.length];
0842:                for (int i = 0; i < args.length; i++)
0843:                    oa[i] = wrap(args[i], paramTypes[i]);
0844:                return oa;
0845:            }
0846:
0847:            /**
0848:            	Wrap primitive values (as indicated by type param) and nulls in the 
0849:            	Primitive class.  Values not primitive or null are left unchanged.
0850:            	Primitive values are represented by their wrapped values in param value.
0851:            	<p/>
0852:            	The value null is mapped to Primitive.NULL.
0853:            	Any value specified with type Void.TYPE is mapped to Primitive.VOID.
0854:             */
0855:            public static Object wrap(Object value, Class type) {
0856:                if (type == Void.TYPE)
0857:                    return Primitive.VOID;
0858:
0859:                if (value == null)
0860:                    return Primitive.NULL;
0861:
0862:                if (value instanceof  Boolean)
0863:                    return ((Boolean) value).booleanValue() ? Primitive.TRUE
0864:                            : Primitive.FALSE;
0865:
0866:                if (type.isPrimitive() && isWrapperType(value.getClass()))
0867:                    return new Primitive(value);
0868:
0869:                return value;
0870:            }
0871:
0872:            /**
0873:            	Get the appropriate default value per JLS 4.5.4
0874:             */
0875:            public static Primitive getDefaultValue(Class type) {
0876:                if (type == null || !type.isPrimitive())
0877:                    return Primitive.NULL;
0878:                if (type == Boolean.TYPE)
0879:                    return Primitive.FALSE;
0880:
0881:                // non boolean primitive, get appropriate flavor of zero
0882:                try {
0883:                    return new Primitive((int) 0).castToType(type, Types.CAST);
0884:                } catch (UtilEvalError e) {
0885:                    throw new InterpreterError("bad cast");
0886:                }
0887:            }
0888:
0889:            /**
0890:            	Get the corresponding java.lang wrapper class for the primitive TYPE
0891:            	class.
0892:            	e.g.  Integer.TYPE -> Integer.class
0893:             */
0894:            public static Class boxType(Class primitiveType) {
0895:                Class c = (Class) wrapperMap.get(primitiveType);
0896:                if (c != null)
0897:                    return c;
0898:                throw new InterpreterError("Not a primitive type: "
0899:                        + primitiveType);
0900:            }
0901:
0902:            /**
0903:            	Get the corresponding primitive TYPE class for the java.lang wrapper
0904:            	class type.
0905:            	e.g.  Integer.class -> Integer.TYPE
0906:             */
0907:            public static Class unboxType(Class wrapperType) {
0908:                Class c = (Class) wrapperMap.get(wrapperType);
0909:                if (c != null)
0910:                    return c;
0911:                throw new InterpreterError("Not a primitive wrapper type: "
0912:                        + wrapperType);
0913:            }
0914:
0915:            /**
0916:            	Cast this bsh.Primitive value to a new bsh.Primitive value
0917:            	This is usually a numeric type cast.  Other cases include:
0918:            		A boolean can be cast to boolen
0919:            		null can be cast to any object type and remains null
0920:            		Attempting to cast a void causes an exception
0921:            	@param toType is the java object or primitive TYPE class
0922:             */
0923:            public Primitive castToType(Class toType, int operation)
0924:                    throws UtilEvalError {
0925:                return castPrimitive(toType, getType()/*fromType*/,
0926:                        this /*fromValue*/, false/*checkOnly*/, operation);
0927:            }
0928:
0929:            /*
0930:            	Cast or check a cast of a primitive type to another type.
0931:            	Normally both types are primitive (e.g. numeric), but a null value
0932:            	(no type) may be cast to any type.
0933:            	<p/>
0934:
0935:            	@param toType is the target type of the cast.  It is normally a
0936:            	java primitive TYPE, but in the case of a null cast can be any object
0937:            	type.
0938:
0939:            	@param fromType is the java primitive TYPE type of the primitive to be
0940:            	cast or null, to indicate that the fromValue was null or void.
0941:
0942:            	@param fromValue is, optionally, the value to be converted.  If
0943:            	checkOnly is true fromValue must be null.  If checkOnly is false,
0944:            	fromValue must be non-null (Primitive.NULL is of course valid).
0945:             */
0946:            static Primitive castPrimitive(Class toType, Class fromType,
0947:                    Primitive fromValue, boolean checkOnly, int operation)
0948:                    throws UtilEvalError {
0949:                /*
0950:                	Lots of preconditions checked here...
0951:                	Once things are running smoothly we might comment these out
0952:                	(That's what assertions are for).
0953:                 */
0954:                if (checkOnly && fromValue != null)
0955:                    throw new InterpreterError("bad cast param 1");
0956:                if (!checkOnly && fromValue == null)
0957:                    throw new InterpreterError("bad cast param 2");
0958:                if (fromType != null && !fromType.isPrimitive())
0959:                    throw new InterpreterError("bad fromType:" + fromType);
0960:                if (fromValue == Primitive.NULL && fromType != null)
0961:                    throw new InterpreterError("inconsistent args 1");
0962:                if (fromValue == Primitive.VOID && fromType != Void.TYPE)
0963:                    throw new InterpreterError("inconsistent args 2");
0964:
0965:                // can't cast void to anything
0966:                if (fromType == Void.TYPE)
0967:                    if (checkOnly)
0968:                        return Types.INVALID_CAST;
0969:                    else
0970:                        throw Types.castError(Reflect
0971:                                .normalizeClassName(toType), "void value",
0972:                                operation);
0973:
0974:                // unwrap Primitive fromValue to its wrapper value, etc.
0975:                Object value = null;
0976:                if (fromValue != null)
0977:                    value = fromValue.getValue();
0978:
0979:                if (toType.isPrimitive()) {
0980:                    // Trying to cast null to primitive type?
0981:                    if (fromType == null)
0982:                        if (checkOnly)
0983:                            return Types.INVALID_CAST;
0984:                        else
0985:                            throw Types.castError("primitive type:" + toType,
0986:                                    "Null value", operation);
0987:
0988:                    // fall through
0989:                } else {
0990:                    // Trying to cast primitive to an object type
0991:                    // Primitive.NULL can be cast to any object type
0992:                    if (fromType == null)
0993:                        return checkOnly ? Types.VALID_CAST : Primitive.NULL;
0994:
0995:                    if (checkOnly)
0996:                        return Types.INVALID_CAST;
0997:                    else
0998:                        throw Types.castError("object type:" + toType,
0999:                                "primitive value", operation);
1000:                }
1001:
1002:                // can only cast boolean to boolean
1003:                if (fromType == Boolean.TYPE) {
1004:                    if (toType != Boolean.TYPE)
1005:                        if (checkOnly)
1006:                            return Types.INVALID_CAST;
1007:                        else
1008:                            throw Types.castError(toType, fromType, operation);
1009:
1010:                    return checkOnly ? Types.VALID_CAST : fromValue;
1011:                }
1012:
1013:                // Do numeric cast
1014:
1015:                // Only allow legal Java assignment unless we're a CAST operation
1016:                if (operation == Types.ASSIGNMENT
1017:                        && !Types.isJavaAssignable(toType, fromType)) {
1018:                    if (checkOnly)
1019:                        return Types.INVALID_CAST;
1020:                    else
1021:                        throw Types.castError(toType, fromType, operation);
1022:                }
1023:
1024:                return checkOnly ? Types.VALID_CAST : new Primitive(
1025:                        castWrapper(toType, value));
1026:            }
1027:
1028:            public static boolean isWrapperType(Class type) {
1029:                return wrapperMap.get(type) != null && !type.isPrimitive();
1030:            }
1031:
1032:            /**
1033:            	Cast a primitive value represented by its java.lang wrapper type to the
1034:            	specified java.lang wrapper type.  e.g.  Byte(5) to Integer(5) or
1035:            	Integer(5) to Byte(5) 
1036:            	@param toType is the java TYPE type
1037:            	@param value is the value in java.lang wrapper.
1038:            	value may not be null.
1039:             */
1040:            static Object castWrapper(Class toType, Object value) {
1041:                if (!toType.isPrimitive())
1042:                    throw new InterpreterError("invalid type in castWrapper: "
1043:                            + toType);
1044:                if (value == null)
1045:                    throw new InterpreterError(
1046:                            "null value in castWrapper, guard");
1047:                if (value instanceof  Boolean) {
1048:                    if (toType != Boolean.TYPE)
1049:                        throw new InterpreterError(
1050:                                "bad wrapper cast of boolean");
1051:                    else
1052:                        return value;
1053:                }
1054:
1055:                // first promote char to Number type to avoid duplicating code
1056:                if (value instanceof  Character)
1057:                    value = new Integer(((Character) value).charValue());
1058:
1059:                if (!(value instanceof  Number))
1060:                    throw new InterpreterError("bad type in cast");
1061:
1062:                Number number = (Number) value;
1063:
1064:                if (toType == Byte.TYPE)
1065:                    return new Byte(number.byteValue());
1066:                if (toType == Short.TYPE)
1067:                    return new Short(number.shortValue());
1068:                if (toType == Character.TYPE)
1069:                    return new Character((char) number.intValue());
1070:                if (toType == Integer.TYPE)
1071:                    return new Integer(number.intValue());
1072:                if (toType == Long.TYPE)
1073:                    return new Long(number.longValue());
1074:                if (toType == Float.TYPE)
1075:                    return new Float(number.floatValue());
1076:                if (toType == Double.TYPE)
1077:                    return new Double(number.doubleValue());
1078:
1079:                throw new InterpreterError("error in wrapper cast");
1080:            }
1081:
1082:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.