<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Andres Vahter (andres.vahter@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

// import local modules
extern crate doppler;
use doppler::predict;
use doppler::tle;
use doppler::usage;
use doppler::usage::Mode::{ConstMode, TrackMode};
use doppler::usage::InputType::{I16, F32};
use doppler::dsp;

// import external modules
use std::thread;
use std::process::exit;
use std::io;
use std::io::Read;
use std::io::Write;

extern crate time;

const SPEED_OF_LIGHT_M_S: f64 = 299792458.;
const BUFFER_SIZE: usize = 8192;

macro_rules! println_stderr(
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
);

fn main() {
    let args = usage::args();

    println_stderr!("doppler {} andres.vahter@gmail.com\n\n", env!("CARGO_PKG_VERSION"));

    let mut stdin = io::stdin();
    let mut stdout = io::stdout();
    let mut inbuf: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
    let mut outbuf: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
    let mut samplenr: u32 = 0;

    let mut shift = |intype: doppler::usage::InputType, shift_hz: f64, samplerate: u32| {
        let mut count_and_buflen: (usize, usize) = (0, 0);
        match stdin.read(&mut inbuf) {
            Ok(size) => {
                match intype {
                    I16 => {
                        count_and_buflen = dsp::shift_frequency_i16(&inbuf[0 .. size],
                                                    &mut samplenr,
                                                    shift_hz,
                                                    samplerate,
                                                    &mut outbuf);
                    },

                    F32 => {
                        count_and_buflen = dsp::shift_frequency_f32(&inbuf[0 .. size],
                                                    &mut samplenr,
                                                    shift_hz,
                                                    samplerate,
                                                    &mut outbuf);
                    },
                }

                let sample_count = count_and_buflen.0;
                let buflen = count_and_buflen.1;

                stdout.write(&outbuf[0 .. buflen]).unwrap();

                if size < BUFFER_SIZE {
                    return (true, sample_count);
                }
            }
            Err(e) => {
                println_stderr!("err: {:?}", e);
                return (true, 0);
            }
        }
        return (false, count_and_buflen.0);
    };

    match *args.mode.as_ref().unwrap() {
        ConstMode => {
            println_stderr!("constant shift mode");
            println_stderr!("\tIQ samplerate   : {}", args.samplerate.as_ref().unwrap());
            println_stderr!("\tIQ input type   : {}", args.inputtype.as_ref().unwrap());
            println_stderr!("\tIQ output type  : i16\n");
            println_stderr!("\tfrequency shift : {} Hz", args.constargs.shift.as_ref().unwrap());

            let intype = args.inputtype.unwrap();
            let shift_hz = args.constargs.shift.unwrap() as f64;
            let samplerate = args.samplerate.unwrap();

            loop {
                let stop_and_count: (bool, usize) = shift(intype, shift_hz, samplerate);
                if stop_and_count.0 {
                    break;
                }
            }
        }

        TrackMode => {
            println_stderr!("tracking mode");
            println_stderr!("\tIQ samplerate   : {}", args.samplerate.as_ref().unwrap());
            println_stderr!("\tIQ input type   : {}", args.inputtype.as_ref().unwrap());
            println_stderr!("\tIQ output type  : i16\n");
            println_stderr!("\tTLE file        : {}", args.trackargs.tlefile.as_ref().unwrap());
            println_stderr!("\tTLE name        : {}", args.trackargs.tlename.as_ref().unwrap());
            println_stderr!("\tlocation        : {:?}", args.trackargs.location.as_ref().unwrap());
            if args.trackargs.time.is_some() {
                println_stderr!("\ttime            : {:.3}", args.trackargs.time.unwrap().to_utc().rfc3339());
            }
            println_stderr!("\tfrequency       : {} Hz", args.trackargs.frequency.as_ref().unwrap());
            println_stderr!("\toffset          : {} Hz\n\n\n", args.trackargs.offset.unwrap_or(0));

            let l = args.trackargs.location.unwrap();
            let location: predict::Location = predict::Location{lat_deg: l.lat, lon_deg: l.lon, alt_m: l.alt};
            let tlename = args.trackargs.tlename.as_ref().unwrap();
            let tlefile = args.trackargs.tlefile.as_ref().unwrap();

            let tle = match tle::create_tle_from_file(&tlename, &tlefile) {
                Ok(t) => {t},
                Err(e) => {
                    println_stderr!("{}", e);
                    exit(1);
                }
            };

            let mut predict: predict::Predict = predict::Predict::new(tle, location);
            let intype = args.inputtype.unwrap();

            let samplerate = args.samplerate.unwrap();
            let mut last_time: time::Tm = time::now_utc();

            if args.trackargs.time.is_some() {

                let mut sample_count = 0;
                let start_time: time::Tm = args.trackargs.time.unwrap();
                let mut dt = time::Duration::seconds(0);
                last_time = start_time;

                loop {
                    predict.update(Some(start_time + dt));
                    let doppler_hz = (predict.sat.range_rate_km_sec * 1000 as f64 / SPEED_OF_LIGHT_M_S as f64) * args.trackargs.frequency.unwrap() as f64 * (-1.0);

                    // advance time based on how many samples are read in
                    dt = time::Duration::seconds((sample_count as f32 / samplerate as f32) as i64);
                    if start_time + dt - last_time >= time::Duration::seconds(5) {
                        last_time = start_time + dt;
                        println_stderr!("time                : {:}", (start_time + dt).to_utc().rfc3339());
                        println_stderr!("az                  : {:.2}°", predict.sat.az_deg);
                        println_stderr!("el                  : {:.2}°", predict.sat.el_deg);
                        println_stderr!("range               : {:.0} km", predict.sat.range_km);
                        println_stderr!("range rate          : {:.3} km/sec", predict.sat.range_rate_km_sec);
                        println_stderr!("doppler@{:.3} MHz : {:.2} Hz\n", args.trackargs.frequency.unwrap() as f64 / 1000_000_f64, doppler_hz);
                    }

                    let (stop, count): (bool, usize) = shift(intype, doppler_hz, samplerate);
                    if stop {
                        break;
                    }
                    //sample_count += count;
                    sample_count += 8120;
                }
            }
            else {
                loop {
                    predict.update(None);
                    let doppler_hz = (predict.sat.range_rate_km_sec * 1000 as f64 / SPEED_OF_LIGHT_M_S as f64) * args.trackargs.frequency.unwrap() as f64 * (-1.0);

                    if time::now_utc() - last_time >= time::Duration::seconds(1) {
                        last_time = time::now_utc();
                        println_stderr!("time                : {:}", time::now_utc().to_utc().rfc3339());
                        println_stderr!("az                  : {:.2}°", predict.sat.az_deg);
                        println_stderr!("el                  : {:.2}°", predict.sat.el_deg);
                        println_stderr!("range               : {:.0} km", predict.sat.range_km);
                        println_stderr!("range rate          : {:.3} km/sec", predict.sat.range_rate_km_sec);
                        println_stderr!("doppler@{:.3} MHz : {:.2} Hz\n", args.trackargs.frequency.unwrap() as f64 / 1000_000_f64, doppler_hz);
                    }

                    let (stop, count): (bool, usize) = shift(intype, doppler_hz, samplerate);
                    if stop {
                        break;
                    }
                    //thread::sleep_ms(1000);
                }
            }
        }
    }
}
<commit_msg>replace if with match, fix sample_count increment<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Andres Vahter (andres.vahter@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

// import local modules
extern crate doppler;
use doppler::predict;
use doppler::tle;
use doppler::usage;
use doppler::usage::Mode::{ConstMode, TrackMode};
use doppler::usage::InputType::{I16, F32};
use doppler::dsp;

// import external modules
use std::process::exit;
use std::io;
use std::io::Read;
use std::io::Write;

extern crate time;

const SPEED_OF_LIGHT_M_S: f64 = 299792458.;
const BUFFER_SIZE: usize = 8192;

macro_rules! println_stderr(
    ($($arg:tt)*) => (
        match writeln!(&mut ::std::io::stderr(), $($arg)* ) {
            Ok(_) => {},
            Err(x) => panic!("Unable to write to stderr: {}", x),
        }
    )
);

fn main() {
    let args = usage::args();

    println_stderr!("doppler {} andres.vahter@gmail.com\n\n", env!("CARGO_PKG_VERSION"));

    let mut stdin = io::stdin();
    let mut stdout = io::stdout();
    let mut inbuf: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
    let mut outbuf: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE];
    let mut samplenr: u32 = 0;

    let mut shift = |intype: doppler::usage::InputType, shift_hz: f64, samplerate: u32| {
        let mut count_and_buflen: (usize, usize) = (0, 0);
        match stdin.read(&mut inbuf) {
            Ok(size) => {
                match intype {
                    I16 => {
                        count_and_buflen = dsp::shift_frequency_i16(&inbuf[0 .. size],
                                                    &mut samplenr,
                                                    shift_hz,
                                                    samplerate,
                                                    &mut outbuf);
                    },

                    F32 => {
                        count_and_buflen = dsp::shift_frequency_f32(&inbuf[0 .. size],
                                                    &mut samplenr,
                                                    shift_hz,
                                                    samplerate,
                                                    &mut outbuf);
                    },
                }

                let sample_count = count_and_buflen.0;
                let buflen = count_and_buflen.1;

                stdout.write(&outbuf[0 .. buflen]).unwrap();

                if size < BUFFER_SIZE {
                    return (true, sample_count);
                }
            }
            Err(e) => {
                println_stderr!("err: {:?}", e);
                return (true, 0);
            }
        }
        return (false, count_and_buflen.0);
    };

    match *args.mode.as_ref().unwrap() {
        ConstMode => {
            println_stderr!("constant shift mode");
            println_stderr!("\tIQ samplerate   : {}", args.samplerate.as_ref().unwrap());
            println_stderr!("\tIQ input type   : {}", args.inputtype.as_ref().unwrap());
            println_stderr!("\tIQ output type  : i16\n");
            println_stderr!("\tfrequency shift : {} Hz", args.constargs.shift.as_ref().unwrap());

            let intype = args.inputtype.unwrap();
            let shift_hz = args.constargs.shift.unwrap() as f64;
            let samplerate = args.samplerate.unwrap();

            loop {
                let stop_and_count: (bool, usize) = shift(intype, shift_hz, samplerate);
                if stop_and_count.0 {
                    break;
                }
            }
        }

        TrackMode => {
            println_stderr!("tracking mode");
            println_stderr!("\tIQ samplerate   : {}", args.samplerate.as_ref().unwrap());
            println_stderr!("\tIQ input type   : {}", args.inputtype.as_ref().unwrap());
            println_stderr!("\tIQ output type  : i16\n");
            println_stderr!("\tTLE file        : {}", args.trackargs.tlefile.as_ref().unwrap());
            println_stderr!("\tTLE name        : {}", args.trackargs.tlename.as_ref().unwrap());
            println_stderr!("\tlocation        : {:?}", args.trackargs.location.as_ref().unwrap());
            if args.trackargs.time.is_some() {
                println_stderr!("\ttime            : {:.3}", args.trackargs.time.unwrap().to_utc().rfc3339());
            }
            println_stderr!("\tfrequency       : {} Hz", args.trackargs.frequency.as_ref().unwrap());
            println_stderr!("\toffset          : {} Hz\n\n\n", args.trackargs.offset.unwrap_or(0));

            let l = args.trackargs.location.unwrap();
            let location: predict::Location = predict::Location{lat_deg: l.lat, lon_deg: l.lon, alt_m: l.alt};
            let tlename = args.trackargs.tlename.as_ref().unwrap();
            let tlefile = args.trackargs.tlefile.as_ref().unwrap();

            let tle = match tle::create_tle_from_file(&tlename, &tlefile) {
                Ok(t) => {t},
                Err(e) => {
                    println_stderr!("{}", e);
                    exit(1);
                }
            };

            let mut predict: predict::Predict = predict::Predict::new(tle, location);
            let intype = args.inputtype.unwrap();

            let samplerate = args.samplerate.unwrap();
            let mut last_time: time::Tm = time::now_utc();

            match args.trackargs.time {
                Some(start_time) => {
                    let mut sample_count = 0;
                    let mut dt = time::Duration::seconds(0);
                    last_time = start_time;

                    loop {
                        predict.update(Some(start_time + dt));
                        let doppler_hz = (predict.sat.range_rate_km_sec * 1000 as f64 / SPEED_OF_LIGHT_M_S as f64) * args.trackargs.frequency.unwrap() as f64 * (-1.0);

                        // advance time based on how many samples are read in
                        dt = time::Duration::seconds((sample_count as f32 / samplerate as f32) as i64);
                        if start_time + dt - last_time >= time::Duration::seconds(5) {
                            last_time = start_time + dt;
                            println_stderr!("time                : {:}", (start_time + dt).to_utc().rfc3339());
                            println_stderr!("az                  : {:.2}°", predict.sat.az_deg);
                            println_stderr!("el                  : {:.2}°", predict.sat.el_deg);
                            println_stderr!("range               : {:.0} km", predict.sat.range_km);
                            println_stderr!("range rate          : {:.3} km/sec", predict.sat.range_rate_km_sec);
                            println_stderr!("doppler@{:.3} MHz : {:.2} Hz\n", args.trackargs.frequency.unwrap() as f64 / 1000_000_f64, doppler_hz);
                        }

                        let (stop, count): (bool, usize) = shift(intype, doppler_hz, samplerate);
                        if stop {
                            break;
                        }

                        sample_count += count;
                    }
                }

                None => {
                    loop {
                        predict.update(None);
                        let doppler_hz = (predict.sat.range_rate_km_sec * 1000 as f64 / SPEED_OF_LIGHT_M_S as f64) * args.trackargs.frequency.unwrap() as f64 * (-1.0);

                        if time::now_utc() - last_time >= time::Duration::seconds(1) {
                            last_time = time::now_utc();
                            println_stderr!("time                : {:}", time::now_utc().to_utc().rfc3339());
                            println_stderr!("az                  : {:.2}°", predict.sat.az_deg);
                            println_stderr!("el                  : {:.2}°", predict.sat.el_deg);
                            println_stderr!("range               : {:.0} km", predict.sat.range_km);
                            println_stderr!("range rate          : {:.3} km/sec", predict.sat.range_rate_km_sec);
                            println_stderr!("doppler@{:.3} MHz : {:.2} Hz\n", args.trackargs.frequency.unwrap() as f64 / 1000_000_f64, doppler_hz);
                        }

                        let (stop, count): (bool, usize) = shift(intype, doppler_hz, samplerate);
                        if stop {
                            break;
                        }
                    }
                }
            };
        }
    }
}
<|endoftext|>


<commit_before>/// from: https://raw.githubusercontent.com/chriskrycho/newrustacean.com/master/src/e002.rs

/// This struct is simple but useful to see how borrowing and moving work.
#[derive(Debug)]
pub struct Circle {
    /// X position of the circle's origin.
    pub x: f64,
    /// Y position of the circle's origin
    pub y: f64,
    /// Radius of the circle
    pub r: f64,

    pub w: Boxx,
}

#[derive(Debug)]
pub struct Boxx {
    pub x: f64,
    pub y: f64,
}

//const nil:Circle= Circle{x:1,y:2,r:3,w:nul};
//const nul:Circle= Circle{x:1,y:2,r:3,w:nil};

impl Drop for Circle {
    fn drop(&mut self) {
        println!("Dropping! {:?}",self);
    }
}

impl Circle {
    /// Creates a `Circle` instance centered on the "origin" (x = 0, y = 0).
    fn origin() -> Circle {
        Circle {
            x: 1.2,
            y: 3.4,
            r: 5.6,
            w: Boxx{x:1.0, y:2.0},
        }
    }

    pub fn by_borrow_x(&self) -> &f64 {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        &self.x
    }

/*    pub fn by_take(self) -> Boxx {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        self.w  //it is moved out... unless defined the trait Drop on the type Circle!
    }*/

    pub fn by_take2(self) -> f64 {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        self.x //it is "moved?" out... and works even if Drop is defined on type Circle! (unlike for self.w)
            //ok, it is copied I guess, since self.x such a simple type
    }

    pub fn by_borrow(&self) -> &Boxx {
        println!("borrowing box");
        &self.w
    }
}

fn main() {
    // Constructors can have default behavior, like this one.
    let immutable = Circle::origin();

    {
        let b = immutable.by_borrow();
        println!("showing borrowed box: {:?}", b);
    }
    {
        let x = immutable.by_borrow_x();
        println!("showing borrowed x: {:?}", x);
    }
//    let y= immutable.by_take2();
    let by_take_box = immutable.by_take2();//TODO: what happened with y,z? or even x? they got destroyed? so the return is a copy/clone then? since self.w is returned! ok, so i'm assuming since the box is moved out, the others are just destroyed; but how is the box moved out? memmove?
    println!("By take: {:?}", by_take_box);
    //println!("Does the circle still exist? {:?}", immutable);//no
}

<commit_msg>commit this dangling note<commit_after>/// from: https://raw.githubusercontent.com/chriskrycho/newrustacean.com/master/src/e002.rs

/// This struct is simple but useful to see how borrowing and moving work.
#[derive(Debug)]
pub struct Circle {
    /// X position of the circle's origin.
    pub x: f64,
    /// Y position of the circle's origin
    pub y: f64,
    /// Radius of the circle
    pub r: f64,

    pub w: Boxx,
}

#[derive(Debug)]
pub struct Boxx {
    pub x: f64,
    pub y: f64,
}

//const nil:Circle= Circle{x:1,y:2,r:3,w:nul};
//const nul:Circle= Circle{x:1,y:2,r:3,w:nil};

impl Drop for Circle {
    fn drop(&mut self) {
        println!("Dropping! {:?}",self);
    }
}

impl Circle {
    /// Creates a `Circle` instance centered on the "origin" (x = 0, y = 0).
    fn origin() -> Circle {
        Circle {
            x: 1.2,
            y: 3.4,
            r: 5.6,
            w: Boxx{x:1.0, y:2.0},
        }
    }

    pub fn by_borrow_x(&self) -> &f64 {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        &self.x
    }

/*    pub fn by_take(self) -> Boxx {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        self.w  //it is moved out... unless defined the trait Drop on the type Circle!
    }*/

    pub fn by_take2(self) -> f64 {
        println!("Taking ownership, not just borrowing a reference. INTENSE.");
        self.x //it is "moved?" out... and works even if Drop is defined on type Circle! (unlike for self.w)
            //ok, it is copied I guess, since self.x such a simple type
    }

    pub fn by_borrow(&self) -> &Boxx {
        println!("borrowing box");
        &self.w
    }
}

fn main() {
    // Constructors can have default behavior, like this one.
    let immutable = Circle::origin();

    {
        let b = immutable.by_borrow();
        println!("showing borrowed box: {:?}", b);
    }
    {
        let x = immutable.by_borrow_x();
        println!("showing borrowed x: {:?}", x);
    }
//    let y= immutable.by_take2();
    let by_take_box = immutable.by_take2();//TODO: what happened with y,z? or even x? they got destroyed? so the return is a copy/clone then? since self.w is returned! ok, so i'm assuming since the box is moved out, the others are just destroyed; but how is the box moved out? memmove? - ok, so, the value returned(self.x) seems to be copied! because when it's a Boxx then this won't be allowed with Drop impl. too!
    println!("By take: {:?}", by_take_box);
    //println!("Does the circle still exist? {:?}", immutable);//no
}

<|endoftext|>


<commit_before>// Copyright 2017 Google Inc.
//
// 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.

extern crate cmake;

use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;

fn git_submodule_update(dir: &PathBuf) {
    let status = Command::new("git")
        .args(&["submodule", "update", "--init"])
        .current_dir(dir)
        .status()
        .expect("cannot execute git submodule");
    if !status.success() {
        panic!("git submodule update --init failed")
    }
}

fn build_shaderc(shaderc_dir: &PathBuf) -> PathBuf {
        cmake::Config::new(shaderc_dir)
            .profile("Release")
            .define("CMAKE_POSITION_INDEPENDENT_CODE", "ON")
            .define("SPIRV_SKIP_EXECUTABLES", "ON")
            .define("SHADERC_SKIP_TESTS", "ON")
            .build()
}

fn build_shaderc_msvc(shaderc_dir: &PathBuf) -> PathBuf {
    cmake::Config::new(shaderc_dir)
            .profile("Release")
            .define("CMAKE_POSITION_INDEPENDENT_CODE", "ON")
            .define("SPIRV_SKIP_EXECUTABLES", "ON")
            .define("SHADERC_SKIP_TESTS", "ON")
            // cmake-rs tries to be clever on Windows by injecting several
            // C/C++ flags, which causes problems. So I have to manually
            // define CMAKE_*_FLAGS_* here to suppress that.
            .define("CMAKE_C_FLAGS", " /nologo /EHsc")
            .define("CMAKE_CXX_FLAGS", " /nologo /EHsc")
            .define("CMAKE_C_FLAGS_RELEASE", " /nologo /EHsc")
            .define("CMAKE_CXX_FLAGS_RELEASE", " /nologo /EHsc")
            .build()
}

fn main() {
    if env::var("CARGO_FEATURE_BUILD_NATIVE_SHADERC").is_err() {
        println!("cargo:warning=requested to skip building native C++ shaderc");
        return
    }

    let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
    let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();

    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let shaderc_dir = Path::new(&manifest_dir).join("build");

    git_submodule_update(&shaderc_dir);

    let mut lib_path = if target_env == "msvc" {
        build_shaderc_msvc(&shaderc_dir)
    } else {
        build_shaderc(&shaderc_dir)
    };

    lib_path.push("lib");

    println!("cargo:rustc-link-search=native={}", lib_path.display());
    if target_os == "windows" {
        println!("cargo:rustc-link-lib=static=shaderc_combined");
    } else {
        println!("cargo:rustc-link-lib=dylib=shaderc_shared");
    }
}
<commit_msg>Use manifest_dir as the cwd for git submodule update<commit_after>// Copyright 2017 Google Inc.
//
// 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.

extern crate cmake;

use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;

fn git_submodule_update<P: AsRef<Path>>(dir: P) {
    let status = Command::new("git")
        .args(&["submodule", "update", "--init"])
        .current_dir(dir)
        .status()
        .expect("cannot execute git submodule");
    if !status.success() {
        panic!("git submodule update --init failed")
    }
}

fn build_shaderc(shaderc_dir: &PathBuf) -> PathBuf {
        cmake::Config::new(shaderc_dir)
            .profile("Release")
            .define("CMAKE_POSITION_INDEPENDENT_CODE", "ON")
            .define("SPIRV_SKIP_EXECUTABLES", "ON")
            .define("SHADERC_SKIP_TESTS", "ON")
            .build()
}

fn build_shaderc_msvc(shaderc_dir: &PathBuf) -> PathBuf {
    cmake::Config::new(shaderc_dir)
            .profile("Release")
            .define("CMAKE_POSITION_INDEPENDENT_CODE", "ON")
            .define("SPIRV_SKIP_EXECUTABLES", "ON")
            .define("SHADERC_SKIP_TESTS", "ON")
            // cmake-rs tries to be clever on Windows by injecting several
            // C/C++ flags, which causes problems. So I have to manually
            // define CMAKE_*_FLAGS_* here to suppress that.
            .define("CMAKE_C_FLAGS", " /nologo /EHsc")
            .define("CMAKE_CXX_FLAGS", " /nologo /EHsc")
            .define("CMAKE_C_FLAGS_RELEASE", " /nologo /EHsc")
            .define("CMAKE_CXX_FLAGS_RELEASE", " /nologo /EHsc")
            .build()
}

fn main() {
    if env::var("CARGO_FEATURE_BUILD_NATIVE_SHADERC").is_err() {
        println!("cargo:warning=requested to skip building native C++ shaderc");
        return
    }

    let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
    let target_env = env::var("CARGO_CFG_TARGET_ENV").unwrap();

    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let shaderc_dir = Path::new(&manifest_dir).join("build");

    git_submodule_update(&manifest_dir);

    let mut lib_path = if target_env == "msvc" {
        build_shaderc_msvc(&shaderc_dir)
    } else {
        build_shaderc(&shaderc_dir)
    };

    lib_path.push("lib");

    println!("cargo:rustc-link-search=native={}", lib_path.display());
    if target_os == "windows" {
        println!("cargo:rustc-link-lib=static=shaderc_combined");
    } else {
        println!("cargo:rustc-link-lib=dylib=shaderc_shared");
    }
}
<|endoftext|>


<commit_before>use std::io::BufWriter;
use std::sync::Arc;

use futures::future::{ok};
use libcantal::{Json, Collection};
use self_meter_http::{ThreadReport, ProcessReport};
use serde_json;
use tk_http::Status;

use config::self_status::SelfStatus;
use incoming::{reply, Request, Input};
use metrics;

pub fn serve<S: 'static>(settings: &Arc<SelfStatus>, inp: Input)
    -> Request<S>
{
    let settings = settings.clone();
    let meter = inp.runtime.meter.clone();
    let fingerprint = inp.runtime.config.fingerprint();
    reply(inp, move |mut e| {

        #[derive(Serialize)]
        struct Response<'a> {
            process: ProcessReport<'a>,
            threads: ThreadReport<'a>,
            metrics: Json<'a, Vec<Box<Collection>>>,
            config_fingerprint: String,
        }

        e.status(Status::Ok);
        e.add_chunked();
        if !settings.overrides_content_type {
            e.add_header("Content-Type", "application/json");
        }
        e.add_extra_headers(&settings.extra_headers);
        if e.done_headers() {
            serde_json::to_writer(BufWriter::new(&mut e), &Response {
                process: meter.process_report(),
                threads: meter.thread_report(),
                metrics: Json(&metrics::all()),
                config_fingerprint: fingerprint,
            }).expect("report is serializable");
        }
        Box::new(ok(e.done()))
    })
}
<commit_msg>Show version in self-status<commit_after>use std::io::BufWriter;
use std::sync::Arc;

