<commit_before>extern crate serialize;

use std::io::process::Command;
use std::io::{File, TempDir};

fn main() {
    use std::io::fs;

    let (args, passthrough) = parse_arguments();

    // getting the path from the ANDROID_HOME env
    let sdk_path = std::os::env().move_iter().find(|&(ref k, _)| k.as_slice() == "ANDROID_HOME")
        .map(|(_, v)| Path::new(v)).expect("Please set the ANDROID_HOME environment variable");

    // hardcoding ndk path
    let ndk_path = std::os::env().move_iter().find(|&(ref k, _)| k.as_slice() == "NDK_HOME")
        .map(|(_, v)| Path::new(v)).expect("Please set the NDK_HOME environment variable");

    // hardcoding ndk path
    let standalone_path = std::os::env().move_iter().find(|&(ref k, _)| k.as_slice() == "NDK_STANDALONE")
        .map(|(_, v)| Path::new(v)).unwrap_or(Path::new("/opt/ndk_standalone"));

    // creating the build directory that will contain all the necessary files to create teh apk
    let directory = build_directory(&sdk_path, args.output.filestem_str().unwrap());

    // compiling android_native_app_glue.c
    if Command::new(standalone_path.join("bin").join("arm-linux-androideabi-gcc"))
        .arg(ndk_path.join("sources").join("android").join("native_app_glue").join("android_native_app_glue.c"))
        .arg("-c")
        .arg("-o").arg(directory.path().join("android_native_app_glue.o"))
        .stdout(std::io::process::InheritFd(1)).stderr(std::io::process::InheritFd(2))
        .status().unwrap() != std::io::process::ExitStatus(0)
    {
        println!("Error while executing gcc");
        std::os::set_exit_status(1);
        return;
    }

    // calling gcc to link to an executable
    if Command::new(standalone_path.join("bin").join("arm-linux-androideabi-gcc"))
        .args(passthrough.as_slice())
        .arg(directory.path().join("android_native_app_glue.o"))
        .arg("-o").arg(directory.path().join("libs").join("armeabi").join("libmain.so"))
        .arg("-Wl,-E")
        .stdout(std::io::process::InheritFd(1))
        .stderr(std::io::process::InheritFd(2))//.cwd(directory.path())
        .status().unwrap() != std::io::process::ExitStatus(0)
    {
        println!("Error while executing gcc");
        std::os::set_exit_status(1);
        return;
    }

    // calling elfedit to turn our executable into a shared object
    if Command::new(standalone_path.join("bin").join("arm-linux-androideabi-elfedit"))
        .arg("--output-type").arg("dyn")
        .arg(directory.path().join("libs").join("armeabi").join("libmain.so"))
        .stdout(std::io::process::InheritFd(1))
        .stderr(std::io::process::InheritFd(2))
        .status().unwrap() != std::io::process::ExitStatus(0)
    {
        println!("Error while executing elfedit");
        std::os::set_exit_status(1);
        return;
    }

    // calling objdump to make sure that our object has `ANativeActivity_onCreate`
    // TODO: not working
    /*{
        let mut process =
            Command::new(standalone_path.join("bin").join("arm-linux-androideabi-objdump"))
            .arg("-x").arg(directory.path().join("libs").join("armeabi").join("libmain.so"))
            .stderr(std::io::process::InheritFd(2))
            .spawn().unwrap();

        // TODO: use UFCS instead
        fn by_ref<'a, T: Reader>(r: &'a mut T) -> std::io::RefReader<'a, T> { r.by_ref() };

        let stdout = process.stdout.as_mut().unwrap();
        let mut stdout = std::io::BufferedReader::new(by_ref(stdout));

        if stdout.lines().filter_map(|l| l.ok())
            .find(|line| line.as_slice().contains("ANativeActivity_onCreate")).is_none()
        {
            println!("Error: the output file doesn't contain ANativeActivity_onCreate");
            std::os::set_exit_status(1);
            return;
        }
    }*/

    // executing ant
    if Command::new("ant").arg("debug").stdout(std::io::process::InheritFd(1))
        .stderr(std::io::process::InheritFd(2)).cwd(directory.path())
        .status().unwrap() != std::io::process::ExitStatus(0)
    {
        println!("Error while executing ant debug");
        std::os::set_exit_status(1);
        return;
    }

    // copying apk file to the requested output
    fs::copy(&directory.path().join("bin").join("rust-android-debug.apk"),
        &args.output).unwrap();
}

struct Args {
    output: Path,
}

fn parse_arguments() -> (Args, Vec<String>) {
    let mut result_output = None;
    let mut result_passthrough = Vec::new();

    let args = std::os::args();
    let mut args = args.move_iter().skip(1);

    loop {
        let arg = match args.next() {
            None => return (
                Args {
                    output: result_output.expect("Could not find -o argument")
                },
                result_passthrough
            ),
            Some(arg) => arg
        };

        match arg.as_slice() {
            "-o" => {
                result_output = Some(Path::new(args.next().expect("-o must be followed by the output name")));
            },
            _ => result_passthrough.push(arg)
        };
    }
}

fn build_directory(sdk_dir: &Path, crate_name: &str) -> TempDir {
    use std::io::fs;

    let build_directory = TempDir::new("android-rs-glue-rust-to-apk")
        .ok().expect("Could not create temporary build directory");

    File::create(&build_directory.path().join("AndroidManifest.xml")).unwrap()
        .write_str(build_manifest(crate_name).as_slice())
        .unwrap();

    File::create(&build_directory.path().join("build.xml")).unwrap()
        .write_str(build_build_xml().as_slice())
        .unwrap();

    File::create(&build_directory.path().join("local.properties")).unwrap()
        .write_str(build_local_properties(sdk_dir).as_slice())
        .unwrap();

    File::create(&build_directory.path().join("project.properties")).unwrap()
        .write_str(build_project_properties().as_slice())
        .unwrap();

    {
        let src_path = build_directory.path().join("src").join("com").join("example")
            .join("native_activity");
        fs::mkdir_recursive(&src_path, std::io::UserRWX).unwrap();
        File::create(&src_path.join("MyNativeActivity.java")).unwrap()
            .write_str(build_java_class().as_slice())
            .unwrap();
    }

    {
        let libs_path = build_directory.path().join("libs").join("armeabi");
        fs::mkdir_recursive(&libs_path, std::io::UserRWX).unwrap();
    }

    build_directory
}

