Skip to content

Commit 9d40f25

Browse files
Merge pull request #1533 from cryspen/fix-1532
feat(hax-lib): `int!`: support hex, octal and binary literals
2 parents e8cb72f + be0da3a commit 9d40f25

File tree

4 files changed

+38
-23
lines changed

4 files changed

+38
-23
lines changed

hax-lib/macros/src/implementation.rs

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -803,33 +803,24 @@ pub fn pv_handwritten(_attr: pm::TokenStream, item: pm::TokenStream) -> pm::Toke
803803
quote! {#attr #item}.into()
804804
}
805805

806-
/// Create a mathematical integer. This macro expects a integer
807-
/// literal that consists in an optional minus sign followed by one or
808-
/// more digits.
806+
/// Create a mathematical integer. This macro expects a Rust integer
807+
/// literal without suffix.
808+
///
809+
/// ## Examples:
810+
/// - `int!(0x101010)`
811+
/// - `int!(42)`
812+
/// - `int!(0o52)`
813+
/// - `int!(0h2A)`
809814
#[proc_macro_error]
810815
#[proc_macro]
811816
pub fn int(payload: pm::TokenStream) -> pm::TokenStream {
812-
let mut tokens = payload.into_iter().peekable();
813-
let negative = matches!(tokens.peek(), Some(pm::TokenTree::Punct(p)) if p.as_char() == '-');
814-
if negative {
815-
tokens.next();
816-
}
817-
let [pm::TokenTree::Literal(lit)] = &tokens.collect::<Vec<_>>()[..] else {
818-
abort_call_site!("Expected exactly one numeric literal");
819-
};
820-
let lit = format!("{lit}");
821-
// Allow negative numbers
822-
let mut lit = lit.strip_prefix("-").unwrap_or(lit.as_str()).to_string();
823-
if let Some(faulty) = lit.chars().find(|ch| !ch.is_ascii_digit()) {
824-
abort_call_site!(format!("Expected a digit, found {faulty}"));
825-
}
826-
if negative {
827-
lit = format!("-{lit}");
817+
let n: LitInt = parse_macro_input!(payload);
818+
let suffix = n.suffix();
819+
if !suffix.is_empty() {
820+
abort_call_site!("The literal suffix `{suffix}` was unexpected.")
828821
}
829-
quote! {
830-
::hax_lib::int::Int::_unsafe_from_str(#lit)
831-
}
832-
.into()
822+
let digits = n.base10_digits();
823+
quote! {::hax_lib::int::Int::_unsafe_from_str(#digits)}.into()
833824
}
834825

835826
macro_rules! make_quoting_item_proc_macro {

test-harness/src/snapshots/toolchain__literals into-coq.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ Export hax_lib.
5050

5151
Definition math_integers (x : t_Int) `{andb (f_gt (x) (impl_Int__e_unsafe_from_str (("0"%string : string)))) (f_lt (x) (impl_Int__e_unsafe_from_str (("16"%string : string)))) = true} : t_u8 :=
5252
let _ : t_Int := f_lift ((3 : t_usize)) in
53+
let e_neg_dec := impl_Int__e_unsafe_from_str (("-340282366920938463463374607431768211455000"%string : string)) in
54+
let e_pos_dec := impl_Int__e_unsafe_from_str (("340282366920938463463374607431768211455000"%string : string)) in
55+
let e_neg_hex := impl_Int__e_unsafe_from_str (("-340282366920938463463374607431768211455000"%string : string)) in
56+
let e_pos_hex := impl_Int__e_unsafe_from_str (("340282366920938463463374607431768211455000"%string : string)) in
57+
let e_neg_octal := impl_Int__e_unsafe_from_str (("-340282366920938463463374607431768211455000"%string : string)) in
58+
let e_pos_octal := impl_Int__e_unsafe_from_str (("340282366920938463463374607431768211455000"%string : string)) in
59+
let e_neg_bin := impl_Int__e_unsafe_from_str (("-340282366920938463463374607431768211455000"%string : string)) in
60+
let e_pos_bin := impl_Int__e_unsafe_from_str (("340282366920938463463374607431768211455000"%string : string)) in
5361
let _ := f_gt (impl_Int__e_unsafe_from_str (("-340282366920938463463374607431768211455000"%string : string))) (impl_Int__e_unsafe_from_str (("340282366920938463463374607431768211455000"%string : string))) in
5462
let _ := f_lt (x) (x) in
5563
let _ := f_ge (x) (x) in

test-harness/src/snapshots/toolchain__literals into-fstar.snap

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ let math_integers (x: Hax_lib.Int.t_Int)
3838
(requires x > (0 <: Hax_lib.Int.t_Int) && x < (16 <: Hax_lib.Int.t_Int))
3939
(fun _ -> Prims.l_True) =
4040
let _:Hax_lib.Int.t_Int = Rust_primitives.Hax.Int.from_machine (mk_usize 3) in
41+
let e_neg_dec:Hax_lib.Int.t_Int = (-340282366920938463463374607431768211455000) in
42+
let e_pos_dec:Hax_lib.Int.t_Int = 340282366920938463463374607431768211455000 in
43+
let e_neg_hex:Hax_lib.Int.t_Int = (-340282366920938463463374607431768211455000) in
44+
let e_pos_hex:Hax_lib.Int.t_Int = 340282366920938463463374607431768211455000 in
45+
let e_neg_octal:Hax_lib.Int.t_Int = (-340282366920938463463374607431768211455000) in
46+
let e_pos_octal:Hax_lib.Int.t_Int = 340282366920938463463374607431768211455000 in
47+
let e_neg_bin:Hax_lib.Int.t_Int = (-340282366920938463463374607431768211455000) in
48+
let e_pos_bin:Hax_lib.Int.t_Int = 340282366920938463463374607431768211455000 in
4149
let _:bool =
4250
((-340282366920938463463374607431768211455000) <: Hax_lib.Int.t_Int) >
4351
(340282366920938463463374607431768211455000 <: Hax_lib.Int.t_Int)

tests/literals/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ use hax_lib::*;
44
#[hax_lib::requires(x > int!(0) && x < int!(16))]
55
fn math_integers(x: Int) -> u8 {
66
let _: Int = 3usize.lift();
7+
let _neg_dec = int!(-340282366920938463463374607431768211455000);
8+
let _pos_dec = int!(340282366920938463463374607431768211455000);
9+
let _neg_hex = int!(-0x3E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC18);
10+
let _pos_hex = int!(0x3E7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFC18);
11+
let _neg_octal = int!(-0o7637777777777777777777777777777777777777776030);
12+
let _pos_octal = int!(0o7637777777777777777777777777777777777777776030);
13+
let _neg_bin = int!(-0b111110011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000011000);
14+
let _pos_bin = int!(0b111110011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000011000);
715
let _ = int!(-340282366920938463463374607431768211455000)
816
> int!(340282366920938463463374607431768211455000);
917
let _ = x < x;

0 commit comments

Comments
 (0)