use futures::future::{ok};
use libcantal::{Json, Collection};
use self_meter_http::{ThreadReport, ProcessReport};
use serde_json;
use tk_http::Status;

use config::self_status::SelfStatus;
use incoming::{reply, Request, Input};
use metrics;

pub fn serve<S: 'static>(settings: &Arc<SelfStatus>, inp: Input)
    -> Request<S>
{
    let settings = settings.clone();
    let meter = inp.runtime.meter.clone();
    let fingerprint = inp.runtime.config.fingerprint();
    reply(inp, move |mut e| {

        #[derive(Serialize)]
        struct Response<'a> {
            process: ProcessReport<'a>,
            threads: ThreadReport<'a>,
            metrics: Json<'a, Vec<Box<Collection>>>,
            config_fingerprint: String,
            version: &'a str,
        }

        e.status(Status::Ok);
        e.add_chunked();
        if !settings.overrides_content_type {
            e.add_header("Content-Type", "application/json");
        }
        e.add_extra_headers(&settings.extra_headers);
        if e.done_headers() {
            serde_json::to_writer(BufWriter::new(&mut e), &Response {
                process: meter.process_report(),
                threads: meter.thread_report(),
                metrics: Json(&metrics::all()),
                config_fingerprint: fingerprint,
                version: env!("CARGO_PKG_VERSION"),
            }).expect("report is serializable");
        }
        Box::new(ok(e.done()))
    })
}
<|endoftext|>


