<commit_before>// Copyright 2012 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.

/*!

The `Ord` and `Eq` comparison traits

This module contains the definition of both `Ord` and `Eq` which define
the common interfaces for doing comparison. Both are language items
that the compiler uses to implement the comparison operators. Rust code
may implement `Ord` to overload the `<`, `<=`, `>`, and `>=` operators,
and `Eq` to overload the `==` and `!=` operators.

*/

/**
* Trait for values that can be compared for equality
* and inequality.
*
* Eventually this may be simplified to only require
* an `eq` method, with the other generated from
* a default implementation. However it should
* remain possible to implement `ne` separately, for
* compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="eq"]
pub trait Eq {
    fn eq(&self, other: &Self) -> bool;
    fn ne(&self, other: &Self) -> bool;
}

#[deriving(Eq)]
pub enum Ordering { Less, Equal, Greater }

/// Trait for types that form a total order
pub trait TotalOrd {
    fn cmp(&self, other: &Self) -> Ordering;
}

#[inline(always)]
fn icmp<T: Ord>(a: &T, b: &T) -> Ordering {
    if *a < *b { Less }
    else if *a > *b { Greater }
    else { Equal }
}

impl TotalOrd for u8 {
    #[inline(always)]
    fn cmp(&self, other: &u8) -> Ordering { icmp(self, other) }
}

impl TotalOrd for u16 {
    #[inline(always)]
    fn cmp(&self, other: &u16) -> Ordering { icmp(self, other) }
}

impl TotalOrd for u32 {
    #[inline(always)]
    fn cmp(&self, other: &u32) -> Ordering { icmp(self, other) }
}

impl TotalOrd for u64 {
    #[inline(always)]
    fn cmp(&self, other: &u64) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i8 {
    #[inline(always)]
    fn cmp(&self, other: &i8) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i16 {
    #[inline(always)]
    fn cmp(&self, other: &i16) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i32 {
    #[inline(always)]
    fn cmp(&self, other: &i32) -> Ordering { icmp(self, other) }
}

impl TotalOrd for i64 {
    #[inline(always)]
    fn cmp(&self, other: &i64) -> Ordering { icmp(self, other) }
}

impl TotalOrd for int {
    #[inline(always)]
    fn cmp(&self, other: &int) -> Ordering { icmp(self, other) }
}

impl TotalOrd for uint {
    #[inline(always)]
    fn cmp(&self, other: &uint) -> Ordering { icmp(self, other) }
}

/**
* Trait for values that can be compared for a sort-order.
*
* Eventually this may be simplified to only require
* an `le` method, with the others generated from
* default implementations. However it should remain
* possible to implement the others separately, for
* compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="ord"]
pub trait Ord {
    fn lt(&self, other: &Self) -> bool;
    fn le(&self, other: &Self) -> bool;
    fn ge(&self, other: &Self) -> bool;
    fn gt(&self, other: &Self) -> bool;
}

#[inline(always)]
pub fn lt<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).lt(v2)
}

#[inline(always)]
pub fn le<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).le(v2)
}

#[inline(always)]
pub fn eq<T:Eq>(v1: &T, v2: &T) -> bool {
    (*v1).eq(v2)
}

#[inline(always)]
pub fn ne<T:Eq>(v1: &T, v2: &T) -> bool {
    (*v1).ne(v2)
}

#[inline(always)]
pub fn ge<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).ge(v2)
}

#[inline(always)]
pub fn gt<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).gt(v2)
}

/// The equivalence relation. Two values may be equivalent even if they are
/// of different types. The most common use case for this relation is
/// container types; e.g. it is often desirable to be able to use `&str`
/// values to look up entries in a container with `~str` keys.
pub trait Equiv<T> {
    fn equiv(&self, other: &T) -> bool;
}

#[inline(always)]
pub fn min<T:Ord>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}

#[inline(always)]
pub fn max<T:Ord>(v1: T, v2: T) -> T {
    if v1 > v2 { v1 } else { v2 }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_int() {
        assert_eq!(5.cmp(&10), Less);
        assert_eq!(10.cmp(&5), Greater);
        assert_eq!(5.cmp(&5), Equal);
        assert_eq!((-5).cmp(&12), Less);
        assert_eq!(12.cmp(-5), Greater);
    }
}
<commit_msg>cmp: rm TotalOrd impl code duplication<commit_after>// Copyright 2012 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.

/*!

The `Ord` and `Eq` comparison traits

This module contains the definition of both `Ord` and `Eq` which define
the common interfaces for doing comparison. Both are language items
that the compiler uses to implement the comparison operators. Rust code
may implement `Ord` to overload the `<`, `<=`, `>`, and `>=` operators,
and `Eq` to overload the `==` and `!=` operators.

*/

/**
* Trait for values that can be compared for equality
* and inequality.
*
* Eventually this may be simplified to only require
* an `eq` method, with the other generated from
* a default implementation. However it should
* remain possible to implement `ne` separately, for
* compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="eq"]
pub trait Eq {
    fn eq(&self, other: &Self) -> bool;
    fn ne(&self, other: &Self) -> bool;
}

#[deriving(Eq)]
pub enum Ordering { Less, Equal, Greater }

/// Trait for types that form a total order
pub trait TotalOrd {
    fn cmp(&self, other: &Self) -> Ordering;
}

macro_rules! totalord_impl(
    ($t:ty) => {
        impl TotalOrd for $t {
            #[inline(always)]
            fn cmp(&self, other: &$t) -> Ordering {
                if *self < *other { Less }
                else if *self > *other { Greater }
                else { Equal }
            }
        }
    }
)

totalord_impl!(u8)
totalord_impl!(u16)
totalord_impl!(u32)
totalord_impl!(u64)

totalord_impl!(i8)
totalord_impl!(i16)
totalord_impl!(i32)
totalord_impl!(i64)

totalord_impl!(int)
totalord_impl!(uint)

/**
* Trait for values that can be compared for a sort-order.
*
* Eventually this may be simplified to only require
* an `le` method, with the others generated from
* default implementations. However it should remain
* possible to implement the others separately, for
* compatibility with floating-point NaN semantics
* (cf. IEEE 754-2008 section 5.11).
*/
#[lang="ord"]
pub trait Ord {
    fn lt(&self, other: &Self) -> bool;
    fn le(&self, other: &Self) -> bool;
    fn ge(&self, other: &Self) -> bool;
    fn gt(&self, other: &Self) -> bool;
}

#[inline(always)]
pub fn lt<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).lt(v2)
}

#[inline(always)]
pub fn le<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).le(v2)
}

#[inline(always)]
pub fn eq<T:Eq>(v1: &T, v2: &T) -> bool {
    (*v1).eq(v2)
}

#[inline(always)]
pub fn ne<T:Eq>(v1: &T, v2: &T) -> bool {
    (*v1).ne(v2)
}

#[inline(always)]
pub fn ge<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).ge(v2)
}

#[inline(always)]
pub fn gt<T:Ord>(v1: &T, v2: &T) -> bool {
    (*v1).gt(v2)
}

/// The equivalence relation. Two values may be equivalent even if they are
/// of different types. The most common use case for this relation is
/// container types; e.g. it is often desirable to be able to use `&str`
/// values to look up entries in a container with `~str` keys.
pub trait Equiv<T> {
    fn equiv(&self, other: &T) -> bool;
}

#[inline(always)]
pub fn min<T:Ord>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}

#[inline(always)]
pub fn max<T:Ord>(v1: T, v2: T) -> T {
    if v1 > v2 { v1 } else { v2 }
}

#[cfg(test)]
mod test {
    #[test]
    fn test_int() {
        assert_eq!(5.cmp(&10), Less);
        assert_eq!(10.cmp(&5), Greater);
        assert_eq!(5.cmp(&5), Equal);
        assert_eq!((-5).cmp(&12), Less);
        assert_eq!(12.cmp(-5), Greater);
    }
}
<|endoftext|>


<commit_before>#[doc = "Generate markdown from a document tree"];

import std::io;
import std::io::writer_util;

export mk_pass;

fn mk_pass(
    writer: fn~() -> io::writer
) -> pass {
    ret fn~(
        _srv: astsrv::srv,
        doc: doc::cratedoc
    ) -> doc::cratedoc {
        write_markdown(doc, writer());
        doc
    };
}

type ctxt = {
    w: io::writer,
    mutable depth: uint
};

fn write_markdown(
    doc: doc::cratedoc,
    writer: io::writer
) {
    let ctxt = {
        w: writer,
        mutable depth: 1u
    };

    write_crate(ctxt, doc);
}

