<commit_before>use redox::*;

// TODO: Structure using loops
// TODO: Make capital commands doing the reverse of the command
//       Y: Yank before the cursor
//       D: Delete before the cursor.

use super::Mode;
use super::Mode::*;
use super::Editor;

// TODO: Move vars to `Editor`
pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool, clipboard: &mut String) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') => editor.left(),
                                (Normal, 'l') => editor.right(),
                                (Normal, 'k') | (Normal, ' ') => editor.up(),
                                (Normal, 'j') | (Normal, '\n') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 'z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = clipboard.clone().to_string() + &editor.cur().to_string();
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'Z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset >= 0 {
                                        clipboard.push(editor.cur());
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        clipboard.push(editor.cur());
                                        editor.right();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.left();
                                    }
                                },
                                (Normal, 'Y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = editor.cur().to_string() + clipboard;
                                        editor.left();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.right();
                                    }
                                },
                                (Normal, 'p') => {
                                    for c in clipboard.chars() {
                                        editor.insert(c, window);
                                    }
                                },
                                (Normal, '$') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal,  '0') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'D') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording, clipboard);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<commit_msg>Fix alias<commit_after> use redox::*;

// TODO: Structure using loops
// TODO: Make capital commands doing the reverse of the command
//       Y: Yank before the cursor
//       D: Delete before the cursor.

use super::Mode;
use super::Mode::*;
use super::Editor;

// TODO: Move vars to `Editor`
pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool, clipboard: &mut String) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') | (Normal, ' ') => editor.left(),
                                (Normal, 'l') => editor.right(),
                                (Normal, 'k') => editor.up(),
                                (Normal, 'j') | (Normal, '\n') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 'z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = clipboard.clone().to_string() + &editor.cur().to_string();
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'Z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset >= 0 {
                                        clipboard.push(editor.cur());
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        clipboard.push(editor.cur());
                                        editor.right();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.left();
                                    }
                                },
                                (Normal, 'Y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = editor.cur().to_string() + clipboard;
                                        editor.left();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.right();
                                    }
                                },
                                (Normal, 'p') => {
                                    for c in clipboard.chars() {
                                        editor.insert(c, window);
                                    }
                                },
                                (Normal, '$') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal,  '0') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'D') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording, clipboard);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate sunrise;
#[macro_use]
extern crate clap;
use clap::{Arg, App, SubCommand};
//use chrono::{NaiveTime, NaiveDateTime};
extern crate chrono;

use chrono::prelude::*;

