more accurate parse_nat/parse_int: avoid corner cases of Int.fromString (e.g. "1.0");
authorwenzelm
Sat, 16 Dec 2017 20:02:40 +0100
changeset 67218 e62d72699666
parent 67217 53867014e299
child 67219 81e9804b2014
more accurate parse_nat/parse_int: avoid corner cases of Int.fromString (e.g. "1.0");
src/Pure/General/value.ML
--- a/src/Pure/General/value.ML	Sat Dec 16 17:23:00 2017 +0100
+++ b/src/Pure/General/value.ML	Sat Dec 16 20:02:40 2017 +0100
@@ -31,19 +31,21 @@
 
 (* nat and int *)
 
+val zero = ord "0";
+val nine = ord "9";
+
 fun parse_nat s =
-  let val i = Int.fromString s in
-    if is_none i orelse the i < 0
-    then raise Fail ("Bad natural number " ^ quote s)
-    else the i
-  end;
+  fold_string (fn c => fn n =>
+    let val i = ord c in
+      if zero <= i andalso i <= nine then 10 * n + (i - zero)
+      else raise Fail ("Bad natural number " ^ quote s)
+    end) s 0;
 
 fun parse_int s =
-  let val i = Int.fromString s in
-    if is_none i orelse String.isPrefix "~" s
-    then raise Fail ("Bad integer " ^ quote s)
-    else the i
-  end;
+  (case try (unprefix "-") s of
+    NONE => parse_nat s
+  | SOME s' => ~ (parse_nat s'))
+  handle Fail _ => raise Fail ("Bad integer " ^ quote s);
 
 val print_int = signed_string_of_int;