Skip to content

make for parse as foreach does #8244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 3, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions doc/tutorial-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,19 +164,18 @@ dropped when they become unnecessary.

## For loops

The `foreach` keyword is transitional, and is going to replace the current
obsolete `for` loop.
The `for` keyword can be used as sugar for iterating through any iterator:

~~~
let xs = [2, 3, 5, 7, 11, 13, 17];

// print out all the elements in the vector
foreach x in xs.iter() {
for x in xs.iter() {
println(x.to_str())
}

// print out all but the first 3 elements in the vector
foreach x in xs.iter().skip(3) {
for x in xs.iter().skip(3) {
println(x.to_str())
}
~~~
Expand All @@ -192,7 +191,7 @@ let ys = ["foo", "bar", "baz", "foobar"];
let mut it = xs.iter().zip(ys.iter());

// print out the pairs of elements up to (&3, &"baz")
foreach (x, y) in it {
for (x, y) in it {
printfln!("%d %s", *x, *y);

if *x == 3 {
Expand Down Expand Up @@ -229,7 +228,7 @@ impl<A, T: Iterator<A>> FromIterator<A, T> for ~[A] {
pub fn from_iterator(iterator: &mut T) -> ~[A] {
let (lower, _) = iterator.size_hint();
let mut xs = with_capacity(lower);
foreach x in iterator {
for x in iterator {
xs.push(x);
}
xs
Expand Down Expand Up @@ -300,7 +299,7 @@ printfln!("%?", it.next()); // prints `Some(&2)`
printfln!("%?", it.next_back()); // prints `Some(&6)`

// prints `5`, `4` and `3`
foreach &x in it.invert() {
for &x in it.invert() {
printfln!("%?", x)
}
~~~
Expand All @@ -319,7 +318,7 @@ let mut it = xs.iter().chain_(ys.iter()).transform(|&x| x * 2);
printfln!("%?", it.next()); // prints `Some(2)`

// prints `16`, `14`, `12`, `10`, `8`, `6`, `4`
foreach x in it.invert() {
for x in it.invert() {
printfln!("%?", x);
}
~~~
Expand Down
17 changes: 6 additions & 11 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -567,11 +567,6 @@ loop {
This code prints out a weird sequence of numbers and stops as soon as
it finds one that can be divided by five.

Rust also has a `for` construct. It's different from C's `for` and it works
best when iterating over collections. See the section on [closures](#closures)
to find out how to use `for` and higher-order functions for enumerating
elements of a collection.

# Data structures

## Structs
Expand Down Expand Up @@ -1397,8 +1392,8 @@ assert!(crayons.len() == 3);
assert!(!crayons.is_empty());

// Iterate over a vector, obtaining a pointer to each element
// (`for` is explained in the next section)
foreach crayon in crayons.iter() {
// (`for` is explained in the container/iterator tutorial)
for crayon in crayons.iter() {
let delicious_crayon_wax = unwrap_crayon(*crayon);
eat_crayon_wax(delicious_crayon_wax);
}
Expand Down Expand Up @@ -1749,7 +1744,7 @@ of `vector`:
~~~~
fn map<T, U>(vector: &[T], function: &fn(v: &T) -> U) -> ~[U] {
let mut accumulator = ~[];
foreach element in vector.iter() {
for element in vector.iter() {
accumulator.push(function(element));
}
return accumulator;
Expand Down Expand Up @@ -2027,7 +2022,7 @@ generic types.
~~~~
# trait Printable { fn print(&self); }
fn print_all<T: Printable>(printable_things: ~[T]) {
foreach thing in printable_things.iter() {
for thing in printable_things.iter() {
thing.print();
}
}
Expand Down Expand Up @@ -2073,7 +2068,7 @@ However, consider this function:
trait Drawable { fn draw(&self); }

fn draw_all<T: Drawable>(shapes: ~[T]) {
foreach shape in shapes.iter() { shape.draw(); }
for shape in shapes.iter() { shape.draw(); }
}
# let c: Circle = new_circle();
# draw_all(~[c]);
Expand All @@ -2088,7 +2083,7 @@ an _object_.
~~~~
# trait Drawable { fn draw(&self); }
fn draw_all(shapes: &[@Drawable]) {
foreach shape in shapes.iter() { shape.draw(); }
for shape in shapes.iter() { shape.draw(); }
}
~~~~

Expand Down
24 changes: 14 additions & 10 deletions src/compiletest/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
let mut pp_exact = None;
let mut debugger_cmds = ~[];
let mut check_lines = ~[];
for iter_header(testfile) |ln| {
do iter_header(testfile) |ln| {
match parse_error_pattern(ln) {
Some(ep) => error_patterns.push(ep),
None => ()
Expand Down Expand Up @@ -74,6 +74,8 @@ pub fn load_props(testfile: &Path) -> TestProps {
Some(cl) => check_lines.push(cl),
None => ()
};

true
};
return TestProps {
error_patterns: error_patterns,
Expand All @@ -87,17 +89,19 @@ pub fn load_props(testfile: &Path) -> TestProps {
}

pub fn is_test_ignored(config: &config, testfile: &Path) -> bool {
for iter_header(testfile) |ln| {
if parse_name_directive(ln, "xfail-test") { return true; }
if parse_name_directive(ln, xfail_target()) { return true; }
if config.mode == common::mode_pretty &&
parse_name_directive(ln, "xfail-pretty") { return true; }
};
return false;

fn xfail_target() -> ~str {
~"xfail-" + os::SYSNAME
}

let val = do iter_header(testfile) |ln| {
if parse_name_directive(ln, "xfail-test") { false }
else if parse_name_directive(ln, xfail_target()) { false }
else if config.mode == common::mode_pretty &&
parse_name_directive(ln, "xfail-pretty") { false }
else { true }
};

!val
}

fn iter_header(testfile: &Path, it: &fn(~str) -> bool) -> bool {
Expand All @@ -109,7 +113,7 @@ fn iter_header(testfile: &Path, it: &fn(~str) -> bool) -> bool {
// module or function. This doesn't seem to be an optimization
// with a warm page cache. Maybe with a cold one.
if ln.starts_with("fn") || ln.starts_with("mod") {
return false;
return true;
} else { if !(it(ln)) { return false; } }
}
return true;
Expand Down
41 changes: 22 additions & 19 deletions src/libextra/bitv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,14 @@ impl BigBitv {
#[inline]
pub fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
let len = b.storage.len();
for uint::iterate(0, len) |i| {
do uint::iterate(0, len) |i| {
let mask = big_mask(nbits, i);
if mask & self.storage[i] != mask & b.storage[i] {
return false;
false
} else {
true
}
}
return true;
}
}

Expand Down Expand Up @@ -358,7 +359,7 @@ impl Bitv {
pub fn clear(&mut self) {
match self.rep {
Small(ref mut b) => b.clear(),
Big(ref mut s) => for s.each_storage() |w| { *w = 0u }
Big(ref mut s) => { do s.each_storage() |w| { *w = 0u; true }; }
}
}

Expand All @@ -367,15 +368,17 @@ impl Bitv {
pub fn set_all(&mut self) {
match self.rep {
Small(ref mut b) => b.set_all(),
Big(ref mut s) => for s.each_storage() |w| { *w = !0u } }
Big(ref mut s) => { do s.each_storage() |w| { *w = !0u; true }; }
}
}

/// Invert all bits
#[inline]
pub fn negate(&mut self) {
match self.rep {
Small(ref mut b) => b.negate(),
Big(ref mut s) => for s.each_storage() |w| { *w = !*w } }
Big(ref mut s) => { do s.each_storage() |w| { *w = !*w; true }; }
}
}

/**
Expand Down Expand Up @@ -718,11 +721,11 @@ impl BitvSet {
}

pub fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool {
for self.common_iter(other).advance |(i, w1, w2)| {
foreach (i, w1, w2) in self.common_iter(other) {
if !iterate_bits(i, w1 & !w2, |b| f(&b)) {
return false;
return false
}
}
};
/* everything we have that they don't also shows up */
self.outlier_iter(other).advance(|(mine, i, w)|
!mine || iterate_bits(i, w, |b| f(&b))
Expand All @@ -731,11 +734,11 @@ impl BitvSet {

pub fn symmetric_difference(&self, other: &BitvSet,
f: &fn(&uint) -> bool) -> bool {
for self.common_iter(other).advance |(i, w1, w2)| {
foreach (i, w1, w2) in self.common_iter(other) {
if !iterate_bits(i, w1 ^ w2, |b| f(&b)) {
return false;
return false
}
}
};
self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
}

Expand All @@ -744,11 +747,11 @@ impl BitvSet {
}

pub fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool {
for self.common_iter(other).advance |(i, w1, w2)| {
foreach (i, w1, w2) in self.common_iter(other) {
if !iterate_bits(i, w1 | w2, |b| f(&b)) {
return false;
return false
}
}
};
self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
}
}
Expand All @@ -758,12 +761,12 @@ impl cmp::Eq for BitvSet {
if self.size != other.size {
return false;
}
for self.common_iter(other).advance |(_, w1, w2)| {
foreach (_, w1, w2) in self.common_iter(other) {
if w1 != w2 {
return false;
}
}
for self.outlier_iter(other).advance |(_, _, w)| {
foreach (_, _, w) in self.outlier_iter(other) {
if w != 0 {
return false;
}
Expand Down Expand Up @@ -798,15 +801,15 @@ impl Set<uint> for BitvSet {
}

fn is_subset(&self, other: &BitvSet) -> bool {
for self.common_iter(other).advance |(_, w1, w2)| {
foreach (_, w1, w2) in self.common_iter(other) {
if w1 & w2 != w1 {
return false;
}
}
/* If anything is not ours, then everything is not ours so we're
definitely a subset in that case. Otherwise if there's any stray
ones that 'other' doesn't have, we're not a subset. */
for self.outlier_iter(other).advance |(mine, _, w)| {
foreach (mine, _, w) in self.outlier_iter(other) {
if !mine {
return true;
} else if w != 0 {
Expand Down
20 changes: 12 additions & 8 deletions src/libextra/crypto/sha2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ impl Engine512State {

// Putting the message schedule inside the same loop as the round calculations allows for
// the compiler to generate better code.
for uint::range_step(0, 64, 8) |t| {
do uint::range_step(0, 64, 8) |t| {
schedule_round!(t + 16);
schedule_round!(t + 17);
schedule_round!(t + 18);
Expand All @@ -130,9 +130,10 @@ impl Engine512State {
sha2_round!(d, e, f, g, h, a, b, c, K64, t + 5);
sha2_round!(c, d, e, f, g, h, a, b, K64, t + 6);
sha2_round!(b, c, d, e, f, g, h, a, K64, t + 7);
}
true
};

for uint::range_step(64, 80, 8) |t| {
do uint::range_step(64, 80, 8) |t| {
sha2_round!(a, b, c, d, e, f, g, h, K64, t);
sha2_round!(h, a, b, c, d, e, f, g, K64, t + 1);
sha2_round!(g, h, a, b, c, d, e, f, K64, t + 2);
Expand All @@ -141,7 +142,8 @@ impl Engine512State {
sha2_round!(d, e, f, g, h, a, b, c, K64, t + 5);
sha2_round!(c, d, e, f, g, h, a, b, K64, t + 6);
sha2_round!(b, c, d, e, f, g, h, a, K64, t + 7);
}
true
};

self.H0 += a;
self.H1 += b;
Expand Down Expand Up @@ -507,7 +509,7 @@ impl Engine256State {

// Putting the message schedule inside the same loop as the round calculations allows for
// the compiler to generate better code.
for uint::range_step(0, 48, 8) |t| {
do uint::range_step(0, 48, 8) |t| {
schedule_round!(t + 16);
schedule_round!(t + 17);
schedule_round!(t + 18);
Expand All @@ -525,9 +527,10 @@ impl Engine256State {
sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
}
true
};

for uint::range_step(48, 64, 8) |t| {
do uint::range_step(48, 64, 8) |t| {
sha2_round!(a, b, c, d, e, f, g, h, K32, t);
sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
Expand All @@ -536,7 +539,8 @@ impl Engine256State {
sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
}
true
};

self.H0 += a;
self.H1 += b;
Expand Down
Loading