<commit_before>use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_middle::ty::TyCtxt;
use rustc_trait_selection::traits::{self, SkipLeakCheck};

pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, crate_num: CrateNum) {
    assert_eq!(crate_num, LOCAL_CRATE);
    let krate = tcx.hir().krate();
    krate.visit_all_item_likes(&mut InherentOverlapChecker { tcx });
}

struct InherentOverlapChecker<'tcx> {
    tcx: TyCtxt<'tcx>,
}

impl InherentOverlapChecker<'tcx> {
    /// Checks whether any associated items in impls 1 and 2 share the same identifier and
    /// namespace.
    fn impls_have_common_items(&self, impl1: DefId, impl2: DefId) -> bool {
        let impl_items1 = self.tcx.associated_items(impl1);
        let impl_items2 = self.tcx.associated_items(impl2);

        let mut impl_items1 = &impl_items1;
        let mut impl_items2 = &impl_items2;

        // Performance optimization: iterate over the smaller list
        if impl_items1.len() > impl_items2.len() {
            std::mem::swap(&mut impl_items1, &mut impl_items2);
        }

        for item1 in impl_items1.in_definition_order() {
            let collision = impl_items2.filter_by_name_unhygienic(item1.ident.name).any(|item2| {
                // Symbols and namespace match, compare hygienically.
                item1.kind.namespace() == item2.kind.namespace()
                    && item1.ident.normalize_to_macros_2_0()
                        == item2.ident.normalize_to_macros_2_0()
            });

            if collision {
                return true;
            }
        }

        false
    }

    fn check_for_common_items_in_impls(
        &self,
        impl1: DefId,
        impl2: DefId,
        overlap: traits::OverlapResult<'_>,
    ) {
        let impl_items1 = self.tcx.associated_items(impl1);
        let impl_items2 = self.tcx.associated_items(impl2);

        for item1 in impl_items1.in_definition_order() {
            let collision = impl_items2.filter_by_name_unhygienic(item1.ident.name).find(|item2| {
                // Symbols and namespace match, compare hygienically.
                item1.kind.namespace() == item2.kind.namespace()
                    && item1.ident.normalize_to_macros_2_0()
                        == item2.ident.normalize_to_macros_2_0()
            });

            if let Some(item2) = collision {
                let name = item1.ident.normalize_to_macros_2_0();
                let mut err = struct_span_err!(
                    self.tcx.sess,
                    self.tcx.span_of_impl(item1.def_id).unwrap(),
                    E0592,
                    "duplicate definitions with name `{}`",
                    name
                );
                err.span_label(
                    self.tcx.span_of_impl(item1.def_id).unwrap(),
                    format!("duplicate definitions for `{}`", name),
                );
                err.span_label(
                    self.tcx.span_of_impl(item2.def_id).unwrap(),
                    format!("other definition for `{}`", name),
                );

                for cause in &overlap.intercrate_ambiguity_causes {
                    cause.add_intercrate_ambiguity_hint(&mut err);
                }

                if overlap.involves_placeholder {
                    traits::add_placeholder_note(&mut err);
                }

                err.emit();
            }
        }
    }

    fn check_for_overlapping_inherent_impls(&self, impl1_def_id: DefId, impl2_def_id: DefId) {
        traits::overlapping_impls(
            self.tcx,
            impl1_def_id,
            impl2_def_id,
            // We go ahead and just skip the leak check for
            // inherent impls without warning.
            SkipLeakCheck::Yes,
            |overlap| {
                self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
                false
            },
            || true,
        );
    }
}

impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
    fn visit_item(&mut self, item: &'v hir::Item<'v>) {
        match item.kind {
            hir::ItemKind::Enum(..)
            | hir::ItemKind::Struct(..)
            | hir::ItemKind::Trait(..)
            | hir::ItemKind::Union(..) => {
                let ty_def_id = self.tcx.hir().local_def_id(item.hir_id);
                let impls = self.tcx.inherent_impls(ty_def_id);

                for (i, &impl1_def_id) in impls.iter().enumerate() {
                    for &impl2_def_id in &impls[(i + 1)..] {
                        if self.impls_have_common_items(impl1_def_id, impl2_def_id) {
                            self.check_for_overlapping_inherent_impls(impl1_def_id, impl2_def_id);
                        }
                    }
                }
            }
            _ => {}
        }
    }

    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'v>) {}

    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'v>) {}
}
<commit_msg>Precompute the associated items<commit_after>use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_middle::ty::{self, TyCtxt};
use rustc_trait_selection::traits::{self, SkipLeakCheck};
use smallvec::SmallVec;

pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, crate_num: CrateNum) {
    assert_eq!(crate_num, LOCAL_CRATE);
    let krate = tcx.hir().krate();
    krate.visit_all_item_likes(&mut InherentOverlapChecker { tcx });
}

struct InherentOverlapChecker<'tcx> {
    tcx: TyCtxt<'tcx>,
}

impl InherentOverlapChecker<'tcx> {
    /// Checks whether any associated items in impls 1 and 2 share the same identifier and
    /// namespace.
    fn impls_have_common_items(
        &self,
        impl_items1: &ty::AssociatedItems<'_>,
        impl_items2: &ty::AssociatedItems<'_>,
    ) -> bool {
        let mut impl_items1 = &impl_items1;
        let mut impl_items2 = &impl_items2;

        // Performance optimization: iterate over the smaller list
        if impl_items1.len() > impl_items2.len() {
            std::mem::swap(&mut impl_items1, &mut impl_items2);
        }

        for item1 in impl_items1.in_definition_order() {
            let collision = impl_items2.filter_by_name_unhygienic(item1.ident.name).any(|item2| {
                // Symbols and namespace match, compare hygienically.
                item1.kind.namespace() == item2.kind.namespace()
                    && item1.ident.normalize_to_macros_2_0()
                        == item2.ident.normalize_to_macros_2_0()
            });

            if collision {
                return true;
            }
        }

        false
    }

    fn check_for_common_items_in_impls(
        &self,
        impl1: DefId,
        impl2: DefId,
        overlap: traits::OverlapResult<'_>,
    ) {
        let impl_items1 = self.tcx.associated_items(impl1);
        let impl_items2 = self.tcx.associated_items(impl2);

        for item1 in impl_items1.in_definition_order() {
            let collision = impl_items2.filter_by_name_unhygienic(item1.ident.name).find(|item2| {
                // Symbols and namespace match, compare hygienically.
                item1.kind.namespace() == item2.kind.namespace()
                    && item1.ident.normalize_to_macros_2_0()
                        == item2.ident.normalize_to_macros_2_0()
            });

            if let Some(item2) = collision {
                let name = item1.ident.normalize_to_macros_2_0();
                let mut err = struct_span_err!(
                    self.tcx.sess,
                    self.tcx.span_of_impl(item1.def_id).unwrap(),
                    E0592,
                    "duplicate definitions with name `{}`",
                    name
                );
                err.span_label(
                    self.tcx.span_of_impl(item1.def_id).unwrap(),
                    format!("duplicate definitions for `{}`", name),
                );
                err.span_label(
                    self.tcx.span_of_impl(item2.def_id).unwrap(),
                    format!("other definition for `{}`", name),
                );

                for cause in &overlap.intercrate_ambiguity_causes {
                    cause.add_intercrate_ambiguity_hint(&mut err);
                }

                if overlap.involves_placeholder {
                    traits::add_placeholder_note(&mut err);
                }

                err.emit();
            }
        }
    }

    fn check_for_overlapping_inherent_impls(&self, impl1_def_id: DefId, impl2_def_id: DefId) {
        traits::overlapping_impls(
            self.tcx,
            impl1_def_id,
            impl2_def_id,
            // We go ahead and just skip the leak check for
            // inherent impls without warning.
            SkipLeakCheck::Yes,
            |overlap| {
                self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
                false
            },
            || true,
        );
    }
}

impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
    fn visit_item(&mut self, item: &'v hir::Item<'v>) {
        match item.kind {
            hir::ItemKind::Enum(..)
            | hir::ItemKind::Struct(..)
            | hir::ItemKind::Trait(..)
            | hir::ItemKind::Union(..) => {
                let ty_def_id = self.tcx.hir().local_def_id(item.hir_id);
                let impls = self.tcx.inherent_impls(ty_def_id);

                // If there is only one inherent impl block,
                // there is nothing to overlap check it with
                if impls.len() <= 1 {
                    return;
                }

                let impls_items = impls
                    .iter()
                    .map(|impl_def_id| (impl_def_id, self.tcx.associated_items(*impl_def_id)))
                    .collect::<SmallVec<[_; 8]>>();

                for (i, &(&impl1_def_id, impl_items1)) in impls_items.iter().enumerate() {
                    for &(&impl2_def_id, impl_items2) in &impls_items[(i + 1)..] {
                        if self.impls_have_common_items(impl_items1, impl_items2) {
                            self.check_for_overlapping_inherent_impls(impl1_def_id, impl2_def_id);
                        }
                    }
                }
            }
            _ => {}
        }
    }

    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'v>) {}

    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'v>) {}
}
<|endoftext|>


<commit_before>pub pure fn Prime() -> Prime {
    Prime { vec: ~[] }
}

pub struct Prime {
    priv mut vec: ~[uint],
}

impl Prime {
    priv pure fn is_coprime(num: uint) -> bool {
        for uint::range(0, self.vec.len()) |i| {
            let p = self.vec[i];
            if p * p > num  { return true; }
            if num % p == 0 { return false; }
        }
        return true;
    }

    priv fn grow_until(cond: fn() -> bool) {
        if cond() { return }

        let mut num = match vec::last_opt(self.vec) {
          None    => { self.vec =  ~[2]; return self.grow_until(cond); }
          Some(2) => { self.vec += ~[3]; return self.grow_until(cond); }
          Some(x) => { x + 2 }
        };

        while !cond() {
            if self.is_coprime(num) {
                self.vec += ~[num];
            }
            num += 2;
        }
    }

    fn get_at(idx: uint) -> uint {
        self.grow_until(|| idx < self.vec.len());
        return self.vec[idx];
    }

    fn is_prime(num: uint) -> bool {
        if num < 2 { return false; }

        for self.each |p| {
            if p * p > num  { return true;  }
            if num % p == 0 { return false; }
        }
        util::unreachable();
    }

    fn each(f: fn(uint) -> bool) {
        let init_len = self.vec.len();
        for uint::range(0, init_len) |i| {
            let p = self.vec[i];
            if !f(p) { return; }
        }

        let mut idx = init_len;
        loop {
            if !f(self.get_at(idx)) { return; }
            idx += 1;
        }
    }
}

priv fn div_multi(&num: uint, f: uint) -> uint {
    let mut exp = 0;
    while (num % f == 0) {
        exp += 1;
        num /= f;
    }
    return exp;
}

pub fn factors(num: uint, primes: &Prime, f: fn((uint, uint)) -> bool) {
    if num == 0 { return; }
    let mut itr = num;
    for primes.each |p| {
        let exp = div_multi(itr, p);
        if exp > 0 {
            if !f((p, exp)) { break; }
        }
        if itr == 1  { break; }
    };
}

pub fn num_of_divisors(num: uint, primes: &Prime) -> uint {
    if num == 0 { return 0; }
    let mut prod = 1;
    for factors(num, primes) |f| {
        let (_base, exp) = f;
        prod *= exp + 1;
    }
    return prod;
}

pub fn sum_of_divisors(num: uint, primes: &Prime) -> uint {
    if num == 0 { return 0; }
    let mut sum = 1;
    for factors(num, primes) |f| {
        let (base, exp) = f;
        sum *= (int::pow(base as int, exp + 1) as uint - 1) / (base - 1);
    }
    return sum;
}

pub fn sum_of_proper_divisors(num: uint, primes: &Prime) -> uint {
    sum_of_divisors(num, primes) - num
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_prime_opidx () {
        let table  = [  2,  3,  5,  7, 11, 13, 17, 19, 23, 29, 31, 37, 41 ];
        let ps = Prime();

        // Generated primes
        for table.eachi() |i, p| { assert ps.get_at(i) == *p; }
        // Memoized primes
        for table.eachi() |i, p| { assert ps.get_at(i) == *p; }
    }

    #[test]
    fn test_prime_each() {
        let table  = ~[  2,  3,  5,  7, 11, 13, 17, 19, 23, 29, 31, 37, 41 ];
        let table2 = ~[ 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 ];
        let ps = Prime();

        let mut v1 = ~[];
        for ps.each |p| {
            if p > table.last() { break; }
            v1 += [ p ];
        }
        assert table == v1;

        let mut v2 = ~[];
        for ps.each |p| {
            if p > table.last() { break; }
            v2 += [ p ];
        }
        assert table == v2;

        let mut v3 = ~[];
        for ps.each |p| {
            if p > table2.last() { break; }
            v3 += [ p ];
        }
        assert table + table2 == v3;
    }

    #[test]
    fn test_prime_is_prime() {
        let p = Prime();
        assert !p.is_prime(0);
        assert !p.is_prime(1);
        assert p.is_prime(2);
        assert p.is_prime(3);
        assert !p.is_prime(4);
        assert p.is_prime(5);
        assert !p.is_prime(6);
        assert p.is_prime(7);
        assert !p.is_prime(100);
    }
}
<commit_msg>Fix: obsolete syntax: by-mutable-reference mode<commit_after>pub pure fn Prime() -> Prime {
    Prime { vec: ~[] }
}

pub struct Prime {
    priv mut vec: ~[uint],
}

impl Prime {
    priv pure fn is_coprime(num: uint) -> bool {
        for uint::range(0, self.vec.len()) |i| {
            let p = self.vec[i];
            if p * p > num  { return true; }
            if num % p == 0 { return false; }
        }
        return true;
    }

    priv fn grow_until(cond: fn() -> bool) {
        if cond() { return }

        let mut num = match vec::last_opt(self.vec) {
          None    => { self.vec =  ~[2]; return self.grow_until(cond); }
          Some(2) => { self.vec += ~[3]; return self.grow_until(cond); }
          Some(x) => { x + 2 }
        };

        while !cond() {
            if self.is_coprime(num) {
                self.vec += ~[num];
            }
            num += 2;
        }
    }

    fn get_at(idx: uint) -> uint {
        self.grow_until(|| idx < self.vec.len());
        return self.vec[idx];
    }

    fn is_prime(num: uint) -> bool {
        if num < 2 { return false; }

        for self.each |p| {
            if p * p > num  { return true;  }
            if num % p == 0 { return false; }
        }
        util::unreachable();
    }