fn main() {
    let matches = App::new("sunrise-exe")
                          .version("1.0")
                          .about("prints out sunrise and sunset time")
                          .args_from_usage(
                              "-c, --config=[FILE] 'Sets a custom config file'
                              <INPUT>              'Sets the input file to use'
                              -v...                'Sets the level of verbosity'")
                          .subcommand(SubCommand::with_name("test")
                                      .about("controls testing features")
                                      .version("1.3")
                                      .author("Someone E. <someone_else@other.com>")
                                      .arg_from_usage("-d, --debug 'Print debug information'"))
                          .get_matches();

    // Gets a value for config if supplied by user, or defaults to "default.conf"
    let config = matches.value_of("config").unwrap_or("default.conf");
    println!("Value for config: {}", config);

    // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't
    // required we could have used an 'if let' to conditionally get the value)
    println!("Using input file: {}", matches.value_of("INPUT").unwrap());

    // Vary the output based on how many times the user used the "verbose" flag
    // (i.e. 'myprog -v -v -v' or 'myprog -vvv' vs 'myprog -v'
    match matches.occurrences_of("v") {
        0 => println!("No verbose info"),
        1 => println!("Some verbose info"),
        2 => println!("Tons of verbose info"),
        3 | _ => println!("Don't be crazy"),
    }

    // You can handle information about subcommands by requesting their matches by name
    // (as below), requesting just the name used, or both at the same time
    if let Some(matches) = matches.subcommand_matches("test") {
        if matches.is_present("debug") {
            println!("Printing debug info...");
        } else {
            println!("Printing normally...");
        }
    }

    // Calculate times for December 11, 2021 in Moscow
    let (sunrise, sunset) = sunrise::sunrise_sunset(
        55.4544,
        37.3763,
        2021,
        12,
        11,
    );
    println!("sunrise: {} sunset: {}", sunrise, sunset);

    // https://stackoverflow.com/questions/50072055/converting-unix-timestamp-to-readable-time-string-in-rust
    // Create a NaiveDateTime from the timestamp
    let naive = NaiveDateTime::from_timestamp(sunrise, 0);

    // Create a normal DateTime from the NaiveDateTime
    let datetime: DateTime<Utc> = DateTime::from_utc(naive, Utc);

    // Format the datetime how you want
    let newdate = datetime.format("%Y-%m-%d %H:%M:%S");

    // Print the newly formatted date and time
    println!("{}", newdate);
}
<commit_msg>set output to `Local` time<commit_after>extern crate sunrise;
#[macro_use]
extern crate clap;
use clap::{Arg, App, SubCommand};

extern crate chrono;
use chrono::prelude::DateTime;
use chrono::{Utc, Local};
use std::time::{SystemTime, UNIX_EPOCH, Duration};
use std::convert::TryInto;

fn main() {
    let matches = App::new("sunrise-exe")
                          .version("1.0")
                          .about("prints out sunrise and sunset time")
                          .args_from_usage(
                              "-c, --config=[FILE] 'Sets a custom config file'
                              <INPUT>              'Sets the input file to use'
                              -v...                'Sets the level of verbosity'")
                          .subcommand(SubCommand::with_name("test")
                                      .about("controls testing features")
                                      .version("1.3")
                                      .author("Someone E. <someone_else@other.com>")
                                      .arg_from_usage("-d, --debug 'Print debug information'"))
                          .get_matches();

    // Gets a value for config if supplied by user, or defaults to "default.conf"
    let config = matches.value_of("config").unwrap_or("default.conf");
    println!("Value for config: {}", config);

    // Calling .unwrap() is safe here because "INPUT" is required (if "INPUT" wasn't
    // required we could have used an 'if let' to conditionally get the value)
    println!("Using input file: {}", matches.value_of("INPUT").unwrap());

    // Vary the output based on how many times the user used the "verbose" flag
    // (i.e. 'myprog -v -v -v' or 'myprog -vvv' vs 'myprog -v'
    match matches.occurrences_of("v") {
        0 => println!("No verbose info"),
        1 => println!("Some verbose info"),
        2 => println!("Tons of verbose info"),
        3 | _ => println!("Don't be crazy"),
    }

    // You can handle information about subcommands by requesting their matches by name
    // (as below), requesting just the name used, or both at the same time
    if let Some(matches) = matches.subcommand_matches("test") {
        if matches.is_present("debug") {
            println!("Printing debug info...");
        } else {
            println!("Printing normally...");
        }
    }

    // Calculate times for December 11, 2021 in Moscow
    let (sunrise, sunset) = sunrise::sunrise_sunset(
        55.4544,
        37.3763,
        2021,
        12,
        11,
    );
    println!("sunrise: {} sunset: {}", sunrise, sunset);

    // https://stackoverflow.com/questions/50072055/converting-unix-timestamp-to-readable-time-string-in-rust

    // Creates a new SystemTime from the specified number of whole seconds
    let d = UNIX_EPOCH + Duration::from_secs(sunrise.try_into().unwrap());
    // Create DateTime from SystemTime
    //let datetime = DateTime::<Utc>::from(d);
    let datetime = DateTime::<Local>::from(d);
    // Formats the combined date and time with the specified format string.
    let timestamp_str = datetime.format("%Y-%m-%d %H:%M:%S.%f").to_string();
    println!{"{}",timestamp_str};

}
<|endoftext|>


<commit_before>use crate::syntax::improper::ImproperCtype;
use crate::syntax::instantiate::ImplKey;
use crate::syntax::map::{OrderedMap, UnorderedMap};
use crate::syntax::report::Errors;
use crate::syntax::resolve::Resolution;
use crate::syntax::set::{OrderedSet, UnorderedSet};
use crate::syntax::trivial::{self, TrivialReason};
use crate::syntax::visit::{self, Visit};
use crate::syntax::{
    toposort, Api, Atom, Enum, ExternType, Impl, Lifetimes, Pair, Struct, Type, TypeAlias,
};
use proc_macro2::Ident;
use quote::ToTokens;

pub struct Types<'a> {
    pub all: OrderedSet<&'a Type>,
    pub structs: UnorderedMap<&'a Ident, &'a Struct>,
    pub enums: UnorderedMap<&'a Ident, &'a Enum>,
    pub cxx: UnorderedSet<&'a Ident>,
    pub rust: UnorderedSet<&'a Ident>,
    pub aliases: UnorderedMap<&'a Ident, &'a TypeAlias>,
    pub untrusted: UnorderedMap<&'a Ident, &'a ExternType>,
    pub required_trivial: UnorderedMap<&'a Ident, Vec<TrivialReason<'a>>>,
    pub impls: OrderedMap<ImplKey<'a>, Option<&'a Impl>>,
    pub resolutions: UnorderedMap<&'a Ident, Resolution<'a>>,
    pub struct_improper_ctypes: UnorderedSet<&'a Ident>,
    pub toposorted_structs: Vec<&'a Struct>,
}

impl<'a> Types<'a> {
    pub fn collect(cx: &mut Errors, apis: &'a [Api]) -> Self {
        let mut all = OrderedSet::new();
        let mut structs = UnorderedMap::new();
        let mut enums = UnorderedMap::new();
        let mut cxx = UnorderedSet::new();
        let mut rust = UnorderedSet::new();
        let mut aliases = UnorderedMap::new();
        let mut untrusted = UnorderedMap::new();
        let mut impls = OrderedMap::new();
        let mut resolutions = UnorderedMap::new();
        let struct_improper_ctypes = UnorderedSet::new();
        let toposorted_structs = Vec::new();

        fn visit<'a>(all: &mut OrderedSet<&'a Type>, ty: &'a Type) {
            struct CollectTypes<'s, 'a>(&'s mut OrderedSet<&'a Type>);

            impl<'s, 'a> Visit<'a> for CollectTypes<'s, 'a> {
                fn visit_type(&mut self, ty: &'a Type) {
                    self.0.insert(ty);
                    visit::visit_type(self, ty);
                }
            }

            CollectTypes(all).visit_type(ty);
        }

        let mut add_resolution = |name: &'a Pair, generics: &'a Lifetimes| {
            resolutions.insert(&name.rust, Resolution { name, generics });
        };

        let mut type_names = UnorderedSet::new();
        let mut function_names = UnorderedSet::new();
        for api in apis {
            // The same identifier is permitted to be declared as both a shared
            // enum and extern C++ type, or shared struct and extern C++ type.
            // That indicates to not emit the C++ enum/struct definition because
            // it's defined by the included headers already.
            //
            // All other cases of duplicate identifiers are reported as an error.
            match api {
                Api::Include(_) => {}
                Api::Struct(strct) => {
                    let ident = &strct.name.rust;
                    if !type_names.insert(ident)
                        && (!cxx.contains(ident)
                            || structs.contains_key(ident)
                            || enums.contains_key(ident))
                    {
                        // If already declared as a struct or enum, or if
                        // colliding with something other than an extern C++
                        // type, then error.
                        duplicate_name(cx, strct, ident);
                    }
                    structs.insert(&strct.name.rust, strct);
                    for field in &strct.fields {
                        visit(&mut all, &field.ty);
                    }
                    add_resolution(&strct.name, &strct.generics);
                }
                Api::Enum(enm) => {
                    all.insert(&enm.repr_type);
                    let ident = &enm.name.rust;
                    if !type_names.insert(ident)
                        && (!cxx.contains(ident)
                            || structs.contains_key(ident)
                            || enums.contains_key(ident))
                    {
                        // If already declared as a struct or enum, or if
                        // colliding with something other than an extern C++
                        // type, then error.
                        duplicate_name(cx, enm, ident);
                    }
                    enums.insert(ident, enm);
                    add_resolution(&enm.name, &enm.generics);
                }
                Api::CxxType(ety) => {
                    let ident = &ety.name.rust;
                    if !type_names.insert(ident)
                        && (cxx.contains(ident)
                            || !structs.contains_key(ident) && !enums.contains_key(ident))
                    {
                        // If already declared as an extern C++ type, or if
                        // colliding with something which is neither struct nor
                        // enum, then error.
                        duplicate_name(cx, ety, ident);
                    }
                    cxx.insert(ident);
                    if !ety.trusted {
                        untrusted.insert(ident, ety);
                    }
                    add_resolution(&ety.name, &ety.generics);
                }
                Api::RustType(ety) => {
                    let ident = &ety.name.rust;
                    if !type_names.insert(ident) {
                        duplicate_name(cx, ety, ident);
                    }
                    rust.insert(ident);
                    add_resolution(&ety.name, &ety.generics);
                }
                Api::CxxFunction(efn) | Api::RustFunction(efn) => {
                    // Note: duplication of the C++ name is fine because C++ has
                    // function overloading.
                    if !function_names.insert((&efn.receiver, &efn.name.rust)) {
                        duplicate_name(cx, efn, &efn.name.rust);
                    }
                    for arg in &efn.args {
                        visit(&mut all, &arg.ty);
                    }
                    if let Some(ret) = &efn.ret {
                        visit(&mut all, ret);
                    }
                }
                Api::TypeAlias(alias) => {
                    let ident = &alias.name.rust;
                    if !type_names.insert(ident) {
                        duplicate_name(cx, alias, ident);
                    }
                    cxx.insert(ident);
                    aliases.insert(ident, alias);
                    add_resolution(&alias.name, &alias.generics);
                }
                Api::Impl(imp) => {
                    visit(&mut all, &imp.ty);
                    if let Some(key) = imp.ty.impl_key() {
                        impls.insert(key, Some(imp));
                    }
                }
            }
        }

        for ty in &all {
            let impl_key = match ty.impl_key() {
                Some(impl_key) => impl_key,
                None => continue,
            };
            let implicit_impl = match impl_key {
                ImplKey::RustBox(ident)
                | ImplKey::RustVec(ident)
                | ImplKey::UniquePtr(ident)
                | ImplKey::SharedPtr(ident)
                | ImplKey::WeakPtr(ident)
                | ImplKey::CxxVector(ident) => {
                    Atom::from(ident.rust).is_none() && !aliases.contains_key(ident.rust)
                }
            };
            if implicit_impl && !impls.contains_key(&impl_key) {
                impls.insert(impl_key, None);
            }
        }

        // All these APIs may contain types passed by value. We need to ensure
        // we check that this is permissible. We do this _after_ scanning all
        // the APIs above, in case some function or struct references a type
        // which is declared subsequently.
        let required_trivial =
            trivial::required_trivial_reasons(apis, &all, &structs, &enums, &cxx);

        let mut types = Types {
            all,
            structs,
            enums,
            cxx,
            rust,
            aliases,
            untrusted,
            required_trivial,
            impls,
            resolutions,
            struct_improper_ctypes,
            toposorted_structs,
        };

        types.toposorted_structs = toposort::sort(cx, apis, &types);

        let mut unresolved_structs = types.structs.keys();
        let mut new_information = true;
        while new_information {
            new_information = false;
            unresolved_structs.retain(|ident| {
                let mut retain = false;
                for var in &types.structs[ident].fields {
                    if match types.determine_improper_ctype(&var.ty) {
                        ImproperCtype::Depends(inner) => {
                            retain = true;
                            types.struct_improper_ctypes.contains(inner)
                        }
                        ImproperCtype::Definite(improper) => improper,
                    } {
                        types.struct_improper_ctypes.insert(ident);
                        new_information = true;
                        return false;
                    }
                }
                // If all fields definite false, remove from unresolved_structs.
                retain
            });
        }

        types
    }

    pub fn needs_indirect_abi(&self, ty: &Type) -> bool {
        match ty {
            Type::RustBox(_) | Type::UniquePtr(_) => false,
            Type::Array(_) => true,
            _ => !self.is_guaranteed_pod(ty),
        }
    }

    // Types that trigger rustc's default #[warn(improper_ctypes)] lint, even if
    // they may be otherwise unproblematic to mention in an extern signature.
    // For example in a signature like `extern "C" fn(*const String)`, rustc
    // refuses to believe that C could know how to supply us with a pointer to a
    // Rust String, even though C could easily have obtained that pointer
    // legitimately from a Rust call.
    pub fn is_considered_improper_ctype(&self, ty: &Type) -> bool {
        match self.determine_improper_ctype(ty) {
            ImproperCtype::Definite(improper) => improper,
            ImproperCtype::Depends(ident) => self.struct_improper_ctypes.contains(ident),
        }
    }

    // Types which we need to assume could possibly exist by value on the Rust
    // side.
    pub fn is_maybe_trivial(&self, ty: &Ident) -> bool {
        self.structs.contains_key(ty)
            || self.enums.contains_key(ty)
            || self.aliases.contains_key(ty)
    }
}

