<commit_before>/*
 * Simple Loop example with 4D noise
 * Daily Sketch 2019/09/23 by Alexis Andre (@mactuitui)
 *
 */

use nannou::noise::*;
use nannou::prelude::*;

fn main() {
    nannou::app(model).update(update).run();
}

struct Model {
    noise: Perlin,
}

fn model(app: &App) -> Model {
    let _window = app
        .new_window()
        .with_dimensions(1024, 1024)
        .view(view)
        .event(window_event)
        .build()
        .unwrap();
    let mut noise = Perlin::new();
    noise = noise.set_seed(1);
    Model { noise }
}

fn update(_app: &App, _model: &mut Model, _update: Update) {}

fn window_event(_app: &App, _model: &mut Model, event: WindowEvent) {
    match event {
        KeyPressed(_key) => {}
        KeyReleased(_key) => {}
        MouseMoved(_pos) => {}
        MousePressed(_button) => {}
        MouseReleased(_button) => {}
        MouseEntered => {}
        MouseExited => {}
        MouseWheel(_amount, _phase) => {}
        Moved(_pos) => {}
        Resized(_size) => {}
        Touch(_touch) => {}
        TouchPressure(_pressure) => {}
        HoveredFile(_path) => {}
        DroppedFile(_path) => {}
        HoveredFileCancelled => {}
        Focused => {}
        Unfocused => {}
        Closed => {}
    }
}

fn view(app: &App, model: &Model, frame: &Frame) {
    // Prepare to draw.
    let draw = app.draw();
    draw.background().color(BLACK);

    //the loop is going to be 200 frames long
    let frac = (app.elapsed_frames() % 200) as f32 / (200.0);

    //we'll rotate in the noise space
    let rotcos = 0.2 * (frac * TAU).cos();
    let rotsin = 0.2 * (frac * TAU).sin();

    //draw the lines
    for j in 0..190 {
        let frac_j = (j as f32) / 189.0;
        let mut pts = Vec::new();
        let mut pts2 = Vec::new();
        for i in 0..200 {
            let frac_i = (i as f32) / 199.0;
            let scale = ((frac_i * PI).sin()).powf(3.0);
            let offset = scale
                * (model.noise.get([
                    i as f64 * 0.03,
                    j as f64 * 0.5,
                    rotcos as f64,
                    rotsin as f64,
                ]) * 0.5
                    + 0.5) as f32;
            pts.push(vec2(
                -512.0 + frac_i * 1024.0,
                342.0 - frac_j * 824.0 + 160.0 * offset,
            ));
            pts2.push(vec2(
                -512.0 + frac_i * 1024.0,
                342.0 - frac_j * 824.0 + 160.0 * offset,
            ));
        }
        //fill the line with black
        draw.polygon().color(BLACK).points(pts);
        //draw the white outline on top
        draw.polyline().color(WHITE).stroke_weight(5.0).points(pts2);
    }

    draw.to_frame(app, &frame).unwrap();
}
<commit_msg>Simplify example<commit_after>/*
 * Simple Loop example with 4D noise
 * Daily Sketch 2019/09/23 by Alexis Andre (@mactuitui)
 *
 */

use nannou::noise::*;
use nannou::prelude::*;

fn main() {
    nannou::app(model).run();
}

struct Model {
    noise: Perlin,
}

fn model(app: &App) -> Model {
    let _window = app
        .new_window()
        .with_dimensions(1024, 1024)
        .view(view)
        .build()
        .unwrap();
    let mut noise = Perlin::new();
    noise = noise.set_seed(1);
    Model { noise }
}

fn view(app: &App, model: &Model, frame: &Frame) {
    // Prepare to draw.
    let draw = app.draw();
    draw.background().color(BLACK);

    //the loop is going to be 200 frames long
    let frac = (app.elapsed_frames() % 200) as f32 / (200.0);

    //we'll rotate in the noise space
    let rotcos = 0.2 * (frac * TAU).cos();
    let rotsin = 0.2 * (frac * TAU).sin();

    //draw the lines
    for j in 0..190 {
        let frac_j = (j as f32) / 189.0;
        let mut pts = Vec::new();
        let mut pts2 = Vec::new();
        for i in 0..200 {
            let frac_i = (i as f32) / 199.0;
            let scale = ((frac_i * PI).sin()).powf(3.0);
            let offset = scale
                * (model.noise.get([
                    i as f64 * 0.03,
                    j as f64 * 0.5,
                    rotcos as f64,
                    rotsin as f64,
                ]) * 0.5
                    + 0.5) as f32;
            pts.push(vec2(
                -512.0 + frac_i * 1024.0,
                342.0 - frac_j * 824.0 + 160.0 * offset,
            ));
            pts2.push(vec2(
                -512.0 + frac_i * 1024.0,
                342.0 - frac_j * 824.0 + 160.0 * offset,
            ));
        }
        //fill the line with black
        draw.polygon().color(BLACK).points(pts);
        //draw the white outline on top
        draw.polyline().color(WHITE).stroke_weight(5.0).points(pts2);
    }

    draw.to_frame(app, &frame).unwrap();
}
<|endoftext|>


<commit_before>fn main() {
    let mut s = String::new();

    let data = "random stuff";

    let s_to_string = data.to_string();

    let s = String::from("Initial content");
}
<commit_msg>Example of mutating string<commit_after>fn main() {
    let mut s = String::new();

    let data = "random stuff";

    let s_to_string = data.to_string();

    let s_from = String::from("Initial content");

    s.push_str("pushed");
}
<|endoftext|>


<commit_before>extern crate structopt;
#[macro_use]
extern crate structopt_derive;

use structopt::StructOpt;
use std::collections::BTreeSet;
use std::fs::File;
use std::io::Read;

fn distribute(blocks: &mut [usize]) {
    if blocks.is_empty() {
        return;
    }
    let (mut idx, mut nblocks) = blocks
        .iter()
        .cloned()
        .enumerate()
        .rev() // need to reverse since max_by_key() returns the last element,
               // and we want the first
        .max_by_key(|&(_, val)| val)
        .expect("blocks should not have been empty");
    blocks[idx] = 0;
    idx = (idx + 1) % blocks.len();
    while nblocks > 0 {
        blocks[idx] += 1;
        nblocks -= 1;
        idx = (idx + 1) % blocks.len();
    }
}

fn part1(input: &str) -> usize {
    let mut states = BTreeSet::new();
    let mut blocks = input
        .split_whitespace()
        .map(|s| s.parse().expect("Could not parse"))
        .collect::<Vec<usize>>();
    let mut count = 0;
    while !states.contains(&blocks) {
        states.insert(blocks.clone());
        distribute(&mut blocks);
        count += 1;
    }
    count
}

fn main() {
    let opt = Opt::from_args();
    let mut contents = String::new();
    if opt.input == "-" {
        std::io::stdin()
            .read_to_string(&mut contents)
            .expect("could not read stdin");
    } else {
        let mut file = File::open(&opt.input)
            .expect(&format!("file {} not found", opt.input));
        file.read_to_string(&mut contents)
            .expect(&format!("could not read file {}", opt.input));
    }
    println!("Part 1: {}", part1(&contents));
}

#[derive(StructOpt, Debug)]
#[structopt(name = "day06", about = "Advent of code 2017 day 06")]
struct Opt {
    #[structopt(help = "Input file")] input: String,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn distribute_test() {
        let mut input = [0, 2, 7, 0];
        distribute(&mut input);
        assert_eq!(input, [2, 4, 1, 2]);
        distribute(&mut input);
        assert_eq!(input, [3, 1, 2, 3]);
        distribute(&mut input);
        assert_eq!(input, [0, 2, 3, 4]);
        distribute(&mut input);
        assert_eq!(input, [1, 3, 4, 1]);
        distribute(&mut input);
        assert_eq!(input, [2, 4, 1, 2]);
    }

    #[test]
    fn part1_test() {
        assert_eq!(part1("0 2 7 0"), 5);
    }
}
<commit_msg>2017 day 06 part 02<commit_after>extern crate structopt;
#[macro_use]
extern crate structopt_derive;

use structopt::StructOpt;
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Read;

fn distribute(blocks: &mut [usize]) {
    if blocks.is_empty() {
        return;
    }
    let (mut idx, mut nblocks) = blocks
        .iter()
        .cloned()
        .enumerate()
        .rev() // need to reverse since max_by_key() returns the last element,
               // and we want the first
        .max_by_key(|&(_, val)| val)
        .expect("blocks should not have been empty");
    blocks[idx] = 0;
    idx = (idx + 1) % blocks.len();
    while nblocks > 0 {
        blocks[idx] += 1;
        nblocks -= 1;
        idx = (idx + 1) % blocks.len();
    }
}

fn cycle_detect(input: &str) -> (usize, usize) {
    let mut states = BTreeMap::new();
    let mut blocks = input
        .split_whitespace()
        .map(|s| s.parse().expect("Could not parse"))
        .collect::<Vec<usize>>();
    let mut count = 0;
    while !states.contains_key(&blocks) {
        states.insert(blocks.clone(), count);
        distribute(&mut blocks);
        count += 1;
    }
    (count, count - states[&blocks])
}

fn main() {
    let opt = Opt::from_args();
    let mut contents = String::new();
    if opt.input == "-" {
        std::io::stdin()
            .read_to_string(&mut contents)
            .expect("could not read stdin");
    } else {
        let mut file = File::open(&opt.input)
            .expect(&format!("file {} not found", opt.input));
        file.read_to_string(&mut contents)
            .expect(&format!("could not read file {}", opt.input));
    }
    let cycles = cycle_detect(&contents);
    println!("Part 1: {}", cycles.0);
    println!("Part 2: {}", cycles.1);
}

#[derive(StructOpt, Debug)]
#[structopt(name = "day06", about = "Advent of code 2017 day 06")]
struct Opt {
    #[structopt(help = "Input file")] input: String,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn distribute_test() {
        let mut input = [0, 2, 7, 0];
        distribute(&mut input);
        assert_eq!(input, [2, 4, 1, 2]);
        distribute(&mut input);
        assert_eq!(input, [3, 1, 2, 3]);
        distribute(&mut input);
        assert_eq!(input, [0, 2, 3, 4]);
        distribute(&mut input);
        assert_eq!(input, [1, 3, 4, 1]);
        distribute(&mut input);
        assert_eq!(input, [2, 4, 1, 2]);
    }

    #[test]
    fn cycle_detect_test() {
        assert_eq!(cycle_detect("0 2 7 0"), (5, 4));
    }
}
<|endoftext|>


<commit_before>use std::{
    ops::Deref,
    sync::{atomic::AtomicUsize, Arc, RwLock},
};

use pagecache::FastMap8;

use super::*;

/// The `sled` embedded database!
#[derive(Clone)]
pub struct Db {
    context: Arc<Context>,
    default: Arc<Tree>,
    tenants: Arc<RwLock<FastMap8<Vec<u8>, Arc<Tree>>>>,
}

unsafe impl Send for Db {}

unsafe impl Sync for Db {}

impl Deref for Db {
    type Target = Tree;

    fn deref(&self) -> &Tree {
        &self.default
    }
}

impl Db {
    /// Load existing or create a new `Db` with a default configuration.
    pub fn start_default<P: AsRef<std::path::Path>>(path: P) -> Result<Db> {
        let config = ConfigBuilder::new().path(path).build();
        Self::start(config)
    }