fn write_header(ctxt: ctxt, title: str) {
    let hashes = str::from_chars(vec::init_elt('#', ctxt.depth));
    ctxt.w.write_line(#fmt("%s %s", hashes, title));
    ctxt.w.write_line("");
}

fn subsection(ctxt: ctxt, f: fn&()) {
    ctxt.depth += 1u;
    f();
    ctxt.depth -= 1u;
}

fn write_crate(
    ctxt: ctxt,
    doc: doc::cratedoc
) {
    write_header(ctxt, #fmt("Crate %s", doc.topmod.name));
    write_top_module(ctxt, doc.topmod);
}

fn write_top_module(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    write_mod_contents(ctxt, moddoc);
}

fn write_mod(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    write_header(ctxt, #fmt("Module `%s`", moddoc.name));
    write_mod_contents(ctxt, moddoc);
}

fn write_mod_contents(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    for fndoc in *moddoc.fns {
        subsection(ctxt) {||
            write_fn(ctxt, fndoc);
        }
    }

    for moddoc in *moddoc.mods {
        subsection(ctxt) {||
            write_mod(ctxt, moddoc);
        }
    }
}

fn write_fn(
    ctxt: ctxt,
    doc: doc::fndoc
) {
    write_header(ctxt, #fmt("Function `%s`", doc.name));
    alt doc.brief {
      some(brief) {
        ctxt.w.write_line(brief);
      }
      none. { }
    }
    alt doc.desc {
        some(_d) {
            ctxt.w.write_line("");
            ctxt.w.write_line(_d);
            ctxt.w.write_line("");
        }
        none. { }
    }
    for (arg, desc) in doc.args {
        ctxt.w.write_str("### Argument `" + arg + "`: ");
        ctxt.w.write_str(desc)
    }
    alt doc.return {
      some(doc) {
        alt doc.ty {
          some(ty) {
            ctxt.w.write_line("### Returns `" + ty + "`");
            alt doc.desc {
              some(d) {
                ctxt.w.write_line(d);
              }
              none. { }
            }
          }
          none. { fail "unimplemented"; }
        }
      }
      none. { }
    }
}

#[cfg(test)]
mod tests {
    fn write_markdown_str(
        doc: doc::cratedoc
    ) -> str {
        let buffer = io::mk_mem_buffer();
        let writer = io::mem_buffer_writer(buffer);
        write_markdown(doc, writer);
        ret io::mem_buffer_str(buffer);
    }

    #[test]
    fn write_markdown_should_write_crate_header() {
        let source = "";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "belch");
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "# Crate belch\n");
    }

    #[test]
    fn write_markdown_should_write_function_header() {
        let source = "fn func() { }";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "");
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "## Function `func`");
    }

    #[test]
    fn write_markdown_should_write_mod_headers() {
        let source = "mod moo { }";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "");
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "## Module `moo`");
    }

    #[test]
    fn should_leave_blank_line_after_header() {
        let source = "mod morp { }";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "");
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "Module `morp`\n");
    }
}<commit_msg>rustdoc: Write blank lines after brief descriptions<commit_after>#[doc = "Generate markdown from a document tree"];

import std::io;
import std::io::writer_util;

export mk_pass;

fn mk_pass(
    writer: fn~() -> io::writer
) -> pass {
    ret fn~(
        _srv: astsrv::srv,
        doc: doc::cratedoc
    ) -> doc::cratedoc {
        write_markdown(doc, writer());
        doc
    };
}

type ctxt = {
    w: io::writer,
    mutable depth: uint
};

fn write_markdown(
    doc: doc::cratedoc,
    writer: io::writer
) {
    let ctxt = {
        w: writer,
        mutable depth: 1u
    };

    write_crate(ctxt, doc);
}

fn write_header(ctxt: ctxt, title: str) {
    let hashes = str::from_chars(vec::init_elt('#', ctxt.depth));
    ctxt.w.write_line(#fmt("%s %s", hashes, title));
    ctxt.w.write_line("");
}

fn subsection(ctxt: ctxt, f: fn&()) {
    ctxt.depth += 1u;
    f();
    ctxt.depth -= 1u;
}

fn write_crate(
    ctxt: ctxt,
    doc: doc::cratedoc
) {
    write_header(ctxt, #fmt("Crate %s", doc.topmod.name));
    write_top_module(ctxt, doc.topmod);
}

fn write_top_module(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    write_mod_contents(ctxt, moddoc);
}

fn write_mod(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    write_header(ctxt, #fmt("Module `%s`", moddoc.name));
    write_mod_contents(ctxt, moddoc);
}

fn write_mod_contents(
    ctxt: ctxt,
    moddoc: doc::moddoc
) {
    for fndoc in *moddoc.fns {
        subsection(ctxt) {||
            write_fn(ctxt, fndoc);
        }
    }

    for moddoc in *moddoc.mods {
        subsection(ctxt) {||
            write_mod(ctxt, moddoc);
        }
    }
}

fn write_fn(
    ctxt: ctxt,
    doc: doc::fndoc
) {
    write_header(ctxt, #fmt("Function `%s`", doc.name));
    alt doc.brief {
      some(brief) {
        ctxt.w.write_line(brief);
        ctxt.w.write_line("");
      }
      none. { }
    }
    alt doc.desc {
        some(_d) {
            ctxt.w.write_line("");
            ctxt.w.write_line(_d);
            ctxt.w.write_line("");
        }
        none. { }
    }
    for (arg, desc) in doc.args {
        ctxt.w.write_str("### Argument `" + arg + "`: ");
        ctxt.w.write_str(desc)
    }
    alt doc.return {
      some(doc) {
        alt doc.ty {
          some(ty) {
            ctxt.w.write_line("### Returns `" + ty + "`");
            alt doc.desc {
              some(d) {
                ctxt.w.write_line(d);
              }
              none. { }
            }
          }
          none. { fail "unimplemented"; }
        }
      }
      none. { }
    }
}

#[cfg(test)]
mod tests {
    fn write_markdown_str(
        doc: doc::cratedoc
    ) -> str {
        let buffer = io::mk_mem_buffer();
        let writer = io::mem_buffer_writer(buffer);
        write_markdown(doc, writer);
        ret io::mem_buffer_str(buffer);
    }

    #[test]
    fn write_markdown_should_write_crate_header() {
        let source = "";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "belch");
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "# Crate belch");
    }

    #[test]
    fn write_markdown_should_write_function_header() {
        let source = "fn func() { }";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "");
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "## Function `func`");
    }

    #[test]
    fn write_markdown_should_write_mod_headers() {
        let source = "mod moo { }";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "");
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "## Module `moo`");
    }

    #[test]
    fn should_leave_blank_line_after_header() {
        let source = "mod morp { }";
        let ast = parse::from_str(source);
        let doc = extract::extract(ast, "");
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "Module `morp`\n\n");
    }

    #[test]
    fn should_leave_blank_line_between_fn_header_and_brief() {
        let source = "#[doc(brief = \"brief\")] fn a() { }";
        let srv = astsrv::mk_srv_from_str(source);
        let doc = extract::from_srv(srv, "");
        let doc = attr_pass::mk_pass()(srv, doc);
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "Function `a`\n\nbrief");
    }

    #[test]
    fn should_leve_blank_line_after_brief() {
        let source = "#[doc(brief = \"brief\")] fn a() { }";
        let srv = astsrv::mk_srv_from_str(source);
        let doc = extract::from_srv(srv, "");
        let doc = attr_pass::mk_pass()(srv, doc);
        let markdown = write_markdown_str(doc);
        assert str::contains(markdown, "brief\n\n");
    }
}<|endoftext|>


<commit_before><commit_msg>Add problem#34<commit_after>fn main() {
    let mut facts = [ mut 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]/10;
    for uint::range(1, facts.len()) |i| {
        facts[i] = facts[i - 1] * i;
    }

    io::println(fmt!("%u", facts[9]));
    let mut answer = 0;
    for uint::range(0, facts[9].to_str().len() * facts[9]) |n| {
        let mut itr = n;
        let mut sum = 0;
        while itr > 0 {
            sum += facts[itr % 10];
            itr /= 10;
        }
        if sum == n {
            io::println(fmt!("%u => %u", n, sum));
            answer += sum;
        }
    }

    io::println(fmt!("answer: %u", answer - 1 - 2));
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for issue #17737<commit_after>// Copyright 2014 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.

#![feature(unboxed_closures)]

// Test generating type visitor glue for unboxed closures

extern crate debug;

fn main() {
    let expected = "fn(); fn(uint, uint) -> uint; fn() -> !";
    let result = format!("{:?}; {:?}; {:?}",
                         |:| {},
                         |&: x: uint, y: uint| { x + y },
                         |&mut:| -> ! { fail!() });
    assert_eq!(expected, result.as_slice());
}
<|endoftext|>


<commit_before><commit_msg>Rust version<commit_after>const REPORT_LEN: i64 = 10000000;

