Skip to content

Commit

Permalink
Resolve #17: allow attributes in contract macro
Browse files Browse the repository at this point in the history
  • Loading branch information
ErichDonGubler committed Jul 13, 2017
1 parent dee64f0 commit a7adaa2
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 12 deletions.
56 changes: 44 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#[macro_export]
macro_rules! contract_processed {
(
$(#[$attribute: meta])*
fn $name: ident ($($args: tt : $types: ty),*)$( -> $return_type: ty)* {
$(#![$inner_attribute: meta])*
pre $pre_body: block
body $body: block
post ($return_value: ident) $post_body: block
invariant $invariant_block: block
}
) => (
$(#[$attribute])*
fn $name($($args : $types),*)$( -> $return_type)* {
$(#![$inner_attribute])*
$pre_body

$invariant_block
Expand All @@ -31,69 +35,80 @@ macro_rules! contract_processed {
#[macro_export]
macro_rules! contract_processing {
(
(pre {}, body $body: tt, post $return_value: tt $post: tt, invariant $invariant: tt)
(pre {}, body $body: tt, post $return_value: tt $post: tt, invariant $invariant: tt, $(#![$inner_attribute: meta])*)
$(#[$attribute: meta])*
fn $name: ident ($($args: tt : $types: ty),*)$( -> $return_type: ty)* {
pre $pre: block
$($tail: tt)*
}
) => {
contract_processing! {
(pre $pre, body $body, post $return_value $post, invariant $invariant)
(pre $pre, body $body, post $return_value $post, invariant $invariant, $(#![$inner_attribute])*)
$(#[$attribute])*
fn $name($($args : $types),*)$( -> $return_type)* {
$($tail)*
}
}
};
(
(pre $pre: tt, body {}, post $return_value: tt $post: tt, invariant $invariant: tt)
(pre $pre: tt, body {}, post $return_value: tt $post: tt, invariant $invariant: tt, $(#![$inner_attribute: meta])*)
$(#[$attribute: meta])*
fn $name: ident ($($args: tt : $types: ty),*)$( -> $return_type: ty)* {
body $body: tt
$($tail: tt)*
}
) => {
contract_processing! {
(pre $pre, body $body, post $return_value $post, invariant $invariant)
(pre $pre, body $body, post $return_value $post, invariant $invariant, $(#![$inner_attribute])*)
$(#[$attribute])*
fn $name($($args : $types),*)$( -> $return_type)* {
$($tail)*
}
}
};
(
(pre $pre: tt, body $body: tt, post (def) {}, invariant $invariant: tt)
(pre $pre: tt, body $body: tt, post (def) {}, invariant $invariant: tt, $(#![$inner_attribute: meta])*)
$(#[$attribute: meta])*
fn $name: ident ($($args: tt : $types: ty),*)$( -> $return_type: ty)* {
post ($return_value: ident) $post: tt
$($tail: tt)*
}
) => {
contract_processing! {
(pre $pre, body $body, post ($return_value) $post, invariant $invariant)
(pre $pre, body $body, post ($return_value) $post, invariant $invariant, $(#![$inner_attribute])*)
$(#[$attribute])*
fn $name($($args : $types),*)$( -> $return_type)* {
$($tail)*
}
}
};
(
(pre $pre: tt, body $body: tt, post $return_value: tt $post: tt, invariant {})
(pre $pre: tt, body $body: tt, post $return_value: tt $post: tt, invariant {}, $(#![$inner_attribute: meta])*)
$(#[$attribute: meta])*
fn $name: ident ($($args: tt : $types: ty),*)$( -> $return_type: ty)* {
invariant $invariant: tt
$($tail: tt)*
}
) => {
contract_processing! {
(pre $pre, body $body, post $return_value $post, invariant $invariant)
(pre $pre, body $body, post $return_value $post, invariant $invariant, $(#![$inner_attribute])*)
$(#[$attribute])*
fn $name($($args : $types),*)$( -> $return_type)* {
$($tail)*
}
}
};
(
(pre $pre: tt, body $body: tt, post $return_value: tt $post: tt, invariant $invariant: tt)
(pre $pre: tt, body $body: tt, post $return_value: tt $post: tt, invariant $invariant: tt, $(#![$inner_attribute: meta])*)
$(#[$attribute: meta])*
fn $name: ident ($($args: tt : $types: ty),*)$( -> $return_type: ty)* {
$($tail: tt)*
}
) => {
contract_processed! {
$(#[$attribute])*
fn $name($($args : $types),*)$( -> $return_type)* {
$(#![$inner_attribute])*
pre $pre
body $body
post $return_value $post
Expand All @@ -106,14 +121,31 @@ macro_rules! contract_processing {
#[macro_export]
macro_rules! contract {
(
$(#[$attribute: meta])*
fn $name: ident ($($args: tt : $types: ty),*)$( -> $return_type: ty)* {
$($block_name: ident $(($return_value: ident))* { $($block_content: tt)* })*
$(#![$inner_attribute: meta])+
$($block_name: ident $(($param: ident))* { $($block_content: tt)* })*
}
) => {
contract_processing! {
(pre {}, body {}, post (def) {}, invariant {})
(pre {}, body {}, post (def) {}, invariant {}, $(#![$inner_attribute])+)
$(#[$attribute])*
fn $name($($args : $types),*)$( -> $return_type)* {
$($block_name $(($return_value))* { $($block_content)* })*
$($block_name $(($param))* { $($block_content)* })*
}
}
};
(
$(#[$attribute: meta])*
fn $name: ident ($($args: tt : $types: ty),*)$( -> $return_type: ty)* {
$($block_name: ident $(($param: ident))* { $($block_content: tt)* })*
}
) => {
contract_processing! {
(pre {}, body {}, post (def) {}, invariant {},)
$(#[$attribute])*
fn $name($($args : $types),*)$( -> $return_type)* {
$($block_name $(($param))* { $($block_content)* })*
}
}
};
Expand Down
20 changes: 20 additions & 0 deletions tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,23 @@ fn ordering_doesnt_matter() {
sqrt(25_f64);
}

#[test]
fn attributes() {
contract! {
#[cold]
fn before() {
body {}
}
}

before();

contract! {
fn after() {
#![cold]
body {}
}
}

after();
}

0 comments on commit a7adaa2

Please sign in to comment.