impl<'t, 'a> IntoIterator for &'t Types<'a> {
    type Item = &'a Type;
    type IntoIter = crate::syntax::set::Iter<'t, 'a, Type>;
    fn into_iter(self) -> Self::IntoIter {
        self.all.into_iter()
    }
}

fn duplicate_name(cx: &mut Errors, sp: impl ToTokens, ident: &Ident) {
    let msg = format!("the name `{}` is defined multiple times", ident);
    cx.error(sp, msg);
}
<commit_msg>Implicltly extern type for enums sourced from header<commit_after>use crate::syntax::improper::ImproperCtype;
use crate::syntax::instantiate::ImplKey;
use crate::syntax::map::{OrderedMap, UnorderedMap};
use crate::syntax::report::Errors;
use crate::syntax::resolve::Resolution;
use crate::syntax::set::{OrderedSet, UnorderedSet};
use crate::syntax::trivial::{self, TrivialReason};
use crate::syntax::visit::{self, Visit};
use crate::syntax::{
    toposort, Api, Atom, Enum, ExternType, Impl, Lifetimes, Pair, Struct, Type, TypeAlias,
};
use proc_macro2::Ident;
use quote::ToTokens;

pub struct Types<'a> {
    pub all: OrderedSet<&'a Type>,
    pub structs: UnorderedMap<&'a Ident, &'a Struct>,
    pub enums: UnorderedMap<&'a Ident, &'a Enum>,
    pub cxx: UnorderedSet<&'a Ident>,
    pub rust: UnorderedSet<&'a Ident>,
    pub aliases: UnorderedMap<&'a Ident, &'a TypeAlias>,
    pub untrusted: UnorderedMap<&'a Ident, &'a ExternType>,
    pub required_trivial: UnorderedMap<&'a Ident, Vec<TrivialReason<'a>>>,
    pub impls: OrderedMap<ImplKey<'a>, Option<&'a Impl>>,
    pub resolutions: UnorderedMap<&'a Ident, Resolution<'a>>,
    pub struct_improper_ctypes: UnorderedSet<&'a Ident>,
    pub toposorted_structs: Vec<&'a Struct>,
}

impl<'a> Types<'a> {
    pub fn collect(cx: &mut Errors, apis: &'a [Api]) -> Self {
        let mut all = OrderedSet::new();
        let mut structs = UnorderedMap::new();
        let mut enums = UnorderedMap::new();
        let mut cxx = UnorderedSet::new();
        let mut rust = UnorderedSet::new();
        let mut aliases = UnorderedMap::new();
        let mut untrusted = UnorderedMap::new();
        let mut impls = OrderedMap::new();
        let mut resolutions = UnorderedMap::new();
        let struct_improper_ctypes = UnorderedSet::new();
        let toposorted_structs = Vec::new();

        fn visit<'a>(all: &mut OrderedSet<&'a Type>, ty: &'a Type) {
            struct CollectTypes<'s, 'a>(&'s mut OrderedSet<&'a Type>);

            impl<'s, 'a> Visit<'a> for CollectTypes<'s, 'a> {
                fn visit_type(&mut self, ty: &'a Type) {
                    self.0.insert(ty);
                    visit::visit_type(self, ty);
                }
            }

