~agam/SimpleCalc

8600337cb1b6c110a79eb03546b35d7d9498dd0b — Agam Brahma 2 years ago 634ee78
Factored out `Operator` wrapper
1 files changed, 19 insertions(+), 12 deletions(-)

M src/main.rs
M src/main.rs => src/main.rs +19 -12
@@ 1,13 1,16 @@

// See `peg` API at https://docs.rs/peg/0.7.0/peg/

fn eval(op: &str, n1: i64, n2: i64) -> i64 {
#[derive(Debug)]
struct Operator(char);

fn eval(op: &Operator, n1: i64, n2: i64) -> i64 {
    match op {
        "+" => n1 + n2,
        "-" => n1 - n2,
        "*" => n1 * n2,
        "/" => n1 / n2,
        &_ =>  { panic!("Bad op: {:?}", op); }
        Operator('+') => n1 + n2,
        Operator('-') => n1 - n2,
        Operator('*') => n1 * n2,
        Operator('/') => n1 / n2,
        _ =>  { panic!("Bad op: {:?}", op); }
    }
}



@@ 18,7 21,10 @@ peg::parser!(
            ? n.parse().or(Err("bad num"))
        }

        rule whitespace() = quiet!{[' ']+}
        rule whitespace() = quiet!{[' ']*}

        rule operator() -> Operator
        = op:$(['*' | '/' | '+' | '-']) { Operator(op.chars().nth(0).unwrap()) }

        rule paren() -> i64 
        = "(" whitespace() n:calculate() whitespace() ")" { n }


@@ 33,16 39,16 @@ peg::parser!(
        = 
        n:factor() { n }
        /
        n1:factor() whitespace() op:$("*" / "/") whitespace() n2:factor() {
            eval(op, n1, n2)
        n1:factor() whitespace() op:operator() whitespace() n2:factor() {
            eval(&op, n1, n2)
        }

        pub rule calculate() -> i64
        =
        n:term() { n }
        / 
        n1:term() whitespace() op:$("+" / "-") whitespace() n2:term() {
            eval(op, n1, n2)
        n1:term() whitespace() op:operator() whitespace() n2:term() {
            eval(&op, n1, n2)
        }
    }
    );


@@ 53,6 59,7 @@ fn main() {
#[test]
fn test_basic_num() {
    assert_eq!(calc_parser::calculate("42"), Ok(42));
    assert_eq!(calc_parser::calculate("2 + 4"), Ok(6));
    assert_eq!(calc_parser::calculate("(4)"), Ok(4));
    // assert_eq!(calc_parser::calculate("2 + 4"), Ok(6));
    assert_eq!(calc_parser::calculate("3 * 8"), Ok(24));
}