    fn each(f: fn(uint) -> bool) {
        let init_len = self.vec.len();
        for uint::range(0, init_len) |i| {
            let p = self.vec[i];
            if !f(p) { return; }
        }

        let mut idx = init_len;
        loop {
            if !f(self.get_at(idx)) { return; }
            idx += 1;
        }
    }
}

priv fn div_multi(num: &mut uint, f: uint) -> uint {
    let mut exp = 0;
    while (*num % f == 0) {
        exp += 1;
        *num /= f;
    }
    return exp;
}

pub fn factors(num: uint, primes: &Prime, f: fn((uint, uint)) -> bool) {
    if num == 0 { return; }
    let mut itr = num;
    for primes.each |p| {
        let exp = div_multi(&mut itr, p);
        if exp > 0 {
            if !f((p, exp)) { break; }
        }
        if itr == 1  { break; }
    };
}

pub fn num_of_divisors(num: uint, primes: &Prime) -> uint {
    if num == 0 { return 0; }
    let mut prod = 1;
    for factors(num, primes) |f| {
        let (_base, exp) = f;
        prod *= exp + 1;
    }
    return prod;
}

pub fn sum_of_divisors(num: uint, primes: &Prime) -> uint {
    if num == 0 { return 0; }
    let mut sum = 1;
    for factors(num, primes) |f| {
        let (base, exp) = f;
        sum *= (int::pow(base as int, exp + 1) as uint - 1) / (base - 1);
    }
    return sum;
}

pub fn sum_of_proper_divisors(num: uint, primes: &Prime) -> uint {
    sum_of_divisors(num, primes) - num
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_prime_opidx () {
        let table  = [  2,  3,  5,  7, 11, 13, 17, 19, 23, 29, 31, 37, 41 ];
        let ps = Prime();

        // Generated primes
        for table.eachi() |i, p| { assert ps.get_at(i) == *p; }
        // Memoized primes
        for table.eachi() |i, p| { assert ps.get_at(i) == *p; }
    }

    #[test]
    fn test_prime_each() {
        let table  = ~[  2,  3,  5,  7, 11, 13, 17, 19, 23, 29, 31, 37, 41 ];
        let table2 = ~[ 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 ];
        let ps = Prime();

        let mut v1 = ~[];
        for ps.each |p| {
            if p > table.last() { break; }
            v1 += [ p ];
        }
        assert table == v1;

        let mut v2 = ~[];
        for ps.each |p| {
            if p > table.last() { break; }
            v2 += [ p ];
        }
        assert table == v2;

        let mut v3 = ~[];
        for ps.each |p| {
            if p > table2.last() { break; }
            v3 += [ p ];
        }
        assert table + table2 == v3;
    }

    #[test]
    fn test_prime_is_prime() {
        let p = Prime();
        assert !p.is_prime(0);
        assert !p.is_prime(1);
        assert p.is_prime(2);
        assert p.is_prime(3);
        assert !p.is_prime(4);
        assert p.is_prime(5);
        assert !p.is_prime(6);
        assert p.is_prime(7);
        assert !p.is_prime(100);
    }

    #[test]
    fn test_factors() {
        let p = Prime();
        for factors(1, &p) |f| {
            fail;
        }

        for factors(8, &p) |f| {
            assert f == (2, 3);
        }

        let mut v = ~[(2, 3), (3, 3)];
        for factors(8 * 27, &p) |f| {
            assert f == v.shift();
        }
    }
}
<|endoftext|>


<commit_before>use super::{Request, FromRequest};

macro_rules! reqwest_impl {
    { $C:ty, $B:ty } => {
        // By default reqwest won't allow us to build a request without a base URI, ie:
        //
        // https://a_host
        //
        impl<URI: ToString> FromRequest<(&$C, URI)> for $B {
            fn from_request(r: Request, params: (&$C, URI)) -> Self {
                use crate::version::USER_AGENT;

                let (uri, body) = r.parameters.uri_and_body(r.path);
                let (client, uri_base) = params;
                let uri = uri_base.to_string() + uri.as_ref();

                let rb = client.request(r.method, uri.as_str());
                let rb = rb.header("User-Agent", USER_AGENT);

                match body {
                    Some(body) => rb.body(body.to_owned()),
                    _ => rb
                }
            }
        }
    }
}