    /// Load existing or create a new `Db`.
    pub fn start(config: Config) -> Result<Db> {
        let _measure = Measure::new(&M.tree_start);

        let context = Arc::new(Context::start(config)?);

        let tx = context.pagecache.begin()?;

        let default = Arc::new(meta::open_tree(
            context.clone(),
            DEFAULT_TREE_ID.to_vec(),
            &tx,
        )?);

        let ret = Db {
            context: context.clone(),
            default,
            tenants: Arc::new(RwLock::new(FastMap8::default())),
        };

        let mut tenants = ret.tenants.write().unwrap();

        for (id, root) in context.pagecache.meta(&tx)?.tenants().into_iter() {
            let tree = Tree {
                tree_id: id.clone(),
                subscriptions: Arc::new(Subscriptions::default()),
                context: context.clone(),
                root: Arc::new(AtomicUsize::new(root)),
            };
            tenants.insert(id, Arc::new(tree));
        }

        drop(tenants);

        #[cfg(feature = "event_log")]
        context.event_log.meta_after_restart(
            context
                .pagecache
                .meta(&tx)
                .expect("should be able to get meta under test")
                .clone(),
        );

        Ok(ret)
    }

    /// Open or create a new disk-backed Tree with its own keyspace,
    /// accessible from the `Db` via the provided identifier.
    pub fn open_tree(&self, name: Vec<u8>) -> Result<Arc<Tree>> {
        let tenants = self.tenants.read().unwrap();
        if let Some(tree) = tenants.get(&name) {
            return Ok(tree.clone());
        }
        drop(tenants);

        let tx = self.context.pagecache.begin()?;

        let mut tenants = self.tenants.write().unwrap();
        let tree =
            Arc::new(meta::open_tree(self.context.clone(), name.clone(), &tx)?);
        tenants.insert(name, tree.clone());
        drop(tenants);
        Ok(tree)
    }

    /// Remove a disk-backed collection.
    pub fn drop_tree(&self, name: &[u8]) -> Result<bool> {
        if name == DEFAULT_TREE_ID {
            return Err(Error::Unsupported(
                "cannot remove the core structures".into(),
            ));
        }
        trace!("dropping tree {:?}", name,);

        let mut tenants = self.tenants.write().unwrap();

        let tree = if let Some(tree) = tenants.remove(&*name) {
            tree
        } else {
            return Ok(false);
        };

        let tx = self.context.pagecache.begin()?;

        let mut root_id =
            Some(self.context.pagecache.meta_pid_for_name(&name, &tx)?);

        let leftmost_chain: Vec<PageId> = tree
            .path_for_key(b"", &tx)?
            .into_iter()
            .map(|(id, _frag, _tp)| id)
            .collect();

        loop {
            let res = self.context.pagecache.cas_root_in_meta(
                name.to_vec(),
                root_id,
                None,
                &tx,
            )?;

            if let Err(actual_root) = res {
                root_id = actual_root;
            } else {
                break;
            }
        }

        tree.root
            .store(usize::max_value(), std::sync::atomic::Ordering::SeqCst);

        // drop writer lock
        drop(tenants);

        tree.gc_pages(leftmost_chain)?;

        tx.flush();

        Ok(true)
    }

    /// Returns `true` if the database was
    /// recovered from a previous process.
    /// Note that database state is only
    /// guaranteed to be present up to the
    /// last call to `flush`! Otherwise state
    /// is synced to disk periodically if the
    /// `sync_every_ms` configuration option
    /// is set to `Some(number_of_ms_between_syncs)`
    /// or if the IO buffer gets filled to
    /// capacity before being rotated.
    pub fn was_recovered(&self) -> bool {
        self.context.was_recovered()
    }

    /// Generate a monotonic ID. Not guaranteed to be
    /// contiguous. Written to disk every `idgen_persist_interval`
    /// operations, followed by a blocking flush. During recovery, we
    /// take the last recovered generated ID and add 2x
    /// the `idgen_persist_interval` to it. While persisting, if the
    /// previous persisted counter wasn't synced to disk yet, we will do
    /// a blocking flush to fsync the latest counter, ensuring
    /// that we will never give out the same counter twice.
    pub fn generate_id(&self) -> Result<u64> {
        self.context.generate_id()
    }
}
<commit_msg>Introduce a method to retrieve the already saved tree names<commit_after>use std::{
    ops::Deref,
    sync::{atomic::AtomicUsize, Arc, RwLock},
};

use pagecache::FastMap8;

use super::*;

/// The `sled` embedded database!
#[derive(Clone)]
pub struct Db {
    context: Arc<Context>,
    default: Arc<Tree>,
    tenants: Arc<RwLock<FastMap8<Vec<u8>, Arc<Tree>>>>,
}

unsafe impl Send for Db {}

unsafe impl Sync for Db {}

impl Deref for Db {
    type Target = Tree;

    fn deref(&self) -> &Tree {
        &self.default
    }
}

impl Db {
    /// Load existing or create a new `Db` with a default configuration.
    pub fn start_default<P: AsRef<std::path::Path>>(path: P) -> Result<Db> {
        let config = ConfigBuilder::new().path(path).build();
        Self::start(config)
    }

    /// Load existing or create a new `Db`.
    pub fn start(config: Config) -> Result<Db> {
        let _measure = Measure::new(&M.tree_start);

        let context = Arc::new(Context::start(config)?);

        let tx = context.pagecache.begin()?;

        let default = Arc::new(meta::open_tree(
            context.clone(),
            DEFAULT_TREE_ID.to_vec(),
            &tx,
        )?);

        let ret = Db {
            context: context.clone(),
            default,
            tenants: Arc::new(RwLock::new(FastMap8::default())),
        };

        let mut tenants = ret.tenants.write().unwrap();

        for (id, root) in context.pagecache.meta(&tx)?.tenants().into_iter() {
            let tree = Tree {
                tree_id: id.clone(),
                subscriptions: Arc::new(Subscriptions::default()),
                context: context.clone(),
                root: Arc::new(AtomicUsize::new(root)),
            };
            tenants.insert(id, Arc::new(tree));
        }

        drop(tenants);

        #[cfg(feature = "event_log")]
        context.event_log.meta_after_restart(
            context
                .pagecache
                .meta(&tx)
                .expect("should be able to get meta under test")
                .clone(),
        );

        Ok(ret)
    }

    /// Open or create a new disk-backed Tree with its own keyspace,
    /// accessible from the `Db` via the provided identifier.
    pub fn open_tree(&self, name: Vec<u8>) -> Result<Arc<Tree>> {
        let tenants = self.tenants.read().unwrap();
        if let Some(tree) = tenants.get(&name) {
            return Ok(tree.clone());
        }
        drop(tenants);

        let tx = self.context.pagecache.begin()?;

        let mut tenants = self.tenants.write().unwrap();
        let tree =
            Arc::new(meta::open_tree(self.context.clone(), name.clone(), &tx)?);
        tenants.insert(name, tree.clone());
        drop(tenants);
        Ok(tree)
    }

    /// Remove a disk-backed collection.
    pub fn drop_tree(&self, name: &[u8]) -> Result<bool> {
        if name == DEFAULT_TREE_ID {
            return Err(Error::Unsupported(
                "cannot remove the core structures".into(),
            ));
        }
        trace!("dropping tree {:?}", name,);

        let mut tenants = self.tenants.write().unwrap();

        let tree = if let Some(tree) = tenants.remove(&*name) {
            tree
        } else {
            return Ok(false);
        };

        let tx = self.context.pagecache.begin()?;

        let mut root_id =
            Some(self.context.pagecache.meta_pid_for_name(&name, &tx)?);

        let leftmost_chain: Vec<PageId> = tree
            .path_for_key(b"", &tx)?
            .into_iter()
            .map(|(id, _frag, _tp)| id)
            .collect();

        loop {
            let res = self.context.pagecache.cas_root_in_meta(
                name.to_vec(),
                root_id,
                None,
                &tx,
            )?;

            if let Err(actual_root) = res {
                root_id = actual_root;
            } else {
                break;
            }
        }

        tree.root
            .store(usize::max_value(), std::sync::atomic::Ordering::SeqCst);

        // drop writer lock
        drop(tenants);

        tree.gc_pages(leftmost_chain)?;

        tx.flush();

        Ok(true)
    }

    /// Returns the trees names saved in this Db.
    pub fn tree_names(&self) -> Vec<Vec<u8>> {
        let tenants = self.tenants.read().unwrap();
        tenants.iter().map(|(name, _)| name.clone()).collect()
    }

    /// Returns `true` if the database was
    /// recovered from a previous process.
    /// Note that database state is only
    /// guaranteed to be present up to the
    /// last call to `flush`! Otherwise state
    /// is synced to disk periodically if the
    /// `sync_every_ms` configuration option
    /// is set to `Some(number_of_ms_between_syncs)`
    /// or if the IO buffer gets filled to
    /// capacity before being rotated.
    pub fn was_recovered(&self) -> bool {
        self.context.was_recovered()
    }

    /// Generate a monotonic ID. Not guaranteed to be
    /// contiguous. Written to disk every `idgen_persist_interval`
    /// operations, followed by a blocking flush. During recovery, we
    /// take the last recovered generated ID and add 2x
    /// the `idgen_persist_interval` to it. While persisting, if the
    /// previous persisted counter wasn't synced to disk yet, we will do
    /// a blocking flush to fsync the latest counter, ensuring
    /// that we will never give out the same counter twice.
    pub fn generate_id(&self) -> Result<u64> {
        self.context.generate_id()
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use futures::{self, Future, Stream, Sink};
use futures::stream::Wait;
use futures::sync::mpsc;
use tokio_core::reactor::Core;
use tokio_timer::{TimeoutStream, Timer};

use std::net::SocketAddr;
use std::thread;
use std::time::{self, Duration};

use crypto::{gen_keypair, PublicKey, Signature};
use messages::{MessageWriter, RawMessage, Connect, Message};
use events::{NetworkEvent, NetworkRequest};
use events::network::{NetworkPart, NetworkConfiguration};
use node::{NodeChannel, EventsPoolCapacity};

#[derive(Debug)]
pub struct TestHandler {
    listen_address: SocketAddr,
    network_events_rx: Wait<TimeoutStream<mpsc::Receiver<NetworkEvent>>>,
    network_requests_tx: mpsc::Sender<NetworkRequest>,
}

impl TestHandler {
    pub fn new(
        listen_address: SocketAddr,
        network_requests_tx: mpsc::Sender<NetworkRequest>,
        network_events_rx: mpsc::Receiver<NetworkEvent>,
    ) -> TestHandler {
        let timer = Timer::default();
        let receiver = timer.timeout_stream(network_events_rx, Duration::from_secs(30));
        TestHandler {
            listen_address,
            network_requests_tx,
            network_events_rx: receiver.wait(),
        }
    }

    pub fn wait_for_event(&mut self) -> Result<NetworkEvent, ()> {
        let event = self.network_events_rx.next().unwrap()?;
        Ok(event)
    }

    pub fn connect_with(&self, addr: SocketAddr) {
        let connect = connect_message(self.listen_address);
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::SendMessage(addr, connect.raw().clone()))
            .wait()
            .unwrap();
    }

    pub fn disconnect_with(&self, addr: SocketAddr) {
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::DisconnectWithPeer(addr))
            .wait()
            .unwrap();
    }

