Adds emulation of Integer.parseInt

This commit is contained in:
konsoletyper 2014-02-10 16:34:40 +04:00
parent 0f2bf64975
commit e094fe4192
4 changed files with 99 additions and 7 deletions

View File

@ -66,5 +66,5 @@ public class TClass<T> extends TObject {
static native TClass<TBoolean> booleanClass(); static native TClass<TBoolean> booleanClass();
@InjectedBy(ClassNativeGenerator.class) @InjectedBy(ClassNativeGenerator.class)
static native TClass<TInteger> integerClass(); static native TClass<TInteger> intClass();
} }

View File

@ -21,15 +21,19 @@ package org.teavm.classlib.java.lang;
*/ */
public class TInteger extends TNumber implements TComparable<TInteger> { public class TInteger extends TNumber implements TComparable<TInteger> {
public static final int SIZE = 32; public static final int SIZE = 32;
public static final int MIN_VALUE = (2 << (SIZE - 1)); public static final int MIN_VALUE = 0x80000000;
public static final int MAX_VALUE = (2 << (SIZE - 1)) - 1; public static final int MAX_VALUE = 0x7FFFFFFF;
public static final TClass<TInteger> TYPE = TClass.integerClass(); public static final TClass<TInteger> TYPE = TClass.intClass();
private int value; private int value;
public TInteger(int value) { public TInteger(int value) {
this.value = value; this.value = value;
} }
public TInteger(TString s) throws NumberFormatException {
this(parseInt(s));
}
@Override @Override
public int compareTo(TInteger other) { public int compareTo(TInteger other) {
return compare(value, other.value); return compare(value, other.value);
@ -59,7 +63,46 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
return x > y ? 1 : x < y ? -1 : 0; return x > y ? 1 : x < y ? -1 : 0;
} }
/*public static int parseInt(TString s, int radix) throws TNumberFormatException { public static int parseInt(TString s, int radix) throws TNumberFormatException {
return 0; if (radix < TCharacter.MIN_RADIX || radix > TCharacter.MAX_RADIX) {
}*/ throw new TNumberFormatException(TString.wrap("Illegal radix: " + radix));
}
if (s == null || s.isEmpty()) {
throw new TNumberFormatException(TString.wrap("String is null or empty"));
}
boolean negative = false;
int index = 0;
switch (s.charAt(0)) {
case '-':
negative = true;
index = 1;
break;
case '+':
index = 1;
break;
}
int value = 0;
while (index < s.length()) {
int digit = TCharacter.digit(s.charAt(index++));
if (digit < 0) {
throw new TNumberFormatException(TString.wrap("String contains invalid digits: " + s));
}
if (digit >= radix) {
throw new TNumberFormatException(TString.wrap("String contains digits out of radix " + radix +
": " + s));
}
value = radix * value + digit;
if (value < 0) {
if (index == s.length() && value == MIN_VALUE && negative) {
return MIN_VALUE;
}
throw new TNumberFormatException(TString.wrap("The value is too big for int type: " + s));
}
}
return negative ? -value : value;
}
public static int parseInt(TString s) throws TNumberFormatException {
return parseInt(s, 10);
}
} }

View File

@ -0,0 +1,48 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.classlib.java.lang;
import static org.junit.Assert.*;
import org.junit.Test;
/**
*
* @author Alexey Andreev
*/
public class IntegerTest {
@Test
public void parsesInteger() {
assertEquals(0, Integer.parseInt("0", 10));
assertEquals(473, Integer.parseInt("473", 10));
assertEquals(42, Integer.parseInt("+42", 10));
assertEquals(0, Integer.parseInt("-0", 10));
assertEquals(-255, Integer.parseInt("-FF", 16));
assertEquals(102, Integer.parseInt("1100110", 2));
assertEquals(2147483647, Integer.parseInt("2147483647", 10));
assertEquals(-2147483648, Integer.parseInt("-2147483648", 10));
assertEquals(411787, Integer.parseInt("Kona", 27));
}
@Test(expected = NumberFormatException.class)
public void rejectsTooBigInteger() {
Integer.parseInt("2147483648", 10);
}
@Test(expected = NumberFormatException.class)
public void rejectsIntegerWithDigitsOutOfRadix() {
Integer.parseInt("99", 8);
}
}

View File

@ -49,6 +49,7 @@ class BlockRefCountVisitor implements StatementVisitor {
@Override @Override
public void visit(SwitchStatement statement) { public void visit(SwitchStatement statement) {
refs.put(statement, 0);
for (SwitchClause clause : statement.getClauses()) { for (SwitchClause clause : statement.getClauses()) {
for (Statement part : clause.getBody()) { for (Statement part : clause.getBody()) {
part.acceptVisitor(this); part.acceptVisitor(this);