#[cfg(feature = "reqwest-async")]
reqwest_impl!(reqwest::r#async::Client, reqwest::r#async::RequestBuilder);
#[cfg(feature = "reqwest-sync")]
reqwest_impl!(reqwest::Client, reqwest::RequestBuilder);
<commit_msg>reqwest: add the request headers rather than some ad-hoc ones<commit_after>use super::{FromRequest, Request};

macro_rules! reqwest_impl {
    { $C:ty, $B:ty } => {
        // By default reqwest won't allow us to build a request without a base URI, ie:
        //
        // https://a_host
        //
        impl<URI: ToString> FromRequest<(&$C, URI)> for $B {
            fn from_request(r: Request, params: (&$C, URI)) -> Self {
                let (uri, body) = r.parameters.uri_and_body(r.path);
                let (client, uri_base) = params;
                let uri = uri_base.to_string() + uri.as_ref();

                let rb = client.request(r.method, uri.as_str()).headers(r.headers);

                match body {
                    Some(body) => rb.body(body.to_owned()),
                    _ => rb
                }
            }
        }
    }
}

#[cfg(feature = "reqwest-async")]
reqwest_impl!(reqwest::r#async::Client, reqwest::r#async::RequestBuilder);
#[cfg(feature = "reqwest-sync")]
reqwest_impl!(reqwest::Client, reqwest::RequestBuilder);
<|endoftext|>


<commit_before>// -*-  indent-tabs-mode:nil; tab-width:2;  -*-
extern crate tensorflow;

use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::result::Result;
use std::path::Path;
use std::process::exit;
use tensorflow::Code;
use tensorflow::DeprecatedSession;
use tensorflow::SessionOptions;
use tensorflow::Status;
use tensorflow::Step;
use tensorflow::Tensor;

fn main() {
  // Putting the main code in another function serves two purposes:
  // 1. We can use the try! macro.
  // 2. We can call exit safely, which does not run any destructors.
  exit(match run() {
    Ok(_) => 0,
    Err(e) => {
      println!("{}", e);
      1
    }
  })
}

fn run() -> Result<(), Box<Error>> {
  let filename = "examples/addition-model/model.pb"; // z = x + y
  if !Path::new(filename).exists() {
    return Err(Box::new(Status::new_set(Code::NotFound, &format!(
      "Run 'python addition.py' to generate {} and try again.", filename)).unwrap()));
  }

  // Create input variables for our addition
  let mut x = Tensor::new(&[1]);
  x[0] = 2i32;
  let mut y = Tensor::new(&[1]);
  y[0] = 40i32;

  // Load the computation graph defined by regression.py.
  let mut session = try!(DeprecatedSession::new(&SessionOptions::new()));
  let mut proto = Vec::new();
  try!(try!(File::open(filename)).read_to_end(&mut proto));
  try!(session.extend_graph(&proto));

  // Run the Step
  let mut step = Step::new();
  step.add_input("x", &x).unwrap();
  step.add_input("y", &y).unwrap();
  let z = try!(step.request_output("z"));
  try!(session.run(&mut step));

  // Check our results.
  let z_res: i32 = try!(step.take_output(z)).data()[0];
  println!("{:?}", z_res);

  Ok(())
}
<commit_msg>Switch addition example to new API<commit_after>// -*-  indent-tabs-mode:nil; tab-width:2;  -*-
extern crate tensorflow;

use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::result::Result;
use std::path::Path;
use std::process::exit;
use tensorflow::Buffer;
use tensorflow::Code;
use tensorflow::Graph;
use tensorflow::ImportGraphDefOptions;
use tensorflow::Session;
use tensorflow::SessionOptions;
use tensorflow::Status;
use tensorflow::StepWithGraph;
use tensorflow::Tensor;

fn main() {
  // Putting the main code in another function serves two purposes:
  // 1. We can use the try! macro.
  // 2. We can call exit safely, which does not run any destructors.
  exit(match run() {
    Ok(_) => 0,
    Err(e) => {
      println!("{}", e);
      1
    }
  })
}

fn run() -> Result<(), Box<Error>> {
  let filename = "examples/addition-model/model.pb"; // z = x + y
  if !Path::new(filename).exists() {
    return Err(Box::new(Status::new_set(Code::NotFound, &format!(
      "Run 'python addition.py' to generate {} and try again.", filename)).unwrap()));
  }

  // Create input variables for our addition
  let mut x = Tensor::new(&[1]);
  x[0] = 2i32;
  let mut y = Tensor::new(&[1]);
  y[0] = 40i32;

  // Load the computation graph defined by regression.py.
  let mut graph = Graph::new();
  let mut proto = Vec::new();
  try!(try!(File::open(filename)).read_to_end(&mut proto));
  graph.import_graph_def(Buffer::from(&proto), &ImportGraphDefOptions::new())?;
  let mut session = Session::new(&SessionOptions::new(), &graph)?;

  // Run the Step
  let mut step = StepWithGraph::new();
  step.add_input(&graph.operation_by_name_required("x")?, 0, &x);
  step.add_input(&graph.operation_by_name_required("y")?, 0, &y);
  let z = step.request_output(&graph.operation_by_name_required("z")?, 0);
  try!(session.run(&mut step));

  // Check our results.
  let z_res: i32 = try!(step.take_output(z)).data()[0];
  println!("{:?}", z_res);

  Ok(())
}
<|endoftext|>


<commit_before>extern crate llvm_sys as llvm;

use std::mem;

use llvm::core::*;
use llvm::execution_engine::*;
use llvm::target::*;

fn main() {
    unsafe {
        // Set up a context, module and builder in that context.
        let context = LLVMContextCreate();
        let module = LLVMModuleCreateWithName(b"sum\0".as_ptr() as *const _);
        let builder = LLVMCreateBuilderInContext(context);

        // get a type for sum function
        let i64t = LLVMInt64TypeInContext(context);
        let argts = [i64t, i64t, i64t];
        let function_type = LLVMFunctionType(
            i64t,
            mem::transmute(&argts[0]), // can't figure out how to make it *mut
            3,
            0);

        // add it to our module
        let function = LLVMAddFunction(
            module,
            b"sum\0".as_ptr() as *const _,
            function_type);

        // Create a basic block in the function and set our builder to generate
        // code in it.
        let bb = LLVMAppendBasicBlockInContext(
            context,
            function,
            b"entry\0".as_ptr() as *const _);

        LLVMPositionBuilderAtEnd(builder, bb);

        // get the functions arguments
        let x = LLVMGetParam(function, 0);
        let y = LLVMGetParam(function, 1);
        let z = LLVMGetParam(function, 2);

        let sum = LLVMBuildAdd(builder, x, y, b"sum.1\0".as_ptr() as *const _);
        let sum = LLVMBuildAdd(builder, sum, z, b"sum.2\0".as_ptr() as *const _);

        // Emit a `ret void` into the function
        LLVMBuildRet(builder, sum);

        // Dump the module as IR to stdout.
        LLVMDumpModule(module);

        // build an execution engine
        let mut ee = mem::uninitialized();
        let mut out = mem::zeroed();

        // who cares about error handing??
        LLVMLinkInMCJIT();
        LLVM_InitializeNativeTarget();
        LLVM_InitializeNativeAsmPrinter();
        LLVMCreateExecutionEngineForModule(&mut ee, module, &mut out);

        let addr = LLVMGetFunctionAddress(ee, b"sum\0".as_ptr() as *const _);

        let f: fn(u64, u64, u64) -> u64 = mem::transmute(addr);

        let x: u64 = 1;
        let y: u64 = 1;
        let z: u64 = 1;
        let res = f(x, y, z);

        println!("{} + {} + {} = {}", x, y, z, res);

        // Clean up. Values created in the context mostly get cleaned up there.
        LLVMDisposeExecutionEngine(ee);
        LLVMDisposeBuilder(builder);
        LLVMDisposeModule(module);
        LLVMContextDispose(context);
    }
}
<commit_msg>better cleanup code, more documentation comments<commit_after>extern crate llvm_sys as llvm;

use std::mem;

use llvm::core::*;
use llvm::execution_engine::*;
use llvm::target::*;

fn main() {
    unsafe {
        // Set up a context, module and builder in that context.
        let context = LLVMContextCreate();
        let module = LLVMModuleCreateWithName(b"sum\0".as_ptr() as *const _);
        let builder = LLVMCreateBuilderInContext(context);

        // get a type for sum function
        let i64t = LLVMInt64TypeInContext(context);
        let argts = [i64t, i64t, i64t];
        let function_type = LLVMFunctionType(
            i64t,
            mem::transmute(&argts[0]), // can't figure out how to make it *mut
            3,
            0);

        // add it to our module
        let function = LLVMAddFunction(
            module,
            b"sum\0".as_ptr() as *const _,
            function_type);

        // Create a basic block in the function and set our builder to generate
        // code in it.
        let bb = LLVMAppendBasicBlockInContext(
            context,
            function,
            b"entry\0".as_ptr() as *const _);

        LLVMPositionBuilderAtEnd(builder, bb);

        // get the function's arguments
        let x = LLVMGetParam(function, 0);
        let y = LLVMGetParam(function, 1);
        let z = LLVMGetParam(function, 2);

        let sum = LLVMBuildAdd(builder, x, y, b"sum.1\0".as_ptr() as *const _);
        let sum = LLVMBuildAdd(builder, sum, z, b"sum.2\0".as_ptr() as *const _);

        // Emit a `ret void` into the function
        LLVMBuildRet(builder, sum);

        // done building
        LLVMDisposeBuilder(builder);

        // Dump the module as IR to stdout.
        LLVMDumpModule(module);

        // build an execution engine
        let mut ee = mem::uninitialized();
        let mut out = mem::zeroed();

        // robust code should check that these calls complete successfully
        // each of these calls is necessary to setup an execution engine which compiles to native
        // code
        LLVMLinkInMCJIT();
        LLVM_InitializeNativeTarget();
        LLVM_InitializeNativeAsmPrinter();

        // takes ownership of the module
        LLVMCreateExecutionEngineForModule(&mut ee, module, &mut out);

        let addr = LLVMGetFunctionAddress(ee, b"sum\0".as_ptr() as *const _);

        let f: fn(u64, u64, u64) -> u64 = mem::transmute(addr);

        let x: u64 = 1;
        let y: u64 = 1;
        let z: u64 = 1;
        let res = f(x, y, z);

        println!("{} + {} + {} = {}", x, y, z, res);

        // Clean up the rest.
        LLVMDisposeExecutionEngine(ee);
        LLVMContextDispose(context);
    }
}
<|endoftext|>


<commit_before>// A port of the simplistic benchmark from
//
//    http://github.com/PaulKeeble/ScalaVErlangAgents
//
// I *think* it's the same, more or less.

#![crate_name = "msgsend"]

extern crate time;
extern crate zmq;

use std::env;
use std::thread;
use std::sync::mpsc::{channel, Sender, Receiver};

fn server(mut pull_socket: zmq::Socket, mut push_socket: zmq::Socket, mut workers: u64) {
    let mut count = 0;
    let mut msg = zmq::Message::new().unwrap();

    while workers != 0 {
        match pull_socket.recv(&mut msg, 0) {
            Err(e) => panic!(e),
            Ok(()) => {
                let s = msg.as_str().unwrap();
                if s.is_empty() {
                    workers -= 1;
                } else {
                    count += s.parse().unwrap();
                }
            }
        }
    }

    match push_socket.send_str(&count.to_string(), 0) {
        Ok(()) => { }
        Err(e) => panic!(e),
    }
}

fn spawn_server(ctx: &mut zmq::Context, workers: u64) -> Sender<()> {
    let mut pull_socket = ctx.socket(zmq::PULL).unwrap();
    let mut push_socket = ctx.socket(zmq::PUSH).unwrap();

    pull_socket.bind("inproc://server-pull").unwrap();
    push_socket.bind("inproc://server-push").unwrap();

    // Spawn the server.
    let (ready_tx, ready_rx) = channel();
    let (start_tx, start_rx) = channel();

    thread::spawn(move|| {
        // Let the main thread know we're ready.
        ready_tx.send(()).unwrap();

        // Wait until we need to start.
        start_rx.recv().unwrap();

        server(pull_socket, push_socket, workers);
    });

    // Wait for the server to start.
    ready_rx.recv().unwrap();

    start_tx
}

fn worker(mut push_socket: zmq::Socket, count: u64) {
    for _ in 0 .. count {
        push_socket.send_str(&100.to_string(), 0).unwrap();
    }

    // Let the server know we're done.
    push_socket.send_str("", 0).unwrap();
}

fn spawn_worker(ctx: &mut zmq::Context, count: u64) -> Receiver<()> {
    let mut push_socket = ctx.socket(zmq::PUSH).unwrap();

    push_socket.connect("inproc://server-pull").unwrap();
    //push_socket.connect("tcp://127.0.0.1:3456").unwrap();

    // Spawn the worker.
    let (tx, rx) = channel();
    thread::spawn(move|| {
        // Let the main thread we're ready.
        tx.send(()).unwrap();

        worker(push_socket, count);

        tx.send(()).unwrap();
    });

    // Wait for the worker to start.
    rx.recv().unwrap();

    rx
}

fn run(ctx: &mut zmq::Context, size: u64, workers: u64) {
    let start_ch = spawn_server(ctx, workers);

    // Create some command/control sockets.
    let mut push_socket = ctx.socket(zmq::PUSH).unwrap();
    let mut pull_socket = ctx.socket(zmq::PULL).unwrap();

    push_socket.connect("inproc://server-pull").unwrap();
    pull_socket.connect("inproc://server-push").unwrap();
    //push_socket.connect("tcp://127.0.0.1:3456").unwrap();
    //pull_socket.connect("tcp://127.0.0.1:3457").unwrap();

    // Spawn all the workers.
    let mut worker_results = Vec::new();
    for _ in 0 .. workers {
        worker_results.push(spawn_worker(ctx, size / workers));
    }

    let start = time::precise_time_s();

    start_ch.send(()).unwrap();

    // Block until all the workers finish.
    for po in worker_results {
        po.recv().unwrap();
    }

    // Receive the final count.
    let result: i32 = match pull_socket.recv_msg(0) {
        Ok(msg) => {
            let msg_str: &str = msg.as_str().unwrap();
            msg_str.parse().unwrap()
        },
        Err(e) => panic!(e),
    };

    let end = time::precise_time_s();
    let elapsed = end - start;

    println!("Count is {}", result);
    println!("Test took {} seconds", elapsed);
    let thruput = ((size / workers * workers) as f64) / elapsed;
    println!("Throughput={} per sec", thruput);
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let args = if env::var("RUST_BENCH").is_ok() {
        vec!("".to_string(), "1000000".to_string(), "10000".to_string())
    } else if args.len() <= 1 {
        vec!("".to_string(), "10000".to_string(), "4".to_string())
    } else {
        args
    };

    let size = args[1].parse().unwrap();
    let workers = args[2].parse().unwrap();

    let mut ctx = zmq::Context::new();

    run(&mut ctx, size, workers);
}
<commit_msg>examples/msgsend: help rust with type inference<commit_after>// A port of the simplistic benchmark from
//
//    http://github.com/PaulKeeble/ScalaVErlangAgents
//
// I *think* it's the same, more or less.

#![crate_name = "msgsend"]

extern crate time;
extern crate zmq;

use std::env;
use std::thread;
use std::sync::mpsc::{channel, Sender, Receiver};

fn server(mut pull_socket: zmq::Socket, mut push_socket: zmq::Socket, mut workers: u64) {
    let mut count = 0;
    let mut msg = zmq::Message::new().unwrap();

    while workers != 0 {
        match pull_socket.recv(&mut msg, 0) {
            Err(e) => panic!(e),
            Ok(()) => {
                let s = msg.as_str().unwrap();
                if s.is_empty() {
                    workers -= 1;
                } else {
                    count += s.parse::<u32>().unwrap();
                }
            }
        }
    }

    match push_socket.send_str(&count.to_string(), 0) {
        Ok(()) => { }
        Err(e) => panic!(e),
    }
}

fn spawn_server(ctx: &mut zmq::Context, workers: u64) -> Sender<()> {
    let mut pull_socket = ctx.socket(zmq::PULL).unwrap();
    let mut push_socket = ctx.socket(zmq::PUSH).unwrap();

    pull_socket.bind("inproc://server-pull").unwrap();
    push_socket.bind("inproc://server-push").unwrap();

    // Spawn the server.
    let (ready_tx, ready_rx) = channel();
    let (start_tx, start_rx) = channel();

    thread::spawn(move|| {
        // Let the main thread know we're ready.
        ready_tx.send(()).unwrap();

        // Wait until we need to start.
        start_rx.recv().unwrap();

        server(pull_socket, push_socket, workers);
    });

    // Wait for the server to start.
    ready_rx.recv().unwrap();

    start_tx
}

fn worker(mut push_socket: zmq::Socket, count: u64) {
    for _ in 0 .. count {
        push_socket.send_str(&100.to_string(), 0).unwrap();
    }

    // Let the server know we're done.
    push_socket.send_str("", 0).unwrap();
}

fn spawn_worker(ctx: &mut zmq::Context, count: u64) -> Receiver<()> {
    let mut push_socket = ctx.socket(zmq::PUSH).unwrap();

    push_socket.connect("inproc://server-pull").unwrap();
    //push_socket.connect("tcp://127.0.0.1:3456").unwrap();

    // Spawn the worker.
    let (tx, rx) = channel();
    thread::spawn(move|| {
        // Let the main thread we're ready.
        tx.send(()).unwrap();

        worker(push_socket, count);

        tx.send(()).unwrap();
    });

    // Wait for the worker to start.
    rx.recv().unwrap();

    rx
}

fn run(ctx: &mut zmq::Context, size: u64, workers: u64) {
    let start_ch = spawn_server(ctx, workers);

    // Create some command/control sockets.
    let mut push_socket = ctx.socket(zmq::PUSH).unwrap();
    let mut pull_socket = ctx.socket(zmq::PULL).unwrap();

    push_socket.connect("inproc://server-pull").unwrap();
    pull_socket.connect("inproc://server-push").unwrap();
    //push_socket.connect("tcp://127.0.0.1:3456").unwrap();
    //pull_socket.connect("tcp://127.0.0.1:3457").unwrap();

    // Spawn all the workers.
    let mut worker_results = Vec::new();
    for _ in 0 .. workers {
        worker_results.push(spawn_worker(ctx, size / workers));
    }

    let start = time::precise_time_s();

    start_ch.send(()).unwrap();

    // Block until all the workers finish.
    for po in worker_results {
        po.recv().unwrap();
    }

    // Receive the final count.
    let result: i32 = match pull_socket.recv_msg(0) {
        Ok(msg) => {
            let msg_str: &str = msg.as_str().unwrap();
            msg_str.parse().unwrap()
        },
        Err(e) => panic!(e),
    };

    let end = time::precise_time_s();
    let elapsed = end - start;

    println!("Count is {}", result);
    println!("Test took {} seconds", elapsed);
    let thruput = ((size / workers * workers) as f64) / elapsed;
    println!("Throughput={} per sec", thruput);
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let args = if env::var("RUST_BENCH").is_ok() {
        vec!("".to_string(), "1000000".to_string(), "10000".to_string())
    } else if args.len() <= 1 {
        vec!("".to_string(), "10000".to_string(), "4".to_string())
    } else {
        args
    };

    let size = args[1].parse().unwrap();
    let workers = args[2].parse().unwrap();

    let mut ctx = zmq::Context::new();

    run(&mut ctx, size, workers);
}
<|endoftext|>


<commit_before>use super::token::{
        Token,
        TokenType,
        Operator,
    };

use super::block_tree;

#[derive(Debug, Clone)]
pub struct Tokenizer {
    tokens: Vec<Token>,
    lines:  u32,
    start:  usize,
    pos:    usize,
    top:    usize,
}

impl<'a> Tokenizer {
    pub fn new() -> Tokenizer {
        Tokenizer {
            tokens: Vec::new(),
            lines:  0,
            start:  0,
            pos:    0,
            top:    0,
        }
    }

    pub fn from(
        tokens: Vec<Token>
    ) -> Tokenizer {
        Tokenizer {
            tokens: tokens,
            lines:  0,
            start:  0,
            pos:    0,
            top:    0,
        }
    }

    pub fn get_tokens(&self) -> &Vec<Token> {
        &self.tokens
    }

    pub fn clear(&mut self) {
        self.tokens = Vec::new();
        self.lines  = 0;
        self.start  = 0;
        self.pos    = 0;
        self.top    = 0;
    }

    fn push(&mut self, token_type: TokenType, line: &str) {
        self.tokens.push(
            Token::new(
                token_type,
                line[self.start .. self.pos].to_string(),
                self.lines,
                self.pos as u32,
            )
        );

        self.start = self.pos
    }

    fn peek(&self, line: &str, offset: usize) -> char {
        match line.chars().nth(self.pos + offset) {
            Some(c) => c,
            None    => ' ',
        }
    }

    fn look(&self, line: &str) -> char {
        self.peek(line, 0)
    }

    fn skip_white(&mut self, line: &str) {
        loop {
            if self.pos >= line.len() - 1 {
                break
            }

            match self.look(line) {
                ' ' => {
                    self.pos   += 1;
                    self.start += 1
                },

                _ => break,
            }
        }
    }

    fn is_operator(&mut self, line: &str) -> bool {
        let mut is_op = false;

        let mut offset = 2; // dirty: longest operator length
        while self.pos + offset >= line.len() {
            offset -= 1
        }

        while offset > 0 && !is_op {
            match operator(&line[self.start .. self.pos + offset]) {
                Some(_) => is_op = true,
                None    => (),
            }

            offset -= 1
        }

        self.pos += offset;

        is_op
    }

    pub fn next_token(&mut self) -> bool {
        if self.top < self.tokens.len() {
            self.top += 1;

            return true
        }

        false
    }

    pub fn prev_token(&mut self) -> bool {
        if self.top < self.tokens.len() {
            self.top -= 1;

            return true
        }

        false
    }

    pub fn remaining(&self) -> usize {
        self.tokens.len() - self.top
    }

    pub fn current(&self) -> &Token {
        if self.top > self.tokens.len() - 1 {
            return &self.tokens[self.tokens.len() - 1]
        }

        &self.tokens[self.top]
    }

    pub fn current_content(&self) -> String {
        self.current().get_content().clone()
    }

    pub fn match_current(&self, token: TokenType) -> Result<&Token, String> {
        match self.current().get_type() == token {
            true  => Ok(self.current()),
            false => Err(
                    format!(
                        "expected {:?} but found {:#?}", token, self.current()
                    )
                )
        }
    }

    fn push_move(&mut self, token: TokenType, line: &str) {
        self.pos += 1;
        self.push(token, line)
    }

    pub fn tokenize(&mut self, source: String) -> Result<(), String> {
        for line in source.lines() {
            self.lines += 1;
            self.start  = 0;
            self.pos    = 0;

            while self.pos < line.len() {
                self.skip_white(line);

                let c = self.look(line);

                if c == '"' || c == '\'' {
                    let del = c;

                    self.pos   += 1;
                    self.start += 1;

                    while self.look(line) != del {
                        self.pos += 1
                    }

                    self.push(TokenType::Text, line);

                    self.pos   += 1;
                    self.start += 1;

                    continue
                }

                if identifier(self.look(line)) {
                    while identifier(self.look(line)) || self.look(line).is_digit(10) {
                        self.pos += 1
                    }

                    match keyword(&line[self.start .. self.pos]) {
                        Some(t) => self.push(t, line),
                        None    => self.push(TokenType::Ident, line),
                    }

                    continue
                }

                let peek = self.peek(line, 1);

                if c.is_digit(10) || c == '.' && peek.is_digit(10)
                                  || c == '-' && peek.is_digit(10) {
                    if c == '-' {
                        self.pos += 1
                    }

                    while self.look(line).is_digit(10) {
                        self.pos += 1
                    }

                    if self.look(line) == '.' && self.peek(line, 1).is_digit(10) {
                        self.pos += 1;

                        while self.look(line).is_digit(10) {
                            self.pos += 1
                        }

                        self.push(TokenType::Float, line);

                        continue
                    }

                    self.push(TokenType::Integer, line);

                    continue
                }

                // TODO: make less hacky
                if c == '-' && self.look(line) == '>' {
                    self.pos += 2;
                    self.push(TokenType::Arrow, line);

                    continue
                }

                if self.is_operator(line) {
                    self.pos += 1;
                    self.push(TokenType::Operator, line);

                    continue
                }

                match c {
                    ' '  => break,
                    '\n' => break,
                    '\0' => break,

                    _ => (),
                }

                match symbol(c) {
                    Some(t) => self.push_move(t, line),
                    None    => panic!(
                                "unexpected symbol: {}, ln {} col {}",
                                &line[self.start .. line.len()],
                                self.lines,
                                self.start,
                            )
                }
            }
        }

        Ok(())
    }

    #[allow(unused_mut, unused_must_use)]
    pub fn tokenize_branch(branch: &block_tree::Branch<'a>) -> block_tree::Branch<'a> {
        let mut product = block_tree::Branch::new(Vec::new());

        for chunk in branch.content.iter() {
            match chunk.get_value() {
                block_tree::ChunkValue::Text(t) => {
                    let mut tokenizer = Tokenizer::new();

                    tokenizer.tokenize(t.to_string());

                    product.content.push(
                        block_tree::Chunk::new(
                            block_tree::ChunkValue::Tokens(
                                    tokenizer.get_tokens().clone(),
                                )
                        )
                    )
                },

                block_tree::ChunkValue::Block(ref b) => product.content.push(
                        block_tree::Chunk::new(
                            block_tree::ChunkValue::Block(Self::tokenize_branch(b)),
                        )
                    ),

                _ => continue,
            }
        }

        product
    }
}

pub fn flatten_tree<'b>(branch: &block_tree::Branch<'b>) -> Vec<Token> {
    let mut flattened: Vec<Token> = Vec::new();

    for chunk in branch.content.iter() {
        match chunk.get_value() {
            block_tree::ChunkValue::Tokens(ref t) => flattened.append(&mut t.clone()),
            block_tree::ChunkValue::Block(ref b)  => flattened.push(
                    Token::new(
                            TokenType::Block(flatten_tree(b)), "".to_string(), 0, 0,
                        )
                ),
            _ => continue,
        }
    }

    flattened
}

fn identifier(c: char) -> bool {
    c.is_alphabetic() || c == '_'
                      || c == '?'
                      || c == '!'
}

fn keyword(v: &str) -> Option<TokenType> {
    match v {
        "true" |
        "false"   => Some(TokenType::Boolean),
        "null"    => Some(TokenType::Null)
        "if"      => Some(TokenType::If),
        "then"    => Some(TokenType::Then),
        "else"    => Some(TokenType::Else),
        "elif"    => Some(TokenType::Elif),
        "while"   => Some(TokenType::While),
        "do"      => Some(TokenType::Do),
        "continue"=> Some(TokenType::Continue),
        "break"   => Some(TokenType::Break),
        "return"  => Some(TokenType::Return),
        _ => None,
    }
}

fn symbol(c: char) -> Option<TokenType> {
    match c {
        '('  => Some(TokenType::LParen),
        ')'  => Some(TokenType::RParen),
        '['  => Some(TokenType::LBracket),
        ']'  => Some(TokenType::RBracket),
        '{'  => Some(TokenType::LBrace),
        '}'  => Some(TokenType::RBrace),
        ':'  => Some(TokenType::Colon),
        ','  => Some(TokenType::Comma),
        '.'  => Some(TokenType::Period),
        ';'  => Some(TokenType::Semicolon),
        '!'  => Some(TokenType::Bang),
        '='  => Some(TokenType::Assign),
        _    => None,
    }
}

pub fn operator(v: &str) -> Option<(Operator, u8)> {
    match v {
        "*"  => Some((Operator::Mul,     1)),
        "/"  => Some((Operator::Div,     1)),
        "%"  => Some((Operator::Mod,     1)),
        "+"  => Some((Operator::Plus,    2)),
        "-"  => Some((Operator::Minus,   2)),
        "==" => Some((Operator::Equal,   3)),
        "!=" => Some((Operator::NEqual,  3)),
        "<"  => Some((Operator::Lt,      4)),
        ">"  => Some((Operator::Gt,      4)),
        "<=" => Some((Operator::LtEqual, 4)),
        ">=" => Some((Operator::GtEqual, 4)),
        "and"=> Some((Operator::And,     5)),
        "or" => Some((Operator::Or,      5)),
        _    => None,
    }
}
<commit_msg>fix error<commit_after>use super::token::{
        Token,
        TokenType,
        Operator,
    };

use super::block_tree;

#[derive(Debug, Clone)]
pub struct Tokenizer {
    tokens: Vec<Token>,
    lines:  u32,
    start:  usize,
    pos:    usize,
    top:    usize,
}

impl<'a> Tokenizer {
    pub fn new() -> Tokenizer {
        Tokenizer {
            tokens: Vec::new(),
            lines:  0,
            start:  0,
            pos:    0,
            top:    0,
        }
    }

    pub fn from(
        tokens: Vec<Token>
    ) -> Tokenizer {
        Tokenizer {
            tokens: tokens,
            lines:  0,
            start:  0,
            pos:    0,
            top:    0,
        }
    }

    pub fn get_tokens(&self) -> &Vec<Token> {
        &self.tokens
    }

    pub fn clear(&mut self) {
        self.tokens = Vec::new();
        self.lines  = 0;
        self.start  = 0;
        self.pos    = 0;
        self.top    = 0;
    }

    fn push(&mut self, token_type: TokenType, line: &str) {
        self.tokens.push(
            Token::new(
                token_type,
                line[self.start .. self.pos].to_string(),
                self.lines,
                self.pos as u32,
            )
        );

        self.start = self.pos
    }

    fn peek(&self, line: &str, offset: usize) -> char {
        match line.chars().nth(self.pos + offset) {
            Some(c) => c,
            None    => ' ',
        }
    }

    fn look(&self, line: &str) -> char {
        self.peek(line, 0)
    }

    fn skip_white(&mut self, line: &str) {
        loop {
            if self.pos >= line.len() - 1 {
                break
            }

            match self.look(line) {
                ' ' => {
                    self.pos   += 1;
                    self.start += 1
                },

                _ => break,
            }
        }
    }

    fn is_operator(&mut self, line: &str) -> bool {
        let mut is_op = false;

        let mut offset = 2; // dirty: longest operator length
        while self.pos + offset >= line.len() {
            offset -= 1
        }

        while offset > 0 && !is_op {
            match operator(&line[self.start .. self.pos + offset]) {
                Some(_) => is_op = true,
                None    => (),
            }

            offset -= 1
        }

        self.pos += offset;

        is_op
    }

    pub fn next_token(&mut self) -> bool {
        if self.top < self.tokens.len() {
            self.top += 1;

            return true
        }

        false
    }

    pub fn prev_token(&mut self) -> bool {
        if self.top < self.tokens.len() {
            self.top -= 1;

            return true
        }

        false
    }

    pub fn remaining(&self) -> usize {
        self.tokens.len() - self.top
    }

    pub fn current(&self) -> &Token {
        if self.top > self.tokens.len() - 1 {
            return &self.tokens[self.tokens.len() - 1]
        }

        &self.tokens[self.top]
    }

    pub fn current_content(&self) -> String {
        self.current().get_content().clone()
    }

    pub fn match_current(&self, token: TokenType) -> Result<&Token, String> {
        match self.current().get_type() == token {
            true  => Ok(self.current()),
            false => Err(
                    format!(
                        "expected {:?} but found {:#?}", token, self.current()
                    )
                )
        }
    }

    fn push_move(&mut self, token: TokenType, line: &str) {
        self.pos += 1;
        self.push(token, line)
    }

    pub fn tokenize(&mut self, source: String) -> Result<(), String> {
        for line in source.lines() {
            self.lines += 1;
            self.start  = 0;
            self.pos    = 0;

            while self.pos < line.len() {
                self.skip_white(line);

                let c = self.look(line);

                if c == '"' || c == '\'' {
                    let del = c;

                    self.pos   += 1;
                    self.start += 1;

                    while self.look(line) != del {
                        self.pos += 1
                    }

                    self.push(TokenType::Text, line);

                    self.pos   += 1;
                    self.start += 1;

                    continue
                }

                if identifier(self.look(line)) {
                    while identifier(self.look(line)) || self.look(line).is_digit(10) {
                        self.pos += 1
                    }

                    match keyword(&line[self.start .. self.pos]) {
                        Some(t) => self.push(t, line),
                        None    => self.push(TokenType::Ident, line),
                    }

                    continue
                }

                let peek = self.peek(line, 1);

                if c.is_digit(10) || c == '.' && peek.is_digit(10)
                                  || c == '-' && peek.is_digit(10) {
                    if c == '-' {
                        self.pos += 1
                    }

                    while self.look(line).is_digit(10) {
                        self.pos += 1
                    }

                    if self.look(line) == '.' && self.peek(line, 1).is_digit(10) {
                        self.pos += 1;

                        while self.look(line).is_digit(10) {
                            self.pos += 1
                        }

                        self.push(TokenType::Float, line);

                        continue
                    }

                    self.push(TokenType::Integer, line);

                    continue
                }

                // TODO: make less hacky
                if c == '-' && self.look(line) == '>' {
                    self.pos += 2;
                    self.push(TokenType::Arrow, line);

                    continue
                }

                if self.is_operator(line) {
                    self.pos += 1;
                    self.push(TokenType::Operator, line);

                    continue
                }

                match c {
                    ' '  => break,
                    '\n' => break,
                    '\0' => break,

                    _ => (),
                }

                match symbol(c) {
                    Some(t) => self.push_move(t, line),
                    None    => panic!(
                                "unexpected symbol: {}, ln {} col {}",
                                &line[self.start .. line.len()],
                                self.lines,
                                self.start,
                            )
                }
            }
        }

        Ok(())
    }

    #[allow(unused_mut, unused_must_use)]
    pub fn tokenize_branch(branch: &block_tree::Branch<'a>) -> block_tree::Branch<'a> {
        let mut product = block_tree::Branch::new(Vec::new());

        for chunk in branch.content.iter() {
            match chunk.get_value() {
                block_tree::ChunkValue::Text(t) => {
                    let mut tokenizer = Tokenizer::new();

                    tokenizer.tokenize(t.to_string());

                    product.content.push(
                        block_tree::Chunk::new(
                            block_tree::ChunkValue::Tokens(
                                    tokenizer.get_tokens().clone(),
                                )
                        )
                    )
                },

                block_tree::ChunkValue::Block(ref b) => product.content.push(
                        block_tree::Chunk::new(
                            block_tree::ChunkValue::Block(Self::tokenize_branch(b)),
                        )
                    ),

                _ => continue,
            }
        }

        product
    }
}

pub fn flatten_tree<'b>(branch: &block_tree::Branch<'b>) -> Vec<Token> {
    let mut flattened: Vec<Token> = Vec::new();

    for chunk in branch.content.iter() {
        match chunk.get_value() {
            block_tree::ChunkValue::Tokens(ref t) => flattened.append(&mut t.clone()),
            block_tree::ChunkValue::Block(ref b)  => flattened.push(
                    Token::new(
                            TokenType::Block(flatten_tree(b)), "".to_string(), 0, 0,
                        )
                ),
            _ => continue,
        }
    }

    flattened
}

