Refactored packagename to net.sourceforge.phpdt.internal.compiler.ast
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / LongLiteral.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/LongLiteral.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/LongLiteral.java
new file mode 100644 (file)
index 0000000..e09a01d
--- /dev/null
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.compiler.ast;
+
+import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor;
+import net.sourceforge.phpdt.internal.compiler.impl.Constant;
+import net.sourceforge.phpdt.internal.compiler.impl.DoubleConstant;
+import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
+import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
+
+
+public class LongLiteral extends NumberLiteral {
+       long value;
+       
+       static final Constant FORMAT_ERROR = new DoubleConstant(1.0/0.0); // NaN;       
+               
+public LongLiteral(char[] token, int s,int e) {
+       super(token, s,e);
+}
+public LongLiteral(char[] token, int s,int e, long value) {
+       this(token, s,e);
+       this.value = value;
+}
+public void computeConstant() {
+       //the overflow (when radix=10) is tested using the fact that
+       //the value should always grow during its computation
+
+       int length = source.length - 1; //minus one because the last char is 'l' or 'L'
+       
+       long computedValue ;
+       if (source[0] == '0')
+       {       if (length == 1) {      constant = Constant.fromValue(0L);      return; }
+               final int shift,radix;
+               int j ;
+               if ( (source[1] == 'x') | (source[1] == 'X') )
+               {       shift = 4 ; j = 2; radix = 16;}
+               else
+               {       shift = 3 ; j = 1; radix = 8;}
+               int nbDigit = 0;
+               while (source[j]=='0') 
+               {       j++; //jump over redondant zero
+                       if ( j == length)
+                       {       //watch for 0000000000000L
+                               constant = Constant.fromValue(value = 0L);
+                               return ;}}
+                               
+               int digitValue ;
+               if ((digitValue = Character.digit(source[j++],radix))   < 0 )   
+               {       constant = FORMAT_ERROR; return ;}
+               if (digitValue >= 8) nbDigit = 4;
+               else    if (digitValue >= 4) nbDigit = 3;
+                               else    if (digitValue >= 2) nbDigit = 2;
+                                               else nbDigit = 1; //digitValue is not 0
+               computedValue = digitValue ;
+               while (j<length)
+               {       if ((digitValue = Character.digit(source[j++],radix))   < 0 )   
+                       {       constant = FORMAT_ERROR; return ;}
+                       if ((nbDigit += shift) > 64) return /*constant stays null*/ ;
+                       computedValue = (computedValue<<shift) | digitValue ;}}
+
+       else
+       {       //-----------case radix=10-----------------
+               long previous = computedValue = 0;
+               for (int i = 0 ; i < length; i++) 
+               {       int digitValue ;        
+                       if ((digitValue = Character.digit(source[i], 10)) < 0 ) return /*constant stays null*/ ;
+                       previous = computedValue;
+                       computedValue = 10 * computedValue + digitValue ;
+                       if (previous > computedValue) return /*constant stays null*/;}}
+       
+       constant = Constant.fromValue(value = computedValue);
+}
+/**
+ * Code generation for long literal
+ *
+ * @param currentScope net.sourceforge.phpdt.internal.compiler.lookup.BlockScope
+ * @param codeStream net.sourceforge.phpdt.internal.compiler.codegen.CodeStream
+ * @param valueRequired boolean
+ */ 
+//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+//     int pc = codeStream.position;
+//     if (valueRequired)
+//             if ((implicitConversion >> 4) == T_long)
+//                     codeStream.generateInlinedValue(value);
+//             else
+//                     codeStream.generateConstant(constant, implicitConversion);
+//     codeStream.recordPositionsFrom(pc, this.sourceStart);
+//}
+public TypeBinding literalType(BlockScope scope) {
+       return LongBinding;
+}
+public final boolean mayRepresentMIN_VALUE(){
+       //a special autorized int literral is 9223372036854775808L
+       //which is ONE over the limit. This special case 
+       //only is used in combinaison with - to denote
+       //the minimal value of int -9223372036854775808L
+
+       return ((source.length == 20) &&
+                       (source[0] == '9') &&
+                       (source[1] == '2') &&
+                       (source[2] == '2') &&
+                       (source[3] == '3') &&                   
+                       (source[4] == '3') &&
+                       (source[5] == '7') &&
+                       (source[6] == '2') &&
+                       (source[7] == '0') &&                   
+                       (source[8] == '3') &&
+                       (source[9] == '6') &&
+                       (source[10] == '8') &&
+                       (source[11] == '5') &&
+                       (source[12] == '4') &&                  
+                       (source[13] == '7') &&
+                       (source[14] == '7') &&
+                       (source[15] == '5') &&
+                       (source[16] == '8') &&                  
+                       (source[17] == '0') &&
+                       (source[18] == '8'));}
+public TypeBinding resolveType(BlockScope scope) {
+       // the format may be incorrect while the scanner could detect
+       // such error only on painfull tests...easier and faster here
+
+       TypeBinding tb = super.resolveType(scope);
+       if (constant == FORMAT_ERROR) {
+               constant = NotAConstant;
+               scope.problemReporter().constantOutOfFormat(this);
+               this.resolvedType = null;
+               return null;
+       }
+       return tb;
+}
+public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+       visitor.visit(this, scope);
+       visitor.endVisit(this, scope);
+}
+}