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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.ast;
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;
20 public class LongLiteral extends NumberLiteral {
23 static final Constant FORMAT_ERROR = new DoubleConstant(1.0/0.0); // NaN;
25 public LongLiteral(char[] token, int s,int e) {
28 public LongLiteral(char[] token, int s,int e, long value) {
32 public void computeConstant() {
33 //the overflow (when radix=10) is tested using the fact that
34 //the value should always grow during its computation
36 int length = source.length - 1; //minus one because the last char is 'l' or 'L'
40 { if (length == 1) { constant = Constant.fromValue(0L); return; }
41 final int shift,radix;
43 if ( (source[1] == 'x') | (source[1] == 'X') )
44 { shift = 4 ; j = 2; radix = 16;}
46 { shift = 3 ; j = 1; radix = 8;}
48 while (source[j]=='0')
49 { j++; //jump over redondant zero
51 { //watch for 0000000000000L
52 constant = Constant.fromValue(value = 0L);
56 if ((digitValue = Character.digit(source[j++],radix)) < 0 )
57 { constant = FORMAT_ERROR; return ;}
58 if (digitValue >= 8) nbDigit = 4;
59 else if (digitValue >= 4) nbDigit = 3;
60 else if (digitValue >= 2) nbDigit = 2;
61 else nbDigit = 1; //digitValue is not 0
62 computedValue = digitValue ;
64 { if ((digitValue = Character.digit(source[j++],radix)) < 0 )
65 { constant = FORMAT_ERROR; return ;}
66 if ((nbDigit += shift) > 64) return /*constant stays null*/ ;
67 computedValue = (computedValue<<shift) | digitValue ;}}
70 { //-----------case radix=10-----------------
71 long previous = computedValue = 0;
72 for (int i = 0 ; i < length; i++)
74 if ((digitValue = Character.digit(source[i], 10)) < 0 ) return /*constant stays null*/ ;
75 previous = computedValue;
76 computedValue = 10 * computedValue + digitValue ;
77 if (previous > computedValue) return /*constant stays null*/;}}
79 constant = Constant.fromValue(value = computedValue);
82 * Code generation for long literal
84 * @param currentScope net.sourceforge.phpdt.internal.compiler.lookup.BlockScope
85 * @param codeStream net.sourceforge.phpdt.internal.compiler.codegen.CodeStream
86 * @param valueRequired boolean
88 //public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
89 // int pc = codeStream.position;
91 // if ((implicitConversion >> 4) == T_long)
92 // codeStream.generateInlinedValue(value);
94 // codeStream.generateConstant(constant, implicitConversion);
95 // codeStream.recordPositionsFrom(pc, this.sourceStart);
97 public TypeBinding literalType(BlockScope scope) {
100 public final boolean mayRepresentMIN_VALUE(){
101 //a special autorized int literral is 9223372036854775808L
102 //which is ONE over the limit. This special case
103 //only is used in combinaison with - to denote
104 //the minimal value of int -9223372036854775808L
106 return ((source.length == 20) &&
107 (source[0] == '9') &&
108 (source[1] == '2') &&
109 (source[2] == '2') &&
110 (source[3] == '3') &&
111 (source[4] == '3') &&
112 (source[5] == '7') &&
113 (source[6] == '2') &&
114 (source[7] == '0') &&
115 (source[8] == '3') &&
116 (source[9] == '6') &&
117 (source[10] == '8') &&
118 (source[11] == '5') &&
119 (source[12] == '4') &&
120 (source[13] == '7') &&
121 (source[14] == '7') &&
122 (source[15] == '5') &&
123 (source[16] == '8') &&
124 (source[17] == '0') &&
125 (source[18] == '8'));}
126 public TypeBinding resolveType(BlockScope scope) {
127 // the format may be incorrect while the scanner could detect
128 // such error only on painfull tests...easier and faster here
130 TypeBinding tb = super.resolveType(scope);
131 if (constant == FORMAT_ERROR) {
132 constant = NotAConstant;
133 scope.problemReporter().constantOutOfFormat(this);
134 this.resolvedType = null;
139 public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
140 visitor.visit(this, scope);
141 visitor.endVisit(this, scope);