I noticed that the current svn code throws an exception if it sees a trailing decimal point on what would otherwise be an integer. This patch ignores them instead, but could be easily modified to throw an exception as well.
I think supporting the Java "0x" and "0" prefixes on integer literals is a generally useful thing. Please consider incorporating functionality like that of the patch into Clojure.
(reviewing this for posting, I noticed that Clojure's "IllegalArgumentException" on "Invalid number" should probably be changed to its subclass "NumberFormatException" as well.)
Index: src/jvm/clojure/lang/LispReader.java
===================================================================
--- src/jvm/clojure/lang/LispReader.java (revision 905)
+++ src/jvm/clojure/lang/LispReader.java (working copy)
@@ -42,7 +42,7 @@
//static Pattern symbolPat = Pattern.compile("[:]?([\\D&&[^:/]][^:/]*/)?[\\D&&[^:/]][^:/]*");
static Pattern symbolPat = Pattern.compile("[:]?([\\D&&[^:/]][^/]*/)?([\\D&&[^:/]][^/]*)");
//static Pattern varPat = Pattern.compile("([\\D&&[^:\\.]][^:\\.]*):([\\D&&[^:\\.]][^:\\.]*)");
-static Pattern intPat = Pattern.compile("[-+]?[0-9]+\\.?");
+static Pattern intPat = Pattern.compile("([-+]?)(?:(0)|([1-9][0-9]*)|0[xX]([0-9A-Fa-f]+)|0([0-7]+)|0[0-9]+)\\.?");
static Pattern ratioPat = Pattern.compile("([-+]?[0-9]+)/([0-9]+)");
static Pattern floatPat = Pattern.compile("[-+]?[0-9]+(\\.[0-9]+)?([eE][-+]?[0-9]+)?[M]?");
static final Symbol SLASH = Symbol.create("/");
@@ -286,8 +286,27 @@
private static Object matchNumber(String s){
Matcher m = intPat.matcher(s);
- if(m.matches())
- return Numbers.reduce(new BigInteger(s));
+ if(m.matches()) {
+ if (m.group(2) != null)
+ return 0;
+ boolean negate = (m.group(1).equals("-"));
+ String g = m.group(3);
+ if (g != null) {
+ BigInteger dec = new BigInteger(g);
+ return Numbers.reduce(negate ? dec.negate() : dec);
+ }
+ g = m.group(4);
+ if (g != null) {
+ BigInteger hex = new BigInteger(g, 16);
+ return Numbers.reduce(negate ? hex.negate() : hex);
+ }
+ g = m.group(5);
+ if (g != null) {
+ BigInteger oct = new BigInteger(g, 8);
+ return Numbers.reduce(negate ? oct.negate() : oct);
+ }
+ return null;
+ }
m = floatPat.matcher(s);
if(m.matches())
{