fn main() {
    let mut a: f64 = 1.0;
    let mut b: f64 = 0.0;

    //println!("Hello, world");
    loop {
        for _i in 0..REPORT_LEN {
            b += 1.0 / a;
            a += 1.0;
        }
        println!("{}", b);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a test doing multiline parsing with optional last newline<commit_after>#[macro_use]
extern crate nom;

use nom::{IResult,alphanumeric,eol};

use std::str;

named!(end_of_line, alt!(eof!() | eol));
named!(read_line <&str>, map_res!(
  terminated!(alphanumeric, end_of_line),
  str::from_utf8
));
named!(read_lines <Vec<&str> >, many0!(read_line));

#[test]
fn read_lines_test() {
  let res = IResult::Done(&b""[..], vec!["Duck", "Dog", "Cow"]);

  assert_eq!(read_lines(&b"Duck\nDog\nCow\n"[..]), res);
  assert_eq!(read_lines(&b"Duck\nDog\nCow"[..]),   res);
}
<|endoftext|>


<commit_before><commit_msg>fix(nickel): fix breakage caused by Nickel change to Request<commit_after><|endoftext|>


<commit_before><commit_msg>add cacheable trait<commit_after>pub trait Cacheable {
    fn to_cache(&self) -> (&[u8], u32);
}

impl <'a> Cacheable for &'a[u8] {
    fn to_cache(&self) -> (&[u8], u32) {
        return (self, 0);
    }
}

impl Cacheable for String {
    fn to_cache(&self) -> (&[u8], u32) {
        return (self.as_bytes(), 1);
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix: Use "ref.relpath" as path to header value<commit_after><|endoftext|>


<commit_before><commit_msg>Added comparator for keyboard modifiers<commit_after><|endoftext|>


<commit_before><commit_msg>Added Lambda code example in Rust<commit_after>/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

// snippet-start:[lambda.rust.main]
use log::{debug, error, info};

#[derive(Deserialize)]
struct Request {
    pub body: String,
}

#[derive(Debug, Serialize)]
struct SuccessResponse {
    pub body: String,
}

#[derive(Debug, Serialize)]
struct FailureResponse {
    pub body: String,
}

// Implement Display for the Failure response so that we can then implement Error.
impl std::fmt::Display for FailureResponse {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.body)
    }
}

// Implement Error for the FailureResponse so that we can `?` (try) the Response
// returned by `lambda_runtime::run(func).await` in `fn main`.
impl std::error::Error for FailureResponse {}

type Response = Result<SuccessResponse, FailureResponse>;

#[tokio::main]
async fn main() -> Result<(), lambda_runtime::Error> {
    // You can view the logs emitted by your app in Amazon CloudWatch.
    tracing_subscriber::fmt::init();
    debug!("logger has been set up");

    let func = handler_fn(handler);
    lambda_runtime::run(func).await?;

    Ok(())
}

async fn handler(req: Request, _ctx: lambda_runtime::Context) -> Response {
    info!("handling a request...");
    let bucket_name = std::env::var("BUCKET_NAME")
        .expect("A BUCKET_NAME must be set in this app's Lambda environment variables.");

    // No extra configuration is needed as long as your Lambda has
    // the necessary permissions attached to its role.
    let config = aws_config::load_from_env().await;
    let s3_client = aws_sdk_s3::Client::new(&config);
    // Generate a filename based on when the request was received.
    let filename = format!("{}.txt", time::OffsetDateTime::now_utc().unix_timestamp());

    let _ = s3_client
        .put_object()
        .bucket(bucket_name)
        .body(req.body.as_bytes().to_owned().into())
        .key(&filename)
        .content_type("text/plain")
        .send()
        .await
        .map_err(|err| {
            // In case of failure, log a detailed error to CloudWatch.
            error!(
                "failed to upload file '{}' to S3 with error: {}",
                &filename, err
            );
            // The sender of the request receives this message in response.
            FailureResponse {
                body: "The lambda encountered an error and your message was not saved".to_owned(),
            }
        })?;

    info!(
        "Successfully stored the incoming request in S3 with the name '{}'",
        &filename
    );

    Ok(SuccessResponse {
        body: format!(
            "the lambda has successfully stored the your request in S3 with name '{}'",
            filename
        ),
    })
}
// snippet-end:[lambda.rust.main]
<|endoftext|>


<commit_before><commit_msg>Fix warnings<commit_after><|endoftext|>


<commit_before>enum color {
    red = 0xff0000,
    green = 0x00ff00,
    blue = 0x0000ff,
    black = 0x000000,
    white = 0xFFFFFF,
    imaginary = -1,
}

fn main() {
    test_color(red, 0xff0000, "red");
    test_color(green, 0x00ff00, "green");
    test_color(blue, 0x0000ff, "blue");
    test_color(black, 0x000000, "black");
    test_color(white, 0xFFFFFF, "white");
    test_color(imaginary, -1, "imaginary");
}

fn test_color(color: color, val: int, name: str) unsafe {
    //assert unsafe::reinterpret_cast(color) == val;
    assert color as int == val;
    assert color as float == val as float;
    assert get_color_alt(color) == name;
    assert get_color_if(color) == name;
}

fn get_color_alt(color: color) -> str {
    alt color {
      red {"red"}
      green {"green"}
      blue {"blue"}
      black {"black"}
      white {"white"}
      imaginary {"imaginary"}
      _ {"unknown"}
    }
}

fn get_color_if(color: color) -> str {
    if color == red {"red"}
    else if color == green {"green"}
    else if color == blue {"blue"}
    else if color == black {"black"}
    else if color == white {"white"}
    else if color == imaginary {"imaginary"}
    else {"unknown"}
}

<commit_msg>test: Add regression test for #1659<commit_after>enum color {
    red = 0xff0000,
    green = 0x00ff00,
    blue = 0x0000ff,
    black = 0x000000,
    white = 0xFFFFFF,
    imaginary = -1,
    purple = 1 << 1,
    orange = 8 >> 1
}

fn main() {
    test_color(red, 0xff0000, "red");
    test_color(green, 0x00ff00, "green");
    test_color(blue, 0x0000ff, "blue");
    test_color(black, 0x000000, "black");
    test_color(white, 0xFFFFFF, "white");
    test_color(imaginary, -1, "imaginary");
    test_color(purple, 2, "purple");
    test_color(orange, 4, "orange");
}

fn test_color(color: color, val: int, name: str) unsafe {
    //assert unsafe::reinterpret_cast(color) == val;
    assert color as int == val;
    assert color as float == val as float;
    assert get_color_alt(color) == name;
    assert get_color_if(color) == name;
}

fn get_color_alt(color: color) -> str {
    alt color {
      red {"red"}
      green {"green"}
      blue {"blue"}
      black {"black"}
      white {"white"}
      imaginary {"imaginary"}
      purple {"purple"}
      orange {"orange"}
      _ {"unknown"}
    }
}

fn get_color_if(color: color) -> str {
    if color == red {"red"}
    else if color == green {"green"}
    else if color == blue {"blue"}
    else if color == black {"black"}
    else if color == white {"white"}
    else if color == imaginary {"imaginary"}
    else if color == purple {"purple"}
    else if color == orange {"orange"}
    else {"unknown"}
}

<|endoftext|>


<commit_before><commit_msg>repo: new module<commit_after><|endoftext|>


<commit_before><commit_msg>Send MediaSessionEvent::PlaybackStateChange when needed<commit_after><|endoftext|>


<commit_before>fn main() {
    // Type annotated variable
    let a_float: f64 = 1.0;

    // This variable is an `int`
    let mut an_integer = 5i;

    // Error! The type of a variable can't be changed
    an_integer = true;
}
<commit_msg>i suffix -> i32<commit_after>fn main() {
    // Type annotated variable
    let a_float: f64 = 1.0;

    // This variable is an `int`
    let mut an_integer = 5i32;

    // Error! The type of a variable can't be changed
    an_integer = true;
}
<|endoftext|>


<commit_before><commit_msg>LLVM tests<commit_after>use weld_ast::Type::*;
use weld_ast::ScalarKind::*;
use super::*;

#[test]
fn types() {
    let mut ctx = GeneratorContext;
    assert_eq!(ctx.llvm_type(&Scalar(I32)).unwrap(), "i32");
    assert_eq!(ctx.llvm_type(&Scalar(Bool)).unwrap(), "i1");

    //let weld_type = parse_type("{i32,bool,i32}").unwrap().to_type().unwrap();
    //assert_eq!(ctx.llvm_type(&weld_type).unwrap(), "%s1");
}<|endoftext|>


<commit_before><commit_msg>Test for `..` in range patterns<commit_after>// Copyright 2014 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.

pub fn main() {
    match 22i {
        0 .. 3 => {} //~ ERROR expected `=>`, found `..`
        _ => {}
    }
}
<|endoftext|>


<commit_before><commit_msg>Initial commit for download.rs<commit_after>/*
    TODO:
    Write code for downloading the package, into a
    specific path.
*/<|endoftext|>


<commit_before><commit_msg>[Rust] IntoIterator<commit_after>use std::iter::{IntoIterator, Iterator};

struct S;

struct Iter(Option<String>);

impl Iterator for Iter {
    type Item = String;
    fn next(&mut self) -> Option<Self::Item> {
        if let Some(value) = self.0.clone() {
            self.0 = None;
            Some(value)
        } else {
            None
        }
    }
}

impl IntoIterator for S {
    type Item = String;
    type IntoIter = Iter;
    fn into_iter(self) -> Self::IntoIter {
        Iter(Some("move".to_string()))
    }
}

impl IntoIterator for &S {
    type Item = String;
    type IntoIter = Iter;
    fn into_iter(self) -> Self::IntoIter {
        Iter(Some("ref".to_string()))
    }
}

impl IntoIterator for &mut S {
    type Item = String;
    type IntoIter = Iter;
    fn into_iter(self) -> Self::IntoIter {
        Iter(Some("mut ref".to_string()))
    }
}

fn main() {
    for x in S {
        println!("{}", x);
    }
    for x in &S {
        println!("{}", x);
    }
    for x in &mut S {
        println!("{}", x);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add check for change<commit_after><|endoftext|>


<commit_before><commit_msg>sam writer stdout test added<commit_after>extern crate rust_htslib;
use self::rust_htslib::bam::SAMWriter;

use std::io::Write;

pub fn main(){
  let example_bam = "./test/bam2sam_test.bam";
  let result = SAMWriter::from_bam_with_filter(example_bam, &"-", |_|{Some(true)});
  assert!(writeln!(&mut std::io::stderr(), "{:?}", result).is_ok());
}
<|endoftext|>


<commit_before>// pp-exact - Make sure we actually print the attributes

class cat {
    #[cat_maker]
    new(name: ~str) { self.name = name; }
    #[cat_dropper]
    drop { error! {"%s landed on hir feet",self.name }; }
    let name: ~str;
}

fn main() { let _kitty = cat(~"Spotty"); }
<commit_msg>s/class/struct/ in a failing test.<commit_after>// pp-exact - Make sure we actually print the attributes

struct cat {
    #[cat_maker]
    new(name: ~str) { self.name = name; }
    #[cat_dropper]
    drop { error! {"%s landed on hir feet",self.name }; }
    let name: ~str;
}

fn main() { let _kitty = cat(~"Spotty"); }
<|endoftext|>


<commit_before><commit_msg>Add benchmarks for tree_fold1<commit_after>#![feature(test)]

extern crate test;
extern crate itertools;

use itertools::Itertools;
use itertools::cloned;
use test::Bencher;

trait IterEx : Iterator {
    // Another efficient implementation against which to compare,
    // but needs `std` so is less desirable.
    fn tree_fold1_vec<F>(self, mut f: F) -> Option<Self::Item>
        where F: FnMut(Self::Item, Self::Item) -> Self::Item,
              Self: Sized,
    {
        let hint = self.size_hint().0;
        let cap = std::mem::size_of::<usize>() * 8 - hint.leading_zeros() as usize;
        let mut stack = Vec::with_capacity(cap);
        self.enumerate().foreach(|(mut i, mut x)| {
            while (i & 1) != 0 {
                x = f(stack.pop().unwrap(), x);
                i >>= 1;
            }
            stack.push(x);
        });
        stack.into_iter().fold1(f)
    }
}
impl<T:Iterator> IterEx for T {}

macro_rules! def_benchs {
    ($N:expr,
     $FUN:ident,
     $BENCH_NAME:ident,
     ) => (
        mod $BENCH_NAME {
        use super::*;

        #[bench]
        fn sum(b: &mut Bencher) {
            let v: Vec<u32> = (0.. $N).collect();
            b.iter(|| {
                cloned(&v).$FUN(|x, y| x + y)
            });
        }

        #[bench]
        fn complex_iter(b: &mut Bencher) {
            let u = (3..).take($N / 2);
            let v = (5..).take($N / 2);
            let it = u.chain(v);

            b.iter(|| {
                it.clone().map(|x| x as f32).$FUN(f32::atan2)
            });
        }

        #[bench]
        fn string_format(b: &mut Bencher) {
            // This goes quadratic with linear `fold1`, so use a smaller
            // size to not waste too much time in travis.  The allocations
            // in here are so expensive anyway that it'll still take
            // way longer per iteration than the other two benchmarks.
            let v: Vec<u32> = (0.. ($N/4)).collect();
            b.iter(|| {
                cloned(&v).map(|x| x.to_string()).$FUN(|x, y| format!("{} + {}", x, y))
            });
        }
        }
    )
}

def_benchs!{
    10_000,
    fold1,
    fold1_10k,
}

def_benchs!{
    10_000,
    tree_fold1,
    tree_fold1_stack_10k,
}

def_benchs!{
    10_000,
    tree_fold1_vec,
    tree_fold1_vec_10k,
}

def_benchs!{
    100,
    fold1,
    fold1_100,
}

def_benchs!{
    100,
    tree_fold1,
    tree_fold1_stack_100,
}

def_benchs!{
    100,
    tree_fold1_vec,
    tree_fold1_vec_100,
}

def_benchs!{
    8,
    fold1,
    fold1_08,
}

def_benchs!{
    8,
    tree_fold1,
    tree_fold1_stack_08,
}

def_benchs!{
    8,
    tree_fold1_vec,
    tree_fold1_vec_08,
}
<|endoftext|>


<commit_before>import driver::session;

import syntax::ast::{crate, expr_, mac_invoc,
                     mac_aq, mac_var};
import syntax::fold::*;
import syntax::visit::*;
import syntax::ext::base::*;
import syntax::ext::build::*;
import syntax::parse::parser;
import syntax::parse::parser::{parser, parse_from_source_str};

import syntax::print::*;
import io::*;

import codemap::span;

type aq_ctxt = @{lo: uint,
                 mutable gather: [{lo: uint, hi: uint,
                                   e: @ast::expr,
                                   constr: str}]};
enum fragment {
    from_expr(@ast::expr),
    from_ty(@ast::ty)
}

iface qq_helper {
    fn span() -> span;
    fn visit(aq_ctxt, vt<aq_ctxt>);
    fn extract_mac() -> option<ast::mac_>;
    fn mk_parse_fn(ext_ctxt,span) -> @ast::expr;
    fn get_fold_fn() -> str;
}

impl of qq_helper for @ast::crate {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_crate(*self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_crate"])
    }
    fn get_fold_fn() -> str {"fold_crate"}
}
impl of qq_helper for @ast::expr {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_expr(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {
        alt (self.node) {
          ast::expr_mac({node: mac, _}) {some(mac)}
          _ {none}
        }
    }
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "parse", "parser", "parse_expr"])
    }
    fn get_fold_fn() -> str {"fold_expr"}
}
impl of qq_helper for @ast::ty {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_ty(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {
        alt (self.node) {
          ast::ty_mac({node: mac, _}) {some(mac)}
          _ {none}
        }
    }
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_ty"])
    }
    fn get_fold_fn() -> str {"fold_ty"}
}
impl of qq_helper for @ast::item {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_item(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_item"])
    }
    fn get_fold_fn() -> str {"fold_item"}
}
impl of qq_helper for @ast::stmt {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_stmt(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_stmt"])
    }
    fn get_fold_fn() -> str {"fold_stmt"}
}
impl of qq_helper for @ast::pat {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_pat(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "parse", "parser", "parse_pat"])
    }
    fn get_fold_fn() -> str {"fold_pat"}
}