    pub fn send_to(&self, addr: SocketAddr, raw: RawMessage) {
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::SendMessage(addr, raw))
            .wait()
            .unwrap();
    }

    pub fn wait_for_connect(&mut self) -> Connect {
        match self.wait_for_event() {
            Ok(NetworkEvent::PeerConnected(_addr, connect)) => connect,
            Ok(other) => panic!("Unexpected connect received, {:?}", other),
            Err(e) => panic!("An error occured, {:?}", e),
        }
    }

    pub fn wait_for_disconnect(&mut self) -> SocketAddr {
        match self.wait_for_event() {
            Ok(NetworkEvent::PeerDisconnected(addr)) => addr,
            Ok(other) => panic!("Unexpected disconnect received, {:?}", other),
            Err(e) => panic!("An error occured, {:?}", e),
        }
    }

    pub fn wait_for_message(&mut self) -> RawMessage {
        match self.wait_for_event() {
            Ok(NetworkEvent::MessageReceived(_addr, msg)) => msg,
            Ok(other) => panic!("Unexpected message received, {:?}", other),
            Err(e) => panic!("An error occured, {:?}", e),
        }
    }
}

impl Drop for TestHandler {
    fn drop(&mut self) {
        if !::std::thread::panicking() {
            self.network_requests_tx
                .clone()
                .send(NetworkRequest::Shutdown)
                .wait()
                .unwrap();
        }
    }
}

#[derive(Debug)]
pub struct TestEvents {
    pub listen_address: SocketAddr,
    pub network_config: NetworkConfiguration,
    pub events_config: EventsPoolCapacity,
}

struct TestHandlerPart {
    handler: TestHandler,
    core: Core,
}

impl TestEvents {
    pub fn with_addr(listen_address: SocketAddr) -> TestEvents {
        TestEvents {
            listen_address,
            network_config: NetworkConfiguration::default(),
            events_config: EventsPoolCapacity::default(),
        }
    }

    pub fn spawn<F>(self, test_fn: F) -> thread::JoinHandle<()>
    where
        F: Fn(&mut TestHandler) + 'static + Send,
    {
        thread::spawn(move || {
            let (handler_part, network_part) = self.into_reactor();
            let network_thread = thread::spawn(move || network_part.run().unwrap());

            let mut handler = handler_part.handler;

            let mut core = handler_part.core;
            let test_fut = futures::lazy(move || -> Result<(), ()> {
                test_fn(&mut handler);
                Ok(())
            });
            core.run(test_fut).unwrap();
            network_thread.join().unwrap();
        })
    }

    fn into_reactor(self) -> (TestHandlerPart, NetworkPart) {
        let channel = NodeChannel::new(self.events_config);
        let core = Core::new().unwrap();
        let network_config = self.network_config;
        let (network_tx, network_rx) = channel.network_events;
        let network_requests_tx = channel.network_requests.0.clone();

        let network_part = NetworkPart {
            listen_address: self.listen_address,
            network_config,
            network_requests: channel.network_requests,
            network_tx: network_tx.clone(),
        };

        let handler_part = TestHandlerPart {
            core,
            handler: TestHandler::new(self.listen_address, network_requests_tx, network_rx),
        };
        (handler_part, network_part)
    }
}

pub fn connect_message(addr: SocketAddr) -> Connect {
    let time = time::UNIX_EPOCH;
    Connect::new_with_signature(&PublicKey::zero(), addr, time, &Signature::zero())
}

pub fn raw_message(id: u16, len: usize) -> RawMessage {
    let writer = MessageWriter::new(
        ::messages::PROTOCOL_MAJOR_VERSION,
        ::messages::TEST_NETWORK_ID,
        0,
        id,
        len,
    );
    RawMessage::new(writer.sign(&gen_keypair().1))
}

#[test]
fn test_network_handshake() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:17230".parse().unwrap(), "127.0.0.1:17231".parse().unwrap()];

    let e1 = TestEvents::with_addr(addrs[0]);
    let e2 = TestEvents::with_addr(addrs[1]);

    let c1 = connect_message(addrs[0]);
    let c2 = connect_message(addrs[1]);

    let t1 = e1.spawn(move |e: &mut TestHandler| {
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_connect(), c2);
        e.disconnect_with(addrs[1]);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
    });
    let t2 = e2.spawn(move |e: &mut TestHandler| {
        assert_eq!(e.wait_for_connect(), c1);
        e.connect_with(addrs[0]);
        assert_eq!(e.wait_for_disconnect(), addrs[0]);
    });

    t1.join().unwrap();
    t2.join().unwrap();
}

#[test]
fn test_network_big_message() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:17200".parse().unwrap(), "127.0.0.1:17201".parse().unwrap()];

    let msg1 = raw_message(15, 100000);
    let msg2 = raw_message(16, 400);

    let e1 = TestEvents::with_addr(addrs[0]);
    let e2 = TestEvents::with_addr(addrs[1]);

    let m1 = msg1.clone();
    let m2 = msg2.clone();
    let t1 = e1.spawn(move |e: &mut TestHandler| {
        e.connect_with(addrs[1]);
        e.wait_for_connect();

        e.send_to(addrs[1], m1.clone());
        e.send_to(addrs[1], m2.clone());
        e.send_to(addrs[1], m1.clone());

        assert_eq!(e.wait_for_message(), m2);
        assert_eq!(e.wait_for_message(), m1);
        assert_eq!(e.wait_for_message(), m2);

        e.disconnect_with(addrs[1]);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
    });

    let m1 = msg1.clone();
    let m2 = msg2.clone();
    let t2 = e2.spawn(move |e: &mut TestHandler| {
        e.connect_with(addrs[0]);
        e.wait_for_connect();

        e.send_to(addrs[0], m2.clone());
        e.send_to(addrs[0], m1.clone());
        e.send_to(addrs[0], m2.clone());

        assert_eq!(e.wait_for_message(), m1);
        assert_eq!(e.wait_for_message(), m2);
        assert_eq!(e.wait_for_message(), m1);

        e.disconnect_with(addrs[0]);
        assert_eq!(e.wait_for_disconnect(), addrs[0]);
    });

    t2.join().unwrap();
    t1.join().unwrap();
}

#[test]
fn test_network_reconnect() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:19100".parse().unwrap(), "127.0.0.1:19101".parse().unwrap()];

    let c1 = connect_message(addrs[0]);
    let c2 = connect_message(addrs[1]);
    let t1 = TestEvents::with_addr(addrs[0]).spawn(move |e: &mut TestHandler| {
        // Handle first attempt
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_connect(), c2);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
        // Handle second attempt
        assert_eq!(e.wait_for_connect(), c2);
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
    });
    // First connect attempt.
    let c1_cloned = c1.clone();
    TestEvents::with_addr(addrs[1])
        .spawn(move |e: &mut TestHandler| {
            assert_eq!(e.wait_for_connect(), c1_cloned);
            e.connect_with(addrs[0]);
            e.disconnect_with(addrs[0]);
            assert_eq!(e.wait_for_disconnect(), addrs[0]);
        })
        .join()
        .unwrap();
    // Second connect attempt.
    let c1_cloned = c1.clone();
    TestEvents::with_addr(addrs[1])
        .spawn(move |e: &mut TestHandler| {
            e.connect_with(addrs[0]);
            assert_eq!(e.wait_for_connect(), c1_cloned);
            e.disconnect_with(addrs[0]);
            assert_eq!(e.wait_for_disconnect(), addrs[0]);
        })
        .join()
        .unwrap();
    // Wait for first server
    t1.join().unwrap();
}
<commit_msg>Make reconnect test more robust<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use futures::{self, Future, Stream, Sink};
use futures::stream::Wait;
use futures::sync::mpsc;
use tokio_core::reactor::Core;
use tokio_timer::{TimeoutStream, Timer};

use std::net::SocketAddr;
use std::thread;
use std::time::{self, Duration};

use crypto::{gen_keypair, PublicKey, Signature};
use messages::{MessageWriter, RawMessage, Connect, Message};
use events::{NetworkEvent, NetworkRequest};
use events::network::{NetworkPart, NetworkConfiguration};
use node::{NodeChannel, EventsPoolCapacity};

#[derive(Debug)]
pub struct TestHandler {
    listen_address: SocketAddr,
    network_events_rx: Wait<TimeoutStream<mpsc::Receiver<NetworkEvent>>>,
    network_requests_tx: mpsc::Sender<NetworkRequest>,
}

impl TestHandler {
    pub fn new(
        listen_address: SocketAddr,
        network_requests_tx: mpsc::Sender<NetworkRequest>,
        network_events_rx: mpsc::Receiver<NetworkEvent>,
    ) -> TestHandler {
        let timer = Timer::default();
        let receiver = timer.timeout_stream(network_events_rx, Duration::from_secs(30));
        TestHandler {
            listen_address,
            network_requests_tx,
            network_events_rx: receiver.wait(),
        }
    }

    pub fn wait_for_event(&mut self) -> Result<NetworkEvent, ()> {
        let event = self.network_events_rx.next().unwrap()?;
        Ok(event)
    }

    pub fn connect_with(&self, addr: SocketAddr) {
        let connect = connect_message(self.listen_address);
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::SendMessage(addr, connect.raw().clone()))
            .wait()
            .unwrap();
    }

    pub fn disconnect_with(&self, addr: SocketAddr) {
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::DisconnectWithPeer(addr))
            .wait()
            .unwrap();
    }

    pub fn send_to(&self, addr: SocketAddr, raw: RawMessage) {
        self.network_requests_tx
            .clone()
            .send(NetworkRequest::SendMessage(addr, raw))
            .wait()
            .unwrap();
    }

    pub fn wait_for_connect(&mut self) -> Connect {
        match self.wait_for_event() {
            Ok(NetworkEvent::PeerConnected(_addr, connect)) => connect,
            Ok(other) => panic!("Unexpected connect received, {:?}", other),
            Err(e) => panic!("An error occured, {:?}", e),
        }
    }

    pub fn wait_for_disconnect(&mut self) -> SocketAddr {
        match self.wait_for_event() {
            Ok(NetworkEvent::PeerDisconnected(addr)) => addr,
            Ok(other) => panic!("Unexpected disconnect received, {:?}", other),
            Err(e) => panic!("An error occured, {:?}", e),
        }
    }

    pub fn wait_for_message(&mut self) -> RawMessage {
        match self.wait_for_event() {
            Ok(NetworkEvent::MessageReceived(_addr, msg)) => msg,
            Ok(other) => panic!("Unexpected message received, {:?}", other),
            Err(e) => panic!("An error occured, {:?}", e),
        }
    }
}

impl Drop for TestHandler {
    fn drop(&mut self) {
        if !::std::thread::panicking() {
            self.network_requests_tx
                .clone()
                .send(NetworkRequest::Shutdown)
                .wait()
                .unwrap();
        }
    }
}

#[derive(Debug)]
pub struct TestEvents {
    pub listen_address: SocketAddr,
    pub network_config: NetworkConfiguration,
    pub events_config: EventsPoolCapacity,
}

struct TestHandlerPart {
    handler: TestHandler,
    core: Core,
}

impl TestEvents {
    pub fn with_addr(listen_address: SocketAddr) -> TestEvents {
        TestEvents {
            listen_address,
            network_config: NetworkConfiguration::default(),
            events_config: EventsPoolCapacity::default(),
        }
    }