            CollectTypes(all).visit_type(ty);
        }

        let mut add_resolution = |name: &'a Pair, generics: &'a Lifetimes| {
            resolutions.insert(&name.rust, Resolution { name, generics });
        };

        let mut type_names = UnorderedSet::new();
        let mut function_names = UnorderedSet::new();
        for api in apis {
            // The same identifier is permitted to be declared as both a shared
            // enum and extern C++ type, or shared struct and extern C++ type.
            // That indicates to not emit the C++ enum/struct definition because
            // it's defined by the included headers already.
            //
            // All other cases of duplicate identifiers are reported as an error.
            match api {
                Api::Include(_) => {}
                Api::Struct(strct) => {
                    let ident = &strct.name.rust;
                    if !type_names.insert(ident)
                        && (!cxx.contains(ident)
                            || structs.contains_key(ident)
                            || enums.contains_key(ident))
                    {
                        // If already declared as a struct or enum, or if
                        // colliding with something other than an extern C++
                        // type, then error.
                        duplicate_name(cx, strct, ident);
                    }
                    structs.insert(&strct.name.rust, strct);
                    for field in &strct.fields {
                        visit(&mut all, &field.ty);
                    }
                    add_resolution(&strct.name, &strct.generics);
                }
                Api::Enum(enm) => {
                    all.insert(&enm.repr_type);
                    let ident = &enm.name.rust;
                    if !type_names.insert(ident)
                        && (!cxx.contains(ident)
                            || structs.contains_key(ident)
                            || enums.contains_key(ident))
                    {
                        // If already declared as a struct or enum, or if
                        // colliding with something other than an extern C++
                        // type, then error.
                        duplicate_name(cx, enm, ident);
                    }
                    enums.insert(ident, enm);
                    if enm.variants_from_header {
                        // #![variants_from_header] enums are implicitly extern
                        // C++ type.
                        cxx.insert(&enm.name.rust);
                    }
                    add_resolution(&enm.name, &enm.generics);
                }
                Api::CxxType(ety) => {
                    let ident = &ety.name.rust;
                    if !type_names.insert(ident)
                        && (cxx.contains(ident)
                            || !structs.contains_key(ident) && !enums.contains_key(ident))
                    {
                        // If already declared as an extern C++ type, or if
                        // colliding with something which is neither struct nor
                        // enum, then error.
                        duplicate_name(cx, ety, ident);
                    }
                    cxx.insert(ident);
                    if !ety.trusted {
                        untrusted.insert(ident, ety);
                    }
                    add_resolution(&ety.name, &ety.generics);
                }
                Api::RustType(ety) => {
                    let ident = &ety.name.rust;
                    if !type_names.insert(ident) {
                        duplicate_name(cx, ety, ident);
                    }
                    rust.insert(ident);
                    add_resolution(&ety.name, &ety.generics);
                }
                Api::CxxFunction(efn) | Api::RustFunction(efn) => {
                    // Note: duplication of the C++ name is fine because C++ has
                    // function overloading.
                    if !function_names.insert((&efn.receiver, &efn.name.rust)) {
                        duplicate_name(cx, efn, &efn.name.rust);
                    }
                    for arg in &efn.args {
                        visit(&mut all, &arg.ty);
                    }
                    if let Some(ret) = &efn.ret {
                        visit(&mut all, ret);
                    }
                }
                Api::TypeAlias(alias) => {
                    let ident = &alias.name.rust;
                    if !type_names.insert(ident) {
                        duplicate_name(cx, alias, ident);
                    }
                    cxx.insert(ident);
                    aliases.insert(ident, alias);
                    add_resolution(&alias.name, &alias.generics);
                }
                Api::Impl(imp) => {
                    visit(&mut all, &imp.ty);
                    if let Some(key) = imp.ty.impl_key() {
                        impls.insert(key, Some(imp));
                    }
                }
            }
        }

        for ty in &all {
            let impl_key = match ty.impl_key() {
                Some(impl_key) => impl_key,
                None => continue,
            };
            let implicit_impl = match impl_key {
                ImplKey::RustBox(ident)
                | ImplKey::RustVec(ident)
                | ImplKey::UniquePtr(ident)
                | ImplKey::SharedPtr(ident)
                | ImplKey::WeakPtr(ident)
                | ImplKey::CxxVector(ident) => {
                    Atom::from(ident.rust).is_none() && !aliases.contains_key(ident.rust)
                }
            };
            if implicit_impl && !impls.contains_key(&impl_key) {
                impls.insert(impl_key, None);
            }
        }

        // All these APIs may contain types passed by value. We need to ensure
        // we check that this is permissible. We do this _after_ scanning all
        // the APIs above, in case some function or struct references a type
        // which is declared subsequently.
        let required_trivial =
            trivial::required_trivial_reasons(apis, &all, &structs, &enums, &cxx);

        let mut types = Types {
            all,
            structs,
            enums,
            cxx,
            rust,
            aliases,
            untrusted,
            required_trivial,
            impls,
            resolutions,
            struct_improper_ctypes,
            toposorted_structs,
        };

        types.toposorted_structs = toposort::sort(cx, apis, &types);

        let mut unresolved_structs = types.structs.keys();
        let mut new_information = true;
        while new_information {
            new_information = false;
            unresolved_structs.retain(|ident| {
                let mut retain = false;
                for var in &types.structs[ident].fields {
                    if match types.determine_improper_ctype(&var.ty) {
                        ImproperCtype::Depends(inner) => {
                            retain = true;
                            types.struct_improper_ctypes.contains(inner)
                        }
                        ImproperCtype::Definite(improper) => improper,
                    } {
                        types.struct_improper_ctypes.insert(ident);
                        new_information = true;
                        return false;
                    }
                }
                // If all fields definite false, remove from unresolved_structs.
                retain
            });
        }

        types
    }

    pub fn needs_indirect_abi(&self, ty: &Type) -> bool {
        match ty {
            Type::RustBox(_) | Type::UniquePtr(_) => false,
            Type::Array(_) => true,
            _ => !self.is_guaranteed_pod(ty),
        }
    }

    // Types that trigger rustc's default #[warn(improper_ctypes)] lint, even if
    // they may be otherwise unproblematic to mention in an extern signature.
    // For example in a signature like `extern "C" fn(*const String)`, rustc
    // refuses to believe that C could know how to supply us with a pointer to a
    // Rust String, even though C could easily have obtained that pointer
    // legitimately from a Rust call.
    pub fn is_considered_improper_ctype(&self, ty: &Type) -> bool {
        match self.determine_improper_ctype(ty) {
            ImproperCtype::Definite(improper) => improper,
            ImproperCtype::Depends(ident) => self.struct_improper_ctypes.contains(ident),
        }
    }

    // Types which we need to assume could possibly exist by value on the Rust
    // side.
    pub fn is_maybe_trivial(&self, ty: &Ident) -> bool {
        self.structs.contains_key(ty)
            || self.enums.contains_key(ty)
            || self.aliases.contains_key(ty)
    }
}

impl<'t, 'a> IntoIterator for &'t Types<'a> {
    type Item = &'a Type;
    type IntoIter = crate::syntax::set::Iter<'t, 'a, Type>;
    fn into_iter(self) -> Self::IntoIter {
        self.all.into_iter()
    }
}

fn duplicate_name(cx: &mut Errors, sp: impl ToTokens, ident: &Ident) {
    let msg = format!("the name `{}` is defined multiple times", ident);
    cx.error(sp, msg);
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, Matthew O'Connor
extern crate system_zero_core;

use std::io;
use std::io::{BufRead, Write};
use system_zero_core::*;
use system_zero_core::ast::*;

const BOOL: &'static str = include_str!("bool.sz");
const NAT: &'static str = include_str!("nat.sz");
const LIST: &'static str = include_str!("list.sz");

fn load_prelude(env: &mut Env) {
  env.load(BOOL);
  env.load(NAT);
  env.load(LIST);
}

const PROMPT: &'static str = "> ";

fn prompt() -> () {
  print!("{}", PROMPT);
  io::stdout().flush().unwrap()
}

fn support(line: &String, mut env: &mut Env, history: &Vec<String>) {
  if line == ":env" {
    print!("{:?}", env);
  } else if line == ":history" {
    println!("{:?}", history);
  } else if line == ":quit" || line == ":exit" {
    std::process::exit(1);
  } else if line == ":clear" {
    env.clear();
    load_prelude(&mut env);
  } else if line.starts_with(":ty ") {
    let name = &line[4..];
    match env.get_ty(&Var::new(name)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No type for `{}`", name),
    }
  } else if line.starts_with(":val ") {
    let name = &line[5..];
    match env.get_val(&Var::new(name)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No value for `{}`", name),
    }
  } else if line.starts_with(":def ") {
    let name = &line[5..];
    match env.get_ty(&Var::new(name)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No type for `{}`", name),
    }
    match env.get_val(&Var::new(name)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No value for `{}`", name),
    }
  }
}

fn eval<'input>(line: &'input str, mut env: &mut Env) -> Result<'input, One> {
  match parse_one(&line) {
    Ok(one) => {
      match one {
        One::Def(ref def) => {
          println!(":type = {:?}", def.expr().type_check(&env));
          let def = def.normalize_in(&mut env);
          let one = One::Def(def.clone());
          env.push(def);
          Ok(one)
        }
        One::Expr(ref e) => {
          println!(":type = {:?}", e.type_check(&env));
          Ok(One::Expr(e.normalize_in(&mut env)))
        }
      }
    }
    Err(error) => Err(error),
  }
}