fn build_manifest(crate_name: &str) -> String {
    format!(r#"<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.native_activity"
        android:versionCode="1"
        android:versionName="1.0">

    <uses-sdk android:minSdkVersion="18" />

    <application android:label="{0}" android:hasCode="true">
        <activity android:name="com.example.native_activity.MyNativeActivity"
                android:label="{0}"
                android:configChanges="orientation|keyboardHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
<!-- END_INCLUDE(manifest) -->
"#, crate_name)
}

fn build_build_xml() -> String {
    format!(r#"<?xml version="1.0" encoding="UTF-8"?>
<project name="rust-android" default="help">
    <property file="local.properties" />
    <loadproperties srcFile="project.properties" />
    <import file="custom_rules.xml" optional="true" />
    <import file="${{sdk.dir}}/tools/ant/build.xml" />
</project>
"#)
}

fn build_local_properties(sdk_dir: &Path) -> String {
    use std::os;
    format!(r"sdk.dir={}", os::make_absolute(sdk_dir).display())
}

fn build_project_properties() -> String {
    format!(r"target=android-18")
}

fn build_java_class() -> String {
    format!(r#"
package com.example.native_activity;

import android.app.NativeActivity;
import android.util.Log;

public class MyNativeActivity extends NativeActivity {{
  static {{
    System.loadLibrary("main");
  }}

  private static String TAG = "MyNativeActivity";

  public MyNativeActivity() {{
    super();
    Log.v(TAG, "Creating MyNativeActivity");
  }}
}}"#)
}
<commit_msg>Set minimum SDK version to 9<commit_after>extern crate serialize;

use std::io::process::Command;
use std::io::{File, TempDir};

fn main() {
    use std::io::fs;

    let (args, passthrough) = parse_arguments();

    // getting the path from the ANDROID_HOME env
    let sdk_path = std::os::env().move_iter().find(|&(ref k, _)| k.as_slice() == "ANDROID_HOME")
        .map(|(_, v)| Path::new(v)).expect("Please set the ANDROID_HOME environment variable");

    // hardcoding ndk path
    let ndk_path = std::os::env().move_iter().find(|&(ref k, _)| k.as_slice() == "NDK_HOME")
        .map(|(_, v)| Path::new(v)).expect("Please set the NDK_HOME environment variable");

    // hardcoding ndk path
    let standalone_path = std::os::env().move_iter().find(|&(ref k, _)| k.as_slice() == "NDK_STANDALONE")
        .map(|(_, v)| Path::new(v)).unwrap_or(Path::new("/opt/ndk_standalone"));

    // creating the build directory that will contain all the necessary files to create teh apk
    let directory = build_directory(&sdk_path, args.output.filestem_str().unwrap());

    // compiling android_native_app_glue.c
    if Command::new(standalone_path.join("bin").join("arm-linux-androideabi-gcc"))
        .arg(ndk_path.join("sources").join("android").join("native_app_glue").join("android_native_app_glue.c"))
        .arg("-c")
        .arg("-o").arg(directory.path().join("android_native_app_glue.o"))
        .stdout(std::io::process::InheritFd(1)).stderr(std::io::process::InheritFd(2))
        .status().unwrap() != std::io::process::ExitStatus(0)
    {
        println!("Error while executing gcc");
        std::os::set_exit_status(1);
        return;
    }

    // calling gcc to link to an executable
    if Command::new(standalone_path.join("bin").join("arm-linux-androideabi-gcc"))
        .args(passthrough.as_slice())
        .arg(directory.path().join("android_native_app_glue.o"))
        .arg("-o").arg(directory.path().join("libs").join("armeabi").join("libmain.so"))
        .arg("-Wl,-E")
        .stdout(std::io::process::InheritFd(1))
        .stderr(std::io::process::InheritFd(2))//.cwd(directory.path())
        .status().unwrap() != std::io::process::ExitStatus(0)
    {
        println!("Error while executing gcc");
        std::os::set_exit_status(1);
        return;
    }

    // calling elfedit to turn our executable into a shared object
    if Command::new(standalone_path.join("bin").join("arm-linux-androideabi-elfedit"))
        .arg("--output-type").arg("dyn")
        .arg(directory.path().join("libs").join("armeabi").join("libmain.so"))
        .stdout(std::io::process::InheritFd(1))
        .stderr(std::io::process::InheritFd(2))
        .status().unwrap() != std::io::process::ExitStatus(0)
    {
        println!("Error while executing elfedit");
        std::os::set_exit_status(1);
        return;
    }

    // calling objdump to make sure that our object has `ANativeActivity_onCreate`
    // TODO: not working
    /*{
        let mut process =
            Command::new(standalone_path.join("bin").join("arm-linux-androideabi-objdump"))
            .arg("-x").arg(directory.path().join("libs").join("armeabi").join("libmain.so"))
            .stderr(std::io::process::InheritFd(2))
            .spawn().unwrap();

        // TODO: use UFCS instead
        fn by_ref<'a, T: Reader>(r: &'a mut T) -> std::io::RefReader<'a, T> { r.by_ref() };

        let stdout = process.stdout.as_mut().unwrap();
        let mut stdout = std::io::BufferedReader::new(by_ref(stdout));

        if stdout.lines().filter_map(|l| l.ok())
            .find(|line| line.as_slice().contains("ANativeActivity_onCreate")).is_none()
        {
            println!("Error: the output file doesn't contain ANativeActivity_onCreate");
            std::os::set_exit_status(1);
            return;
        }
    }*/

    // executing ant
    if Command::new("ant").arg("debug").stdout(std::io::process::InheritFd(1))
        .stderr(std::io::process::InheritFd(2)).cwd(directory.path())
        .status().unwrap() != std::io::process::ExitStatus(0)
    {
        println!("Error while executing ant debug");
        std::os::set_exit_status(1);
        return;
    }

    // copying apk file to the requested output
    fs::copy(&directory.path().join("bin").join("rust-android-debug.apk"),
        &args.output).unwrap();
}

struct Args {
    output: Path,
}

fn parse_arguments() -> (Args, Vec<String>) {
    let mut result_output = None;
    let mut result_passthrough = Vec::new();

    let args = std::os::args();
    let mut args = args.move_iter().skip(1);

    loop {
        let arg = match args.next() {
            None => return (
                Args {
                    output: result_output.expect("Could not find -o argument")
                },
                result_passthrough
            ),
            Some(arg) => arg
        };

        match arg.as_slice() {
            "-o" => {
                result_output = Some(Path::new(args.next().expect("-o must be followed by the output name")));
            },
            _ => result_passthrough.push(arg)
        };
    }
}

fn build_directory(sdk_dir: &Path, crate_name: &str) -> TempDir {
    use std::io::fs;

    let build_directory = TempDir::new("android-rs-glue-rust-to-apk")
        .ok().expect("Could not create temporary build directory");

    File::create(&build_directory.path().join("AndroidManifest.xml")).unwrap()
        .write_str(build_manifest(crate_name).as_slice())
        .unwrap();

    File::create(&build_directory.path().join("build.xml")).unwrap()
        .write_str(build_build_xml().as_slice())
        .unwrap();

    File::create(&build_directory.path().join("local.properties")).unwrap()
        .write_str(build_local_properties(sdk_dir).as_slice())
        .unwrap();

    File::create(&build_directory.path().join("project.properties")).unwrap()
        .write_str(build_project_properties().as_slice())
        .unwrap();

    {
        let src_path = build_directory.path().join("src").join("com").join("example")
            .join("native_activity");
        fs::mkdir_recursive(&src_path, std::io::UserRWX).unwrap();
        File::create(&src_path.join("MyNativeActivity.java")).unwrap()
            .write_str(build_java_class().as_slice())
            .unwrap();
    }

    {
        let libs_path = build_directory.path().join("libs").join("armeabi");
        fs::mkdir_recursive(&libs_path, std::io::UserRWX).unwrap();
    }

    build_directory
}

fn build_manifest(crate_name: &str) -> String {
    format!(r#"<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.native_activity"
        android:versionCode="1"
        android:versionName="1.0">

    <uses-sdk android:minSdkVersion="9" />

    <application android:label="{0}" android:hasCode="true">
        <activity android:name="com.example.native_activity.MyNativeActivity"
                android:label="{0}"
                android:configChanges="orientation|keyboardHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
<!-- END_INCLUDE(manifest) -->
"#, crate_name)
}

fn build_build_xml() -> String {
    format!(r#"<?xml version="1.0" encoding="UTF-8"?>
<project name="rust-android" default="help">
    <property file="local.properties" />
    <loadproperties srcFile="project.properties" />
    <import file="custom_rules.xml" optional="true" />
    <import file="${{sdk.dir}}/tools/ant/build.xml" />
</project>
"#)
}

fn build_local_properties(sdk_dir: &Path) -> String {
    use std::os;
    format!(r"sdk.dir={}", os::make_absolute(sdk_dir).display())
}

fn build_project_properties() -> String {
    format!(r"target=android-18")
}

fn build_java_class() -> String {
    format!(r#"
package com.example.native_activity;

import android.app.NativeActivity;
import android.util.Log;

public class MyNativeActivity extends NativeActivity {{
  static {{
    System.loadLibrary("main");
  }}

  private static String TAG = "MyNativeActivity";

  public MyNativeActivity() {{
    super();
    Log.v(TAG, "Creating MyNativeActivity");
  }}
}}"#)
}
<|endoftext|>


<commit_before><commit_msg>Add panicking test for calling macro in same file<commit_after><|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Active_object
#![feature(mpsc_select)]

extern crate num;
extern crate schedule_recv;

use num::traits::Zero;
use num::Float;
use std::f64::consts::PI;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use std::sync::mpsc::{self, Sender, SendError};
use std::ops::Mul;
use schedule_recv::periodic_ms;

/// Rust supports both shared-memory and actor models of concurrency, and the `Integrator` utilizes
/// both.  We use a `Sender` (actor model) to send the `Integrator` new functions, while we use a
/// `Mutex` (shared-memory concurrency) to hold the result of the integration.
///
/// Note that these are not the only options here--there are many, many ways you can deal with
/// concurrent access.  But when in doubt, a plain old `Mutex` is often a good bet.  For example,
/// this might look like a good situation for a `RwLock`--after all, there's no reason for a read
/// in the main task to block writes.  Unfortunately, unless you have significantly more reads than
/// writes (which is certainly not the case here), a `Mutex` will usually outperform a `RwLock`.
pub struct Integrator<S: 'static, T: Send> {
    input: Sender<Box<Fn(u32) -> S + Send>>,
    output: Arc<Mutex<T>>,
}

/// In Rust, time durations are strongly typed.  This is usually exactly what you want, but for a
/// problem like this--where the integrated value has unusual (unspecified?) units--it can actually
/// be a bit tricky.  Right now, `Duration`s can only be multiplied or divided by `i32`s, so in
/// order to be able to actually do math with them we say that the type parameter `S` (the result
/// of the function being integrated) must yield `T` (the type of the integrated value) when
/// multiplied by `f64`.  We could possibly replace `f64` with a generic as well, but it would make
/// things a bit more complex.
impl<S: Mul<f64, Output = T> + Float + Zero, T: 'static + Clone + Send + Float> Integrator<S, T> {
    pub fn new(frequency: u32) -> Integrator<S, T> {
        // We create a pipe allowing functions to be sent from tx (the sending end) to input (the
        // receiving end).  In order to change the function we are integrating from the task in
        // which the Integrator lives, we simply send the function through tx.
        let (tx, input) = mpsc::channel();
        // The easiest way to do shared-memory concurrency in Rust is to use atomic reference
        // counting, or Arc, around a synchronized type (like Mutex<T>).  Arc gives you a guarantee
        // that memory will not be freed as long as there is at least one reference to it.
        // It is similar to C++'s shared_ptr, but it is guaranteed to be safe and is never
        // incremented unless explicitly cloned (by default, it is moved).
        let s: Arc<Mutex<T>> = Arc::new(Mutex::new(Zero::zero()));
        let integrator = Integrator {
            input: tx,
            // Here is the aforementioned clone.  We have to do it before s enters the closure,
            // because once that happens it is moved into the closure (and later, the new task) and
            // becomes inaccessible to the outside world.
            output: s.clone(),
        };
        thread::spawn(move || -> () {
            // The frequency is how often we want to "tick" as we update our integrated total.  In
            // Rust, timers can yield Receivers that are periodically notified with an empty
            // message (where the period is the frequency).  This is useful because it lets us wait
            // on either a tick or another type of message (in this case, a request to change the
            // function we are integrating).
            let periodic = periodic_ms(frequency);
            let mut t = 0;
            let mut k: Box<Fn(u32) -> S + Send> = Box::new(|_| Zero::zero());
            let mut k_0: S = Zero::zero();
            loop {
                // Here's the selection we talked about above.  Note that we are careful to call
                // the *non*-failing function, recv(), here.  The reason we do this is because
                // recv() will return Err when the sending end of a channel is dropped.  While
                // this is unlikely to happen for the timer (so again, you could argue for failure
                // there), it's normal behavior for the sending end of input to be dropped, since
                // it just happens when the Integrator falls out of scope.  So we handle it cleanly
                // and break out of the loop, rather than failing.
                select! {
                    res = periodic.recv() => match res {
                        Ok(_) => {
                            t += frequency;
                            let k_1: S = k(t);
                            // Rust Mutexes are a bit different from Mutexes in many other
                            // languages, in that the protected data is actually encapsulated by
                            // the Mutex.  The reason for this is that Rust is actually capable of
                            // enforcing (via its borrow checker) the invariant that the contents
                            // of a Mutex may only be read when you have acquired its lock.  This
                            // is enforced by way of a MutexGuard, the return value of lock(),
                            // which implements some special traits (Deref and DerefMut) that allow
                            // access to the inner element "through" the guard.  The element so
                            // acquired has a lifetime bounded by that of the MutexGuard, the
                            // MutexGuard can only be acquired by taking a lock, and the only way
                            // to release the lock is by letting the MutexGuard fall out of scope,
                            // so it's impossible to access the data incorrectly.  There are some
                            // additional subtleties around the actual implementation, but that's
                            // the basic idea.
                            let mut s = s.lock().unwrap();
                            *s = *s + (k_1 + k_0) * (frequency as f64 / 2.);
                            k_0 = k_1;
                        }
                        Err(_) => break,
                    },
                    res = input.recv() => match res {
                        Ok(k_new) => k = k_new,
                        Err(_) => break,
                    }
                }
            }
        });
        integrator
    }

    pub fn input(&self,
                 k: Box<Fn(u32) -> S + Send>)
                 -> Result<(), SendError<Box<Fn(u32) -> S + Send>>> {
        // The meat of the work is done in the other thread, so to set the
        // input we just send along the Sender we set earlier...
        self.input.send(k)
    }

    pub fn output(&self) -> T {
        // ...and to read the input, we simply acquire a lock on the output Mutex and return a
        // copy. Why do we have to copy it?  Because, as mentioned above, Rust won't let us
        // retain access to the interior of the Mutex unless we have possession of its lock.  There
        // are ways and circumstances in which one can avoid this (e.g. by using atomic types) but
        // a copy is a perfectly reasonable solution as well, and a lot easier to reason about :)
        *self.output.lock().unwrap()
    }
}

/// This function is fairly straightforward.  We create the integrator, set its input function k(t)
/// to 2pi * f * t, and then wait as described in the Rosetta stone problem.
fn integrate() -> f64 {
    let object = Integrator::new(10);
    object.input(Box::new(|t: u32| {
            let two_seconds_ms = 2 * 1000;
            let f = 1. / two_seconds_ms as f64;
            (2. * PI * f * t as f64).sin()
        }))
        .expect("Failed to set input");
    thread::sleep(Duration::from_secs(2));
    object.input(Box::new(|_| 0.)).expect("Failed to set input");
    thread::sleep(Duration::from_millis(500));
    object.output()
}

fn main() {
    println!("{}", integrate());
}

/// Will fail on a heavily loaded machine
#[test]
#[ignore]
fn solution() {
    // We should just be able to call integrate, but can't represent the closure properly due to
    // rust-lang/rust issue #17060 if we make frequency or period a variable.
    // FIXME(pythonesque): When unboxed closures are fixed, fix integrate() to take two arguments.
    let object = Integrator::new(10);
    object.input(Box::new(|t: u32| {
            let two_seconds_ms = 2 * 1000;
            let f = 1. / (two_seconds_ms / 10) as f64;
            (2. * PI * f * t as f64).sin()
        }))
        .expect("Failed to set input");
    thread::sleep(Duration::from_millis(200));
    object.input(Box::new(|_| 0.)).expect("Failed to set input");
    thread::sleep(Duration::from_millis(100));
    assert_eq!(object.output() as u32, 0)
}
<commit_msg>use type aliases for complex types<commit_after>// http://rosettacode.org/wiki/Active_object
#![feature(mpsc_select)]

extern crate num;
extern crate schedule_recv;

use num::traits::Zero;
use num::Float;
use std::f64::consts::PI;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use std::sync::mpsc::{self, Sender, SendError};
use std::ops::Mul;
use schedule_recv::periodic_ms;

pub type Actor<S> = Sender<Box<Fn(u32) -> S + Send>>;
pub type ActorResult<S> = Result<(), SendError<Box<Fn(u32) -> S + Send>>>;

/// Rust supports both shared-memory and actor models of concurrency, and the `Integrator` utilizes
/// both.  We use an `Actor` to send the `Integrator` new functions, while we use a `Mutex`
/// (shared-memory concurrency) to hold the result of the integration.
///
/// Note that these are not the only options here--there are many, many ways you can deal with
/// concurrent access.  But when in doubt, a plain old `Mutex` is often a good bet.  For example,
/// this might look like a good situation for a `RwLock`--after all, there's no reason for a read
/// in the main task to block writes.  Unfortunately, unless you have significantly more reads than
/// writes (which is certainly not the case here), a `Mutex` will usually outperform a `RwLock`.
pub struct Integrator<S: 'static, T: Send> {
    input: Actor<S>,
    output: Arc<Mutex<T>>,
}

/// In Rust, time durations are strongly typed.  This is usually exactly what you want, but for a
/// problem like this--where the integrated value has unusual (unspecified?) units--it can actually
/// be a bit tricky.  Right now, `Duration`s can only be multiplied or divided by `i32`s, so in
/// order to be able to actually do math with them we say that the type parameter `S` (the result
/// of the function being integrated) must yield `T` (the type of the integrated value) when
/// multiplied by `f64`.  We could possibly replace `f64` with a generic as well, but it would make
/// things a bit more complex.
impl<S, T> Integrator<S, T>
    where S: Mul<f64, Output = T> + Float + Zero,
          T: 'static + Clone + Send + Float
{
    pub fn new(frequency: u32) -> Integrator<S, T> {
        // We create a pipe allowing functions to be sent from tx (the sending end) to input (the
        // receiving end).  In order to change the function we are integrating from the task in
        // which the Integrator lives, we simply send the function through tx.
        let (tx, input) = mpsc::channel();
        // The easiest way to do shared-memory concurrency in Rust is to use atomic reference
        // counting, or Arc, around a synchronized type (like Mutex<T>).  Arc gives you a guarantee
        // that memory will not be freed as long as there is at least one reference to it.
        // It is similar to C++'s shared_ptr, but it is guaranteed to be safe and is never
        // incremented unless explicitly cloned (by default, it is moved).
        let s: Arc<Mutex<T>> = Arc::new(Mutex::new(Zero::zero()));
        let integrator = Integrator {
            input: tx,
            // Here is the aforementioned clone.  We have to do it before s enters the closure,
            // because once that happens it is moved into the closure (and later, the new task) and
            // becomes inaccessible to the outside world.
            output: s.clone(),
        };
        thread::spawn(move || -> () {
            // The frequency is how often we want to "tick" as we update our integrated total.  In
            // Rust, timers can yield Receivers that are periodically notified with an empty
            // message (where the period is the frequency).  This is useful because it lets us wait
            // on either a tick or another type of message (in this case, a request to change the
            // function we are integrating).
            let periodic = periodic_ms(frequency);
            let mut t = 0;
            let mut k: Box<Fn(u32) -> S + Send> = Box::new(|_| Zero::zero());
            let mut k_0: S = Zero::zero();
            loop {
                // Here's the selection we talked about above.  Note that we are careful to call
                // the *non*-failing function, recv(), here.  The reason we do this is because
                // recv() will return Err when the sending end of a channel is dropped.  While
                // this is unlikely to happen for the timer (so again, you could argue for failure
                // there), it's normal behavior for the sending end of input to be dropped, since
                // it just happens when the Integrator falls out of scope.  So we handle it cleanly
                // and break out of the loop, rather than failing.
                select! {
                    res = periodic.recv() => match res {
                        Ok(_) => {
                            t += frequency;
                            let k_1: S = k(t);
                            // Rust Mutexes are a bit different from Mutexes in many other
                            // languages, in that the protected data is actually encapsulated by
                            // the Mutex.  The reason for this is that Rust is actually capable of
                            // enforcing (via its borrow checker) the invariant that the contents
                            // of a Mutex may only be read when you have acquired its lock.  This
                            // is enforced by way of a MutexGuard, the return value of lock(),
                            // which implements some special traits (Deref and DerefMut) that allow
                            // access to the inner element "through" the guard.  The element so
                            // acquired has a lifetime bounded by that of the MutexGuard, the
                            // MutexGuard can only be acquired by taking a lock, and the only way
                            // to release the lock is by letting the MutexGuard fall out of scope,
                            // so it's impossible to access the data incorrectly.  There are some
                            // additional subtleties around the actual implementation, but that's
                            // the basic idea.
                            let mut s = s.lock().unwrap();
                            *s = *s + (k_1 + k_0) * (frequency as f64 / 2.);
                            k_0 = k_1;
                        }
                        Err(_) => break,
                    },
                    res = input.recv() => match res {
                        Ok(k_new) => k = k_new,
                        Err(_) => break,
                    }
                }
            }
        });
        integrator
    }

    pub fn input(&self, k: Box<Fn(u32) -> S + Send>) -> ActorResult<S> {
        // The meat of the work is done in the other thread, so to set the
        // input we just send along the Sender we set earlier...
        self.input.send(k)
    }

    pub fn output(&self) -> T {
        // ...and to read the input, we simply acquire a lock on the output Mutex and return a
        // copy. Why do we have to copy it?  Because, as mentioned above, Rust won't let us
        // retain access to the interior of the Mutex unless we have possession of its lock.  There
        // are ways and circumstances in which one can avoid this (e.g. by using atomic types) but
        // a copy is a perfectly reasonable solution as well, and a lot easier to reason about :)
        *self.output.lock().unwrap()
    }
}

/// This function is fairly straightforward.  We create the integrator, set its input function k(t)
/// to 2pi * f * t, and then wait as described in the Rosetta stone problem.
fn integrate() -> f64 {
    let object = Integrator::new(10);
    object.input(Box::new(|t: u32| {
            let two_seconds_ms = 2 * 1000;
            let f = 1. / two_seconds_ms as f64;
            (2. * PI * f * t as f64).sin()
        }))
        .expect("Failed to set input");
    thread::sleep(Duration::from_secs(2));
    object.input(Box::new(|_| 0.)).expect("Failed to set input");
    thread::sleep(Duration::from_millis(500));
    object.output()
}

fn main() {
    println!("{}", integrate());
}

/// Will fail on a heavily loaded machine
#[test]
#[ignore]
fn solution() {
    // We should just be able to call integrate, but can't represent the closure properly due to
    // rust-lang/rust issue #17060 if we make frequency or period a variable.
    // FIXME(pythonesque): When unboxed closures are fixed, fix integrate() to take two arguments.
    let object = Integrator::new(10);
    object.input(Box::new(|t: u32| {
            let two_seconds_ms = 2 * 1000;
            let f = 1. / (two_seconds_ms / 10) as f64;
            (2. * PI * f * t as f64).sin()
        }))
        .expect("Failed to set input");
    thread::sleep(Duration::from_millis(200));
    object.input(Box::new(|_| 0.)).expect("Failed to set input");
    thread::sleep(Duration::from_millis(100));
    assert_eq!(object.output() as u32, 0)
}
<|endoftext|>


<commit_before>
use crate::*;
use crate::wpublisher::bool::*;
use wca::*;
use std::env;
use std::fs;
use std::fmt::Write;
use std::path::PathBuf;
use toml_edit::value;
use cargo_metadata::MetadataCommand;
use wtools::error::Error;

///
/// Publish package.
///

pub fn publish( instruction : &instruction::Instruction ) -> Result<(), Error>
{
  let current_path = env::current_dir().unwrap();

  let paths = files::find( &current_path, instruction.subject.split( " " ).collect::<Vec<&str>>().as_slice() );
  let mut paths = paths.iter().filter_map( | s | if s.ends_with( "Cargo.toml" ) { Some( s.into() ) } else { None } ).collect::<Vec<PathBuf>>();
  if paths.is_empty() /* && !path.glob_is( &instruction.subject ) qqq : implement `glob_is` */
  {
    paths.push( PathBuf::from( &instruction.subject ) );
  }

  for path in paths
  {
    let mut manifest = manifest_get( path ).unwrap();
    if !manifest.package_is() || manifest.local_is()
    {
      continue;
    }
    let data = manifest.manifest_data.as_deref_mut().unwrap();

    let mut package_dir = manifest.manifest_path.clone();
    package_dir.pop();

    let output = process::start_sync( "cargo package", &package_dir ).unwrap();
    process::log_output( &output );

    let name = &data[ "package" ][ "name" ].clone();
    let name = name.as_str().unwrap();
    let version = &data[ "package" ][ "version" ].clone();
    let version = version.as_str().unwrap();
    let local_package_path = local_package_path_get( name, version, &manifest.manifest_path );

    let local_package = fs::read( &local_package_path ).unwrap();
    let remote_package = http::retrieve_bytes( name, version ).unwrap_or_default();

    let digest_of_local = digest::hash( &local_package );
    let digest_of_remote = digest::hash( &remote_package );

    if digest_of_local != digest_of_remote
    {
      data[ "package" ][ "version" ] = bump( version ).unwrap();
      let version = &data[ "package" ][ "version" ].clone();
      let version = version.as_str().unwrap();
      manifest.store().unwrap();

      let dry = match instruction.properties_map.get( "dry" )
      {
        Some( x ) => x.to_bool_like(),
        None => BoolLike::False,
      };

      if dry == BoolLike::True
      {
        let mut buf = String::new();
        write!( &mut buf, "git commit --dry-run -am \"{} v{}\"", name, version ).unwrap();
        let output = process::start_sync( &buf, &current_path ).unwrap();
        process::log_output( &output );

        let output = process::start_sync( "git push --dry-run", &current_path ).unwrap();
        process::log_output( &output );

        let output = process::start_sync( "cargo publish --dry-run --allow-dirty", &package_dir ).unwrap();
        process::log_output( &output );
      }
      else
      {
        let mut buf = String::new();
        write!( &mut buf, "git commit -am \"{} v{}\"", name, version ).unwrap();
        let output = process::start_sync( &buf, &current_path ).unwrap();
        process::log_output( &output );

        let output = process::start_sync( "git push", &current_path ).unwrap();
        process::log_output( &output );

        let output = process::start_sync( "cargo publish", &package_dir ).unwrap();
        process::log_output( &output );
      }
    }
    else
    {
      println!( "Package {} is up to date", name );
    }
  }

  Ok( () )
}

fn manifest_get( path : impl Into<PathBuf> ) -> anyhow::Result<manifest::Manifest>
{
  let mut manifest = manifest::Manifest::new();
  manifest.manifest_path_from_str( path )?;
  manifest.load()?;
  Ok( manifest )
}

fn local_package_path_get<'a>( name : &'a str, version : &'a str, manifest_path : &'a std::path::PathBuf ) -> std::path::PathBuf
{
  let mut buf = String::new();
  write!( &mut buf, "package/{0}-{1}.crate", name, version ).unwrap();
  let package_metadata = MetadataCommand::new()
  .manifest_path( manifest_path )
  .exec()
  .unwrap();
  let mut local_package_path = std::path::PathBuf::new();
  local_package_path.push( package_metadata.target_directory );
  local_package_path.push( buf );
  local_package_path
}

fn bump( version : &str ) -> anyhow::Result<toml_edit::Item>
{
  let mut splits : Vec<&str> = version.split( "." ).collect();
  let patch_version = splits[ 2 ].parse::<u32>()? + 1;
  let v = &patch_version.to_string();
  splits[ 2 ] = v;
  Ok( value( splits.join( "." ) ) )
}
<commit_msg>Fix routine `publish`, use inner value of wrapper type `OpType`<commit_after>
use crate::*;
use crate::wpublisher::bool::*;
use wca::*;
use std::env;
use std::fs;
use std::fmt::Write;
use std::path::PathBuf;
use toml_edit::value;
use cargo_metadata::MetadataCommand;
use wtools::error::Error;

///
/// Publish package.
///

pub fn publish( instruction : &instruction::Instruction ) -> Result<(), Error>
{
  let current_path = env::current_dir().unwrap();

  let paths = files::find( &current_path, instruction.subject.split( " " ).collect::<Vec<&str>>().as_slice() );
  let mut paths = paths.iter().filter_map( | s | if s.ends_with( "Cargo.toml" ) { Some( s.into() ) } else { None } ).collect::<Vec<PathBuf>>();
  if paths.is_empty() /* && !path.glob_is( &instruction.subject ) qqq : implement `glob_is` */
  {
    paths.push( PathBuf::from( &instruction.subject ) );
  }

  for path in paths
  {
    let mut manifest = manifest_get( path ).unwrap();
    if !manifest.package_is() || manifest.local_is()
    {
      continue;
    }
    let data = manifest.manifest_data.as_deref_mut().unwrap();

    let mut package_dir = manifest.manifest_path.clone();
    package_dir.pop();

    let output = process::start_sync( "cargo package", &package_dir ).unwrap();
    process::log_output( &output );

    let name = &data[ "package" ][ "name" ].clone();
    let name = name.as_str().unwrap();
    let version = &data[ "package" ][ "version" ].clone();
    let version = version.as_str().unwrap();
    let local_package_path = local_package_path_get( name, version, &manifest.manifest_path );

    let local_package = fs::read( &local_package_path ).unwrap();
    let remote_package = http::retrieve_bytes( name, version ).unwrap_or_default();

    let digest_of_local = digest::hash( &local_package );
    let digest_of_remote = digest::hash( &remote_package );

    if digest_of_local != digest_of_remote
    {
      data[ "package" ][ "version" ] = bump( version ).unwrap();
      let version = &data[ "package" ][ "version" ].clone();
      let version = version.as_str().unwrap();
      manifest.store().unwrap();

      let dry = match instruction.properties_map.get( "dry" )
      {
        Some( x ) => x.clone().primitive().unwrap().to_bool_like(),
        None => BoolLike::False,
      };

      if dry == BoolLike::True
      {
        let mut buf = String::new();
        write!( &mut buf, "git commit --dry-run -am \"{} v{}\"", name, version ).unwrap();
        let output = process::start_sync( &buf, &current_path ).unwrap();
        process::log_output( &output );

        let output = process::start_sync( "git push --dry-run", &current_path ).unwrap();
        process::log_output( &output );

        let output = process::start_sync( "cargo publish --dry-run --allow-dirty", &package_dir ).unwrap();
        process::log_output( &output );
      }
      else
      {
        let mut buf = String::new();
        write!( &mut buf, "git commit -am \"{} v{}\"", name, version ).unwrap();
        let output = process::start_sync( &buf, &current_path ).unwrap();
        process::log_output( &output );

        let output = process::start_sync( "git push", &current_path ).unwrap();
        process::log_output( &output );

        let output = process::start_sync( "cargo publish", &package_dir ).unwrap();
        process::log_output( &output );
      }
    }
    else
    {
      println!( "Package {} is up to date", name );
    }
  }

  Ok( () )
}

fn manifest_get( path : impl Into<PathBuf> ) -> anyhow::Result<manifest::Manifest>
{
  let mut manifest = manifest::Manifest::new();
  manifest.manifest_path_from_str( path )?;
  manifest.load()?;
  Ok( manifest )
}

fn local_package_path_get<'a>( name : &'a str, version : &'a str, manifest_path : &'a std::path::PathBuf ) -> std::path::PathBuf
{
  let mut buf = String::new();
  write!( &mut buf, "package/{0}-{1}.crate", name, version ).unwrap();
  let package_metadata = MetadataCommand::new()
  .manifest_path( manifest_path )
  .exec()
  .unwrap();
  let mut local_package_path = std::path::PathBuf::new();
  local_package_path.push( package_metadata.target_directory );
  local_package_path.push( buf );
  local_package_path
}

fn bump( version : &str ) -> anyhow::Result<toml_edit::Item>
{
  let mut splits : Vec<&str> = version.split( "." ).collect();
  let patch_version = splits[ 2 ].parse::<u32>()? + 1;
  let v = &patch_version.to_string();
  splits[ 2 ] = v;
  Ok( value( splits.join( "." ) ) )
}
<|endoftext|>


<commit_before>
use super::*;
mod tools
{
  #[ allow( unused_imports ) ]
  pub use super::super::*;
}

/// Private namespace of the module.
mod private
{
}

TheModule::mod_interface!
{

  // xxx : test with `layer { layer_a, layer_a };`
  // xxx : test with `use { layer_a, layer_a };`

  /// layer_a
  layer layer_a;
  /// layer_b
  layer layer_b;

}

//

// include!( "../../only_test/layer_divergent_only_test.rs" );
include!( "../../only_test/layer_simple_only_test.rs" );
<commit_msg>!test<commit_after>
use super::*;
mod tools
{
  #[ allow( unused_imports ) ]
  pub use super::super::*;
}

/// Private namespace of the module.
mod private
{
}

TheModule::mod_interface!
{

  // xxx : test with `layer { layer_a, layer_a };`
  // xxx : test with `use { layer_a, layer_a };`

  /// layer_a
  layer layer_a;
  /// layer_b
  layer layer_b;

}

//

// include!( "../../only_test/layer_divergent_only_test.rs" );
include!( "../../only_test/layer_simple_only_test.rs" );

<|endoftext|>


<commit_before><commit_msg>Remove redundant namespaces passed around by parser<commit_after><|endoftext|>


<commit_before>use std::process::exit;

use libllama::dbgcore;
use libllama::utils::from_hex;

/// Prints disassembly for the next instruction
/// Command format: "asm [address hex]"
///
/// `args`: Iterator over &str items
fn cmd_asm<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {

    use capstone::{Capstone, CsArch, CsMode};
    let _ = args;

    let mut ctx = debugger.ctx();
    let hw = ctx.hw();

    let pause_addr = match args.next().map(from_hex) {
        Some(Ok(x)) => x,
        Some(Err(_)) => { error!("Could not parse hex value!"); return }
        None => hw.pause_addr(),
    };

    let cpu_mode = if hw.is_thumb() {
        CsMode::MODE_THUMB
    } else {
        CsMode::MODE_LITTLE_ENDIAN
    };

    if let Some(cs) = Capstone::new(CsArch::ARCH_ARM, cpu_mode) {
        let mut inst_bytes = [0u8; 4];
        hw.read_mem(pause_addr, &mut inst_bytes);

        match cs.disasm(&inst_bytes, pause_addr as u64, 1) {
            Some(insts) => {
                let inst = insts.iter().next().unwrap();
                info!("{:X}: {} {}", pause_addr,
                                     inst.mnemonic().unwrap(),
                                     inst.op_str().unwrap())
            }
            None => error!("Failed to disassemble instruction at 0x{:X}", pause_addr),
        }
    } else {
        error!("Could not initialize capstone!");
    }
}

/// Adds CPU breakpoint at instruction address
/// Command format: "brk <address hex>"
///
/// `args`: Iterator over &str items
fn cmd_brk<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {

    let addr_str = match args.next() {
        Some(arg) => from_hex(arg),
        None => { info!("Usage: `brk <addr>"); return }
    };

    // Check for from_hex errors
    let addr = match addr_str {
        Ok(x) => x,
        _ => { error!("Could not parse hex value!"); return }
    };

    info!("Toggling breakpoint at 0x{:X}", addr);

    let mut ctx = debugger.ctx();
    let mut hw = ctx.hw();

    if !hw.has_breakpoint(addr) {
        hw.set_breakpoint(addr);
    } else {
        hw.del_breakpoint(addr);
    }
}

/// Prints memory to the screen based on provided address, number of bytes
/// Command format: "mem <start address hex> [# bytes hex]"
///
/// `args`: Iterator over &str items
fn cmd_mem<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {
    use libllama::utils::from_hex;

    // Tuple: (u32: start, u32: num)
    let arg_res = match (args.next(), args.next()) {
        (Some(ss), Some(ns)) => from_hex(ss).and_then(|s| Ok((s, from_hex(ns)?))),
        (Some(ss), None) => from_hex(ss).and_then(|s| Ok((s, 1))),
        (None, _) => { info!("Usage: `mem <start> [num]"); return }
    };

    // Check for from_hex errors, validate `num` input
    let (start, num) = match arg_res {
        Ok((s, n)) if n > 0 => (s, n),
        Ok((s, _)) => (s, 1),
        _ => { error!("Could not parse hex value!"); return }
    };

    trace!("Printing {} bytes of RAM starting at 0x{:08X}", num, start);

    let mut ctx = debugger.ctx();
    let hw = ctx.hw();

    let mut mem_bytes = vec![0u8; num as usize];
    hw.read_mem(start, &mut mem_bytes);

    let mut strbuf = String::new();
    strbuf.push_str(&format!("{:02X}", mem_bytes[0]));
    for i in 1 .. num as usize {
        strbuf.push_str(&format!(" {:02X}", mem_bytes[i]));
    }
    info!("{}", &strbuf);
}

/// Prints registers to the screen based on provided register name
/// Command format: "reg [register name]"
///
/// `args`: Iterator over &str items
fn cmd_reg<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {
    let mut ctx = debugger.ctx();
    let hw = ctx.hw();

    let print_reg = |reg_num| info!("R{} = 0x{:08X}", reg_num, hw.read_reg(reg_num));

    let reg_str = match args.next() {
        Some(arg) => arg.to_owned().to_lowercase(),
        None => {
            for i in 0..16 {
                print_reg(i);
            }
            return;
        }
    };

    match reg_str.as_str() {
        "r0" => print_reg(0),
        "r1" => print_reg(1),
        "r2" => print_reg(2),
        "r3" => print_reg(3),
        "r4" => print_reg(4),
        "r5" => print_reg(5),
        "r6" => print_reg(6),
        "r7" => print_reg(7),
        "r8" => print_reg(8),
        "r9" => print_reg(9),
        "r10" => print_reg(10),
        "r11" => print_reg(11),
        "r12" => print_reg(12),
        "sp" | "r13" => print_reg(13),
        "lr" | "r14" => print_reg(14),
        "pc" | "r15" => print_reg(15),
        _ => error!("Unrecognized register!"),
    }
}

/// Runs one instruction on the CPU
/// Command format: "step"
///
/// `args`: Unused
fn cmd_step<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {
    let _ = args;
    let mut ctx = debugger.ctx();
    let mut hw = ctx.hw();

    hw.step();
}

/// Controls debugger behavior based on user-provided commands
///
/// `command`: Iterator over &str items
pub fn handle<'a, It>(debugger: &mut dbgcore::DbgCore, mut command: It)
    where It: Iterator<Item=&'a str> {

    match command.next() {
        Some("run") => { debugger.ctx().resume() },
        Some("brk") => cmd_brk(debugger, command),
        Some("asm") => cmd_asm(debugger, command),
        Some("mem") => cmd_mem(debugger, command),
        Some("reg") => cmd_reg(debugger, command),
        Some("step") => cmd_step(debugger, command),
        Some("quit") | Some("exit") => {
            debugger.ctx().hwcore_mut().stop();
            // TODO: Cleaner exit?
            exit(0);
        }
        None => {},
        Some(unk_cmd @ _) => error!("Unrecognized command `{}`", unk_cmd),
    }
}<commit_msg>Fix errors associated with capstone 0.0.4 => 0.0.5 upgrade<commit_after>use std::process::exit;