fn gather_anti_quotes<N: qq_helper>(lo: uint, node: N) -> aq_ctxt
{
    let v = @{visit_expr: visit_aq_expr,
              visit_ty: visit_aq_ty
              with *default_visitor()};
    let cx = @{lo:lo, mutable gather: []};
    node.visit(cx, mk_vt(v));
    // FIXME: Maybe this is an overkill (merge_sort), it might be better
    //   to just keep the gather array in sorted order ...
    cx.gather = std::sort::merge_sort({|a,b| a.lo < b.lo}, copy cx.gather);
    ret cx;
}

fn visit_aq<T:qq_helper>(node: T, constr: str, &&cx: aq_ctxt, v: vt<aq_ctxt>)
{
    alt (node.extract_mac()) {
      some(mac_aq(sp, e)) {
        cx.gather += [{lo: sp.lo - cx.lo, hi: sp.hi - cx.lo,
                       e: e, constr: constr}];
      }
      _ {node.visit(cx, v);}
    }
}
// FIXME: these are only here because I (kevina) couldn't figure out how to
// get bind to work in gather_anti_quotes
fn visit_aq_expr(node: @ast::expr, &&cx: aq_ctxt, v: vt<aq_ctxt>) {
    visit_aq(node,"from_expr",cx,v);
}
fn visit_aq_ty(node: @ast::ty, &&cx: aq_ctxt, v: vt<aq_ctxt>) {
    visit_aq(node,"from_ty",cx,v);
}

fn is_space(c: char) -> bool {
    syntax::parse::lexer::is_whitespace(c)
}

fn expand_ast(ecx: ext_ctxt, _sp: span,
              arg: ast::mac_arg, body: ast::mac_body)
    -> @ast::expr
{
    let what = "expr";
    option::may(arg) {|arg|
        let args: [@ast::expr] =
            alt arg.node {
              ast::expr_vec(elts, _) { elts }
              _ {
                ecx.span_fatal
                    (_sp, "#ast requires arguments of the form `[...]`.")
              }
            };
        if vec::len::<@ast::expr>(args) != 1u {
            ecx.span_fatal(_sp, "#ast requires exactly one arg");
        }
        alt (args[0].node) {
          ast::expr_path(@{node: {idents: id, _},_}) if vec::len(id) == 1u
              {what = id[0]}
          _ {ecx.span_fatal(args[0].span, "expected an identifier");}
        }
    }
    let body = get_mac_body(ecx,_sp,body);

    ret alt what {
      "crate" {finish(ecx, body, parse_crate)}
      "expr" {finish(ecx, body, parser::parse_expr)}
      "ty" {finish(ecx, body, parse_ty)}
      "item" {finish(ecx, body, parse_item)}
      "stmt" {finish(ecx, body, parse_stmt)}
      "pat" {finish(ecx, body, parser::parse_pat)}
      _ {ecx.span_fatal(_sp, "unsupported ast type")}
    };
}

fn parse_crate(p: parser) -> @ast::crate {
    parser::parse_crate_mod(p, [])
}

fn parse_ty(p: parser) -> @ast::ty {
    parser::parse_ty(p, false)
}

fn parse_stmt(p: parser) -> @ast::stmt {
    parser::parse_stmt(p, [])
}

fn parse_item(p: parser) -> @ast::item {
    alt (parser::parse_item(p, [])) {
      some(item) {item}
      none {fail; /* FIXME: Error message, somehow */}
    }
}

fn finish<T: qq_helper>
    (ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: parser) -> T)
    -> @ast::expr
{
    let cm = ecx.session().parse_sess.cm;
    let str = @codemap::span_to_snippet(body.span, cm);
    #debug["qquote--str==%?", str];
    let fname = codemap::mk_substr_filename(cm, body.span);
    let node = parse_from_source_str
        (f, fname, codemap::fss_internal(body.span), str,
         ecx.session().opts.cfg, ecx.session().parse_sess);
    let loc = codemap::lookup_char_pos(cm, body.span.lo);

    let sp = node.span();
    let qcx = gather_anti_quotes(sp.lo, node);
    let cx = qcx;

    uint::range(1u, vec::len(cx.gather)) {|i|
        assert cx.gather[i-1u].lo < cx.gather[i].lo;
        // ^^ check that the vector is sorted
        assert cx.gather[i-1u].hi <= cx.gather[i].lo;
        // ^^ check that the spans are non-overlapping
    }

    let str2 = "";
    enum state {active, skip(uint), blank};
    let state = active;
    let i = 0u, j = 0u;
    let g_len = vec::len(cx.gather);
    str::chars_iter(*str) {|ch|
        if (j < g_len && i == cx.gather[j].lo) {
            assert ch == '$';
            let repl = #fmt("$%u ", j);
            state = skip(str::char_len(repl));
            str2 += repl;
        }
        alt state {
          active {str::push_char(str2, ch);}
          skip(1u) {state = blank;}
          skip(sk) {state = skip (sk-1u);}
          blank if is_space(ch) {str::push_char(str2, ch);}
          blank {str::push_char(str2, ' ');}
        }
        i += 1u;
        if (j < g_len && i == cx.gather[j].hi) {
            assert ch == ')';
            state = active;
            j += 1u;
        }
    }

    let cx = ecx;
    let session_call = bind mk_call_(cx,sp,
                                     mk_access(cx,sp,["ext_cx"], "session"),
                                     []);
    let pcall = mk_call(cx,sp,
                       ["syntax", "parse", "parser",
                        "parse_from_source_str"],
                       [node.mk_parse_fn(cx,sp),
                        mk_str(cx,sp, fname),
                        mk_call(cx,sp,
                                ["syntax","ext","qquote", "mk_file_substr"],
                                [mk_str(cx,sp, loc.file.name),
                                 mk_uint(cx,sp, loc.line),
                                 mk_uint(cx,sp, loc.col)]),
                        mk_unary(cx,sp, ast::box(ast::m_imm),
                                 mk_str(cx,sp, str2)),
                        mk_access_(cx,sp,
                                   mk_access_(cx,sp, session_call(), "opts"),
                                   "cfg"),
                        mk_access_(cx,sp, session_call(), "parse_sess")]
                      );
    let rcall = pcall;
    if (g_len > 0u) {
        rcall = mk_call(cx,sp,
                        ["syntax", "ext", "qquote", "replace"],
                        [pcall,
                         mk_vec_e(cx,sp, vec::map(copy qcx.gather) {|g|
                             mk_call(cx,sp,
                                     ["syntax", "ext", "qquote", g.constr],
                                     [g.e])}),
                         mk_path(cx,sp,
                                 ["syntax", "ext", "qquote",
                                  node.get_fold_fn()])]);
    }
    ret rcall;
}

