Improve handling of '_' in numeric literals
* The first character of octal literals is consumed early to
disambiguate with a literal 0, and the next character may
be '_'.
* Double.parseDouble and Float.parseFloat don't handle '_'.
MOE_MIGRATED_REVID=137779638
diff --git a/java/com/google/turbine/parse/ConstExpressionParser.java b/java/com/google/turbine/parse/ConstExpressionParser.java
index c8bca7b..3c89ffe 100644
--- a/java/com/google/turbine/parse/ConstExpressionParser.java
+++ b/java/com/google/turbine/parse/ConstExpressionParser.java
@@ -338,14 +338,14 @@
break;
case FLOAT:
try {
- value = new Const.FloatValue(Float.parseFloat(text));
+ value = new Const.FloatValue(Float.parseFloat(text.replace("_", "")));
} catch (NumberFormatException e) {
throw error("invalid float literal");
}
break;
case DOUBLE:
try {
- value = new Const.DoubleValue(Double.parseDouble(text));
+ value = new Const.DoubleValue(Double.parseDouble(text.replace("_", "")));
} catch (NumberFormatException e) {
throw error("invalid double literal");
}
diff --git a/java/com/google/turbine/parse/StreamLexer.java b/java/com/google/turbine/parse/StreamLexer.java
index 4aef7a8..2303645 100644
--- a/java/com/google/turbine/parse/StreamLexer.java
+++ b/java/com/google/turbine/parse/StreamLexer.java
@@ -751,6 +751,7 @@
case '5':
case '6':
case '7':
+ case '_':
eat();
break;
default:
diff --git a/javatests/com/google/turbine/lower/LowerIntegrationTest.java b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
index cd41dd6..6d943c4 100644
--- a/javatests/com/google/turbine/lower/LowerIntegrationTest.java
+++ b/javatests/com/google/turbine/lower/LowerIntegrationTest.java
@@ -255,6 +255,7 @@
"static_member_type_import.test",
"type_anno_qual.test",
"array_class_literal.test",
+ "underscore_literal.test",
};
List<Object[]> tests =
ImmutableList.copyOf(testCases).stream().map(x -> new Object[] {x}).collect(toList());
diff --git a/javatests/com/google/turbine/lower/testdata/underscore_literal.test b/javatests/com/google/turbine/lower/testdata/underscore_literal.test
new file mode 100644
index 0000000..a4aaac2
--- /dev/null
+++ b/javatests/com/google/turbine/lower/testdata/underscore_literal.test
@@ -0,0 +1,14 @@
+=== Test.java ===
+class Test {
+ static final double A1 = 1_000.0d;
+ static final double A2 = 1__000.0d;
+ static final double A3 = 1_0__00.0d;
+
+ static final float B1 = 1_000.0f;
+ static final float B2 = 1__000.0f;
+ static final float B3 = 1_0__00.0f;
+
+ static final long C1 = 0_000_000L;
+ static final long C2 = 0___000_000L;
+ static final long C3 = 0_000___000L;
+}
\ No newline at end of file