fn repl() -> io::Result<()> {
  let mut history: Vec<String> = vec![];
  let mut env = Env::new();
  load_prelude(&mut env);
  prompt();
  let stdin = io::stdin();
  for line in stdin.lock().lines() {
    let line = line.unwrap();
    history.push(line.clone());
    if line.starts_with("--") {
      ()
    } else if line.starts_with(":") {
      support(&line, &mut env, &history);
    } else if line.len() > 0 {
      match eval(&line[..], &mut env) {
        Ok(one) => print!("{:?}", one),
        Err(error) => println!("Couldn't parse: {:?}", error),
      }
    }
    prompt();
  }
  Ok(())
}

fn main() {
  println!("szi - system zero interpreter");
  println!("Copyright (c) 2016, Matthew O'Connor <thegreendragon@gmail.com>");
  repl().unwrap()
}
<commit_msg>exit(0) on success. Add more println! to aid development.<commit_after>// Copyright (c) 2016, Matthew O'Connor
extern crate system_zero_core;

use std::io;
use std::io::{BufRead, Write};
use system_zero_core::*;
use system_zero_core::ast::*;

const BOOL: &'static str = include_str!("bool.sz");
const NAT: &'static str = include_str!("nat.sz");
const LIST: &'static str = include_str!("list.sz");

fn load_prelude(env: &mut Env) {
  // env.load(BOOL);
  // env.load(NAT);
  // env.load(LIST);
}

const PROMPT: &'static str = "> ";

fn prompt() -> () {
  print!("{}", PROMPT);
  io::stdout().flush().unwrap()
}

fn support(line: &String, mut env: &mut Env, history: &Vec<String>) {
  if line == ":env" {
    print!("{:?}", env);
  } else if line == ":history" {
    println!("{:?}", history);
  } else if line == ":quit" || line == ":exit" {
    std::process::exit(0);
  } else if line == ":clear" {
    env.clear();
    load_prelude(&mut env);
  } else if line.starts_with(":ty ") {
    let name = &line[4..];
    match env.get_ty(&Var::new(name)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No type for `{}`", name),
    }
  } else if line.starts_with(":val ") {
    let name = &line[5..];
    match env.get_val(&Var::new(name)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No value for `{}`", name),
    }
  } else if line.starts_with(":def ") {
    let name = &line[5..];
    match env.get_ty(&Var::new(name)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No type for `{}`", name),
    }
    match env.get_val(&Var::new(name)) {
      Some(ref def) => println!("{:?}", def),
      None => println!("No value for `{}`", name),
    }
  }
}

fn eval<'input>(line: &'input str, mut env: &mut Env) -> Result<'input, One> {
  match parse_one(&line) {
    Ok(one) => {
      match one {
        One::Def(ref def) => {
          println!(":type = {:?}", def.expr().type_check(&env));
          let def = def.normalize_in(&mut env);
          let one = One::Def(def.clone());
          env.push(def);
          Ok(one)
        }
        One::Expr(ref e) => {
          println!(":type = {:?}", e.type_check(&env));
          println!("canonical is {:?}", e.canonicalize(&env));
          println!("canonical normalized is {:?}",
                   e.canonicalize(&env).normalize());
          Ok(One::Expr(e.normalize_in(&mut env)))
        }
      }
    }
    Err(error) => Err(error),
  }
}

fn repl() -> io::Result<()> {
  let mut history: Vec<String> = vec![];
  let mut env = Env::new();
  load_prelude(&mut env);
  prompt();
  let stdin = io::stdin();
  for line in stdin.lock().lines() {
    let line = line.unwrap();
    history.push(line.clone());
    if line.starts_with("--") {
      ()
    } else if line.starts_with(":") {
      support(&line, &mut env, &history);
    } else if line.len() > 0 {
      match eval(&line[..], &mut env) {
        Ok(one) => print!("normalized is {:?}", one),
        Err(error) => println!("Couldn't parse: {:?}", error),
      }
    }
    prompt();
  }
  Ok(())
}

fn main() {
  println!("szi - system zero interpreter");
  println!("Copyright (c) 2016, Matthew O'Connor <thegreendragon@gmail.com>");
  repl().unwrap()
}
<|endoftext|>


<commit_before>#[desc = "C64 emulator"];
#[copyright = "Andreas Neuhaus <info@zargony.com>"];
#[license = "MIT"];

extern crate native;

use cpu::Mos6510;
use mem::{Addressable, Ram, Rom, SharedMemory};

mod cpu;
mod mem;
mod ui;

#[start]
fn start (argc: int, argv: **u8) -> int {
	// Ensure that main is started on the native main os thread (required for SDL2)
	native::start(argc, argv, main)
}

fn main () {
	let mut c64 = C64::new();
	c64.run();
}

// General information on C64 : http://unusedino.de/ec64/technical/aay/c64/
// Useful emulator information: http://emudocs.org/?page=Commodore%2064
// C64 memory map overview: http://www.c64-wiki.com/index.php/Memory_Map
// Details about the PLA: http://www.c64-wiki.de/index.php/PLA_(C64-Chip)
// Even more PLA details: http://skoe.de/docs/c64-dissected/pla/c64_pla_dissected_r1.1_a4ss.pdf

// 64K RAM (not every part is always accessible)
// 8K BASIC ROM at $A000
// 4K character ROM at $D000
// 8K kernal ROM at $E000

struct C64Memory {
	ram: Ram<u16>,
	kernal: Rom<u16>,
	basic: Rom<u16>,
	characters: Rom<u16>,
}

impl C64Memory {
	fn new () -> C64Memory {
		C64Memory {
			ram: Ram::new(),
			kernal: Rom::new(&Path::new("c64/kernal.rom")),
			basic: Rom::new(&Path::new("c64/basic.rom")),
			characters: Rom::new(&Path::new("c64/characters.rom")),
		}
	}
}

impl Addressable<u16> for C64Memory {
	fn get (&self, addr: u16) -> u8 {
		match addr {
			// TODO: Switch memory access based on LORAM/HIRAM/CHAREN
			0xa000..0xbfff => self.basic.get(addr - 0xa000),
			0xd000..0xdfff => self.characters.get(addr - 0xd000),
			0xe000..0xffff => self.kernal.get(addr - 0xe000),
			_              => self.ram.get(addr),
		}
	}

	fn set (&mut self, addr: u16, data: u8) {
		self.ram.set(addr, data);
	}
}

pub struct C64 {
	priv cpu: Mos6510<SharedMemory<C64Memory>>,
	priv mem: SharedMemory<C64Memory>,
}

impl C64 {
	pub fn new () -> C64 {
		let mem = SharedMemory::new(C64Memory::new());
		C64 {
			cpu: Mos6510::new(mem.clone()),
			mem: mem,
		}
	}

	pub fn run (&mut self) {
		// TODO
	}
}
<commit_msg>Implement C64 CPU and VIC memory mapping<commit_after>#[desc = "C64 emulator"];
#[copyright = "Andreas Neuhaus <info@zargony.com>"];
#[license = "MIT"];

extern crate native;

use cpu::Mos6510;
use mem::{Addressable, Ram, Rom, SharedMemory};

mod cpu;
mod mem;
mod ui;

#[start]
fn start (argc: int, argv: **u8) -> int {
	// Ensure that main is started on the native main os thread (required for SDL2)
	native::start(argc, argv, main)
}

fn main () {
	let mut c64 = C64::new();
	c64.run();
}

// General information on C64 : http://unusedino.de/ec64/technical/aay/c64/
// Useful emulator information: http://emudocs.org/?page=Commodore%2064
// C64 memory map overview: http://www.c64-wiki.com/index.php/Memory_Map
// Details about the PLA: http://www.c64-wiki.de/index.php/PLA_(C64-Chip)
// Even more PLA details: http://skoe.de/docs/c64-dissected/pla/c64_pla_dissected_r1.1_a4ss.pdf