fn replace<T>(node: T, repls: [fragment], ff: fn (ast_fold, T) -> T)
    -> T
{
    let aft = default_ast_fold();
    let f_pre = {fold_expr: bind replace_expr(repls, _, _, _,
                                              aft.fold_expr),
                 fold_ty: bind replace_ty(repls, _, _, _,
                                          aft.fold_ty)
                 with *aft};
    ret ff(make_fold(f_pre), node);
}
fn fold_crate(f: ast_fold, &&n: @ast::crate) -> @ast::crate {
    @f.fold_crate(*n)
}
fn fold_expr(f: ast_fold, &&n: @ast::expr) -> @ast::expr {f.fold_expr(n)}
fn fold_ty(f: ast_fold, &&n: @ast::ty) -> @ast::ty {f.fold_ty(n)}
fn fold_item(f: ast_fold, &&n: @ast::item) -> @ast::item {f.fold_item(n)}
fn fold_stmt(f: ast_fold, &&n: @ast::stmt) -> @ast::stmt {f.fold_stmt(n)}
fn fold_pat(f: ast_fold, &&n: @ast::pat) -> @ast::pat {f.fold_pat(n)}

fn replace_expr(repls: [fragment],
                e: ast::expr_, s: span, fld: ast_fold,
                orig: fn@(ast::expr_, span, ast_fold)->(ast::expr_, span))
    -> (ast::expr_, span)
{
    alt e {
      ast::expr_mac({node: mac_var(i), _}) {
        alt (repls[i]) {
          from_expr(r) {(r.node, r.span)}
          _ {fail /* fixme error message */}}}
      _ {orig(e,s,fld)}
    }
}

fn replace_ty(repls: [fragment],
                e: ast::ty_, s: span, fld: ast_fold,
                orig: fn@(ast::ty_, span, ast_fold)->(ast::ty_, span))
    -> (ast::ty_, span)
{
    alt e {
      ast::ty_mac({node: mac_var(i), _}) {
        alt (repls[i]) {
          from_ty(r) {(r.node, r.span)}
          _ {fail /* fixme error message */}}}
      _ {orig(e,s,fld)}
    }
}

fn print_expr(expr: @ast::expr) {
    let stdout = io::stdout();
    let pp = pprust::rust_printer(stdout);
    pprust::print_expr(pp, expr);
    pp::eof(pp.s);
    stdout.write_str("\n");
}

fn mk_file_substr(fname: str, line: uint, col: uint) -> codemap::file_substr {
    codemap::fss_external({filename: fname, line: line, col: col})
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>rustc: Make the quasiquote operator stop reusing nodes (and therefore stop reusing node IDs). Should fix issue #1947 for real.<commit_after>import driver::session;

import syntax::ast::{crate, expr_, mac_invoc,
                     mac_aq, mac_var};
import syntax::fold::*;
import syntax::visit::*;
import syntax::ext::base::*;
import syntax::ext::build::*;
import syntax::parse::parser;
import syntax::parse::parser::{parser, parse_from_source_str};

import syntax::print::*;
import io::*;

import codemap::span;

type aq_ctxt = @{lo: uint,
                 mutable gather: [{lo: uint, hi: uint,
                                   e: @ast::expr,
                                   constr: str}]};
enum fragment {
    from_expr(@ast::expr),
    from_ty(@ast::ty)
}

iface qq_helper {
    fn span() -> span;
    fn visit(aq_ctxt, vt<aq_ctxt>);
    fn extract_mac() -> option<ast::mac_>;
    fn mk_parse_fn(ext_ctxt,span) -> @ast::expr;
    fn get_fold_fn() -> str;
}

impl of qq_helper for @ast::crate {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_crate(*self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_crate"])
    }
    fn get_fold_fn() -> str {"fold_crate"}
}
impl of qq_helper for @ast::expr {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_expr(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {
        alt (self.node) {
          ast::expr_mac({node: mac, _}) {some(mac)}
          _ {none}
        }
    }
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "parse", "parser", "parse_expr"])
    }
    fn get_fold_fn() -> str {"fold_expr"}
}
impl of qq_helper for @ast::ty {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_ty(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {
        alt (self.node) {
          ast::ty_mac({node: mac, _}) {some(mac)}
          _ {none}
        }
    }
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_ty"])
    }
    fn get_fold_fn() -> str {"fold_ty"}
}
impl of qq_helper for @ast::item {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_item(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_item"])
    }
    fn get_fold_fn() -> str {"fold_item"}
}
impl of qq_helper for @ast::stmt {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_stmt(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "ext", "qquote", "parse_stmt"])
    }
    fn get_fold_fn() -> str {"fold_stmt"}
}
impl of qq_helper for @ast::pat {
    fn span() -> span {self.span}
    fn visit(cx: aq_ctxt, v: vt<aq_ctxt>) {visit_pat(self, cx, v);}
    fn extract_mac() -> option<ast::mac_> {fail}
    fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr {
        mk_path(cx, sp, ["syntax", "parse", "parser", "parse_pat"])
    }
    fn get_fold_fn() -> str {"fold_pat"}
}

fn gather_anti_quotes<N: qq_helper>(lo: uint, node: N) -> aq_ctxt
{
    let v = @{visit_expr: visit_aq_expr,
              visit_ty: visit_aq_ty
              with *default_visitor()};
    let cx = @{lo:lo, mutable gather: []};
    node.visit(cx, mk_vt(v));
    // FIXME: Maybe this is an overkill (merge_sort), it might be better
    //   to just keep the gather array in sorted order ...
    cx.gather = std::sort::merge_sort({|a,b| a.lo < b.lo}, copy cx.gather);
    ret cx;
}

fn visit_aq<T:qq_helper>(node: T, constr: str, &&cx: aq_ctxt, v: vt<aq_ctxt>)
{
    alt (node.extract_mac()) {
      some(mac_aq(sp, e)) {
        cx.gather += [{lo: sp.lo - cx.lo, hi: sp.hi - cx.lo,
                       e: e, constr: constr}];
      }
      _ {node.visit(cx, v);}
    }
}
// FIXME: these are only here because I (kevina) couldn't figure out how to
// get bind to work in gather_anti_quotes
fn visit_aq_expr(node: @ast::expr, &&cx: aq_ctxt, v: vt<aq_ctxt>) {
    visit_aq(node,"from_expr",cx,v);
}
fn visit_aq_ty(node: @ast::ty, &&cx: aq_ctxt, v: vt<aq_ctxt>) {
    visit_aq(node,"from_ty",cx,v);
}

fn is_space(c: char) -> bool {
    syntax::parse::lexer::is_whitespace(c)
}

fn expand_ast(ecx: ext_ctxt, _sp: span,
              arg: ast::mac_arg, body: ast::mac_body)
    -> @ast::expr
{
    let what = "expr";
    option::may(arg) {|arg|
        let args: [@ast::expr] =
            alt arg.node {
              ast::expr_vec(elts, _) { elts }
              _ {
                ecx.span_fatal
                    (_sp, "#ast requires arguments of the form `[...]`.")
              }
            };
        if vec::len::<@ast::expr>(args) != 1u {
            ecx.span_fatal(_sp, "#ast requires exactly one arg");
        }
        alt (args[0].node) {
          ast::expr_path(@{node: {idents: id, _},_}) if vec::len(id) == 1u
              {what = id[0]}
          _ {ecx.span_fatal(args[0].span, "expected an identifier");}
        }
    }
    let body = get_mac_body(ecx,_sp,body);

    ret alt what {
      "crate" {finish(ecx, body, parse_crate)}
      "expr" {finish(ecx, body, parser::parse_expr)}
      "ty" {finish(ecx, body, parse_ty)}
      "item" {finish(ecx, body, parse_item)}
      "stmt" {finish(ecx, body, parse_stmt)}
      "pat" {finish(ecx, body, parser::parse_pat)}
      _ {ecx.span_fatal(_sp, "unsupported ast type")}
    };
}

fn parse_crate(p: parser) -> @ast::crate {
    parser::parse_crate_mod(p, [])
}

fn parse_ty(p: parser) -> @ast::ty {
    parser::parse_ty(p, false)
}

fn parse_stmt(p: parser) -> @ast::stmt {
    parser::parse_stmt(p, [])
}

fn parse_item(p: parser) -> @ast::item {
    alt (parser::parse_item(p, [])) {
      some(item) {item}
      none {fail; /* FIXME: Error message, somehow */}
    }
}

