1 #[macro_use]
2 extern crate nom;
3
4 use std::fmt;
is_graph_style(int grf)5 use std::fmt::{Display, Debug, Formatter};
6
7 use std::str;
8 use std::str::FromStr;
9
10 use nom::{IResult, digit, multispace};
11
12 pub enum Expr {
13 Value(i64),
14 Add(Box<Expr>, Box<Expr>),
15 Sub(Box<Expr>, Box<Expr>),
16 Mul(Box<Expr>, Box<Expr>),
17 Div(Box<Expr>, Box<Expr>),
18 Paren(Box<Expr>),
19 }
20
21 pub enum Oper {
22 Add,
23 Sub,
24 Mul,
25 Div,
get_cp(Xen snd,Xen x_chn_n,const char * caller)26 }
27
28 impl Display for Expr {
29 fn fmt(&self, format: &mut Formatter) -> fmt::Result {
30 use self::Expr::*;
31 match *self {
32 Value(val) => write!(format, "{}", val),
33 Add(ref left, ref right) => write!(format, "{} + {}", left, right),
34 Sub(ref left, ref right) => write!(format, "{} - {}", left, right),
35 Mul(ref left, ref right) => write!(format, "{} * {}", left, right),
36 Div(ref left, ref right) => write!(format, "{} / {}", left, right),
37 Paren(ref expr) => write!(format, "({})", expr),
38 }
39 }
40 }
41
42 impl Debug for Expr {
43 fn fmt(&self, format: &mut Formatter) -> fmt::Result {
44 use self::Expr::*;
45 match *self {
46 Value(val) => write!(format, "{}", val),
47 Add(ref left, ref right) => write!(format, "({:?} + {:?})", left, right),
48 Sub(ref left, ref right) => write!(format, "({:?} - {:?})", left, right),
49 Mul(ref left, ref right) => write!(format, "({:?} * {:?})", left, right),
50 Div(ref left, ref right) => write!(format, "({:?} / {:?})", left, right),
51 Paren(ref expr) => write!(format, "[{:?}]", expr),
52 }
53 }
54 }
55
56 named!(parens< Expr >, delimited!(
57 delimited!(opt!(multispace), tag!("("), opt!(multispace)),
58 map!(map!(expr, Box::new), Expr::Paren),
59 delimited!(opt!(multispace), tag!(")"), opt!(multispace))
60 )
61 );
62
63 named!(factor< Expr >, alt_complete!(
64 map!(
65 map_res!(
66 map_res!(
after_transform(chan_info * cp,mus_float_t scaler)67 delimited!(opt!(multispace), digit, opt!(multispace)),
68 str::from_utf8
69 ),
70 FromStr::from_str
71 ),
72 Expr::Value)
73 | parens
74 )
75 );
76
77 fn fold_exprs(initial: Expr, remainder: Vec<(Oper, Expr)>) -> Expr {
run_after_graph_hook(chan_info * cp)78 remainder.into_iter().fold(initial, |acc, pair| {
79 let (oper, expr) = pair;
80 match oper {
81 Oper::Add => Expr::Add(Box::new(acc), Box::new(expr)),
82 Oper::Sub => Expr::Sub(Box::new(acc), Box::new(expr)),
83 Oper::Mul => Expr::Mul(Box::new(acc), Box::new(expr)),
84 Oper::Div => Expr::Div(Box::new(acc), Box::new(expr)),
85 }
86 })
87 }
88
89 named!(term< Expr >, do_parse!(
90 initial: factor >>
91 remainder: many0!(
chans_time_graph_type(chan_info * cp,int value)92 alt!(
93 do_parse!(tag!("*") >> mul: factor >> (Oper::Mul, mul)) |
94 do_parse!(tag!("/") >> div: factor >> (Oper::Div, div))
95 )
96 ) >>
97 (fold_exprs(initial, remainder))
98 ));
99
100 named!(expr< Expr >, do_parse!(
101 initial: term >>
102 remainder: many0!(
103 alt!(
104 do_parse!(tag!("+") >> add: term >> (Oper::Add, add)) |
set_time_graph_type(graph_type_t val)105 do_parse!(tag!("-") >> sub: term >> (Oper::Sub, sub))
106 )
107 ) >>
108 (fold_exprs(initial, remainder))
109 ));
110
111 #[test]
chans_wavo_hop(chan_info * cp,int hop)112 fn factor_test() {
113 assert_eq!(factor(&b" 3 "[..]).map(|x| format!("{:?}", x)),
114 IResult::Done(&b""[..], String::from("3")));
115 }
116
117 #[test]
set_wavo_hop(int uval)118 fn term_test() {
119 assert_eq!(term(&b" 3 * 5 "[..]).map(|x| format!("{:?}", x)),
120 IResult::Done(&b""[..], String::from("(3 * 5)")));
121 }
122
123 #[test]
124 fn expr_test() {
125 assert_eq!(expr(&b" 1 + 2 * 3 "[..]).map(|x| format!("{:?}", x)),
126 IResult::Done(&b""[..], String::from("(1 + (2 * 3))")));
127 assert_eq!(expr(&b" 1 + 2 * 3 / 4 - 5 "[..]).map(|x| format!("{:?}", x)),
128 IResult::Done(&b""[..], String::from("((1 + ((2 * 3) / 4)) - 5)")));
chans_wavo_trace(chan_info * cp,int value)129 assert_eq!(expr(&b" 72 / 2 / 3 "[..]).map(|x| format!("{:?}", x)),
130 IResult::Done(&b""[..], String::from("((72 / 2) / 3)")));
131 }
132
133 #[test]
134 fn parens_test() {
set_wavo_trace(int uval)135 assert_eq!(expr(&b" ( 1 + 2 ) * 3 "[..]).map(|x| format!("{:?}", x)),
136 IResult::Done(&b""[..], String::from("([(1 + 2)] * 3)")));
137 }
138