/// Represents the memory as seen by the CPU (memory layout is based on the
/// settings of bits 2..0 of the processor port (/CHAREN, /HIRAM and /LORAM)
struct CpuMemory {
	ram: SharedMemory<Ram<u16>>,
	basic: Rom<u16>,
	characters: Rom<u16>,
	kernal: Rom<u16>,
	charen: bool,
	hiram: bool,
	loram: bool,
}

impl CpuMemory {
	fn new () -> CpuMemory {
		CpuMemory {
			ram: SharedMemory::new(Ram::new()),
			basic: Rom::new(&Path::new("c64/basic.rom")),
			characters: Rom::new(&Path::new("c64/characters.rom")),
			kernal: Rom::new(&Path::new("c64/kernal.rom")),
			charen: false,
			hiram: false,
			loram: false,
		}
	}
}

impl Addressable<u16> for CpuMemory {
	fn get (&self, addr: u16) -> u8 {
		// Switch memory access based on processor port lines:
		//
		//    /CHAREN /HIRAM /LORAM $A000-$BFFF $D000-$DFFF $E000-$FFFF
		// #1    1      1       1      BASIC        I/O        KERNAL
		// #6    1      1       0       RAM         I/O        KERNAL
		// #3    1      0       1       RAM         I/O         RAM
		// #5    X      0       0       RAM         RAM         RAM
		// #2    0      1       1      BASIC       CHARS       KERNAL
		// #7    0      1       0       RAM        CHARS       KERNAL
		// #4    0      0       1       RAM        CHARS        RAM
		// #5    X      0       0       RAM         RAM         RAM
		//
		// TODO: Hardware cartridges can as well use /GAME and /EXROM
		match (addr, self.charen, self.hiram, self.loram) {
			(0xa000..0xbfff,     _, false, false) => self.basic.get(addr - 0xa000),				// #1,2
			(0xd000..0xdfff, false, false,     _) => 0, // TODO: self.io.get(addr - 0xd000),	// #1,6
			(0xd000..0xdfff, false,  true, false) => 0, // TODO: self.io.get(addr - 0xd000),	// #3
			(0xd000..0xdfff,  true, false,     _) => self.characters.get(addr - 0xd000),		// #2,7
			(0xd000..0xdfff,  true,  true, false) => self.characters.get(addr - 0xd000),		// #4
			(0xe000..0xffff,     _, false,     _) => self.kernal.get(addr - 0xe000),			// #1,6,2,7
			_                                     => self.ram.get(addr),
		}
	}

	fn set (&mut self, addr: u16, data: u8) {
		// Writing to an address will always store the data to RAM,
		// no matter if an address is accessed that is mapped to ROM
		self.ram.set(addr, data);
	}
}

pub struct C64 {
	priv cpu: Mos6510<CpuMemory>,
}

impl C64 {
	pub fn new () -> C64 {
		let mem = CpuMemory::new();
		C64 {
			cpu: Mos6510::new(mem),
		}
	}

	pub fn run (&mut self) {
		// TODO
	}
}
<|endoftext|>


<commit_before>#[desc = "C64 emulator"];
#[copyright = "Andreas Neuhaus <info@zargony.com>"];
#[license = "MIT"];

use cpu::Mos6510;
use mem::{Addressable, Ram, Rom, SharedMemory};

mod cpu;
mod mem;
mod ui;

fn main () {
	let mut c64 = C64::new();
	c64.run();
}

// General information on C64 : http://unusedino.de/ec64/technical/aay/c64/
// Useful emulator information: http://emudocs.org/?page=Commodore%2064
// C64 memory map overview: http://www.c64-wiki.com/index.php/Memory_Map
// Details about the PLA: http://www.c64-wiki.de/index.php/PLA_(C64-Chip)
// Even more PLA details: http://skoe.de/docs/c64-dissected/pla/c64_pla_dissected_r1.1_a4ss.pdf

// 64K RAM (not every part is always accessible)
// 8K BASIC ROM at $A000
// 4K character ROM at $D000
// 8K kernal ROM at $E000

struct C64Memory {
	ram: Ram<u16>,
	kernal: Rom<u16>,
	basic: Rom<u16>,
	characters: Rom<u16>,
}

impl C64Memory {
	fn new () -> C64Memory {
		C64Memory {
			ram: Ram::new(),
			kernal: Rom::new(&Path::new("c64/kernal.rom")),
			basic: Rom::new(&Path::new("c64/basic.rom")),
			characters: Rom::new(&Path::new("c64/characters.rom")),
		}
	}
}

impl Addressable<u16> for C64Memory {
	fn get (&self, addr: u16) -> u8 {
		match addr {
			// TODO: Switch memory access based on LORAM/HIRAM/CHAREN
			0xa000..0xbfff => self.basic.get(addr - 0xa000),
			0xd000..0xdfff => self.characters.get(addr - 0xd000),
			0xe000..0xffff => self.kernal.get(addr - 0xe000),
			_              => self.ram.get(addr),
		}
	}

	fn set (&mut self, addr: u16, data: u8) {
		self.ram.set(addr, data);
	}
}

pub struct C64 {
	priv cpu: Mos6510<SharedMemory<C64Memory>>,
	priv mem: SharedMemory<C64Memory>,
}

impl C64 {
	pub fn new () -> C64 {
		let mem = SharedMemory::new(C64Memory::new());
		C64 {
			cpu: Mos6510::new(mem.clone()),
			mem: mem,
		}
	}

	pub fn run (&mut self) {
		// TODO
	}
}
<commit_msg>Ensure that main is started on the native main os thread (required for SDL2)<commit_after>#[desc = "C64 emulator"];
#[copyright = "Andreas Neuhaus <info@zargony.com>"];
#[license = "MIT"];

extern mod native;

use cpu::Mos6510;
use mem::{Addressable, Ram, Rom, SharedMemory};

mod cpu;
mod mem;
mod ui;

#[start]
fn start (argc: int, argv: **u8) -> int {
	// Ensure that main is started on the native main os thread (required for SDL2)
	native::start(argc, argv, main)
}

fn main () {
	let mut c64 = C64::new();
	c64.run();
}

// General information on C64 : http://unusedino.de/ec64/technical/aay/c64/
// Useful emulator information: http://emudocs.org/?page=Commodore%2064
// C64 memory map overview: http://www.c64-wiki.com/index.php/Memory_Map
// Details about the PLA: http://www.c64-wiki.de/index.php/PLA_(C64-Chip)
// Even more PLA details: http://skoe.de/docs/c64-dissected/pla/c64_pla_dissected_r1.1_a4ss.pdf

// 64K RAM (not every part is always accessible)
// 8K BASIC ROM at $A000
// 4K character ROM at $D000
// 8K kernal ROM at $E000

struct C64Memory {
	ram: Ram<u16>,
	kernal: Rom<u16>,
	basic: Rom<u16>,
	characters: Rom<u16>,
}

impl C64Memory {
	fn new () -> C64Memory {
		C64Memory {
			ram: Ram::new(),
			kernal: Rom::new(&Path::new("c64/kernal.rom")),
			basic: Rom::new(&Path::new("c64/basic.rom")),
			characters: Rom::new(&Path::new("c64/characters.rom")),
		}
	}
}

impl Addressable<u16> for C64Memory {
	fn get (&self, addr: u16) -> u8 {
		match addr {
			// TODO: Switch memory access based on LORAM/HIRAM/CHAREN
			0xa000..0xbfff => self.basic.get(addr - 0xa000),
			0xd000..0xdfff => self.characters.get(addr - 0xd000),
			0xe000..0xffff => self.kernal.get(addr - 0xe000),
			_              => self.ram.get(addr),
		}
	}