fn finish<T: qq_helper>
    (ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: parser) -> T)
    -> @ast::expr
{
    let cm = ecx.session().parse_sess.cm;
    let str = @codemap::span_to_snippet(body.span, cm);
    #debug["qquote--str==%?", str];
    let fname = codemap::mk_substr_filename(cm, body.span);
    let node = parse_from_source_str
        (f, fname, codemap::fss_internal(body.span), str,
         ecx.session().opts.cfg, ecx.session().parse_sess);
    let loc = codemap::lookup_char_pos(cm, body.span.lo);

    let sp = node.span();
    let qcx = gather_anti_quotes(sp.lo, node);
    let cx = qcx;

    uint::range(1u, vec::len(cx.gather)) {|i|
        assert cx.gather[i-1u].lo < cx.gather[i].lo;
        // ^^ check that the vector is sorted
        assert cx.gather[i-1u].hi <= cx.gather[i].lo;
        // ^^ check that the spans are non-overlapping
    }

    let str2 = "";
    enum state {active, skip(uint), blank};
    let state = active;
    let i = 0u, j = 0u;
    let g_len = vec::len(cx.gather);
    str::chars_iter(*str) {|ch|
        if (j < g_len && i == cx.gather[j].lo) {
            assert ch == '$';
            let repl = #fmt("$%u ", j);
            state = skip(str::char_len(repl));
            str2 += repl;
        }
        alt state {
          active {str::push_char(str2, ch);}
          skip(1u) {state = blank;}
          skip(sk) {state = skip (sk-1u);}
          blank if is_space(ch) {str::push_char(str2, ch);}
          blank {str::push_char(str2, ' ');}
        }
        i += 1u;
        if (j < g_len && i == cx.gather[j].hi) {
            assert ch == ')';
            state = active;
            j += 1u;
        }
    }

    let cx = ecx;
    let session_call = {||
        mk_call_(cx, sp, mk_access(cx, sp, ["ext_cx"], "session"), [])
    };

    let pcall = mk_call(cx,sp,
                       ["syntax", "parse", "parser",
                        "parse_from_source_str"],
                       [node.mk_parse_fn(cx,sp),
                        mk_str(cx,sp, fname),
                        mk_call(cx,sp,
                                ["syntax","ext","qquote", "mk_file_substr"],
                                [mk_str(cx,sp, loc.file.name),
                                 mk_uint(cx,sp, loc.line),
                                 mk_uint(cx,sp, loc.col)]),
                        mk_unary(cx,sp, ast::box(ast::m_imm),
                                 mk_str(cx,sp, str2)),
                        mk_access_(cx,sp,
                                   mk_access_(cx,sp, session_call(), "opts"),
                                   "cfg"),
                        mk_access_(cx,sp, session_call(), "parse_sess")]
                      );
    let rcall = pcall;
    if (g_len > 0u) {
        rcall = mk_call(cx,sp,
                        ["syntax", "ext", "qquote", "replace"],
                        [pcall,
                         mk_vec_e(cx,sp, vec::map(copy qcx.gather) {|g|
                             mk_call(cx,sp,
                                     ["syntax", "ext", "qquote", g.constr],
                                     [g.e])}),
                         mk_path(cx,sp,
                                 ["syntax", "ext", "qquote",
                                  node.get_fold_fn()])]);
    }
    ret rcall;
}

fn replace<T>(node: T, repls: [fragment], ff: fn (ast_fold, T) -> T)
    -> T
{
    let aft = default_ast_fold();
    let f_pre = {fold_expr: bind replace_expr(repls, _, _, _,
                                              aft.fold_expr),
                 fold_ty: bind replace_ty(repls, _, _, _,
                                          aft.fold_ty)
                 with *aft};
    ret ff(make_fold(f_pre), node);
}
fn fold_crate(f: ast_fold, &&n: @ast::crate) -> @ast::crate {
    @f.fold_crate(*n)
}
fn fold_expr(f: ast_fold, &&n: @ast::expr) -> @ast::expr {f.fold_expr(n)}
fn fold_ty(f: ast_fold, &&n: @ast::ty) -> @ast::ty {f.fold_ty(n)}
fn fold_item(f: ast_fold, &&n: @ast::item) -> @ast::item {f.fold_item(n)}
fn fold_stmt(f: ast_fold, &&n: @ast::stmt) -> @ast::stmt {f.fold_stmt(n)}
fn fold_pat(f: ast_fold, &&n: @ast::pat) -> @ast::pat {f.fold_pat(n)}

fn replace_expr(repls: [fragment],
                e: ast::expr_, s: span, fld: ast_fold,
                orig: fn@(ast::expr_, span, ast_fold)->(ast::expr_, span))
    -> (ast::expr_, span)
{
    alt e {
      ast::expr_mac({node: mac_var(i), _}) {
        alt (repls[i]) {
          from_expr(r) {(r.node, r.span)}
          _ {fail /* fixme error message */}}}
      _ {orig(e,s,fld)}
    }
}

fn replace_ty(repls: [fragment],
                e: ast::ty_, s: span, fld: ast_fold,
                orig: fn@(ast::ty_, span, ast_fold)->(ast::ty_, span))
    -> (ast::ty_, span)
{
    alt e {
      ast::ty_mac({node: mac_var(i), _}) {
        alt (repls[i]) {
          from_ty(r) {(r.node, r.span)}
          _ {fail /* fixme error message */}}}
      _ {orig(e,s,fld)}
    }
}

fn print_expr(expr: @ast::expr) {
    let stdout = io::stdout();
    let pp = pprust::rust_printer(stdout);
    pprust::print_expr(pp, expr);
    pp::eof(pp.s);
    stdout.write_str("\n");
}

fn mk_file_substr(fname: str, line: uint, col: uint) -> codemap::file_substr {
    codemap::fss_external({filename: fname, line: line, col: col})
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before><commit_msg>match example added<commit_after>fn main()
{
    let x = 5;

    match x
    {
        1 => println!("one"),
        2 => println!("two"),
        3 => println!("three"),
        4 => println!("four"),
        5 => println!("five"),
        _ => println!("something else"),
    }
}
<|endoftext|>


<commit_before><commit_msg>Start TAR loader<commit_after>// ba6ce90ac85fd41a3ff1d9b203f6de3e73a6b6da

/// Get the first file of the tar string (Header + Content)
pub fn get_file(s: &[u8]) -> File {

}

pub struct File<'a> {
    file: &'a [u8],
    header: TarHeader<'a>,
}

pub struct TarHeader<'a> {
    // I really need constant sized pointers here :(
    name: &'a [u8],
    mode: &'a [u8],
    group: &'a [u8],
    user: &'a [u8],
    size: &'a [u8],
    last_mod: &'a [u8],
    checksum: &'a [u8],
    link_ind: &u8,
    link: &[u8],
    ustar_header: UStarHeader,
}
<|endoftext|>


<commit_before>/**

An implementation of the Graph500 Bread First Search problem in Rust.

*/

use std;
import std::time;
import std::map;
import std::map::hashmap;
import std::deque;
import std::deque::t;
import std::arc;
import std::par;
import io::writer_util;
import comm::*;
import int::abs;

type node_id = i64;
type graph = [[node_id]];
type bfs_result = [node_id];

fn make_edges(scale: uint, edgefactor: uint) -> [(node_id, node_id)] {
    let r = rand::rng();

    fn choose_edge(i: node_id, j: node_id, scale: uint, r: rand::rng)
        -> (node_id, node_id) {

        let A = 0.57;
        let B = 0.19;
        let C = 0.19;

        if scale == 0u {
            (i, j)
        }
        else {
            let i = i * 2i64;
            let j = j * 2i64;
            let scale = scale - 1u;

            let x = r.gen_float();

            if x < A {
                choose_edge(i, j, scale, r)
            }
            else {
                let x = x - A;
                if x < B {
                    choose_edge(i + 1i64, j, scale, r)
                }
                else {
                    let x = x - B;
                    if x < C {
                        choose_edge(i, j + 1i64, scale, r)
                    }
                    else {
                        choose_edge(i + 1i64, j + 1i64, scale, r)
                    }
                }
            }
        }
    }

    vec::from_fn((1u << scale) * edgefactor) {|_i|
        choose_edge(0i64, 0i64, scale, r)
    }
}

fn make_graph(N: uint, edges: [(node_id, node_id)]) -> graph {
    let graph = vec::from_fn(N) {|_i|
        map::hashmap::<node_id, ()>({|x| x as uint }, {|x, y| x == y })
    };

    vec::each(edges) {|e|
        let (i, j) = e;
        map::set_add(graph[i], j);
        map::set_add(graph[j], i);
        true
    }

    graph.map() {|v|
        map::vec_from_set(v)
    }
}

fn gen_search_keys(graph: graph, n: uint) -> [node_id] {
    let keys = map::hashmap::<node_id, ()>({|x| x as uint }, {|x, y| x == y });
    let r = rand::rng();

    while keys.size() < n {
        let k = r.gen_uint_range(0u, graph.len());

        if graph[k].len() > 0u && vec::any(graph[k]) {|i|
            i != k as node_id
        } {
            map::set_add(keys, k as node_id);
        }
    }
    map::vec_from_set(keys)
}

#[doc="Returns a vector of all the parents in the BFS tree rooted at key.

Nodes that are unreachable have a parent of -1."]
fn bfs(graph: graph, key: node_id) -> bfs_result {
    let marks : [mut node_id]
        = vec::to_mut(vec::from_elem(vec::len(graph), -1i64));

    let Q = deque::create();

    Q.add_back(key);
    marks[key] = key;

    while Q.size() > 0u {
        let t = Q.pop_front();

        graph[t].each() {|k|
            if marks[k] == -1i64 {
                marks[k] = t;
                Q.add_back(k);
            }
            true
        };
    }

    vec::from_mut(marks)
}

#[doc="Another version of the bfs function.

