Refactored packagename to net.sourceforge.phpdt.internal.compiler.ast
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / IntLiteral.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.ast;
12
13 import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor;
14 import net.sourceforge.phpdt.internal.compiler.impl.Constant;
15 import net.sourceforge.phpdt.internal.compiler.impl.DoubleConstant;
16 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
17 import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
18
19
20 public class IntLiteral extends NumberLiteral {
21         public int value;
22         
23         public static final IntLiteral
24                 One = new IntLiteral(new char[]{'1'},0,0,1);//used for ++ and -- 
25
26         static final Constant FORMAT_ERROR = new DoubleConstant(1.0/0.0); // NaN;
27 public IntLiteral(char[] token, int s, int e) {
28         super(token, s,e);
29 }
30 public IntLiteral(char[] token, int s,int e, int value) {
31         this(token, s,e);
32         this.value = value;
33 }
34 public IntLiteral(int intValue) {
35         //special optimized constructor : the cst is the argument 
36
37         //value that should not be used
38         //      tokens = null ;
39         //      sourceStart = 0;
40         //      sourceEnd = 0;
41         super(null,0,0);
42         constant = Constant.fromValue(intValue);
43         value = intValue;
44         
45 }
46 public void computeConstant() {
47         //a special constant is use for the potential Integer.MAX_VALUE+1
48         //which is legal if used with a - as prefix....cool....
49         //notice that Integer.MIN_VALUE  == -2147483648
50
51         long MAX = Integer.MAX_VALUE;
52         if (this == One) {      constant = Constant.One; return ;}
53         
54         int length = source.length;
55         long computedValue = 0L;
56         if (source[0] == '0')
57         {       MAX = 0xFFFFFFFFL ; //a long in order to be positive !  
58                 if (length == 1) {      constant = Constant.fromValue(0); return ;}
59                 final int shift,radix;
60                 int j ;
61                 if ( (source[1] == 'x') | (source[1] == 'X') )
62                 {       shift = 4 ; j = 2; radix = 16;}
63                 else
64                 {       shift = 3 ; j = 1; radix = 8;}
65                 while (source[j]=='0') 
66                 {       j++; //jump over redondant zero
67                         if (j == length)
68                         {       //watch for 000000000000000000  :-(
69                                 constant = Constant.fromValue(value = (int)computedValue);
70                                 return ;}}
71                 
72                 while (j<length)
73                 {       int digitValue ;
74                         if ((digitValue = Character.digit(source[j++],radix))   < 0 )   
75                         {       constant = FORMAT_ERROR; return ;}
76                         computedValue = (computedValue<<shift) | digitValue ;
77                         if (computedValue > MAX) return /*constant stays null*/ ;}}
78         else
79         {       //-----------regular case : radix = 10-----------
80                 for (int i = 0 ; i < length;i++)
81                 {       int digitValue ;
82                         if ((digitValue = Character.digit(source[i],10))        < 0 ) 
83                         {       constant = FORMAT_ERROR; return ;}
84                         computedValue = 10*computedValue + digitValue;
85                         if (computedValue > MAX) return /*constant stays null*/ ; }}
86
87         constant = Constant.fromValue(value = (int)computedValue);
88                 
89 }
90 /**
91  * Code generation for int literal
92  *
93  * @param currentScope net.sourceforge.phpdt.internal.compiler.lookup.BlockScope
94  * @param codeStream net.sourceforge.phpdt.internal.compiler.codegen.CodeStream
95  * @param valueRequired boolean
96  */ 
97 //public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
98 //      int pc = codeStream.position;
99 //      if (valueRequired)
100 //              if ((implicitConversion >> 4) == T_int)
101 //                      codeStream.generateInlinedValue(value);
102 //              else
103 //                      codeStream.generateConstant(constant, implicitConversion);
104 //      codeStream.recordPositionsFrom(pc, this.sourceStart);
105 //}
106 public TypeBinding literalType(BlockScope scope) {
107         return IntBinding;
108 }
109 public final boolean mayRepresentMIN_VALUE(){
110         //a special autorized int literral is 2147483648
111         //which is ONE over the limit. This special case 
112         //only is used in combinaison with - to denote
113         //the minimal value of int -2147483648
114
115         return ((source.length == 10) &&
116                         (source[0] == '2') &&
117                         (source[1] == '1') &&
118                         (source[2] == '4') &&
119                         (source[3] == '7') &&                   
120                         (source[4] == '4') &&
121                         (source[5] == '8') &&
122                         (source[6] == '3') &&
123                         (source[7] == '6') &&                   
124                         (source[8] == '4') &&
125                         (source[9] == '8'));}
126 public TypeBinding resolveType(BlockScope scope) {
127         // the format may be incorrect while the scanner could detect
128         // such an error only on painfull tests...easier and faster here
129
130         TypeBinding tb = super.resolveType(scope);
131         if (constant == FORMAT_ERROR) {
132                 constant = NotAConstant;
133                 scope.problemReporter().constantOutOfFormat(this);
134                 this.resolvedType = null;
135                 return null;
136         }
137         return tb;
138 }
139 public String toStringExpression(){
140
141         if (source == null)
142         /* special optimized IntLiteral that are created by the compiler */
143                 return String.valueOf(value);
144                 
145         return super.toStringExpression();}
146 public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
147         visitor.visit(this, scope);
148         visitor.endVisit(this, scope);
149 }
150 }