use libllama::dbgcore;
use libllama::utils::from_hex;

/// Prints disassembly for the next instruction
/// Command format: "asm [address hex]"
///
/// `args`: Iterator over &str items
fn cmd_asm<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {

    use capstone::{Capstone, CsArch, CsMode};
    let _ = args;

    let mut ctx = debugger.ctx();
    let hw = ctx.hw();

    let pause_addr = match args.next().map(from_hex) {
        Some(Ok(x)) => x,
        Some(Err(_)) => { error!("Could not parse hex value!"); return }
        None => hw.pause_addr(),
    };

    let cpu_mode = if hw.is_thumb() {
        CsMode::MODE_THUMB
    } else {
        CsMode::MODE_LITTLE_ENDIAN
    };

    if let Ok(cs) = Capstone::new(CsArch::ARCH_ARM, cpu_mode) {
        let mut inst_bytes = [0u8; 4];
        hw.read_mem(pause_addr, &mut inst_bytes);

        match cs.disasm(&inst_bytes, pause_addr as u64, 1) {
            Ok(insts) => {
                let inst = insts.iter().next().unwrap();
                info!("{:X}: {} {}", pause_addr,
                                     inst.mnemonic().unwrap(),
                                     inst.op_str().unwrap())
            }
            Err(_) => error!("Failed to disassemble instruction at 0x{:X}", pause_addr),
        }
    } else {
        error!("Could not initialize capstone!");
    }
}