fn identifier(c: char) -> bool {
    c.is_alphabetic() || c == '_'
                      || c == '?'
                      || c == '!'
}

fn keyword(v: &str) -> Option<TokenType> {
    match v {
        "true" |
        "false"   => Some(TokenType::Boolean),
        "null"    => Some(TokenType::Null),
        "if"      => Some(TokenType::If),
        "then"    => Some(TokenType::Then),
        "else"    => Some(TokenType::Else),
        "elif"    => Some(TokenType::Elif),
        "while"   => Some(TokenType::While),
        "do"      => Some(TokenType::Do),
        "continue"=> Some(TokenType::Continue),
        "break"   => Some(TokenType::Break),
        "return"  => Some(TokenType::Return),
        _ => None,
    }
}

fn symbol(c: char) -> Option<TokenType> {
    match c {
        '('  => Some(TokenType::LParen),
        ')'  => Some(TokenType::RParen),
        '['  => Some(TokenType::LBracket),
        ']'  => Some(TokenType::RBracket),
        '{'  => Some(TokenType::LBrace),
        '}'  => Some(TokenType::RBrace),
        ':'  => Some(TokenType::Colon),
        ','  => Some(TokenType::Comma),
        '.'  => Some(TokenType::Period),
        ';'  => Some(TokenType::Semicolon),
        '!'  => Some(TokenType::Bang),
        '='  => Some(TokenType::Assign),
        _    => None,
    }
}

pub fn operator(v: &str) -> Option<(Operator, u8)> {
    match v {
        "*"  => Some((Operator::Mul,     1)),
        "/"  => Some((Operator::Div,     1)),
        "%"  => Some((Operator::Mod,     1)),
        "+"  => Some((Operator::Plus,    2)),
        "-"  => Some((Operator::Minus,   2)),
        "==" => Some((Operator::Equal,   3)),
        "!=" => Some((Operator::NEqual,  3)),
        "<"  => Some((Operator::Lt,      4)),
        ">"  => Some((Operator::Gt,      4)),
        "<=" => Some((Operator::LtEqual, 4)),
        ">=" => Some((Operator::GtEqual, 4)),
        "and"=> Some((Operator::And,     5)),
        "or" => Some((Operator::Or,      5)),
        _    => None,
    }
}
<|endoftext|>