X-Git-Url: http://git.phpeclipse.com 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 index e09a01d..7ee1423 100644 --- 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 @@ -16,128 +16,152 @@ 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 64) return /*constant stays null*/ ; - computedValue = (computedValue< 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; + + 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); } - return tb; -} -public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { - visitor.visit(this, scope); - visitor.endVisit(this, scope); -} }