/// Adds CPU breakpoint at instruction address
/// Command format: "brk <address hex>"
///
/// `args`: Iterator over &str items
fn cmd_brk<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {

    let addr_str = match args.next() {
        Some(arg) => from_hex(arg),
        None => { info!("Usage: `brk <addr>"); return }
    };

    // Check for from_hex errors
    let addr = match addr_str {
        Ok(x) => x,
        _ => { error!("Could not parse hex value!"); return }
    };

    info!("Toggling breakpoint at 0x{:X}", addr);

    let mut ctx = debugger.ctx();
    let mut hw = ctx.hw();

    if !hw.has_breakpoint(addr) {
        hw.set_breakpoint(addr);
    } else {
        hw.del_breakpoint(addr);
    }
}

/// Prints memory to the screen based on provided address, number of bytes
/// Command format: "mem <start address hex> [# bytes hex]"
///
/// `args`: Iterator over &str items
fn cmd_mem<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {
    use libllama::utils::from_hex;

    // Tuple: (u32: start, u32: num)
    let arg_res = match (args.next(), args.next()) {
        (Some(ss), Some(ns)) => from_hex(ss).and_then(|s| Ok((s, from_hex(ns)?))),
        (Some(ss), None) => from_hex(ss).and_then(|s| Ok((s, 1))),
        (None, _) => { info!("Usage: `mem <start> [num]"); return }
    };

    // Check for from_hex errors, validate `num` input
    let (start, num) = match arg_res {
        Ok((s, n)) if n > 0 => (s, n),
        Ok((s, _)) => (s, 1),
        _ => { error!("Could not parse hex value!"); return }
    };

    trace!("Printing {} bytes of RAM starting at 0x{:08X}", num, start);

    let mut ctx = debugger.ctx();
    let hw = ctx.hw();

    let mut mem_bytes = vec![0u8; num as usize];
    hw.read_mem(start, &mut mem_bytes);

    let mut strbuf = String::new();
    strbuf.push_str(&format!("{:02X}", mem_bytes[0]));
    for i in 1 .. num as usize {
        strbuf.push_str(&format!(" {:02X}", mem_bytes[i]));
    }
    info!("{}", &strbuf);
}