    pub fn spawn<F>(self, test_fn: F) -> thread::JoinHandle<()>
    where
        F: Fn(&mut TestHandler) + 'static + Send,
    {
        thread::spawn(move || {
            let (handler_part, network_part) = self.into_reactor();
            let network_thread = thread::spawn(move || network_part.run().unwrap());

            let mut handler = handler_part.handler;

            let mut core = handler_part.core;
            let test_fut = futures::lazy(move || -> Result<(), ()> {
                test_fn(&mut handler);
                Ok(())
            });
            core.run(test_fut).unwrap();
            network_thread.join().unwrap();
        })
    }

    fn into_reactor(self) -> (TestHandlerPart, NetworkPart) {
        let channel = NodeChannel::new(self.events_config);
        let core = Core::new().unwrap();
        let network_config = self.network_config;
        let (network_tx, network_rx) = channel.network_events;
        let network_requests_tx = channel.network_requests.0.clone();

        let network_part = NetworkPart {
            listen_address: self.listen_address,
            network_config,
            network_requests: channel.network_requests,
            network_tx: network_tx.clone(),
        };

        let handler_part = TestHandlerPart {
            core,
            handler: TestHandler::new(self.listen_address, network_requests_tx, network_rx),
        };
        (handler_part, network_part)
    }
}

pub fn connect_message(addr: SocketAddr) -> Connect {
    let time = time::UNIX_EPOCH;
    Connect::new_with_signature(&PublicKey::zero(), addr, time, &Signature::zero())
}

pub fn raw_message(id: u16, len: usize) -> RawMessage {
    let writer = MessageWriter::new(
        ::messages::PROTOCOL_MAJOR_VERSION,
        ::messages::TEST_NETWORK_ID,
        0,
        id,
        len,
    );
    RawMessage::new(writer.sign(&gen_keypair().1))
}

#[test]
fn test_network_handshake() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:17230".parse().unwrap(), "127.0.0.1:17231".parse().unwrap()];

    let e1 = TestEvents::with_addr(addrs[0]);
    let e2 = TestEvents::with_addr(addrs[1]);

    let c1 = connect_message(addrs[0]);
    let c2 = connect_message(addrs[1]);

    let t1 = e1.spawn(move |e: &mut TestHandler| {
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_connect(), c2);
        e.disconnect_with(addrs[1]);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
    });
    let t2 = e2.spawn(move |e: &mut TestHandler| {
        assert_eq!(e.wait_for_connect(), c1);
        e.connect_with(addrs[0]);
        assert_eq!(e.wait_for_disconnect(), addrs[0]);
    });

    t1.join().unwrap();
    t2.join().unwrap();
}

#[test]
fn test_network_big_message() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:17200".parse().unwrap(), "127.0.0.1:17201".parse().unwrap()];

    let msg1 = raw_message(15, 100000);
    let msg2 = raw_message(16, 400);

    let e1 = TestEvents::with_addr(addrs[0]);
    let e2 = TestEvents::with_addr(addrs[1]);

    let m1 = msg1.clone();
    let m2 = msg2.clone();
    let t1 = e1.spawn(move |e: &mut TestHandler| {
        e.connect_with(addrs[1]);
        e.wait_for_connect();

        e.send_to(addrs[1], m1.clone());
        e.send_to(addrs[1], m2.clone());
        e.send_to(addrs[1], m1.clone());

        assert_eq!(e.wait_for_message(), m2);
        assert_eq!(e.wait_for_message(), m1);
        assert_eq!(e.wait_for_message(), m2);

        e.disconnect_with(addrs[1]);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
    });

    let m1 = msg1.clone();
    let m2 = msg2.clone();
    let t2 = e2.spawn(move |e: &mut TestHandler| {
        e.connect_with(addrs[0]);
        e.wait_for_connect();

        e.send_to(addrs[0], m2.clone());
        e.send_to(addrs[0], m1.clone());
        e.send_to(addrs[0], m2.clone());

        assert_eq!(e.wait_for_message(), m1);
        assert_eq!(e.wait_for_message(), m2);
        assert_eq!(e.wait_for_message(), m1);

        e.disconnect_with(addrs[0]);
        assert_eq!(e.wait_for_disconnect(), addrs[0]);
    });

    t2.join().unwrap();
    t1.join().unwrap();
}

#[test]
fn test_network_reconnect() {
    let addrs: [SocketAddr; 2] =
        ["127.0.0.1:19100".parse().unwrap(), "127.0.0.1:19101".parse().unwrap()];

    let msg = raw_message(11, 400);
    let c1 = connect_message(addrs[0]);
    let c2 = connect_message(addrs[1]);
    let msg_cloned = msg.clone();
    let t1 = TestEvents::with_addr(addrs[0]).spawn(move |e: &mut TestHandler| {
        // Handle first attempt
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_connect(), c2);
        assert_eq!(e.wait_for_message(), msg_cloned);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
        // Handle second attempt
        assert_eq!(e.wait_for_connect(), c2);
        e.connect_with(addrs[1]);
        assert_eq!(e.wait_for_message(), msg_cloned);
        assert_eq!(e.wait_for_disconnect(), addrs[1]);
    });
    // First connect attempt.
    let c1_cloned = c1.clone();
    let msg_cloned = msg.clone();
    TestEvents::with_addr(addrs[1])
        .spawn(move |e: &mut TestHandler| {
            assert_eq!(e.wait_for_connect(), c1_cloned);
            e.connect_with(addrs[0]);
            e.send_to(addrs[0], msg_cloned.clone());
            e.disconnect_with(addrs[0]);
            assert_eq!(e.wait_for_disconnect(), addrs[0]);
        })
        .join()
        .unwrap();
    // Second connect attempt.
    let c1_cloned = c1.clone();
    let msg_cloned = msg.clone();
    TestEvents::with_addr(addrs[1])
        .spawn(move |e: &mut TestHandler| {
            e.connect_with(addrs[0]);
            assert_eq!(e.wait_for_connect(), c1_cloned);
            e.send_to(addrs[0], msg_cloned.clone());
            e.disconnect_with(addrs[0]);
            assert_eq!(e.wait_for_disconnect(), addrs[0]);
        })
        .join()
        .unwrap();
    // Wait for first server
    t1.join().unwrap();
}
<|endoftext|>


<commit_before>#![feature(std_misc, io, collections)]

extern crate time;
#[macro_use]
extern crate log;

extern crate game;
extern crate search;
extern crate timer;

pub use self::start::start;
pub use self::types::{Cmd, Response, InfoParam};

mod types;
mod state;

mod start;
mod input;
mod output;
mod parse;
mod process;
<commit_msg>Fix compiler breaking changes<commit_after>#![feature(std_misc, io, collections, str_words)]

extern crate time;
#[macro_use]
extern crate log;

extern crate game;
extern crate search;
extern crate timer;

pub use self::start::start;
pub use self::types::{Cmd, Response, InfoParam};

mod types;
mod state;

mod start;
mod input;
mod output;
mod parse;
mod process;
<|endoftext|>


