読者です 読者をやめる 読者になる 読者になる

( ꒪⌓꒪) ゆるよろ日記

( ゚∀゚)o彡°オパーイ!オパーイ! ( ;゚皿゚)ノシΣ フィンギィィーーッ!!!

Java SE 7 - Project Coinの整数リテラル区切り文字をScalaにも

Java SE7も Developer Preview Releaseが出てもうみんな当然のように入れてると思います。
で、JavaSE7に入るProject Coinに、整数リテラル区切り文字ってのがあります。ようは、数値リテラル中で"_"による区切りを入れることを許すって仕様です。

 int a = 123_456_789; 
 int b = 0xFF_99_66;
 int c = 0b1010_1000_1111;

Java技術最前線 - Java SE 7徹底理解 第1回 言語仕様の小さな変更 - Project Coin:ITpro


この仕様は最新のScala2.9.0にも入ってません。ScalaJavaとはコンパイラが違うから当然ですね。


f:id:yuroyoro:20110510181246p:image


で、これをScalaでも使えるようにしてみます。やり方はとっても簡単。最新のScalaコンパイラソースコードをGithubから取得して、以下のパッチを当てるだけです。

diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 4323dd5..4dd4c58 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -769,8 +769,8 @@ trait Scanners extends ScannersCommon {
       def isDigit(c: Char) = java.lang.Character isDigit c
       val base1 = if (base < 10) 10 else base 
         // read 8,9's even if format is octal, produce a malformed number error afterwards.
-      while (digit2int(ch, base1) >= 0) {
-        putChar(ch)
+      while (digit2int(ch, base1) >= 0 || ch == '_') {
+        if( ch != '_') putChar(ch)
         nextChar()
       }
       token = INTLIT


このpatchを当ててコンパイルし直すと、整数リテラル区切り文字を使ってもコンパイルエラーになりません。実装はものすごい適当だから仕様的に正しいかわからんけどねーアハハハハハハハ。


f:id:yuroyoro:20110510181247p:image


0b0111とかの2進数リテラルは面倒だからやってないけどそんなに難しくないと思う。コード修正するよりコンパイルの方が時間かかったのは内緒だぜ?