let parse_integer s =
let max_int = get_max_value_of_type type_int in
let max_unsigned_int = get_max_value_of_type type_unsigned_int in
let max_long = get_max_value_of_type type_long in
let max_unsigned_long = get_max_value_of_type type_unsigned_long in
let max_long_long = get_max_value_of_type type_long_long in
let max_default = zero_big_int in
let is_octal c = '0' <= c && c <= '7' in
let length = String.length s in
let u_count = ref 0 in
let l_count = ref 0 in
for i = 0 to length - 1 do
match s.[i] with
'u' -> incr u_count
| 'U' -> incr u_count
| 'l' -> incr l_count
| 'L' -> incr l_count
| _ -> ()
done;
let decimal_type_list, octal_type_list =
match !u_count, !l_count with
0, 0 ->
[ max_int, type_int;
max_long, type_long;
max_default, type_long_long ],
[ max_int, type_int;
max_unsigned_int, type_unsigned_int;
max_long, type_long;
max_unsigned_long, type_unsigned_long;
max_long_long, type_long_long;
max_default, type_unsigned_long_long ]
| 0, 1 ->
[ max_long, type_long;
max_default, type_long_long ],
[ max_long, type_long;
max_unsigned_long, type_unsigned_long;
max_long_long, type_long_long;
max_default, type_unsigned_long_long ]
| 0, 2 ->
[ max_default, type_long_long ],
[ max_long_long, type_long_long;
max_default, type_unsigned_long_long ]
| 1, 0 ->
[ max_unsigned_int, type_unsigned_int;
max_unsigned_long, type_unsigned_long;
max_default, type_unsigned_long_long ],
[ max_unsigned_int, type_unsigned_int;
max_unsigned_long, type_unsigned_long;
max_default, type_unsigned_long_long ]
| 1, 1 ->
[ max_unsigned_long, type_unsigned_long;
max_default, type_unsigned_long_long ],
[ max_unsigned_long, type_unsigned_long;
max_default, type_unsigned_long_long ]
| 1, 2 ->
[ max_default, type_unsigned_long_long ],
[ max_default, type_unsigned_long_long ]
| _ -> failwith "parse_const"
in
let find_decimal_type n =
let rec continue = function
[] -> failwith "parse_const"
| ( max, t )::l ->
if max = max_default then
t
else if le_big_int n max then
t
else
continue l
in
continue decimal_type_list
in
let find_octal_type n =
let rec continue = function
[] -> failwith "parse_const"
| ( max, t )::l ->
if max = max_default then
t
else if le_big_int n max then
t
else
continue l
in
continue octal_type_list
in
let s = String.sub s 0 (length - !u_count - !l_count) in
let length = String.length s in
if length >= 3 && s.[0] = '0' && (s.[1] = 'x' || s.[1] = 'X') then
let n = big_int_of_number 16 2 s in
n, find_octal_type n
else if s.[0] = '0' then begin
let is_octal =
let rec continue i =
if i >= length then
true
else
if is_octal s.[i] then continue (i + 1) else false
in
continue 1
in
if is_octal then
let n = big_int_of_number 8 1 s in
n, find_octal_type n
else
let n = big_int_of_number 10 0 s in
n, find_decimal_type n
end
else
let n = big_int_of_number 10 0 s in
n, find_decimal_type n