/// Prints registers to the screen based on provided register name
/// Command format: "reg [register name]"
///
/// `args`: Iterator over &str items
fn cmd_reg<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {
    let mut ctx = debugger.ctx();
    let hw = ctx.hw();

    let print_reg = |reg_num| info!("R{} = 0x{:08X}", reg_num, hw.read_reg(reg_num));

    let reg_str = match args.next() {
        Some(arg) => arg.to_owned().to_lowercase(),
        None => {
            for i in 0..16 {
                print_reg(i);
            }
            return;
        }
    };

    match reg_str.as_str() {
        "r0" => print_reg(0),
        "r1" => print_reg(1),
        "r2" => print_reg(2),
        "r3" => print_reg(3),
        "r4" => print_reg(4),
        "r5" => print_reg(5),
        "r6" => print_reg(6),
        "r7" => print_reg(7),
        "r8" => print_reg(8),
        "r9" => print_reg(9),
        "r10" => print_reg(10),
        "r11" => print_reg(11),
        "r12" => print_reg(12),
        "sp" | "r13" => print_reg(13),
        "lr" | "r14" => print_reg(14),
        "pc" | "r15" => print_reg(15),
        _ => error!("Unrecognized register!"),
    }
}

/// Runs one instruction on the CPU
/// Command format: "step"
///
/// `args`: Unused
fn cmd_step<'a, It>(debugger: &mut dbgcore::DbgCore, mut args: It)
    where It: Iterator<Item=&'a str> {
    let _ = args;
    let mut ctx = debugger.ctx();
    let mut hw = ctx.hw();

    hw.step();
}

/// Controls debugger behavior based on user-provided commands
///
/// `command`: Iterator over &str items
pub fn handle<'a, It>(debugger: &mut dbgcore::DbgCore, mut command: It)
    where It: Iterator<Item=&'a str> {

    match command.next() {
        Some("run") => { debugger.ctx().resume() },
        Some("brk") => cmd_brk(debugger, command),
        Some("asm") => cmd_asm(debugger, command),
        Some("mem") => cmd_mem(debugger, command),
        Some("reg") => cmd_reg(debugger, command),
        Some("step") => cmd_step(debugger, command),
        Some("quit") | Some("exit") => {
            debugger.ctx().hwcore_mut().stop();
            // TODO: Cleaner exit?
            exit(0);
        }
        None => {},
        Some(unk_cmd @ _) => error!("Unrecognized command `{}`", unk_cmd),
    }
}<|endoftext|>


<commit_before>
use geometry::Point;
use core::rand::RngUtil;
use core::float::pow;
mod geometry;

//
// Cellule
//

struct Cell {
    center: Point,
    id: uint,
    radius: f64,
    velocity: Point,
    acc: Point,
    generation: int,
    age: int
}

pub impl Cell {
    fn new(ident: uint) -> Cell {
        let radius = 1.0;
        //let r=rand::random::<float>();
        //io::println(fmt!("%f\n", r));
        let center : Point =rand::random();

        Cell{ center: center, id: ident, radius: radius, velocity: Point::new(), acc: Point::new(), generation: 0, age:0}
    }