<commit_before>use front::run::compiler::Compiler;
use syntax::ast::constant::*;
use syntax::ast::op::*;
use syntax::ast::expr::Expr;
use jit::{
    Context,
    Compile,
    Function,
    Value,
    get_type,
    SysBool,
    Int,
    UInt,
    NInt,
    NUInt,
    Float64,
    Pointer
};
type CompiledValue<'a> = (Value<'a>, &'a Function<'a>);
/// A compiler using the LibJIT backend
pub struct JitCompiler<'a> {
    curr: Function<'a>
}
impl<'a> JitCompiler<'a> {
    /// Construct a new JIT Compiler on the given context
    pub fn new(context: &'a Context) -> JitCompiler<'a> {
        let main_t = get_type::<fn(*const int, *const int, *const int) -> *const int>();
        JitCompiler {
            curr: Function::new(context, &main_t)
        }
    }
    fn convert_bool(&'a self, val:Value<'a>) -> Value<'a> {
        let bool_t = get_type::<bool>();
        let val_kind = val.get_type().get_kind();
        let convert = |v| self.curr.insn_convert(&v, &bool_t, false);
        if val_kind.contains(SysBool) {
            val
        } else if val_kind.contains(Float64) {
            let zero = 0.0f64.compile(&self.curr);
            let not_zero = self.curr.insn_neq(&val, &zero);
            let not_nan = !self.curr.insn_is_nan(&val);
            convert(not_zero & not_nan)
        } else if val_kind.contains(Int) || val_kind.contains(UInt) || val_kind.contains(NInt) || val_kind.contains(NUInt) {
            let zero = 0i.compile(&self.curr);
            convert(self.curr.insn_neq(&val, &zero))
        } else if val_kind.contains(Pointer) {
            let one = 1i.compile(&self.curr);
            convert(self.curr.insn_gt(&val, &one))
        } else {
            convert(val)
        }
    }
    fn undefined(&'a self) -> Value<'a> {
        let ptr = Value::new(&self.curr, &get_type::<&int>());
        let val = 0u8.compile(&self.curr);
        self.curr.insn_store(&ptr, &val);
        ptr
    }
}
impl<'a> Compiler<'a, (Value<'a>, &'a Function<'a>)> for JitCompiler<'a> {
    fn compile_const(&'a self, constant:&Const) -> CompiledValue<'a> {
        (match constant.clone() {
            CString(v) =>
                v.compile(&self.curr),
            CNum(v) =>
                v.compile(&self.curr),
            CInt(v) =>
                v.compile(&self.curr),
            CBool(v) =>
                v.compile(&self.curr),
            CNull => {
                let ptr = Value::new(&self.curr, &get_type::<&int>());
                let val = 1u8.compile(&self.curr);
                self.curr.insn_store(&ptr, &val);
                ptr
            },
            CUndefined => {
                self.undefined()
            },
            _ => unimplemented!()
        }, &self.curr)
    }
    fn compile_block(&'a self, block:Vec<Expr>) -> CompiledValue<'a> {
        let last = block.last();
        for expr in block.iter() {
            let comp = self.compile(expr);
            if expr == last.unwrap() {
                return comp
            }
        }
        unreachable!()
    }
    fn compile_num_op(&'a self, op:NumOp, left:&Expr, right:&Expr) -> CompiledValue<'a> {
        let (c_left, _) = self.compile(left);
        let (c_right, _) = self.compile(right);
        (match op {
            OpAdd => c_left + c_right,
            OpSub => c_left - c_right,
            OpDiv => c_left / c_right,
            OpMul => c_left * c_right,
            OpMod => c_left % c_right
        }, &self.curr)
    }
    fn compile_bit_op(&'a self, op:BitOp, left:&Expr, right:&Expr) -> CompiledValue<'a> {
        let int_t = get_type::<i32>();
        let (c_left, _) = self.compile(left);
        let c_left = self.curr.insn_convert(&c_left, &int_t, false);
        let (c_right, _) = self.compile(right);
        let c_right = self.curr.insn_convert(&c_right, &int_t, false);
        (match op {
            BitAnd => c_left & c_right,
            BitOr => c_left | c_right,
            BitXor => c_left ^ c_right,
            BitShl => c_left << c_right,
            BitShr => c_left >> c_right
        }, &self.curr)
    }
    fn compile_log_op(&'a self, op:LogOp, left:&Expr, right:&Expr) -> CompiledValue<'a> {
        let (c_left, _) = self.compile(left);
        let c_left = self.convert_bool(c_left);
        let (c_right, _) = self.compile(right);
        let c_right = self.convert_bool(c_right);
        (match op {
            LogAnd => c_left & c_right,
            LogOr => c_left | c_right
        }, &self.curr)
    }
    fn compile_comp_op(&'a self, op:CompOp, left:&Expr, right:&Expr) -> CompiledValue<'a> {
        let (c_left, _) = self.compile(left);
        let (c_right, _) = self.compile(right);
        let val = match op {
            CompEqual | CompStrictEqual =>
                self.curr.insn_eq(&c_left, &c_right),
            CompNotEqual | CompStrictNotEqual =>
                self.curr.insn_neq(&c_left, &c_right),
            CompGreaterThan =>
                self.curr.insn_gt(&c_left, &c_right),
            CompGreaterThanOrEqual =>
                self.curr.insn_geq(&c_left, &c_right),
            CompLessThan =>
                self.curr.insn_lt(&c_left, &c_right),
            CompLessThanOrEqual =>
                self.curr.insn_leq(&c_left, &c_right),
        };
        let bool_val = self.curr.insn_convert(&val, &get_type::<bool>(), false);
        (bool_val, &self.curr)
    }
    fn compile_unary_op(&'a self, op:UnaryOp, val:&Expr) -> CompiledValue<'a> {
        let (c_val, _) = self.compile(val);
        (match op {
            UnaryMinus => -c_val,
            UnaryPlus => c_val,
            UnaryNot => {
                let c_not = !c_val;
                self.curr.insn_convert(&c_not, &get_type::<bool>(), false)
            },
            _ => unimplemented!()
        }, &self.curr)
    }
    fn compile_return(&'a self, val:Option<Box<Expr>>) -> CompiledValue<'a> {
        match val {
            Some(val) => {
                let (c_val, _) = self.compile(val);
                self.curr.insn_return(&c_val)
            },
            None => {
                self.curr.insn_default_return()
            }
        };
        (self.undefined(), &self.curr)
    }
}<commit_msg>Pass `jit::Type` by value, not reference<commit_after>use front::run::compiler::Compiler;
use syntax::ast::constant::*;
use syntax::ast::op::*;
use syntax::ast::expr::Expr;
use jit::{
    Context,
    Compile,
    Function,
    Value,
    get_type,
    SysBool,
    Int,
    UInt,
    NInt,
    NUInt,
    Float64,
    Pointer
};
type CompiledValue<'a> = (Value<'a>, &'a Function<'a>);
/// A compiler using the LibJIT backend
pub struct JitCompiler<'a> {
    curr: Function<'a>
}
impl<'a> JitCompiler<'a> {
    /// Construct a new JIT Compiler on the given context
    pub fn new(context: &'a Context) -> JitCompiler<'a> {
        let main_t = get_type::<fn(*const int, *const int, *const int) -> *const int>();
        JitCompiler {
            curr: Function::new(context, main_t)
        }
    }
    fn convert_bool(&'a self, val:Value<'a>) -> Value<'a> {
        let bool_t = get_type::<bool>();
        let val_kind = val.get_type().get_kind();
        let convert = |v| self.curr.insn_convert(&v, bool_t, false);
        if val_kind.contains(SysBool) {
            val
        } else if val_kind.contains(Float64) {
            let zero = 0.0f64.compile(&self.curr);
            let not_zero = self.curr.insn_neq(&val, &zero);
            let not_nan = !self.curr.insn_is_nan(&val);
            convert(not_zero & not_nan)
        } else if val_kind.contains(Int) || val_kind.contains(UInt) || val_kind.contains(NInt) || val_kind.contains(NUInt) {
            let zero = 0i.compile(&self.curr);
            convert(self.curr.insn_neq(&val, &zero))
        } else if val_kind.contains(Pointer) {
            let one = 1i.compile(&self.curr);
            convert(self.curr.insn_gt(&val, &one))
        } else {
            convert(val)
        }
    }
    fn undefined(&'a self) -> Value<'a> {
        let ptr = Value::new(&self.curr, get_type::<&int>());
        let val = 0u8.compile(&self.curr);
        self.curr.insn_store(&ptr, &val);
        ptr
    }
}
impl<'a> Compiler<'a, (Value<'a>, &'a Function<'a>)> for JitCompiler<'a> {
    fn compile_const(&'a self, constant:&Const) -> CompiledValue<'a> {
        (match constant.clone() {
            CString(v) =>
                v.compile(&self.curr),
            CNum(v) =>
                v.compile(&self.curr),
            CInt(v) =>
                v.compile(&self.curr),
            CBool(v) =>
                v.compile(&self.curr),
            CNull => {
                let ptr = Value::new(&self.curr, get_type::<&int>());
                let val = 1u8.compile(&self.curr);
                self.curr.insn_store(&ptr, &val);
                ptr
            },
            CUndefined => {
                self.undefined()
            },
            _ => unimplemented!()
        }, &self.curr)
    }
    fn compile_block(&'a self, block:Vec<Expr>) -> CompiledValue<'a> {
        let last = block.last();
        for expr in block.iter() {
            let comp = self.compile(expr);
            if expr == last.unwrap() {
                return comp
            }
        }
        unreachable!()
    }
    fn compile_num_op(&'a self, op:NumOp, left:&Expr, right:&Expr) -> CompiledValue<'a> {
        let (c_left, _) = self.compile(left);
        let (c_right, _) = self.compile(right);
        (match op {
            OpAdd => c_left + c_right,
            OpSub => c_left - c_right,
            OpDiv => c_left / c_right,
            OpMul => c_left * c_right,
            OpMod => c_left % c_right
        }, &self.curr)
    }
    fn compile_bit_op(&'a self, op:BitOp, left:&Expr, right:&Expr) -> CompiledValue<'a> {
        let int_t = get_type::<i32>();
        let (c_left, _) = self.compile(left);
        let c_left = self.curr.insn_convert(&c_left, int_t.clone(), false);
        let (c_right, _) = self.compile(right);
        let c_right = self.curr.insn_convert(&c_right, int_t, false);
        (match op {
            BitAnd => c_left & c_right,
            BitOr => c_left | c_right,
            BitXor => c_left ^ c_right,
            BitShl => c_left << c_right,
            BitShr => c_left >> c_right
        }, &self.curr)
    }
    fn compile_log_op(&'a self, op:LogOp, left:&Expr, right:&Expr) -> CompiledValue<'a> {
        let (c_left, _) = self.compile(left);
        let c_left = self.convert_bool(c_left);
        let (c_right, _) = self.compile(right);
        let c_right = self.convert_bool(c_right);
        (match op {
            LogAnd => c_left & c_right,
            LogOr => c_left | c_right
        }, &self.curr)
    }
    fn compile_comp_op(&'a self, op:CompOp, left:&Expr, right:&Expr) -> CompiledValue<'a> {
        let (c_left, _) = self.compile(left);
        let (c_right, _) = self.compile(right);
        let val = match op {
            CompEqual | CompStrictEqual =>
                self.curr.insn_eq(&c_left, &c_right),
            CompNotEqual | CompStrictNotEqual =>
                self.curr.insn_neq(&c_left, &c_right),
            CompGreaterThan =>
                self.curr.insn_gt(&c_left, &c_right),
            CompGreaterThanOrEqual =>
                self.curr.insn_geq(&c_left, &c_right),
            CompLessThan =>
                self.curr.insn_lt(&c_left, &c_right),
            CompLessThanOrEqual =>
                self.curr.insn_leq(&c_left, &c_right),
        };
        let bool_val = self.curr.insn_convert(&val, get_type::<bool>(), false);
        (bool_val, &self.curr)
    }
    fn compile_unary_op(&'a self, op:UnaryOp, val:&Expr) -> CompiledValue<'a> {
        let (c_val, _) = self.compile(val);
        (match op {
            UnaryMinus => -c_val,
            UnaryPlus => c_val,
            UnaryNot => {
                let c_not = !c_val;
                self.curr.insn_convert(&c_not, get_type::<bool>(), false)
            },
            _ => unimplemented!()
        }, &self.curr)
    }
    fn compile_return(&'a self, val:Option<Box<Expr>>) -> CompiledValue<'a> {
        match val {
            Some(val) => {
                let (c_val, _) = self.compile(val);
                self.curr.insn_return(&c_val)
            },
            None => {
                self.curr.insn_default_return()
            }
        };
        (self.undefined(), &self.curr)
    }
}<|endoftext|>


<commit_before>use core::ptr;

pub struct UnsafeList<T> where T: Node<T> {
    head: Link<T>,
}

impl<T> UnsafeList<T> where T: Node<T> {
    pub const fn new() -> Self {
        UnsafeList {
            head: Link::none(),
        }
    }

    pub unsafe fn push_front(&mut self, mut elem: Link<T>) {
        match self.head.as_mut() {
            None => {
                if let Some(node) = elem.as_mut() {
                    *node.prev_mut() = Link::none();
                    *node.next_mut() = Link::none();
                }
            },
            Some(node) => {
                if let Some(elem_node) = elem.as_mut() {
                    *node.prev_mut() = elem.clone();

                    *elem_node.prev_mut() = Link::none();
                    *elem_node.next_mut() = self.head.clone();
                }
            }
        }

        self.head = elem;
    }

    pub unsafe fn pop(&mut self, mut elem: Link<T>) {
        if let Some(node) = elem.as_mut() {
            if let Some(prev) = node.prev_mut().as_mut() {
                *prev.next_mut() = node.next().clone();
            }

            if let Some(next) = node.next_mut().as_mut() {
                *next.prev_mut() = node.prev().clone();
            }
        } else {
            return;
        }

        if elem == self.head {
            if let Some(head) = self.head.as_mut() {
                self.head = head.next().clone();
            } else {
                self.head = Link::none();
            }
        }
    }

    pub unsafe fn cursor<'a>(&'a mut self) -> UnsafeCursor<'a, T> {
        let head_dup = self.head.clone();

        UnsafeCursor {
            head: &mut self.head,
            current: head_dup,
        }
    }
}

pub struct UnsafeCursor<'a, T: Node<T> + 'a> {
    head: &'a mut Link<T>,
    current: Link<T>,
}

impl<'a, T: Node<T> + 'a> UnsafeCursor<'a, T> {
    pub unsafe fn remove(&mut self) -> Link<T> {
        if self.current.is_null() {
            return Link::none();
        }

        let mut res = self.current.clone();
        let update_head = *self.head == self.current;

        self.next();

        if let Some(node) = res.as_mut() {
            if let Some(prev) = node.prev_mut().as_mut() {
                *prev.next_mut() = node.next().clone();
            }

            if let Some(next) = node.next_mut().as_mut() {
                *next.prev_mut() = node.prev().clone();
            }

            *node.next_mut() = Link::none();
            *node.prev_mut() = Link::none();
        }

        if update_head {
            *self.head = self.current.clone();
        }

        res
    }

    pub unsafe fn next(&mut self) {
        if let Some(node) = self.current.as_mut() {
            self.current = node.next().clone();
        }
    }

    pub unsafe fn as_ref(&self) -> Option<&T> {
        self.current.as_ref()
    }
}

pub trait Node<T> where T: Node<T> + Sized {
    fn prev(&self) -> &Link<T>;
    fn next(&self) -> &Link<T>;

    fn prev_mut(&mut self) -> &mut Link<T>;
    fn next_mut(&mut self) -> &mut Link<T>;
}

pub struct DataNode<T> {
    elem: T,
    prev: Link<DataNode<T>>,
    next: Link<DataNode<T>>,
}

impl<T> DataNode<T> {
    pub fn new(elem: T) -> Self {
        DataNode {
            elem: elem,
            prev: Link::none(),
            next: Link::none(),
        }
    }

    pub fn data(&self) -> &T {
        &self.elem
    }

    pub fn data_mut(&mut self) -> &mut T {
        &mut self.elem
    }
}

impl<T> Node<DataNode<T>> for DataNode<T> {
    fn prev(&self) -> &Link<DataNode<T>> {
        &self.prev
    }

    fn next(&self) -> &Link<DataNode<T>> {
        &self.next
    }

    fn prev_mut(&mut self) -> &mut Link<DataNode<T>> {
        &mut self.prev
    }

    fn next_mut(&mut self) -> &mut Link<DataNode<T>> {
        &mut self.next
    }
}

pub struct PhantomNode {
    prev: Link<PhantomNode>,
    next: Link<PhantomNode>,
}

impl Node<PhantomNode> for PhantomNode {
    fn prev(&self) -> &Link<PhantomNode> {
        &self.prev
    }

    fn next(&self) -> &Link<PhantomNode> {
        &self.next
    }

    fn prev_mut(&mut self) -> &mut Link<PhantomNode> {
        &mut self.prev
    }

    fn next_mut(&mut self) -> &mut Link<PhantomNode> {
        &mut self.next
    }
}

pub struct Link<T> {
    ptr: *mut T,
}

impl<T> Link<T> {
    pub const fn some(ptr: *mut T) -> Self {
        Link {
            ptr: ptr,
        }
    }

    pub const fn none() -> Self {
        Link {
            ptr: ptr::null_mut(),
        }
    }

    pub fn is_null(&self) -> bool {
        self.ptr == ptr::null_mut()
    }

    pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
        self.ptr.as_ref()
    }

    pub unsafe fn as_mut<'a>(&mut self) -> Option<&'a mut T> {
        self.ptr.as_mut()
    }
}

impl<T> Clone for Link<T> {
    fn clone(&self) -> Self {
        Link {
            ptr: self.ptr,
        }
    }
}

impl<T> PartialEq<Link<T>> for Link<T> {
    fn eq(&self, rhs: &Link<T>) -> bool {
        self.ptr == rhs.ptr
    }
}
<commit_msg>libheap: Add UnsafeList<T>::pop_front()<commit_after>use core::ptr;

pub struct UnsafeList<T> where T: Node<T> {
    head: Link<T>,
}

impl<T> UnsafeList<T> where T: Node<T> {
    pub const fn new() -> Self {
        UnsafeList {
            head: Link::none(),
        }
    }

    pub unsafe fn push_front(&mut self, mut elem: Link<T>) {
        match self.head.as_mut() {
            None => {
                if let Some(node) = elem.as_mut() {
                    *node.prev_mut() = Link::none();
                    *node.next_mut() = Link::none();
                }
            },
            Some(node) => {
                if let Some(elem_node) = elem.as_mut() {
                    *node.prev_mut() = elem.clone();

                    *elem_node.prev_mut() = Link::none();
                    *elem_node.next_mut() = self.head.clone();
                }
            }
        }

        self.head = elem;
    }

    pub unsafe fn pop_front(&mut self) -> Link<T> {
        if self.head == Link::none() {
            return Link::none();
        }

        let ret = self.head.clone();
        let head = self.head.clone();

        self.pop(head);

        ret
    }

    pub unsafe fn pop(&mut self, mut elem: Link<T>) {
        if let Some(node) = elem.as_mut() {
            if let Some(prev) = node.prev_mut().as_mut() {
                *prev.next_mut() = node.next().clone();
            }

            if let Some(next) = node.next_mut().as_mut() {
                *next.prev_mut() = node.prev().clone();
            }
        } else {
            return;
        }

        if elem == self.head {
            if let Some(head) = self.head.as_mut() {
                self.head = head.next().clone();
            } else {
                self.head = Link::none();
            }
        }
    }

    pub unsafe fn cursor<'a>(&'a mut self) -> UnsafeCursor<'a, T> {
        let head_dup = self.head.clone();

        UnsafeCursor {
            head: &mut self.head,
            current: head_dup,
        }
    }
}

pub struct UnsafeCursor<'a, T: Node<T> + 'a> {
    head: &'a mut Link<T>,
    current: Link<T>,
}

impl<'a, T: Node<T> + 'a> UnsafeCursor<'a, T> {
    pub unsafe fn remove(&mut self) -> Link<T> {
        if self.current.is_null() {
            return Link::none();
        }

        let mut res = self.current.clone();
        let update_head = *self.head == self.current;

        self.next();

        if let Some(node) = res.as_mut() {
            if let Some(prev) = node.prev_mut().as_mut() {
                *prev.next_mut() = node.next().clone();
            }

            if let Some(next) = node.next_mut().as_mut() {
                *next.prev_mut() = node.prev().clone();
            }

            *node.next_mut() = Link::none();
            *node.prev_mut() = Link::none();
        }

        if update_head {
            *self.head = self.current.clone();
        }

        res
    }

    pub unsafe fn next(&mut self) {
        if let Some(node) = self.current.as_mut() {
            self.current = node.next().clone();
        }
    }

    pub unsafe fn as_ref(&self) -> Option<&T> {
        self.current.as_ref()
    }
}

pub trait Node<T> where T: Node<T> + Sized {
    fn prev(&self) -> &Link<T>;
    fn next(&self) -> &Link<T>;

    fn prev_mut(&mut self) -> &mut Link<T>;
    fn next_mut(&mut self) -> &mut Link<T>;
}

pub struct DataNode<T> {
    elem: T,
    prev: Link<DataNode<T>>,
    next: Link<DataNode<T>>,
}

impl<T> DataNode<T> {
    pub fn new(elem: T) -> Self {
        DataNode {
            elem: elem,
            prev: Link::none(),
            next: Link::none(),
        }
    }

    pub fn data(&self) -> &T {
        &self.elem
    }

    pub fn data_mut(&mut self) -> &mut T {
        &mut self.elem
    }
}

impl<T> Node<DataNode<T>> for DataNode<T> {
    fn prev(&self) -> &Link<DataNode<T>> {
        &self.prev
    }

    fn next(&self) -> &Link<DataNode<T>> {
        &self.next
    }

    fn prev_mut(&mut self) -> &mut Link<DataNode<T>> {
        &mut self.prev
    }

    fn next_mut(&mut self) -> &mut Link<DataNode<T>> {
        &mut self.next
    }
}

pub struct PhantomNode {
    prev: Link<PhantomNode>,
    next: Link<PhantomNode>,
}

impl Node<PhantomNode> for PhantomNode {
    fn prev(&self) -> &Link<PhantomNode> {
        &self.prev
    }

    fn next(&self) -> &Link<PhantomNode> {
        &self.next
    }

    fn prev_mut(&mut self) -> &mut Link<PhantomNode> {
        &mut self.prev
    }

    fn next_mut(&mut self) -> &mut Link<PhantomNode> {
        &mut self.next
    }
}

pub struct Link<T> {
    ptr: *mut T,
}

impl<T> Link<T> {
    pub const fn some(ptr: *mut T) -> Self {
        Link {
            ptr: ptr,
        }
    }

    pub const fn none() -> Self {
        Link {
            ptr: ptr::null_mut(),
        }
    }

    pub fn is_null(&self) -> bool {
        self.ptr == ptr::null_mut()
    }

    pub unsafe fn as_ref<'a>(&self) -> Option<&'a T> {
        self.ptr.as_ref()
    }

    pub unsafe fn as_mut<'a>(&mut self) -> Option<&'a mut T> {
        self.ptr.as_mut()
    }
}

impl<T> Clone for Link<T> {
    fn clone(&self) -> Self {
        Link {
            ptr: self.ptr,
        }
    }
}

impl<T> PartialEq<Link<T>> for Link<T> {
    fn eq(&self, rhs: &Link<T>) -> bool {
        self.ptr == rhs.ptr
    }
}
<|endoftext|>


<commit_before>#![feature(globs)]
#![feature(phase)]
#![feature(slicing_syntax)]

extern crate mpc;
extern crate phf;

#[phase(plugin)]
extern crate phf_mac;

#[cfg(test)]
extern crate test;

use cell::{Cell, CurriedBuiltinSpec, LambdaSpec};
use environment::Environment;
use parser::Parser;

#[cfg(test)]
use self::test::Bencher;

mod types;
mod cell;
mod globals;
mod environment;
mod builtin;
mod parser;

pub struct Rlisp<'a> {
    parser: Parser,
    environment: Environment,
}

impl<'a> Rlisp<'a> {
    pub fn new() -> Rlisp<'a> {
        Rlisp {
            parser: Parser::new(),
            environment: Environment::new(),
        }
    }

    pub fn execute(&mut self, input: &str) -> String {
        format!("{}", eval(self.environment.clone(), &self.parser.parse(input)))
    }
}

fn apply(env: Environment, procedure: &Cell, args: &[Cell]) -> Cell {
    if let Some(e) = first_error(args) {
         return e.clone();
    }

    let evaled_args = args.iter().map(|a| eval(env.clone(), a)).collect::<Vec<Cell>>();

    if let Some(e) = first_error(evaled_args[]) {
         return e.clone();
    }

    match procedure {
        &Cell::Lambda(box ref lambda) => {
            let sub_env = lambda.environment.make_sub_environment();

            let mut found_elipsis = false;

            for (i, arg) in evaled_args.iter().enumerate() {
                if let Some(&Cell::Symbol(ref s)) = lambda.arguments.get(i) {
                    match (s[] == "...", i == lambda.arguments.len() - 1) {
                        (true, true)  => { sub_env.insert(s, &Cell::Qexpr(evaled_args[i..].to_vec())); found_elipsis = true; break; },
                        (true, false) => return Cell::Error("Lambda can only have ... as it's last argument".to_string()),
                        (false, _)    => sub_env.insert(s, arg),
                    }
                }
            }

            if evaled_args.len() == 0 {
                if let Some(&Cell::Symbol(ref s)) = lambda.arguments.get(0) {
                    if s[] == "..." {
                        sub_env.insert(s, &Cell::Qexpr(Vec::new()));
                        found_elipsis = true;
                    }
                }
            }

            if evaled_args.len() == lambda.arguments.len() || found_elipsis {
                eval(sub_env.clone(), &Cell::Sexpr(lambda.body.clone()))
            } else if evaled_args.len() < lambda.arguments.len() {
                if evaled_args.len() == 0 {
                    Cell::Error(format!("{} got no arguments", procedure))
                } else {
                    Cell::Lambda(box LambdaSpec {
                        arguments:   lambda.arguments[evaled_args.len()..].to_vec(),
                        body:        lambda.body.clone(),
                        environment: sub_env.clone(),
                    })
                }
            } else {
                Cell::Error(format!("{} got to many arguments expected {} got {}",
                                    procedure, lambda.arguments.len(), evaled_args.len()))
            }
        },
        &Cell::Builtin(builtin) => {
            let arity = types::get_arity(builtin.argument_types);

            if evaled_args.len() as i32 >= arity.requierd {
                if let Some(e) = types::validate(builtin, evaled_args[]) {
                    return Cell::Error(e);
                }

                (builtin.func)(env, evaled_args[])
            } else {
                Cell::CurriedBuiltin(box CurriedBuiltinSpec {
                    builtin: builtin,
                    bound_args: evaled_args,
                })
            }
        },
        &Cell::CurriedBuiltin(box ref cb) => {
            let arity = types::get_arity(cb.builtin.argument_types);
            let mut evaled_and_bound_args = Vec::new();
            evaled_and_bound_args.push_all(cb.bound_args[]);
            evaled_and_bound_args.push_all(evaled_args[]);

            if evaled_and_bound_args.len() as i32 >= arity.requierd {
                if let Some(e) = types::validate(cb.builtin, evaled_and_bound_args[]) {
                    return Cell::Error(e);
                }

                (cb.builtin.func)(env, evaled_and_bound_args[])
            } else {
                Cell::CurriedBuiltin(box CurriedBuiltinSpec {
                    builtin: cb.builtin,
                    bound_args: evaled_and_bound_args,
                })
            }
        },
        _ => Cell::Error(format!("{} is not a procedure, is {}", *procedure, procedure.get_type().to_string())),
    }
}

fn eval(env: Environment, c: &Cell) -> Cell {
    match c {
        &Cell::Sexpr(ref v) => match v[] {
            [ref procedure, args..] => {
                let evaled_procedure = eval(env.clone(), procedure);

                if let Cell::Error(_) = evaled_procedure {
                    return evaled_procedure.clone();
                }

                apply(env.clone(), &evaled_procedure, args)
            },
            _ => c.clone(),
        },
        &Cell::Symbol(ref s) => env.lookup(s),
        _ => c.clone(),
    }
}

fn first_error(c: &[Cell]) -> Option<&Cell> {
    for e in c.iter() {
        if let &Cell::Error(_) = e {
            return Some(e);
        }
    }
    None
}

#[test]
fn test_rlisp() {
    let mut rlisp = Rlisp::new();

    assert_eq!(rlisp.execute("(def {a} 12)"), "()".to_string());

    assert_eq!(rlisp.execute("(+ a a)"), "24".to_string());

    assert_eq!(rlisp.execute("(- a 4)"), "8".to_string());

    assert_eq!(rlisp.execute("(eval (head {(+ 1 2) (+ 10 20)}))"), "3".to_string());

    assert_eq!(rlisp.execute("((lambda {a} {+ a 1}) 2)"), "3".to_string());

    assert_eq!(rlisp.execute("((lambda {a} {+ a 1}) a)"), "13".to_string());

    assert_eq!(rlisp.execute("(def {addgen} (lambda {a} {lambda {} {+ a 1}}))"), "()".to_string());
    assert_eq!(rlisp.execute("(def {adder} (addgen 1))"), "()".to_string());
    assert_eq!(rlisp.execute("(adder)"), "2".to_string());

    assert_eq!(rlisp.execute("(def {defgen} (lambda {a} {lambda {} {def {o} a}}))"), "()".to_string());
    assert_eq!(rlisp.execute("(def {defer} (defgen 10))"), "()".to_string());
    assert_eq!(rlisp.execute("(defer)"), "()".to_string());
    assert_eq!(rlisp.execute("o"), "10".to_string());

    assert_eq!(rlisp.execute("((lambda {x y} {+ x y}) 10 20)"), "30".to_string());

    assert_eq!(rlisp.execute("(def {add-mul} (lambda {x y} {+ x (* x y)}))"), "()".to_string());
    assert_eq!(rlisp.execute("(add-mul 10 20)"), "210".to_string());

    assert_eq!(rlisp.execute("(def {add-mul-10} (add-mul 10))"), "()".to_string());
    assert_eq!(rlisp.execute("(add-mul-10 50)"), "510".to_string());

    assert_eq!(rlisp.execute("(def {f x y} {+ x (/ (+ x x) y)})"), "()".to_string());
    assert_eq!(rlisp.execute("(f 10 20)"), "11".to_string());

    assert_eq!(rlisp.execute("(def {hof f} {f 12 12})"), "()".to_string());
    assert_eq!(rlisp.execute("(hof +)"), "24".to_string());
    assert_eq!(rlisp.execute("(hof (lambda {a b} {+ a (/ b 2)}))"), "18".to_string());

    assert_eq!(rlisp.execute("(def {elipse ...} {head (list ...)})"), "()".to_string());
    assert_eq!(rlisp.execute("(elipse 1 2 3)"), "{1 2 3}".to_string());
    assert_eq!(rlisp.execute("(elipse 1 2 3 4 5)"), "{1 2 3 4 5}".to_string());
 }

#[test]
fn test_elipsis_emty_arg_list() {
    let mut rlisp = Rlisp::new();

    assert_eq!(rlisp.execute("(def {a ...} {head (list ...)})"), "()".to_string());

    assert_eq!(rlisp.execute("(a)"), "{}".to_string());
}

#[test]
fn test_curried_builtin() {
    let mut rlisp = Rlisp::new();

    assert_eq!(rlisp.execute("(def {a} (* 5))"), "()".to_string());

    assert_eq!(rlisp.execute("(a 10)"), "50".to_string());
}

 #[bench]
fn bench_rlisp_add(b: &mut Bencher) {
    let mut rlisp = Rlisp::new();

    b.iter(|| {
        test::black_box(rlisp.execute("(+ 1 1)"));
    });
}

#[bench]
fn bench_rlisp_lookup(b: &mut Bencher) {
    let mut rlisp = Rlisp::new();

    rlisp.execute("(def {a} 12)");

    b.iter(|| {
        test::black_box(rlisp.execute("a"));
    });
}

#[bench]
fn bench_rlisp_add_lookup(b: &mut Bencher) {
    let mut rlisp = Rlisp::new();

    rlisp.execute("(def {a} 12)");

    b.iter(|| {
        test::black_box(rlisp.execute("(+ a a)"));
    });
}<commit_msg>Spelling<commit_after>#![feature(globs)]
#![feature(phase)]
#![feature(slicing_syntax)]

extern crate mpc;
extern crate phf;

#[phase(plugin)]
extern crate phf_mac;

#[cfg(test)]
extern crate test;

use cell::{Cell, CurriedBuiltinSpec, LambdaSpec};
use environment::Environment;
use parser::Parser;

#[cfg(test)]
use self::test::Bencher;

mod types;
mod cell;
mod globals;
mod environment;
mod builtin;
mod parser;

pub struct Rlisp<'a> {
    parser: Parser,
    environment: Environment,
}

impl<'a> Rlisp<'a> {
    pub fn new() -> Rlisp<'a> {
        Rlisp {
            parser: Parser::new(),
            environment: Environment::new(),
        }
    }

    pub fn execute(&mut self, input: &str) -> String {
        format!("{}", eval(self.environment.clone(), &self.parser.parse(input)))
    }
}

fn apply(env: Environment, procedure: &Cell, args: &[Cell]) -> Cell {
    if let Some(e) = first_error(args) {
         return e.clone();
    }

    let evaled_args = args.iter().map(|a| eval(env.clone(), a)).collect::<Vec<Cell>>();

    if let Some(e) = first_error(evaled_args[]) {
         return e.clone();
    }

    match procedure {
        &Cell::Lambda(box ref lambda) => {
            let sub_env = lambda.environment.make_sub_environment();

            let mut found_elipsis = false;

            for (i, arg) in evaled_args.iter().enumerate() {
                if let Some(&Cell::Symbol(ref s)) = lambda.arguments.get(i) {
                    match (s[] == "...", i == lambda.arguments.len() - 1) {
                        (true, true)  => { sub_env.insert(s, &Cell::Qexpr(evaled_args[i..].to_vec())); found_elipsis = true; break; },
                        (true, false) => return Cell::Error("Lambda can only have ... as it's last argument".to_string()),
                        (false, _)    => sub_env.insert(s, arg),
                    }
                }
            }

            if evaled_args.len() == 0 {
                if let Some(&Cell::Symbol(ref s)) = lambda.arguments.get(0) {
                    if s[] == "..." {
                        sub_env.insert(s, &Cell::Qexpr(Vec::new()));
                        found_elipsis = true;
                    }
                }
            }

            if evaled_args.len() == lambda.arguments.len() || found_elipsis {
                eval(sub_env.clone(), &Cell::Sexpr(lambda.body.clone()))
            } else if evaled_args.len() < lambda.arguments.len() {
                if evaled_args.len() == 0 {
                    Cell::Error(format!("{} got no arguments", procedure))
                } else {
                    Cell::Lambda(box LambdaSpec {
                        arguments:   lambda.arguments[evaled_args.len()..].to_vec(),
                        body:        lambda.body.clone(),
                        environment: sub_env.clone(),
                    })
                }
            } else {
                Cell::Error(format!("{} got to many arguments expected {} got {}",
                                    procedure, lambda.arguments.len(), evaled_args.len()))
            }
        },
        &Cell::Builtin(builtin) => {
            let arity = types::get_arity(builtin.argument_types);

            if evaled_args.len() as i32 >= arity.requierd {
                if let Some(e) = types::validate(builtin, evaled_args[]) {
                    return Cell::Error(e);
                }

                (builtin.func)(env, evaled_args[])
            } else {
                Cell::CurriedBuiltin(box CurriedBuiltinSpec {
                    builtin: builtin,
                    bound_args: evaled_args,
                })
            }
        },
        &Cell::CurriedBuiltin(box ref cb) => {
            let arity = types::get_arity(cb.builtin.argument_types);
            let mut evaled_and_bound_args = Vec::new();
            evaled_and_bound_args.push_all(cb.bound_args[]);
            evaled_and_bound_args.push_all(evaled_args[]);

            if evaled_and_bound_args.len() as i32 >= arity.requierd {
                if let Some(e) = types::validate(cb.builtin, evaled_and_bound_args[]) {
                    return Cell::Error(e);
                }

                (cb.builtin.func)(env, evaled_and_bound_args[])
            } else {
                Cell::CurriedBuiltin(box CurriedBuiltinSpec {
                    builtin: cb.builtin,
                    bound_args: evaled_and_bound_args,
                })
            }
        },
        _ => Cell::Error(format!("{} is not a procedure, is {}", *procedure, procedure.get_type().to_string())),
    }
}

fn eval(env: Environment, c: &Cell) -> Cell {
    match c {
        &Cell::Sexpr(ref v) => match v[] {
            [ref procedure, args..] => {
                let evaled_procedure = eval(env.clone(), procedure);

                if let Cell::Error(_) = evaled_procedure {
                    return evaled_procedure.clone();
                }

                apply(env.clone(), &evaled_procedure, args)
            },
            _ => c.clone(),
        },
        &Cell::Symbol(ref s) => env.lookup(s),
        _ => c.clone(),
    }
}

fn first_error(c: &[Cell]) -> Option<&Cell> {
    for e in c.iter() {
        if let &Cell::Error(_) = e {
            return Some(e);
        }
    }
    None
}

#[test]
fn test_rlisp() {
    let mut rlisp = Rlisp::new();

    assert_eq!(rlisp.execute("(def {a} 12)"), "()".to_string());

    assert_eq!(rlisp.execute("(+ a a)"), "24".to_string());

    assert_eq!(rlisp.execute("(- a 4)"), "8".to_string());

    assert_eq!(rlisp.execute("(eval (head {(+ 1 2) (+ 10 20)}))"), "3".to_string());

    assert_eq!(rlisp.execute("((lambda {a} {+ a 1}) 2)"), "3".to_string());

    assert_eq!(rlisp.execute("((lambda {a} {+ a 1}) a)"), "13".to_string());

    assert_eq!(rlisp.execute("(def {addgen} (lambda {a} {lambda {} {+ a 1}}))"), "()".to_string());
    assert_eq!(rlisp.execute("(def {adder} (addgen 1))"), "()".to_string());
    assert_eq!(rlisp.execute("(adder)"), "2".to_string());

    assert_eq!(rlisp.execute("(def {defgen} (lambda {a} {lambda {} {def {o} a}}))"), "()".to_string());
    assert_eq!(rlisp.execute("(def {defer} (defgen 10))"), "()".to_string());
    assert_eq!(rlisp.execute("(defer)"), "()".to_string());
    assert_eq!(rlisp.execute("o"), "10".to_string());

    assert_eq!(rlisp.execute("((lambda {x y} {+ x y}) 10 20)"), "30".to_string());

    assert_eq!(rlisp.execute("(def {add-mul} (lambda {x y} {+ x (* x y)}))"), "()".to_string());
    assert_eq!(rlisp.execute("(add-mul 10 20)"), "210".to_string());

    assert_eq!(rlisp.execute("(def {add-mul-10} (add-mul 10))"), "()".to_string());
    assert_eq!(rlisp.execute("(add-mul-10 50)"), "510".to_string());

    assert_eq!(rlisp.execute("(def {f x y} {+ x (/ (+ x x) y)})"), "()".to_string());
    assert_eq!(rlisp.execute("(f 10 20)"), "11".to_string());

    assert_eq!(rlisp.execute("(def {hof f} {f 12 12})"), "()".to_string());
    assert_eq!(rlisp.execute("(hof +)"), "24".to_string());
    assert_eq!(rlisp.execute("(hof (lambda {a b} {+ a (/ b 2)}))"), "18".to_string());

    assert_eq!(rlisp.execute("(def {elipse ...} {head (list ...)})"), "()".to_string());
    assert_eq!(rlisp.execute("(elipse 1 2 3)"), "{1 2 3}".to_string());
    assert_eq!(rlisp.execute("(elipse 1 2 3 4 5)"), "{1 2 3 4 5}".to_string());
 }

#[test]
fn test_elipsis_empty_arg_list() {
    let mut rlisp = Rlisp::new();

    assert_eq!(rlisp.execute("(def {a ...} {head (list ...)})"), "()".to_string());

    assert_eq!(rlisp.execute("(a)"), "{}".to_string());
}

#[test]
fn test_curried_builtin() {
    let mut rlisp = Rlisp::new();

    assert_eq!(rlisp.execute("(def {a} (* 5))"), "()".to_string());

    assert_eq!(rlisp.execute("(a 10)"), "50".to_string());
}

 #[bench]
fn bench_rlisp_add(b: &mut Bencher) {
    let mut rlisp = Rlisp::new();

    b.iter(|| {
        test::black_box(rlisp.execute("(+ 1 1)"));
    });
}

#[bench]
fn bench_rlisp_lookup(b: &mut Bencher) {
    let mut rlisp = Rlisp::new();

    rlisp.execute("(def {a} 12)");

    b.iter(|| {
        test::black_box(rlisp.execute("a"));
    });
}

#[bench]
fn bench_rlisp_add_lookup(b: &mut Bencher) {
    let mut rlisp = Rlisp::new();

    rlisp.execute("(def {a} 12)");

    b.iter(|| {
        test::black_box(rlisp.execute("(+ a a)"));
    });
}<|endoftext|>


<commit_before>// adventofcode - day 17
// part 2

use std::io::prelude::*;
use std::fs::File;
use std::str::FromStr;
use std::i32::MAX;

fn main(){
    println!("Advent of Code - day 17 | part 2");

    // import data
    let data = import_data();

    let mut containers = Vec::new();
    for line in data.lines() {
        containers.push( i32::from_str(line).unwrap() );
    }

    containers.sort();
    containers.reverse();

    let store = 150;
    let (combi, times) = count_combinations(store, &containers[0..]);

    println!("Minimum combi: {} ({} times)", combi, times);

}

// recursive approach to find the number of combinations
// NOTE: This assumes a descending sorted array of containers
fn count_min_combination(store: i32, containers: &[i32]) -> (i32, i32) {

    if store == 0 {
        // if there's nothing left to fill we found a valid combination
        return (1, 1);
    } else if store < 0 {
        // if we are below 0 we did something wrong. so we return something
        // "invalid"
        return (std::i32::MAX, 0);
    }

    let mut min_combi = std::i32::MAX;
    let mut min_combi_times = 0;
    for ii in 0..containers.len() {
        if containers[ii] > store {
            // if the container is too large for our remaining eggnag, we'll
            // skip it
            continue;
        }

        // after "adding" the container to our list (we dont keep track of our
        // combination-list because we just want to have the lowest amount of
        // containers required; and how many possibilities there are for this)
        // we check how many remaining combinations are left for the other
        // containers (and the reduced amount to fill up)
        let (mut combi, times) = count_min_combination(store - containers[ii],
                                                &containers[ii+1..]);

        // if we found combination we have to add one because of the container
        // we just added.
        // std::i32::MAX is only returned in case of an error or if no
        // combination could be found
        if combi != std::i32::MAX {
            combi += 1;
        }

        if combi == min_combi {
            // if we already found this combination"score" we need to add the
            // ones we just found
            min_combi_times += times;
        } else if combi < min_combi {
            // otherwise, if we found a new lowest combination score we'll take
            // this one
            min_combi = combi;
            min_combi_times = times;
        }

    }

    // in the end, return everything
    (min_combi, min_combi_times)
}

// This function simply imports the data set from a file called input.txt
fn import_data() -> String {
    let mut file = match File::open("../../inputs/17.txt") {
        Ok(f) => f,
        Err(e) => panic!("file error: {}", e),
    };

    let mut data = String::new();
    match file.read_to_string(&mut data){
        Ok(_) => {},
        Err(e) => panic!("file error: {}", e),
    };

    // remove trailing '\n'
    data.pop();
    data
}
<commit_msg>Rust - 17: Fix compile error of part 2<commit_after>// adventofcode - day 17
// part 2

use std::io::prelude::*;
use std::fs::File;
use std::str::FromStr;
use std::i32::MAX;

fn main(){
    println!("Advent of Code - day 17 | part 2");

    // import data
    let data = import_data();

    let mut containers = Vec::new();
    for line in data.lines() {
        containers.push( i32::from_str(line).unwrap() );
    }

    containers.sort();
    containers.reverse();

    let store = 150;
    let (combi, times) = count_min_combination(store, &containers[0..]);

    println!("Minimum combi: {} ({} times)", combi, times);

}

// recursive approach to find the number of combinations
// NOTE: This assumes a descending sorted array of containers
fn count_min_combination(store: i32, containers: &[i32]) -> (i32, i32) {

    if store == 0 {
        // if there's nothing left to fill we found a valid combination
        return (1, 1);
    } else if store < 0 {
        // if we are below 0 we did something wrong. so we return something
        // "invalid"
        return (std::i32::MAX, 0);
    }

    let mut min_combi = std::i32::MAX;
    let mut min_combi_times = 0;
    for ii in 0..containers.len() {
        if containers[ii] > store {
            // if the container is too large for our remaining eggnag, we'll
            // skip it
            continue;
        }

        // after "adding" the container to our list (we dont keep track of our
        // combination-list because we just want to have the lowest amount of
        // containers required; and how many possibilities there are for this)
        // we check how many remaining combinations are left for the other
        // containers (and the reduced amount to fill up)
        let (mut combi, times) = count_min_combination(store - containers[ii],
                                                &containers[ii+1..]);

        // if we found combination we have to add one because of the container
        // we just added.
        // std::i32::MAX is only returned in case of an error or if no
        // combination could be found
        if combi != std::i32::MAX {
            combi += 1;
        }

        if combi == min_combi {
            // if we already found this combination"score" we need to add the
            // ones we just found
            min_combi_times += times;
        } else if combi < min_combi {
            // otherwise, if we found a new lowest combination score we'll take
            // this one
            min_combi = combi;
            min_combi_times = times;
        }

    }

    // in the end, return everything
    (min_combi, min_combi_times)
}

// This function simply imports the data set from a file called input.txt
fn import_data() -> String {
    let mut file = match File::open("../../inputs/17.txt") {
        Ok(f) => f,
        Err(e) => panic!("file error: {}", e),
    };

    let mut data = String::new();
    match file.read_to_string(&mut data){
        Ok(_) => {},
        Err(e) => panic!("file error: {}", e),
    };

    // remove trailing '\n'
    data.pop();
    data
}
<|endoftext|>


<commit_before>trait Good {
    fn name(&self) -> String;
    fn manufacturer(&self) -> String;
}

trait Drink : Good {
    fn flavor(&self) -> String;
}

trait Snack : Good {
    fn snack_type(&self) -> String;
}

struct Chocolate {
    _name: String,
    _manufacturer: String
}

impl Good for Chocolate {
    fn name(&self) -> String {
        return format!("{} {}", self._manufacturer, self._name);
    }
    fn manufacturer(&self) -> String {
        return format!("{}", self._manufacturer);
    }
}

impl Snack for Chocolate {
    fn snack_type(&self) -> String {
        return String::from("Chocolate");
    }
}

impl Good for Chips {
    fn
}

fn main() {
    let lindt = Chocolate {
        _name: String::from("Milk"),
        _manufacturer: String::from("Lindt")
    };

    println!("{}: {}", lindt.snack_type(), lindt.name());
}
<commit_msg>Playing with Rust's OOP, part 2.<commit_after>trait Good {
    fn name(&self) -> String;
    fn manufacturer(&self) -> String;
}

trait Drink : Good {
    fn flavour(&self) -> String;
}

trait Snack : Good {
    fn snack_type(&self) -> String;
}

/* Chocolate */

struct Chocolate {
    name: String,
    manufacturer: String
}

impl Good for Chocolate {
    fn name(&self) -> String {
        return format!("{} {}", self.manufacturer, self.name);
    }
    fn manufacturer(&self) -> String {
        return format!("{}", self.manufacturer);
    }
}

impl Snack for Chocolate {
    fn snack_type(&self) -> String {
        return String::from("Chocolate");
    }
}

/* Crisps */

struct Crisps {
    manufacturer: String,
    flavour: String
}

impl Good for Crisps {
    fn name(&self) -> String {
        return format!("{} — {} flavour", self.manufacturer, self.flavour);
    }
    fn manufacturer(&self) -> String {
        return format!("{}", self.manufacturer);
    }
}

impl Snack for Crisps {
    fn snack_type(&self) -> String {
        return String::from("Crisps");
    }
}

/* Coke */

struct Coke {
    manufacturer: String,
    name: String
}

impl Good for Coke {
    fn name(&self) -> String {
        return format!("{}", self.name);
    }
    fn manufacturer(&self) -> String {
        return format!("{}", self.manufacturer);
    }
}

impl Drink for Coke {
    fn flavour(&self) -> String { return String::from("Coke") }
}

/* Main */

fn main() {
    let lindt = Chocolate {
        name: String::from("Milk"),
        manufacturer: String::from("Lindt")
    };
    let lays_salt = Crisps {
        manufacturer: String::from("Lays"),
        flavour: String::from("Salt")
    };

    println!("{}: {}", lindt.snack_type(), lindt.name());
    println!("{}", lays_salt.name());
}
<|endoftext|>