1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use std::io::{self, Write};

pub fn run_shell() {
    let mut accumulator: u64 = 0;

    loop {
        print!(">>> ");
        io::stdout().flush().expect("Error flushing stdout");

        let input = read_line();

        if !input.is_empty() {
            run(&mut accumulator, &input)
        }
    }
}

pub fn run_once(code: &str) {
    let mut accumulator: u64 = 0;

    run(&mut accumulator, code);
}

fn run(accumulator: &mut u64, code: &str) {
    let tokens: Vec<_> = code
        .split("")
        .map(str::to_lowercase)
        .filter(|x| x != "" && x != " ")
        .collect();

    for token in tokens {
        match token.as_str() {
            "h" => println!("Hello, sailor!"),
            "q" => println!("{}", code),
            "9" => {
                for x in (3..=99).rev() {
                    println!(
                        "{0} bottles of root beer on the wall, \
                         {0} bottles of root beer. Take one down, pass it around. \
                         {1} bottles of root beer on the wall.",
                        x,
                        x - 1
                    )
                }
                println!(
                    "2 bottles of root beer on the wall, \
                     2 bottles of root beer. Take one down, pass it around. \
                     1 bottle of root beer on the wall.\n\
                     1 bottle of root beer on the wall, \
                     1 bottle of root beer. Take one down, pass it around. \
                     Now there are no bottles of root beer on the wall."
                );
            }
            "+" => *accumulator += 1,
            _ => {
                println!("Invalid character in sequence!");
                break;
            }
        }
    }
}

fn read_line() -> String {
    let mut input = String::new();
    io::stdin()
        .read_line(&mut input)
        .expect("Error reading stdin");
    input.trim().to_owned()
}