    fn move(&mut self, tumeur: &Crowd, dt: f64) {
        let old_acc = copy self.acc;

        // Nouvelle position
        self.center+=self.velocity+self.acc*(0.5*float::pow(dt,2.0) as f64);

        // Force aléatoire
        let F_alea: Point=rand::random();
        self.acc=self.calc_rep_force(tumeur)+F_alea*(0.0005 as f64);

        // Nouvelle vitesse
        let lambda : f64=5.0;
        let denom : f64 = 1.0/(1.0+lambda*dt/2.0);
        self.velocity=(self.velocity*(1.0-lambda*dt/2.0)+(self.acc+old_acc)*dt/(2.0 as f64))*denom;

    }

    fn replicate(&mut self, tumeur: &Crowd, dt: f64) {
        io::println(fmt!("%d @ %f\n",tumeur.size() as int, dt as float));

        self.age+=1;
    }

    fn calc_rep_force(&self, tumeur: &Crowd) -> Point {
        let seuil=3.0*self.radius;
        let mut force = Point::new();
        for tumeur.cells.each |&cell| {
            if(cell.id != self.id) {
                let dist_cells=(self.dist(cell)+2.0*self.radius)/seuil;
                let factor = 1.0/pow(dist_cells,3.0)*1e-7 as f64;
                force += (self.center-cell.center)*factor;
            }
        }
        force
    }

    #[inline(always)]
    fn x(&self) -> f64 {
        self.center.x
    }

    #[inline(always)]
    fn y(&self) -> f64 {
        self.center.y
    }

    fn dist(&self, other: &Cell) -> f64 {
        self.center.dist(&other.center)
    }

}

impl ToStr for Cell {
    fn to_str(&self) -> ~str {
        fmt!("%d @ (%f, %f)", self.id as int, self.center.x as float, self.center.y as float)
    }
}

#[test]
fn test_new() {
    let cell1=Cell::new(0);
    let cell2=Cell::new(1);
    assert!(cell1.center != cell2.center);
}

//
// Population
//

struct Crowd {
    cells : ~[@mut Cell],
    time : float
}

pub impl Crowd {
    fn new(init_pop : uint) -> Crowd {

        let mut pop : ~[@mut Cell]=~[];
        for uint::range(1,init_pop+1) |num| {
            let lonely_one = @mut Cell::new(num);
            pop.push(copy lonely_one);
        }
        Crowd{ cells : pop, time: 0.0}
    }

    fn size(&self) -> uint {
        self.cells.len()
    }

    fn evolve(&self, dt: f64) {
        for self.cells.each |cell| {
            cell.move(self, dt);
        }
    }
}

impl ToStr for Crowd {
    fn to_str(&self) -> ~str {
        let mut desc =~"";
        for self.cells.each |cell| {
            let mut lcell_desc=~"";
            lcell_desc.push_str(cell.to_str()); lcell_desc.push_str("\n");
             desc.push_str(lcell_desc);
        }
        desc
    }
}

#[test]
fn test_size() {
    let crowd=Crowd::new(13);
    assert!(crowd.size()==13);
}
<commit_msg>On considère toutes les directions pour la force aléatoire<commit_after>
use geometry::Point;
use core::rand::RngUtil;
use core::float::pow;
mod geometry;

//
// Cellule
//

struct Cell {
    center: Point,
    id: uint,
    radius: f64,
    velocity: Point,
    acc: Point,
    generation: int,
    age: int
}

pub impl Cell {
    fn new(ident: uint) -> Cell {
        let radius = 1.0;
        //let r=rand::random::<float>();
        //io::println(fmt!("%f\n", r));
        let center : Point =rand::random();

        Cell{ center: center, id: ident, radius: radius, velocity: Point::new(), acc: Point::new(), generation: 0, age:0}
    }

    fn move(&mut self, tumeur: &Crowd, dt: f64) {
        let old_acc = copy self.acc;

        // Nouvelle position
        self.center+=self.velocity+self.acc*(0.5*float::pow(dt,2.0) as f64);

        // Force aléatoire
        let mut F_alea: Point=rand::random();
        F_alea-=0.5 as f64;
        self.acc=self.calc_rep_force(tumeur)+F_alea*(0.05 as f64);

        // Nouvelle vitesse
        let lambda : f64=5.0;
        let denom : f64 = 1.0/(1.0+lambda*dt/2.0);
        self.velocity=(self.velocity*(1.0-lambda*dt/2.0)+(self.acc+old_acc)*dt/(2.0 as f64))*denom;

    }

    fn replicate(&mut self, tumeur: &Crowd, dt: f64) {
        io::println(fmt!("%d @ %f\n",tumeur.size() as int, dt as float));

        self.age+=1;
    }

    fn calc_rep_force(&self, tumeur: &Crowd) -> Point {
        let seuil=3.0*self.radius;
        let mut force = Point::new();
        for tumeur.cells.each |&cell| {
            if(cell.id != self.id) {
                let dist_cells=(self.dist(cell)+2.0*self.radius)/seuil;
                let factor = 1.0/pow(dist_cells,3.0)*1e-7 as f64;
                force += (self.center-cell.center)*factor;
            }
        }
        force
    }

    #[inline(always)]
    fn x(&self) -> f64 {
        self.center.x
    }

    #[inline(always)]
    fn y(&self) -> f64 {
        self.center.y
    }

    fn dist(&self, other: &Cell) -> f64 {
        self.center.dist(&other.center)
    }

}

impl ToStr for Cell {
    fn to_str(&self) -> ~str {
        fmt!("%d @ (%f, %f)", self.id as int, self.center.x as float, self.center.y as float)
    }
}

#[test]
fn test_new() {
    let cell1=Cell::new(0);
    let cell2=Cell::new(1);
    assert!(cell1.center != cell2.center);
}

//
// Population
//

struct Crowd {
    cells : ~[@mut Cell],
    time : float
}

pub impl Crowd {
    fn new(init_pop : uint) -> Crowd {

        let mut pop : ~[@mut Cell]=~[];
        for uint::range(1,init_pop+1) |num| {
            let lonely_one = @mut Cell::new(num);
            pop.push(copy lonely_one);
        }
        Crowd{ cells : pop, time: 0.0}
    }

    fn size(&self) -> uint {
        self.cells.len()
    }

    fn evolve(&self, dt: f64) {
        for self.cells.each |cell| {
            cell.move(self, dt);
        }
    }
}

impl ToStr for Crowd {
    fn to_str(&self) -> ~str {
        let mut desc =~"";
        for self.cells.each |cell| {
            let mut lcell_desc=~"";
            lcell_desc.push_str(cell.to_str()); lcell_desc.push_str("\n");
             desc.push_str(lcell_desc);
        }
        desc
    }
}

#[test]
fn test_size() {
    let crowd=Crowd::new(13);
    assert!(crowd.size()==13);
}
<|endoftext|>


<commit_before><commit_msg>Add the other readme example to test<commit_after><|endoftext|>


<commit_before>#![feature(test)]
#![feature(alloc)]
#![feature(heap_api)]
#[macro_use]
extern crate adapton ;

// mod AAAzip {
//     fn doit() {
//         let mut st = &mut (AdaptonState::new()) ;
//         for _ in 1..(n-1) {
//             memo!(st, fib, x:x );
//         }
//         memo!(st, fib, x:x )
//     }
//     #[bench]
//     fn bench(b:&mut Bencher) {
//         b.iter(||doit());
//     }
// }

mod fib {
    const INPUT_SIZE:u64 = 20;
    const REPEAT_COUNT:u64 = 100;

    #[cfg(test)]
    mod rust {
        use super::INPUT_SIZE;
        use super::REPEAT_COUNT;

        extern crate test;
        use self::test::Bencher;

        pub fn fib (x:u64) -> u64 { test::black_box (
            match x {
                0 => 0,
                1 => 1,
                x => fib(x-1) + fib(x-2)
            })
        }

        pub fn fib_repeat (x:u64, n:u64) -> u64 {
            for _ in 1..(n-1) {
                test::black_box(fib(x));
            }
            test::black_box(fib(x))
        }

        #[test]
        fn it_works() {
            assert_eq!(5 as u64, fib(5));
        }

        #[bench]
        fn bench_fib(b: &mut Bencher) {
            b.iter(|| test::black_box(fib(INPUT_SIZE)));
        }

        #[bench]
        fn bench_fib_repeat(b: &mut Bencher) {
            b.iter(|| test::black_box(fib_repeat(INPUT_SIZE, REPEAT_COUNT)));
        }
    }

    #[cfg(test)]
    mod adapton {
        mod fs {
            extern crate test;
            use self::test::Bencher;

            extern crate alloc;
            use std::rc::Rc;
            use adapton::adapton_syntax::* ;
            use adapton::adapton_sigs::* ;
            //use adapton::adapton_state::* ;
            use adapton::adapton_fromscratch::* ;
            use super::super::INPUT_SIZE;
            use super::super::REPEAT_COUNT;

            pub fn fib<A:Adapton> (st:&mut A, x:u64 ) -> u64 {
                match x {
                    0 => 0,
                    1 => 1,
                    x => { memo!(st, fib, x:x-1)
                           +
                           memo!(st, fib, x:x-2) }}
            }

            pub fn run_fib (x:u64) -> u64 {
                let mut st = &mut AdaptonFromScratch::new() ;
                memo!(st, fib, x:x )
            }

            pub fn run_fib_repeat (x:u64, n:u64) -> u64 {
                let mut st = &mut AdaptonFromScratch::new() ;
                for _ in 1..(n-1) {
                    memo!(st, fib, x:x );
                }
                memo!(st, fib, x:x )
            }

            #[test]
            fn it_works() {
                assert_eq!(5 as u64, run_fib(5));
            }

            #[bench]
            fn bench_fib(b: &mut Bencher) {
                b.iter(|| test::black_box(run_fib(INPUT_SIZE)));
            }

            #[bench]
            fn bench_fib_repeat(b: &mut Bencher) {
                b.iter(|| test::black_box(run_fib_repeat(INPUT_SIZE, REPEAT_COUNT)));
            }

        }

        mod state {
            extern crate test;
            use self::test::Bencher;

            extern crate alloc;
            use std::rc::Rc;
            use adapton::adapton_syntax::* ;
            use adapton::adapton_sigs::* ;
            use adapton::adapton_state::* ;
            //use adapton::adapton_fromscratch::* ;
            use super::super::INPUT_SIZE;
            use super::super::REPEAT_COUNT;

            pub fn fib<A:Adapton> (st:&mut A, x:u64 ) -> u64 {
                match x {
                    0 => 0,
                    1 => 1,
                    x => { memo!(st, fib, x:x-1)
                           +
                           memo!(st, fib, x:x-2) }}
            }

            pub fn run_fib (x:u64) -> u64 {
                let mut st = &mut AdaptonState::new() ;
                memo!(st, fib, x:x )
            }