	fn set (&mut self, addr: u16, data: u8) {
		self.ram.set(addr, data);
	}
}

pub struct C64 {
	priv cpu: Mos6510<SharedMemory<C64Memory>>,
	priv mem: SharedMemory<C64Memory>,
}

impl C64 {
	pub fn new () -> C64 {
		let mem = SharedMemory::new(C64Memory::new());
		C64 {
			cpu: Mos6510::new(mem.clone()),
			mem: mem,
		}
	}

	pub fn run (&mut self) {
		// TODO
	}
}
<|endoftext|>


<commit_before>extern crate clap;

use types::ToResult;
use std::path::PathBuf;
use std::fmt;
use std::env;
use std::fs;

#[derive(Debug)]
pub enum Action {
    Get,
    Put,
    Delete,
    List,
    Last,
    ChangeDirectory,
}

pub fn parse_matches(matches: clap::ArgMatches) -> ToResult<Request> {
    let (get, put, delete, list, last) = (matches.is_present("get"),
                                          matches.is_present("put"),
                                          matches.is_present("delete"),
                                          matches.is_present("list"),
                                          matches.is_present("last"));

    let action = match (get, put, delete, list, last) {
        (true, _, _, _, _) => Action::Get,
        (_, true, _, _, _) => Action::Put,
        (_, _, true, _, _) => Action::Delete,
        (_, _, _, true, _) => Action::List,
        (_, _, _, _, true) => Action::Last,
        _                  => Action::ChangeDirectory,
    };

    // to --save,--put # Save current dir as a bookmark
    // to --save,--put foo # Save current directory as bookmark foo
    // to --delete foo # Delete bookmark foo
    // to --info foo # Show details of the bookmark foo
    // to --list # List all the bookmarks
    // to foo # Go to the foo bookmark
    // reserve "-" so it can be used later.
    // to - # go to the last bookmark you visited

    println!("action: {:?}", action);
    let req = Request::new("foo", &PathBuf::from("."));
    return Ok(req);
}

// fn parse(cli: clap::App) -> ToResult<Request> {
//     let matches = cli.get_matches();
//     let pathname = matches.value_of("directory").unwrap_or("");
//
//     let directory = match resolve(pathname) {
//         Ok(value) => value,
//         Err(err) => return Err(err),
//     };
//
//     // Validate that the directory exists and is a directory.
//     // TODO: Move this into the resolve step.
//     if !is_valid_dir(&directory) {
//         panic!("invalid directory");
//     }
//
//     let name = match matches.value_of("name") {
//         Some(value) => value,
//         // directory.file_stem().map(|stem| stem.to_str()).unwrap()
//         None => "",
//     };
//
//     println!("directory: {:?}", directory);
//     println!("name: {:?}", name);
//
//     // let mut action = "save";
//     // // Increment the one requested (in a real program, we'd reset the lower numbers)
//     // let (save, delete, info, list) = (matches.is_present("save"),
//     //                              matches.is_present("delete"),
//     //                              matches.is_present("info"),
//     //                              matches.is_present("list"));
//     //
//     // match (save, delete, info, list) {
//     //     (true, _, _, _) => action = "save",
//     //     (_, true, _, _) => action = "delete",
//     //     (_, _, true, _) => action = "info",
//     //     (_, _, _, true) => action = "list",
//     //     _            => unreachable!(),
//     // };
//     //
//     // println!("action: {:?}", action);
//
//     let req = Request{ name: name.to_string(), directory: directory };
//
//     return Ok(req);
// }
//
// fn resolve(pathname: &str) -> ToResult<PathBuf> {
//     // TODO: Use a custom results tuple instead of panic!.
//     let mut absolute = match env::current_dir() {
//         Ok(value) => value,
//         Err(err) => return Err(ToError::Io(err)),
//     };
//
//     // Don't default to "." since it will be a literal translation creating
//     // dumb directories like "/foo/bar/."
//     if pathname != "." {
//         absolute.push(pathname);
//     }
//
//     return Ok(absolute);
// }
//
// fn is_valid_dir(directory: &PathBuf) -> bool {
//     let path = directory.clone();
//
//     let metadata = match fs::metadata(path) {
//         Ok(value) => value,
//         Err(_) => return false,
//     };
//
//     if metadata.is_dir() {
//         return true;
//     }
//
//     return false;
// }
//
//
// // static NUMBERS: &'static [i32] = &'static [1, 2, 3, 4, 5];
// // static C: [E; 3] = [E::V0, E::V1(0xDEADBEE), E::V0];
// static ACTIONS: [Arg; 1] = [
//     Arg::with_name("save")
//         .help("Saves bookmark")
//         .long("save")
//         .short("s")
// ];
//
// // .arg(Arg::with_name("delete")
// //     .help("Delete bookmark")
// //     .long("delete")
// //     .short("d"))
//
// // ["save", "delete", "info", "list"];

#[derive(Debug)]
pub struct Request {
    pub name: String,
    pub directory: PathBuf,
    pub action: Action,
}

impl Request {
    fn new(name: &str, directory: &PathBuf) -> Request {
        Request{ name: "foo".to_string(), directory: PathBuf::from("."), action: Action::Get}
    }
}
<commit_msg>Adds directory resolution.<commit_after>extern crate clap;

use types::{ToResult, ToError};
use std::path::PathBuf;
use std::fmt;
use std::env;
use std::fs;
use std::option::Option;

#[derive(Debug)]
pub enum Action {
    Get,
    Put,
    Delete,
    List,
    Last,
    ChangeDirectory,
}

pub fn parse_matches(matches: clap::ArgMatches) -> ToResult<Request> {
    let (get, put, delete, list, last) = (matches.is_present("get"),
                                          matches.is_present("put"),
                                          matches.is_present("delete"),
                                          matches.is_present("list"),
                                          matches.is_present("last"));

    let action = match (get, put, delete, list, last) {
        (true, _, _, _, _) => Action::Get,
        (_, true, _, _, _) => Action::Put,
        (_, _, true, _, _) => Action::Delete,
        (_, _, _, true, _) => Action::List,
        (_, _, _, _, true) => Action::Last,
        _                  => Action::ChangeDirectory,
    };

    // to --save,--put # Save current dir as a bookmark
    // to --save,--put foo # Save current directory as bookmark foo
    // to --delete foo # Delete bookmark foo
    // to --info foo # Show details of the bookmark foo
    // to --list # List all the bookmarks
    // to foo # Go to the foo bookmark
    // reserve "-" so it can be used later.
    // to - # go to the last bookmark you visited

    println!("action: {:?}", action);

    let directory = match resolve(matches.value_of("directory")) {
        Ok(value) => value,
        Err(err) => return Err(err),
    };

    println!("directory: {:?}", directory);

    let req = Request::new("foo", &PathBuf::from("."));
    return Ok(req);
}

fn resolve(pathname: Option<&str>) -> ToResult<PathBuf> {
    let pathname = match pathname {
        Some(value) => value,
        None => "",
    };

    let mut absolute = match env::current_dir() {
        Ok(value) => value,
        Err(err) => return Err(ToError::Io(err)),
    };

    // Don't default to "." since it will be a literal translation creating
    // dumb directories like "/foo/bar/."
    if pathname != "." {
        absolute.push(pathname);
    }

    return Ok(absolute);
}