This one uses the same algorithm as the parallel one, just without
using the parallel vector operators."]
fn bfs2(graph: graph, key: node_id) -> bfs_result {
    // This works by doing functional updates of a color vector.

    enum color {
        white,
        // node_id marks which node turned this gray/black.
        // the node id later becomes the parent.
        gray(node_id),
        black(node_id)
    };

    let mut colors = vec::from_fn(graph.len()) {|i|
        if i as node_id == key {
            gray(key)
        }
        else {
            white
        }
    };

    fn is_gray(c: color) -> bool {
        alt c {
          gray(_) { true }
          _ { false }
        }
    }

    let mut i = 0u;
    while vec::any(colors, is_gray) {
        // Do the BFS.
        log(info, #fmt("PBFS iteration %?", i));
        i += 1u;
        colors = colors.mapi() {|i, c|
            let c : color = c;
            alt c {
              white {
                let i = i as node_id;

                let neighbors = graph[i];

                let mut color = white;

                neighbors.each() {|k|
                    if is_gray(colors[k]) {
                        color = gray(k);
                        false
                    }
                    else { true }
                };

                color
              }
              gray(parent) { black(parent) }
              black(parent) { black(parent) }
            }
        }
    }

    // Convert the results.
    vec::map(colors) {|c|
        alt c {
          white { -1i64 }
          black(parent) { parent }
          _ { fail "Found remaining gray nodes in BFS" }
        }
    }
}

#[doc="A parallel version of the bfs function."]
fn pbfs(graph: graph, key: node_id) -> bfs_result {
    // This works by doing functional updates of a color vector.

    enum color {
        white,
        // node_id marks which node turned this gray/black.
        // the node id later becomes the parent.
        gray(node_id),
        black(node_id)
    };

    let mut colors = vec::from_fn(graph.len()) {|i|
        if i as node_id == key {
            gray(key)
        }
        else {
            white
        }
    };

    #[inline(always)]
    fn is_gray(c: color) -> bool {
        alt c {
          gray(_) { true }
          _ { false }
        }
    }

    let graph = arc::arc(copy graph);

    let mut i = 0u;
    while par::any(colors, is_gray) {
        // Do the BFS.
        log(info, #fmt("PBFS iteration %?", i));
        i += 1u;
        let old_len = colors.len();

        let color = arc::arc(colors);

        colors = par::mapi_factory(*arc::get(&color)) {||
            let colors = arc::clone(&color);
            let graph = arc::clone(&graph);
            fn~(i: uint, c: color) -> color {
                let c : color = c;
                let colors = arc::get(&colors);
                let graph = arc::get(&graph);
                alt c {
                  white {
                    let i = i as node_id;

                    let neighbors = (*graph)[i];

                    let mut color = white;

                    neighbors.each() {|k|
                        if is_gray((*colors)[k]) {
                            color = gray(k);
                            false
                        }
                        else { true }
                    };
                    color
                  }
                  gray(parent) { black(parent) }
                  black(parent) { black(parent) }
                }
            }
        };
        assert(colors.len() == old_len);
    }

    // Convert the results.
    par::map(colors) {|c|
        alt c {
          white { -1i64 }
          black(parent) { parent }
          _ { fail "Found remaining gray nodes in BFS" }
        }
    }
}

#[doc="Performs at least some of the validation in the Graph500 spec."]
fn validate(edges: [(node_id, node_id)],
            root: node_id, tree: bfs_result) -> bool {
    // There are 5 things to test. Below is code for each of them.

    // 1. The BFS tree is a tree and does not contain cycles.
    //
    // We do this by iterating over the tree, and tracing each of the
    // parent chains back to the root. While we do this, we also
    // compute the levels for each node.

    log(info, "Verifying tree structure...");

    let mut status = true;
    let level = tree.map() {|parent|
        let mut parent = parent;
        let mut path = [];

        if parent == -1i64 {
            // This node was not in the tree.
            -1
        }
        else {
            while parent != root {
                if vec::contains(path, parent) {
                    status = false;
                }

                path += [parent];
                parent = tree[parent];
            }

            // The length of the path back to the root is the current
            // level.
            path.len() as int
        }
    };

    if !status { ret status }

    // 2. Each tree edge connects vertices whose BFS levels differ by
    //    exactly one.

    log(info, "Verifying tree edges...");

    let status = tree.alli() {|k, parent|
        if parent != root && parent != -1i64 {
            level[parent] == level[k] - 1
        }
        else {
            true
        }
    };

    if !status { ret status }

    // 3. Every edge in the input list has vertices with levels that
    //    differ by at most one or that both are not in the BFS tree.

    log(info, "Verifying graph edges...");

    let status = edges.all() {|e|
        let (u, v) = e;

        abs(level[u] - level[v]) <= 1
    };

    if !status { ret status }

    // 4. The BFS tree spans an entire connected component's vertices.

    // This is harder. We'll skip it for now...

    // 5. A node and its parent are joined by an edge of the original
    //    graph.

    log(info, "Verifying tree and graph edges...");

    let status = par::alli(tree) {|u, v|
        let u = u as node_id;
        if v == -1i64 || u == root {
            true
        }
        else {
            edges.contains((u, v)) || edges.contains((v, u))
        }
    };

    if !status { ret status }

    // If we get through here, all the tests passed!
    true
}

fn main(args: [str]) {
    let args = if os::getenv("RUST_BENCH").is_some() {
        ["", "15", "48"]
    } else if args.len() <= 1u {
        ["", "10", "16"]
    } else {
        args
    };

    let scale = uint::from_str(args[1]).get();
    let num_keys = uint::from_str(args[2]).get();
    let do_validate = false;
    let do_sequential = true;

    let start = time::precise_time_s();
    let edges = make_edges(scale, 16u);
    let stop = time::precise_time_s();

    io::stdout().write_line(#fmt("Generated %? edges in %? seconds.",
                                 vec::len(edges), stop - start));

    let start = time::precise_time_s();
    let graph = make_graph(1u << scale, edges);
    let stop = time::precise_time_s();

    let mut total_edges = 0u;
    vec::each(graph) {|edges| total_edges += edges.len(); true };

    io::stdout().write_line(#fmt("Generated graph with %? edges in %? seconds.",
                                 total_edges / 2u,
                                 stop - start));

    let mut total_seq = 0.0;
    let mut total_par = 0.0;

    gen_search_keys(graph, num_keys).map() {|root|
        io::stdout().write_line("");
        io::stdout().write_line(#fmt("Search key: %?", root));

        if do_sequential {
            let start = time::precise_time_s();
            let bfs_tree = bfs(graph, root);
            let stop = time::precise_time_s();

            //total_seq += stop - start;

            io::stdout().write_line(
                #fmt("Sequential BFS completed in %? seconds.",
                     stop - start));

            if do_validate {
                let start = time::precise_time_s();
                assert(validate(edges, root, bfs_tree));
                let stop = time::precise_time_s();

                io::stdout().write_line(
                    #fmt("Validation completed in %? seconds.",
                         stop - start));
            }

            let start = time::precise_time_s();
            let bfs_tree = bfs2(graph, root);
            let stop = time::precise_time_s();

            total_seq += stop - start;

            io::stdout().write_line(
                #fmt("Alternate Sequential BFS completed in %? seconds.",
                     stop - start));

            if do_validate {
                let start = time::precise_time_s();
                assert(validate(edges, root, bfs_tree));
                let stop = time::precise_time_s();

                io::stdout().write_line(
                    #fmt("Validation completed in %? seconds.",
                         stop - start));
            }
        }

        let start = time::precise_time_s();
        let bfs_tree = pbfs(graph, root);
        let stop = time::precise_time_s();

        total_par += stop - start;

        io::stdout().write_line(#fmt("Parallel BFS completed in %? seconds.",
                                     stop - start));

        if do_validate {
            let start = time::precise_time_s();
            assert(validate(edges, root, bfs_tree));
            let stop = time::precise_time_s();

            io::stdout().write_line(#fmt("Validation completed in %? seconds.",
                                         stop - start));
        }
    };

    io::stdout().write_line("");
    io::stdout().write_line(
        #fmt("Total sequential: %? \t Total Parallel: %? \t Speedup: %?x",
             total_seq, total_par, total_seq / total_par));
}
<commit_msg>Avoid some more copies.<commit_after>/**

An implementation of the Graph500 Bread First Search problem in Rust.

*/

use std;
import std::time;
import std::map;
import std::map::hashmap;
import std::deque;
import std::deque::t;
import std::arc;
import std::par;
import io::writer_util;
import comm::*;
import int::abs;

type node_id = i64;
type graph = [[node_id]];
type bfs_result = [node_id];

fn make_edges(scale: uint, edgefactor: uint) -> [(node_id, node_id)] {
    let r = rand::rng();

    fn choose_edge(i: node_id, j: node_id, scale: uint, r: rand::rng)
        -> (node_id, node_id) {

        let A = 0.57;
        let B = 0.19;
        let C = 0.19;

        if scale == 0u {
            (i, j)
        }
        else {
            let i = i * 2i64;
            let j = j * 2i64;
            let scale = scale - 1u;

            let x = r.gen_float();

            if x < A {
                choose_edge(i, j, scale, r)
            }
            else {
                let x = x - A;
                if x < B {
                    choose_edge(i + 1i64, j, scale, r)
                }
                else {
                    let x = x - B;
                    if x < C {
                        choose_edge(i, j + 1i64, scale, r)
                    }
                    else {
                        choose_edge(i + 1i64, j + 1i64, scale, r)
                    }
                }
            }
        }
    }

    vec::from_fn((1u << scale) * edgefactor) {|_i|
        choose_edge(0i64, 0i64, scale, r)
    }
}