            pub fn run_fib_repeat (x:u64, n:u64) -> u64 {
                let mut st = &mut AdaptonState::new() ;
                for _ in 1..(n-1) {
                    memo!(st, fib, x:x );
                }
                memo!(st, fib, x:x )
            }

            #[test]
            fn it_works() {
                assert_eq!(5 as u64, run_fib(5));
            }

            #[bench]
            fn bench_fib(b: &mut Bencher) {
                b.iter(|| test::black_box(run_fib(INPUT_SIZE)));
            }

            #[bench]
            fn bench_fib_repeat(b: &mut Bencher) {
                b.iter(|| test::black_box(run_fib_repeat(INPUT_SIZE, REPEAT_COUNT)));
            }
        }
    }
}

mod fact {
    const INPUT_SIZE:u64 = 100;
    const REPEAT_COUNT:u64 = 100;

    #[cfg(test)]
    mod no_caching {
        use super::INPUT_SIZE;
        use super::REPEAT_COUNT;

        extern crate test;
        use self::test::Bencher;

        pub fn fact (x:u64) -> u64 {
            if x == 0 { 1 } else { test::black_box(x) * fact(x-1) }
        }

        pub fn fact_repeat (x:u64, n:u64) -> u64 {
            for _ in 1..(n-1) {
                test::black_box(fact(x));
            }
            fact(x)
        }

        #[test]
        fn it_works() {
            assert_eq!(120 as u64, fact(5));
        }

        #[bench]
        fn bench_fact(b: &mut Bencher) {
            b.iter(|| test::black_box(fact(INPUT_SIZE)));
        }

        #[bench]
        fn bench_fact_repeat(b: &mut Bencher) {
            b.iter(|| test::black_box(fact_repeat(INPUT_SIZE, REPEAT_COUNT)));
        }
    }

    #[cfg(test)]
    mod pure_caching {
        use super::INPUT_SIZE;
        use super::REPEAT_COUNT;

        extern crate test;
        use self::test::Bencher;

        use std::rc::Rc;

        use adapton::adapton_syntax::* ;
        use adapton::adapton_sigs::* ;
        use adapton::adapton_state::* ;

        pub fn fact<A:Adapton> (st:&mut A, x:u64 ) -> u64 {
            if x == 0 { 1 } else { x * (memo!(st, fact, x:x-1 )) }
        }

        pub fn run_fact (x:u64) -> u64 {
            let mut st = &mut (AdaptonState::new()) ;
            memo!(st, fact, x:x )
        }

        pub fn run_fact_repeat (x:u64, n:u64) -> u64 {
            let mut st = &mut (AdaptonState::new()) ;
            for _ in 1..(n-1) {
                memo!(st, fact, x:x );
            }
            memo!(st, fact, x:x )
        }

        #[test]
        fn it_works() {
            assert_eq!(120 as u64, run_fact(5));
        }

        #[bench]
        fn bench_fact(b: &mut Bencher) {
            b.iter(|| test::black_box(run_fact(INPUT_SIZE)));
        }

        #[bench]
        fn bench_fact_repeat(b: &mut Bencher) {
            b.iter(|| test::black_box(run_fact_repeat(INPUT_SIZE, REPEAT_COUNT)));
        }
    }
}

mod hourglass {
    //const INPUT_ARRAY:Vec<u64> = vec![2; 64];
    const REPEAT_COUNT:u64 = 100;

    #[cfg(test)]
    mod eager_ids {
        //use super::INPUT_ARRAY;
        use super::REPEAT_COUNT;

        extern crate test;
        use self::test::Bencher;

        use std::rc::Rc;

        use adapton::adapton_syntax::* ;
        use adapton::adapton_sigs::* ;
        use adapton::adapton_fromscratch::* ;
        //use adapton::adapton_state::* ;
        use adapton::structures::* ;

        // Thunks needs to *own* the arguments we give them.
        fn ident<A:Adapton,T>(st:&mut A, x:T) -> T {x}
        fn depend_mult<A:Adapton>(st:&mut A, x: Art<u64,A::Loc>,y: Art<u64,A::Loc>) -> u64 {
            st.force(&x) * st.force(&y)
        }
        fn depend_add<A:Adapton>(st:&mut A, x: Art<u64,A::Loc>,y: Art<u64,A::Loc>) -> u64 {
            //println!("depend_add:({:?},{:?})", x, y);
            st.force(&x) + st.force(&y)
        }

        pub fn hourglass<A:Adapton> (st:&mut A) -> u64 {
            let cells = vec![2;64];
            let mut nodes = vec![];
            for i in 0..64 {
                nodes.push(thunk!(st, ident, x:cells[i]));
            }
            let mut item_num = 0;
            loop {
                if nodes.len() == 126 { break; }
                let first = nodes[item_num].clone();
                let second = nodes[item_num+1].clone();
                nodes.push(thunk!(st, depend_add, x:first, y:second));
                //println!("{} --> {}, {}", nodes.len()-1, item_num, item_num+1);
                if item_num < 122 { item_num += 2 } else { item_num += 1 }
            }
            let thk = &nodes[nodes.len()-1];
            //println!("past checkpoint");
            st.force(thk)
        }

        pub fn run_hourglass () -> u64 {
            let mut st = &mut (AdaptonState::new());
            let res = hourglass(st);
            //assert!(res == );
            res
        }

        pub fn run_hourglass_repeat (n:u64) -> u64 {
            let mut st = &mut (AdaptonState::new());
            for _ in 1..(n-1) {
                test::black_box(hourglass(st));
            }
            hourglass(st)
        }

        // output value uncertain, test is changing
        // #[test]
        // fn it_works() {
        //     assert_eq!(2 as u64, run_hourglass());
        // }

        #[bench]
        fn bench_hourglass(b: &mut Bencher) {
            b.iter(|| test::black_box(run_hourglass()));
        }

        // Rewrite this as multiple changes in the input list
        // #[bench]
        // fn bench_hourglass_repeat(b: &mut Bencher) {
        //     b.iter(|| test::black_box(run_hourglass_repeat(REPEAT_COUNT)));
        // }
    }
}
<commit_msg>fixed merge<commit_after>#![feature(test)]
#![feature(alloc)]
#![feature(heap_api)]
#[macro_use]
extern crate adapton ;

// mod AAAzip {
//     fn doit() {
//         let mut st = &mut (AdaptonState::new()) ;
//         for _ in 1..(n-1) {
//             memo!(st, fib, x:x );
//         }
//         memo!(st, fib, x:x )
//     }
//     #[bench]
//     fn bench(b:&mut Bencher) {
//         b.iter(||doit());
//     }
// }

mod fib {
    const INPUT_SIZE:u64 = 20;
    const REPEAT_COUNT:u64 = 100;

    #[cfg(test)]
    mod rust {
        use super::INPUT_SIZE;
        use super::REPEAT_COUNT;

        extern crate test;
        use self::test::Bencher;

        pub fn fib (x:u64) -> u64 { test::black_box (
            match x {
                0 => 0,
                1 => 1,
                x => fib(x-1) + fib(x-2)
            })
        }

        pub fn fib_repeat (x:u64, n:u64) -> u64 {
            for _ in 1..(n-1) {
                test::black_box(fib(x));
            }
            test::black_box(fib(x))
        }

        #[test]
        fn it_works() {
            assert_eq!(5 as u64, fib(5));
        }

        #[bench]
        fn bench_fib(b: &mut Bencher) {
            b.iter(|| test::black_box(fib(INPUT_SIZE)));
        }

        #[bench]
        fn bench_fib_repeat(b: &mut Bencher) {
            b.iter(|| test::black_box(fib_repeat(INPUT_SIZE, REPEAT_COUNT)));
        }
    }

    #[cfg(test)]
    mod adapton {
        mod fs {
            extern crate test;
            use self::test::Bencher;

            extern crate alloc;
            use std::rc::Rc;
            use adapton::adapton_syntax::* ;
            use adapton::adapton_sigs::* ;
            //use adapton::adapton_state::* ;
            use adapton::adapton_fromscratch::* ;
            use super::super::INPUT_SIZE;
            use super::super::REPEAT_COUNT;

            pub fn fib<A:Adapton> (st:&mut A, x:u64 ) -> u64 {
                match x {
                    0 => 0,
                    1 => 1,
                    x => { memo!(st, fib, x:x-1)
                           +
                           memo!(st, fib, x:x-2) }}
            }

            pub fn run_fib (x:u64) -> u64 {
                let mut st = &mut AdaptonFromScratch::new() ;
                memo!(st, fib, x:x )
            }

            pub fn run_fib_repeat (x:u64, n:u64) -> u64 {
                let mut st = &mut AdaptonFromScratch::new() ;
                for _ in 1..(n-1) {
                    memo!(st, fib, x:x );
                }
                memo!(st, fib, x:x )
            }

            #[test]
            fn it_works() {
                assert_eq!(5 as u64, run_fib(5));
            }

            #[bench]
            fn bench_fib(b: &mut Bencher) {
                b.iter(|| test::black_box(run_fib(INPUT_SIZE)));
            }

            #[bench]
            fn bench_fib_repeat(b: &mut Bencher) {
                b.iter(|| test::black_box(run_fib_repeat(INPUT_SIZE, REPEAT_COUNT)));
            }

        }

        mod state {
            extern crate test;
            use self::test::Bencher;

            extern crate alloc;
            use std::rc::Rc;
            use adapton::adapton_syntax::* ;
            use adapton::adapton_sigs::* ;
            use adapton::adapton_state::* ;
            //use adapton::adapton_fromscratch::* ;
            use super::super::INPUT_SIZE;
            use super::super::REPEAT_COUNT;

            pub fn fib<A:Adapton> (st:&mut A, x:u64 ) -> u64 {
                match x {
                    0 => 0,
                    1 => 1,
                    x => { memo!(st, fib, x:x-1)
                           +
                           memo!(st, fib, x:x-2) }}
            }

            pub fn run_fib (x:u64) -> u64 {
                let mut st = &mut AdaptonState::new() ;
                memo!(st, fib, x:x )
            }

            pub fn run_fib_repeat (x:u64, n:u64) -> u64 {
                let mut st = &mut AdaptonState::new() ;
                for _ in 1..(n-1) {
                    memo!(st, fib, x:x );
                }
                memo!(st, fib, x:x )
            }

            #[test]
            fn it_works() {
                assert_eq!(5 as u64, run_fib(5));
            }

            #[bench]
            fn bench_fib(b: &mut Bencher) {
                b.iter(|| test::black_box(run_fib(INPUT_SIZE)));
            }

            #[bench]
            fn bench_fib_repeat(b: &mut Bencher) {
                b.iter(|| test::black_box(run_fib_repeat(INPUT_SIZE, REPEAT_COUNT)));
            }
        }
    }
}

mod fact {
    const INPUT_SIZE:u64 = 100;
    const REPEAT_COUNT:u64 = 100;

