diff options
| author | Brendan Zabarauskas <bjzaba@yahoo.com.au> | 2013-05-09 01:38:39 +1000 |
|---|---|---|
| committer | Brendan Zabarauskas <bjzaba@yahoo.com.au> | 2013-05-15 07:02:43 +1000 |
| commit | b9824e18c2b02d74bd1bf646fea5f05477ca5071 (patch) | |
| tree | 855c8c7f4c9f59d9790a4ee9ac74bf7d0f587735 | |
| parent | d217174987466010cd8810179c5fdb7ae4a126d0 (diff) | |
| download | rust-b9824e18c2b02d74bd1bf646fea5f05477ca5071.tar.gz rust-b9824e18c2b02d74bd1bf646fea5f05477ca5071.zip | |
Add Scheme-style `cond!` macro to syntax::ext::expand
Addresses issue #6037
| -rw-r--r-- | src/libstd/fun_treemap.rs | 51 | ||||
| -rw-r--r-- | src/libstd/std.rc | 1 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 36 | ||||
| -rw-r--r-- | src/test/run-pass/cond-macro-no-default.rs | 23 | ||||
| -rw-r--r-- | src/test/run-pass/cond-macro.rs | 23 |
5 files changed, 105 insertions, 29 deletions
diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs index 3bffeddbe09..30edd535a88 100644 --- a/src/libstd/fun_treemap.rs +++ b/src/libstd/fun_treemap.rs @@ -33,45 +33,40 @@ enum TreeNode<K, V> { pub fn init<K, V>() -> Treemap<K, V> { @Empty } /// Insert a value into the map -pub fn insert<K:Copy + Eq + Ord,V:Copy>(m: Treemap<K, V>, k: K, v: V) - -> Treemap<K, V> { +pub fn insert<K:Copy + Eq + Ord,V:Copy>(m: Treemap<K, V>, k: K, v: V) -> Treemap<K, V> { @match m { - @Empty => Node(@k, @v, @Empty, @Empty), - @Node(@copy kk, vv, left, right) => { - if k < kk { - Node(@kk, vv, insert(left, k, v), right) - } else if k == kk { - Node(@kk, @v, left, right) - } else { Node(@kk, vv, left, insert(right, k, v)) } - } - } + @Empty => Node(@k, @v, @Empty, @Empty), + @Node(@copy kk, vv, left, right) => cond!( + | k < kk { Node(@kk, vv, insert(left, k, v), right) } + | k == kk { Node(@kk, @v, left, right) } + _ { Node(@kk, vv, left, insert(right, k, v)) } + ) + } } /// Find a value based on the key pub fn find<K:Eq + Ord,V:Copy>(m: Treemap<K, V>, k: K) -> Option<V> { match *m { - Empty => None, - Node(@ref kk, @copy v, left, right) => { - if k == *kk { - Some(v) - } else if k < *kk { find(left, k) } else { find(right, k) } - } + Empty => None, + Node(@ref kk, @copy v, left, right) => cond!( + | k == *kk { Some(v) } + | k < *kk { find(left, k) } + _ { find(right, k) } + ) } } /// Visit all pairs in the map in order. pub fn traverse<K, V: Copy>(m: Treemap<K, V>, f: &fn(&K, &V)) { match *m { - Empty => (), - /* - Previously, this had what looked like redundant - matches to me, so I changed it. but that may be a - de-optimization -- tjc - */ - Node(@ref k, @ref v, left, right) => { - traverse(left, f); - f(k, v); - traverse(right, f); - } + Empty => (), + // Previously, this had what looked like redundant + // matches to me, so I changed it. but that may be a + // de-optimization -- tjc + Node(@ref k, @ref v, left, right) => { + traverse(left, f); + f(k, v); + traverse(right, f); + } } } diff --git a/src/libstd/std.rc b/src/libstd/std.rc index 915aab59a71..d29791449b6 100644 --- a/src/libstd/std.rc +++ b/src/libstd/std.rc @@ -63,6 +63,7 @@ pub mod flatpipes; pub mod bitv; pub mod deque; +#[cfg(not(stage0))] pub mod fun_treemap; pub mod list; pub mod priority_queue; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9afbe1e479d..ad1da0a8685 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -542,7 +542,41 @@ pub fn core_macros() -> ~str { } ) - + // + // A scheme-style conditional that helps to improve code clarity in some instances when + // the `if`, `else if`, and `else` keywords obscure predicates undesirably. + // + // # Example + // + // ~~~ + // let clamped = + // if x > mx { mx } + // else if x < mn { mn } + // else { x }; + // ~~~ + // + // Using `cond!`, the above could be written as: + // + // ~~~ + // let clamped = cond!( + // | x > mx { mx } + // | x < mn { mn } + // _ { x } + // ); + // ~~~ + // + // The optional default case is denoted by `_`. + // + macro_rules! cond ( + ($( | $pred:expr $body:block)+ _ $default:block ) => ( + $(if $pred $body else)+ + $default + ); + // for if the default case was ommitted + ( $( | $pred:expr $body:block )+ ) => ( + $(if $pred $body)else+ + ); + ) }"; } diff --git a/src/test/run-pass/cond-macro-no-default.rs b/src/test/run-pass/cond-macro-no-default.rs new file mode 100644 index 00000000000..b8280c30e08 --- /dev/null +++ b/src/test/run-pass/cond-macro-no-default.rs @@ -0,0 +1,23 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn clamp<T:Copy + Ord + Signed>(x: T, mn: T, mx: T) -> T { + cond!( + | x > mx { return mx; } + | x < mn { return mn; } + ) + return x; +} + +fn main() { + assert_eq!(clamp(1, 2, 4), 2); + assert_eq!(clamp(8, 2, 4), 4); + assert_eq!(clamp(3, 2, 4), 3); +} \ No newline at end of file diff --git a/src/test/run-pass/cond-macro.rs b/src/test/run-pass/cond-macro.rs new file mode 100644 index 00000000000..ebe1cbbfd82 --- /dev/null +++ b/src/test/run-pass/cond-macro.rs @@ -0,0 +1,23 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn clamp<T:Copy + Ord + Signed>(x: T, mn: T, mx: T) -> T { + cond!( + | x > mx { mx } + | x < mn { mn } + _ { x } + ) +} + +fn main() { + assert_eq!(clamp(1, 2, 4), 2); + assert_eq!(clamp(8, 2, 4), 4); + assert_eq!(clamp(3, 2, 4), 3); +} \ No newline at end of file |