fn make_graph(N: uint, edges: [(node_id, node_id)]) -> graph {
    let graph = vec::from_fn(N) {|_i|
        map::hashmap::<node_id, ()>({|x| x as uint }, {|x, y| x == y })
    };

    vec::each(edges) {|e|
        let (i, j) = e;
        map::set_add(graph[i], j);
        map::set_add(graph[j], i);
        true
    }

    graph.map() {|v|
        map::vec_from_set(v)
    }
}

fn gen_search_keys(graph: graph, n: uint) -> [node_id] {
    let keys = map::hashmap::<node_id, ()>({|x| x as uint }, {|x, y| x == y });
    let r = rand::rng();

    while keys.size() < n {
        let k = r.gen_uint_range(0u, graph.len());

        if graph[k].len() > 0u && vec::any(graph[k]) {|i|
            i != k as node_id
        } {
            map::set_add(keys, k as node_id);
        }
    }
    map::vec_from_set(keys)
}

#[doc="Returns a vector of all the parents in the BFS tree rooted at key.

Nodes that are unreachable have a parent of -1."]
fn bfs(graph: graph, key: node_id) -> bfs_result {
    let marks : [mut node_id]
        = vec::to_mut(vec::from_elem(vec::len(graph), -1i64));

    let Q = deque::create();

    Q.add_back(key);
    marks[key] = key;

    while Q.size() > 0u {
        let t = Q.pop_front();

        graph[t].each() {|k|
            if marks[k] == -1i64 {
                marks[k] = t;
                Q.add_back(k);
            }
            true
        };
    }

    vec::from_mut(marks)
}

#[doc="Another version of the bfs function.

This one uses the same algorithm as the parallel one, just without
using the parallel vector operators."]
fn bfs2(graph: graph, key: node_id) -> bfs_result {
    // This works by doing functional updates of a color vector.

    enum color {
        white,
        // node_id marks which node turned this gray/black.
        // the node id later becomes the parent.
        gray(node_id),
        black(node_id)
    };

    let mut colors = vec::from_fn(graph.len()) {|i|
        if i as node_id == key {
            gray(key)
        }
        else {
            white
        }
    };

    fn is_gray(c: color) -> bool {
        alt c {
          gray(_) { true }
          _ { false }
        }
    }

    let mut i = 0u;
    while vec::any(colors, is_gray) {
        // Do the BFS.
        log(info, #fmt("PBFS iteration %?", i));
        i += 1u;
        colors = colors.mapi() {|i, c|
            let c : color = c;
            alt c {
              white {
                let i = i as node_id;

                let neighbors = graph[i];

                let mut color = white;

                neighbors.each() {|k|
                    if is_gray(colors[k]) {
                        color = gray(k);
                        false
                    }
                    else { true }
                };

                color
              }
              gray(parent) { black(parent) }
              black(parent) { black(parent) }
            }
        }
    }

    // Convert the results.
    vec::map(colors) {|c|
        alt c {
          white { -1i64 }
          black(parent) { parent }
          _ { fail "Found remaining gray nodes in BFS" }
        }
    }
}

#[doc="A parallel version of the bfs function."]
fn pbfs(&&graph: arc::arc<graph>, key: node_id) -> bfs_result {
    // This works by doing functional updates of a color vector.

    enum color {
        white,
        // node_id marks which node turned this gray/black.
        // the node id later becomes the parent.
        gray(node_id),
        black(node_id)
    };

    let mut colors = vec::from_fn((*arc::get(&graph)).len()) {|i|
        if i as node_id == key {
            gray(key)
        }
        else {
            white
        }
    };

    #[inline(always)]
    fn is_gray(c: color) -> bool {
        alt c {
          gray(_) { true }
          _ { false }
        }
    }

    let mut i = 0u;
    while par::any(colors, is_gray) {
        // Do the BFS.
        log(info, #fmt("PBFS iteration %?", i));
        i += 1u;
        let old_len = colors.len();

        let color = arc::arc(colors);

        colors = par::mapi_factory(*arc::get(&color)) {||
            let colors = arc::clone(&color);
            let graph = arc::clone(&graph);
            fn~(i: uint, c: color) -> color {
                let c : color = c;
                let colors = arc::get(&colors);
                let graph = arc::get(&graph);
                alt c {
                  white {
                    let i = i as node_id;

                    let neighbors = (*graph)[i];

                    let mut color = white;

                    neighbors.each() {|k|
                        if is_gray((*colors)[k]) {
                            color = gray(k);
                            false
                        }
                        else { true }
                    };
                    color
                  }
                  gray(parent) { black(parent) }
                  black(parent) { black(parent) }
                }
            }
        };
        assert(colors.len() == old_len);
    }

    // Convert the results.
    par::map(colors) {|c|
        alt c {
          white { -1i64 }
          black(parent) { parent }
          _ { fail "Found remaining gray nodes in BFS" }
        }
    }
}

#[doc="Performs at least some of the validation in the Graph500 spec."]
fn validate(edges: [(node_id, node_id)],
            root: node_id, tree: bfs_result) -> bool {
    // There are 5 things to test. Below is code for each of them.

    // 1. The BFS tree is a tree and does not contain cycles.
    //
    // We do this by iterating over the tree, and tracing each of the
    // parent chains back to the root. While we do this, we also
    // compute the levels for each node.

    log(info, "Verifying tree structure...");

    let mut status = true;
    let level = tree.map() {|parent|
        let mut parent = parent;
        let mut path = [];

        if parent == -1i64 {
            // This node was not in the tree.
            -1
        }
        else {
            while parent != root {
                if vec::contains(path, parent) {
                    status = false;
                }

                path += [parent];
                parent = tree[parent];
            }

            // The length of the path back to the root is the current
            // level.
            path.len() as int
        }
    };

    if !status { ret status }

    // 2. Each tree edge connects vertices whose BFS levels differ by
    //    exactly one.

    log(info, "Verifying tree edges...");

    let status = tree.alli() {|k, parent|
        if parent != root && parent != -1i64 {
            level[parent] == level[k] - 1
        }
        else {
            true
        }
    };

    if !status { ret status }

    // 3. Every edge in the input list has vertices with levels that
    //    differ by at most one or that both are not in the BFS tree.

    log(info, "Verifying graph edges...");

    let status = edges.all() {|e|
        let (u, v) = e;

        abs(level[u] - level[v]) <= 1
    };

    if !status { ret status }

    // 4. The BFS tree spans an entire connected component's vertices.

    // This is harder. We'll skip it for now...

    // 5. A node and its parent are joined by an edge of the original
    //    graph.

    log(info, "Verifying tree and graph edges...");

    let status = par::alli(tree) {|u, v|
        let u = u as node_id;
        if v == -1i64 || u == root {
            true
        }
        else {
            edges.contains((u, v)) || edges.contains((v, u))
        }
    };

    if !status { ret status }

    // If we get through here, all the tests passed!
    true
}

fn main(args: [str]) {
    let args = if os::getenv("RUST_BENCH").is_some() {
        ["", "15", "48"]
    } else if args.len() <= 1u {
        ["", "10", "16"]
    } else {
        args
    };

    let scale = uint::from_str(args[1]).get();
    let num_keys = uint::from_str(args[2]).get();
    let do_validate = false;
    let do_sequential = false;

    let start = time::precise_time_s();
    let edges = make_edges(scale, 16u);
    let stop = time::precise_time_s();

    io::stdout().write_line(#fmt("Generated %? edges in %? seconds.",
                                 vec::len(edges), stop - start));

    let start = time::precise_time_s();
    let graph = make_graph(1u << scale, edges);
    let stop = time::precise_time_s();

    let mut total_edges = 0u;
    vec::each(graph) {|edges| total_edges += edges.len(); true };

    io::stdout().write_line(#fmt("Generated graph with %? edges in %? seconds.",
                                 total_edges / 2u,
                                 stop - start));

    let mut total_seq = 0.0;
    let mut total_par = 0.0;

    let graph_arc = arc::arc(copy graph);

    gen_search_keys(graph, num_keys).map() {|root|
        io::stdout().write_line("");
        io::stdout().write_line(#fmt("Search key: %?", root));

        if do_sequential {
            let start = time::precise_time_s();
            let bfs_tree = bfs(graph, root);
            let stop = time::precise_time_s();

            //total_seq += stop - start;

            io::stdout().write_line(
                #fmt("Sequential BFS completed in %? seconds.",
                     stop - start));

            if do_validate {
                let start = time::precise_time_s();
                assert(validate(edges, root, bfs_tree));
                let stop = time::precise_time_s();

                io::stdout().write_line(
                    #fmt("Validation completed in %? seconds.",
                         stop - start));
            }

            let start = time::precise_time_s();
            let bfs_tree = bfs2(graph, root);
            let stop = time::precise_time_s();

            total_seq += stop - start;

            io::stdout().write_line(
                #fmt("Alternate Sequential BFS completed in %? seconds.",
                     stop - start));

            if do_validate {
                let start = time::precise_time_s();
                assert(validate(edges, root, bfs_tree));
                let stop = time::precise_time_s();

                io::stdout().write_line(
                    #fmt("Validation completed in %? seconds.",
                         stop - start));
            }
        }

        let start = time::precise_time_s();
        let bfs_tree = pbfs(graph_arc, root);
        let stop = time::precise_time_s();

        total_par += stop - start;

        io::stdout().write_line(#fmt("Parallel BFS completed in %? seconds.",
                                     stop - start));

        if do_validate {
            let start = time::precise_time_s();
            assert(validate(edges, root, bfs_tree));
            let stop = time::precise_time_s();

            io::stdout().write_line(#fmt("Validation completed in %? seconds.",
                                         stop - start));
        }
    };

    io::stdout().write_line("");
    io::stdout().write_line(
        #fmt("Total sequential: %? \t Total Parallel: %? \t Speedup: %?x",
             total_seq, total_par, total_seq / total_par));
}
<|endoftext|>