    #[cfg(test)]
    mod no_caching {
        use super::INPUT_SIZE;
        use super::REPEAT_COUNT;

        extern crate test;
        use self::test::Bencher;

        pub fn fact (x:u64) -> u64 {
            if x == 0 { 1 } else { test::black_box(x) * fact(x-1) }
        }

        pub fn fact_repeat (x:u64, n:u64) -> u64 {
            for _ in 1..(n-1) {
                test::black_box(fact(x));
            }
            fact(x)
        }

        #[test]
        fn it_works() {
            assert_eq!(120 as u64, fact(5));
        }

        #[bench]
        fn bench_fact(b: &mut Bencher) {
            b.iter(|| test::black_box(fact(INPUT_SIZE)));
        }

        #[bench]
        fn bench_fact_repeat(b: &mut Bencher) {
            b.iter(|| test::black_box(fact_repeat(INPUT_SIZE, REPEAT_COUNT)));
        }
    }

    #[cfg(test)]
    mod pure_caching {
        use super::INPUT_SIZE;
        use super::REPEAT_COUNT;

        extern crate test;
        use self::test::Bencher;

        use std::rc::Rc;

        use adapton::adapton_syntax::* ;
        use adapton::adapton_sigs::* ;
        use adapton::adapton_state::* ;

        pub fn fact<A:Adapton> (st:&mut A, x:u64 ) -> u64 {
            if x == 0 { 1 } else { x * (memo!(st, fact, x:x-1 )) }
        }

        pub fn run_fact (x:u64) -> u64 {
            let mut st = &mut (AdaptonState::new()) ;
            memo!(st, fact, x:x )
        }

        pub fn run_fact_repeat (x:u64, n:u64) -> u64 {
            let mut st = &mut (AdaptonState::new()) ;
            for _ in 1..(n-1) {
                memo!(st, fact, x:x );
            }
            memo!(st, fact, x:x )
        }

        #[test]
        fn it_works() {
            assert_eq!(120 as u64, run_fact(5));
        }

        #[bench]
        fn bench_fact(b: &mut Bencher) {
            b.iter(|| test::black_box(run_fact(INPUT_SIZE)));
        }

        #[bench]
        fn bench_fact_repeat(b: &mut Bencher) {
            b.iter(|| test::black_box(run_fact_repeat(INPUT_SIZE, REPEAT_COUNT)));
        }
    }
}

mod hourglass {
    //const INPUT_ARRAY:Vec<u64> = vec![2; 64];
    const REPEAT_COUNT:u64 = 100;

    #[cfg(test)]
    mod eager_ids {
        //use super::INPUT_ARRAY;
        use super::REPEAT_COUNT;

        extern crate test;
        use self::test::Bencher;

        use std::rc::Rc;

        use adapton::adapton_syntax::* ;
        use adapton::adapton_sigs::* ;
        //use adapton::adapton_fromscratch::* ;
        use adapton::adapton_state::* ;
        use adapton::structures::* ;

        // Thunks needs to *own* the arguments we give them.
        fn ident<A:Adapton,T>(st:&mut A, x:T) -> T {x}
        fn depend_mult<A:Adapton>(st:&mut A, x: Art<u64,A::Loc>,y: Art<u64,A::Loc>) -> u64 {
            st.force(&x) * st.force(&y)
        }
        fn depend_add<A:Adapton>(st:&mut A, x: Art<u64,A::Loc>,y: Art<u64,A::Loc>) -> u64 {
            //println!("depend_add:({:?},{:?})", x, y);
            st.force(&x) + st.force(&y)
        }

        pub fn hourglass<A:Adapton> (st:&mut A) -> u64 {
            let cells = vec![2;64];
            let mut nodes = vec![];
            for i in 0..64 {
                nodes.push(thunk!(st, ident, x:cells[i]));
            }
            let mut item_num = 0;
            loop {
                if nodes.len() == 126 { break; }
                let first = nodes[item_num].clone();
                let second = nodes[item_num+1].clone();
                nodes.push(thunk!(st, depend_add, x:first, y:second));
                //println!("{} --> {}, {}", nodes.len()-1, item_num, item_num+1);
                if item_num < 122 { item_num += 2 } else { item_num += 1 }
            }
            let thk = &nodes[nodes.len()-1];
            //println!("past checkpoint");
            st.force(thk)
        }

        pub fn run_hourglass () -> u64 {
            let mut st = &mut (AdaptonState::new());
            let res = hourglass(st);
            //assert!(res == );
            res
        }

        pub fn run_hourglass_repeat (n:u64) -> u64 {
            let mut st = &mut (AdaptonState::new());
            for _ in 1..(n-1) {
                test::black_box(hourglass(st));
            }
            hourglass(st)
        }

        // output value uncertain, test is changing
        // #[test]
        // fn it_works() {
        //     assert_eq!(2 as u64, run_hourglass());
        // }

        #[bench]
        fn bench_hourglass(b: &mut Bencher) {
            b.iter(|| test::black_box(run_hourglass()));
        }

        // Rewrite this as multiple changes in the input list
        // #[bench]
        // fn bench_hourglass_repeat(b: &mut Bencher) {
        //     b.iter(|| test::black_box(run_hourglass_repeat(REPEAT_COUNT)));
        // }
    }
}
<|endoftext|>


<commit_before>#[deriving(Show)]
struct Vec2<T> {
    x: T,
    y: T,
}

// The Add<T, U> trait overloads the + operator: (Self + T = U)
impl<
    // bound: T implements the Add trait
    T: Add<T, T>
> Add<Vec2<T>, Vec2<T>>
for Vec2<T> {
    // add() is a required method of the Add trait
    fn add(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            // x and y are of type T, and implement the add() method
            x: self.x.add(&rhs.x),
            y: self.x.add(&rhs.y),
        }
    }
}

// The Sub<T, U> trait overloads the - operator: (Self - T = U)
impl<
    // bound: T implements the Sub trait
    T: Sub<T, T>
> Sub<Vec2<T>, Vec2<T>>
for Vec2<T> {
    // sub() is a required method of the Sub trait
    fn sub(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            // x and y are of type T, and implement the sub() method
            x: self.x.sub(&rhs.x),
            y: self.x.sub(&rhs.y),
        }
    }
}

impl<
    // bound: T implements the Add trait and the Mul trait
    T: Add<T, T> + Mul<T, T>
> Vec2<T> {
    fn dot(&self, rhs: &Vec2<T>) -> T {
        self.x.mul(&rhs.x).add(&self.y.mul(&rhs.y))
    }
}

fn main() {
    let v1 = Vec2 { x: 1.0, y: 2.0 };
    let v2 = Vec2 { x: 2.0, y: 1.0 };

    println!("{} + {} = {}", v1, v2, v1 + v2);
    println!("{} - {} = {}", v1, v2, v1 - v2);
    println!("{} . {} = {}", v1, v2, v1.dot(&v2));
}
<commit_msg>simplify chapter on bounds<commit_after>#[deriving(Show)]
struct Vec2<T> {
    x: T,
    y: T,
}

impl<
    // bound: T implements the Add trait
    T: Add<T, T>
> Add<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn add(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            // x and y are of type T, and implement the add() method
            x: self.x.add(&rhs.x),
            y: self.x.add(&rhs.y),
        }
    }
}

impl<
    // bound: T implements the Sub trait
    T: Sub<T, T>
> Sub<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn sub(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            // x and y are of type T, and implement the sub() method
            x: self.x.sub(&rhs.x),
            y: self.x.sub(&rhs.y),
        }
    }
}

impl<
    // bound: T implements *both* the Add trait and the Mul trait
    T: Add<T, T> + Mul<T, T>
> Vec2<T> {
    fn dot(&self, rhs: &Vec2<T>) -> T {
        // the sugary versions of mul() and add() can be used as well
        (self.x * rhs.x) + (self.y * rhs.y)
    }
}

fn main() {
    let v1 = Vec2 { x: 1.0, y: 2.0 };
    let v2 = Vec2 { x: 2.0, y: 1.0 };

    println!("{} + {} = {}", v1, v2, v1 + v2);
    println!("{} - {} = {}", v1, v2, v1 - v2);
    println!("{} . {} = {}", v1, v2, v1.dot(&v2));
}
<|endoftext|>


<commit_before>#[deriving(Show)]
struct Vec2<T> {
    x: T,
    y: T,
}

impl<
    // bound: T implements the Add trait
    T: Add<T, T>
> Add<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn add(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            // x and y are of type T, and implement the add() method
            x: self.x.add(&rhs.x),
            y: self.y.add(&rhs.y),
        }
    }
}

impl<
    // bound: T implements the Sub trait
    T: Sub<T, T>
> Sub<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn sub(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            // x and y are of type T, and implement the sub() method
            x: self.x.sub(&rhs.x),
            y: self.y.sub(&rhs.y),
        }
    }
}

impl<
    // bound: T implements *both* the Add trait and the Mul trait
    T: Add<T, T> + Mul<T, T>
> Vec2<T> {
    fn dot(&self, rhs: &Vec2<T>) -> T {
        // the sugary versions of mul() and add() can be used as well
        (self.x * rhs.x) + (self.y * rhs.y)
    }
}

fn main() {
    let v1 = Vec2 { x: 1.0, y: 2.0 };
    let v2 = Vec2 { x: 2.0, y: 1.0 };

    println!("{} + {} = {}", v1, v2, v1 + v2);
    println!("{} - {} = {}", v1, v2, v1 - v2);
    println!("{} . {} = {}", v1, v2, v1.dot(&v2));
}
<commit_msg>Fix #50<commit_after>#[deriving(Show)]
struct Vec2<T> {
    x: T,
    y: T,
}

impl<
    // bound: T implements the Add trait
    T: Add<T, T>
> Add<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn add(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            // x and y are of type T, and implement the add() method
            x: self.x.add(&rhs.x),
            // the sugary + operator can also be used
            y: self.y + rhs.y,
        }
    }
}

impl<
    // bound: T implements the Sub trait
    T: Sub<T, T>
> Sub<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn sub(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            x: self.x - rhs.x,
            y: self.y - rhs.y,
        }
    }
}

impl<
    // bound: T implements *both* the Add trait and the Mul trait
    T: Add<T, T> + Mul<T, T>
> Vec2<T> {
    fn dot(&self, rhs: &Vec2<T>) -> T {
        (self.x * rhs.x) + (self.y * rhs.y)
    }
}

fn main() {
    let v1 = Vec2 { x: 1.0, y: 2.0 };
    let v2 = Vec2 { x: 2.0, y: 1.0 };

    println!("{} + {} = {}", v1, v2, v1 + v2);
    println!("{} - {} = {}", v1, v2, v1 - v2);
    println!("{} . {} = {}", v1, v2, v1.dot(&v2));
}
<|endoftext|>