//     // Validate that the directory exists and is a directory.
//     // TODO: Move this into the resolve step.
//     if !is_valid_dir(&directory) {
//         panic!("invalid directory");
//     }
//
//     let name = match matches.value_of("name") {
//         Some(value) => value,
//         // directory.file_stem().map(|stem| stem.to_str()).unwrap()
//         None => "",
//     };
//
//     println!("directory: {:?}", directory);
//     println!("name: {:?}", name);
//
//     // let mut action = "save";
//     // // Increment the one requested (in a real program, we'd reset the lower numbers)
//     // let (save, delete, info, list) = (matches.is_present("save"),
//     //                              matches.is_present("delete"),
//     //                              matches.is_present("info"),
//     //                              matches.is_present("list"));
//     //
//     // match (save, delete, info, list) {
//     //     (true, _, _, _) => action = "save",
//     //     (_, true, _, _) => action = "delete",
//     //     (_, _, true, _) => action = "info",
//     //     (_, _, _, true) => action = "list",
//     //     _            => unreachable!(),
//     // };
//     //
//     // println!("action: {:?}", action);
//
//     let req = Request{ name: name.to_string(), directory: directory };
//
//     return Ok(req);
// }
//
//
// fn is_valid_dir(directory: &PathBuf) -> bool {
//     let path = directory.clone();
//
//     let metadata = match fs::metadata(path) {
//         Ok(value) => value,
//         Err(_) => return false,
//     };
//
//     if metadata.is_dir() {
//         return true;
//     }
//
//     return false;
// }
//
//
// // static NUMBERS: &'static [i32] = &'static [1, 2, 3, 4, 5];
// // static C: [E; 3] = [E::V0, E::V1(0xDEADBEE), E::V0];
// static ACTIONS: [Arg; 1] = [
//     Arg::with_name("save")
//         .help("Saves bookmark")
//         .long("save")
//         .short("s")
// ];
//
// // .arg(Arg::with_name("delete")
// //     .help("Delete bookmark")
// //     .long("delete")
// //     .short("d"))
//
// // ["save", "delete", "info", "list"];

#[derive(Debug)]
pub struct Request {
    pub name: String,
    pub directory: PathBuf,
    pub action: Action,
}

impl Request {
    fn new(name: &str, directory: &PathBuf) -> Request {
        Request{ name: "foo".to_string(), directory: PathBuf::from("."), action: Action::Get}
    }
}
<|endoftext|>


<commit_before>#![feature(core, test)]

extern crate coatcheck;
extern crate test;

use test::Bencher;
use std::collections::HashMap;

use coatcheck::*;

#[bench]
fn bench_hash_map(b: &mut Bencher) {
    let mut map = HashMap::with_capacity(6);
    b.iter(|| {
        map.insert(0us, "something");
        map.insert(1, "something");
        let _ = map.remove(&0);
        map.insert(2, "something");
        map.insert(3, "something");
        map.insert(4, "something");
        let _ = map.remove(&3);
        map.insert(5, "something");
        let _ = map.remove(&2);
        let _ = map.remove(&1);
        let _ = map.remove(&4);
        let _ = map.remove(&5);
    });
}

#[bench]
fn bench_coat_check(b: &mut Bencher) {
    let mut cc = CoatCheck::with_capacity(6);
    b.iter(|| {
        let t1 = cc.check("something");
        let t2 = cc.check("something");
        let _ = cc.claim(t1);
        let t3 = cc.check("something");
        let t4 = cc.check("something");
        let t5 = cc.check("something");
        let _ = cc.claim(t4);
        let t6 = cc.check("something");
        let _ = cc.claim(t3);
        let _ = cc.claim(t2);
        let _ = cc.claim(t5);
        let _ = cc.claim(t6);
    });
}

#[bench]
fn bench_box(b: &mut Bencher) {
    b.iter(|| {
        let b1 = Box::new("something");
        let b2 = Box::new("something");
        drop(b1);
        let b3 = Box::new("something");
        let b4 = Box::new("something");
        let b5 = Box::new("something");
        drop(b4);
        let b6 = Box::new("something");
        drop(b3);
        drop(b2);
        drop(b5);
        drop(b6);
    });
}

#[bench]
fn bench_coat_check_init(b: &mut Bencher) {
    b.iter(|| {
        for _ in 0..1000 {
            test::black_box(CoatCheck::<u64>::new());
        }
    });
}

#[bench]
fn bench_coat_check_access(b: &mut Bencher) {
    let mut cc = CoatCheck::new();
    let mut tickets = Vec::with_capacity(100);
    for _ in 0..100 {
        tickets.push(cc.check("something"));
    }
    let ref t = tickets[20];
    b.iter(|&: | {
        test::black_box(&cc[*t]);
    });
}

#[bench]
fn bench_hash_map_access(b: &mut Bencher) {
    let mut map = HashMap::with_capacity(100);
    for i in 0i32..100 {
        map.insert(i, "something");
    }
    b.iter(|&:| {
        test::black_box(&map[20i32]);
    });
}

<commit_msg>Remove core feature from benches.<commit_after>#![feature(test)]

extern crate coatcheck;
extern crate test;

use test::Bencher;
use std::collections::HashMap;

use coatcheck::*;

#[bench]
fn bench_hash_map(b: &mut Bencher) {
    let mut map = HashMap::with_capacity(6);
    b.iter(|| {
        map.insert(0us, "something");
        map.insert(1, "something");
        let _ = map.remove(&0);
        map.insert(2, "something");
        map.insert(3, "something");
        map.insert(4, "something");
        let _ = map.remove(&3);
        map.insert(5, "something");
        let _ = map.remove(&2);
        let _ = map.remove(&1);
        let _ = map.remove(&4);
        let _ = map.remove(&5);
    });
}

#[bench]
fn bench_coat_check(b: &mut Bencher) {
    let mut cc = CoatCheck::with_capacity(6);
    b.iter(|| {
        let t1 = cc.check("something");
        let t2 = cc.check("something");
        let _ = cc.claim(t1);
        let t3 = cc.check("something");
        let t4 = cc.check("something");
        let t5 = cc.check("something");
        let _ = cc.claim(t4);
        let t6 = cc.check("something");
        let _ = cc.claim(t3);
        let _ = cc.claim(t2);
        let _ = cc.claim(t5);
        let _ = cc.claim(t6);
    });
}

#[bench]
fn bench_box(b: &mut Bencher) {
    b.iter(|| {
        let b1 = Box::new("something");
        let b2 = Box::new("something");
        drop(b1);
        let b3 = Box::new("something");
        let b4 = Box::new("something");
        let b5 = Box::new("something");
        drop(b4);
        let b6 = Box::new("something");
        drop(b3);
        drop(b2);
        drop(b5);
        drop(b6);
    });
}

#[bench]
fn bench_coat_check_init(b: &mut Bencher) {
    b.iter(|| {
        for _ in 0..1000 {
            test::black_box(CoatCheck::<u64>::new());
        }
    });
}

#[bench]
fn bench_coat_check_access(b: &mut Bencher) {
    let mut cc = CoatCheck::new();
    let mut tickets = Vec::with_capacity(100);
    for _ in 0..100 {
        tickets.push(cc.check("something"));
    }
    let ref t = tickets[20];
    b.iter(|&: | {
        test::black_box(&cc[*t]);
    });
}

#[bench]
fn bench_hash_map_access(b: &mut Bencher) {
    let mut map = HashMap::with_capacity(100);
    for i in 0i32..100 {
        map.insert(i, "something");
    }
    b.iter(|&:| {
        test::black_box(&map[20i32]);
    });
}

<|endoftext|>