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;
19 public class LongLiteral extends NumberLiteral {
22 static final Constant FORMAT_ERROR = new DoubleConstant(1.0 / 0.0); // NaN;
24 public LongLiteral(char[] token, int s, int e) {
28 public LongLiteral(char[] token, int s, int e, long value) {
33 public void computeConstant() {
34 // the overflow (when radix=10) is tested using the fact that
35 // the value should always grow during its computation
37 int length = source.length - 1; // minus one because the last char is
41 if (source[0] == '0') {
43 constant = Constant.fromValue(0L);
46 final int shift, radix;
48 if ((source[1] == 'x') | (source[1] == 'X')) {
58 while (source[j] == '0') {
59 j++; // jump over redondant zero
60 if (j == length) { // watch for 0000000000000L
61 constant = Constant.fromValue(value = 0L);
67 if ((digitValue = Character.digit(source[j++], radix)) < 0) {
68 constant = FORMAT_ERROR;
73 else if (digitValue >= 4)
75 else if (digitValue >= 2)
78 nbDigit = 1; // digitValue is not 0
79 computedValue = digitValue;
81 if ((digitValue = Character.digit(source[j++], radix)) < 0) {
82 constant = FORMAT_ERROR;
85 if ((nbDigit += shift) > 64)
86 return /* constant stays null */;
87 computedValue = (computedValue << shift) | digitValue;
91 else { // -----------case radix=10-----------------
92 long previous = computedValue = 0;
93 for (int i = 0; i < length; i++) {
95 if ((digitValue = Character.digit(source[i], 10)) < 0)
96 return /* constant stays null */;
97 previous = computedValue;
98 computedValue = 10 * computedValue + digitValue;
99 if (previous > computedValue)
100 return /* constant stays null */;
104 constant = Constant.fromValue(value = computedValue);
108 * Code generation for long literal
110 * @param currentScope
111 * net.sourceforge.phpdt.internal.compiler.lookup.BlockScope
113 * net.sourceforge.phpdt.internal.compiler.codegen.CodeStream
114 * @param valueRequired
117 // public void generateCode(BlockScope currentScope, CodeStream codeStream,
118 // boolean valueRequired) {
119 // int pc = codeStream.position;
120 // if (valueRequired)
121 // if ((implicitConversion >> 4) == T_long)
122 // codeStream.generateInlinedValue(value);
124 // codeStream.generateConstant(constant, implicitConversion);
125 // codeStream.recordPositionsFrom(pc, this.sourceStart);
127 public TypeBinding literalType(BlockScope scope) {
131 public final boolean mayRepresentMIN_VALUE() {
132 // a special autorized int literral is 9223372036854775808L
133 // which is ONE over the limit. This special case
134 // only is used in combinaison with - to denote
135 // the minimal value of int -9223372036854775808L
137 return ((source.length == 20) && (source[0] == '9')
138 && (source[1] == '2') && (source[2] == '2')
139 && (source[3] == '3') && (source[4] == '3')
140 && (source[5] == '7') && (source[6] == '2')
141 && (source[7] == '0') && (source[8] == '3')
142 && (source[9] == '6') && (source[10] == '8')
143 && (source[11] == '5') && (source[12] == '4')
144 && (source[13] == '7') && (source[14] == '7')
145 && (source[15] == '5') && (source[16] == '8')
146 && (source[17] == '0') && (source[18] == '8'));
149 public TypeBinding resolveType(BlockScope scope) {
150 // the format may be incorrect while the scanner could detect
151 // such error only on painfull tests...easier and faster here
153 TypeBinding tb = super.resolveType(scope);
154 if (constant == FORMAT_ERROR) {
155 constant = NotAConstant;
156 scope.problemReporter().constantOutOfFormat(this);
157 this.resolvedType = null;
163 public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
164 visitor.visit(this, scope);
165 visitor.endVisit(this, scope);