custom_expression/
custom_expression.rs1extern crate ripin;
2
3use std::env;
4use std::marker::PhantomData;
5use ripin::{Stack, pop_two_operands};
6use ripin::convert_ref::TryFromRef;
7use ripin::expression::Expression;
8use ripin::evaluate::Evaluate;
9use ripin::variable::DummyVariable;
10
11#[derive(Debug, Copy, Clone)]
18enum MyOperand {
19 Number1,
20 Number2,
21}
22
23impl<'a> TryFromRef<&'a str> for MyOperand {
24 type Err = MyOperandErr<&'a str>;
25 fn try_from_ref(s: &&'a str) -> Result<Self, Self::Err> {
26 match *s {
27 "1" => Ok(MyOperand::Number1),
28 "2" => Ok(MyOperand::Number2),
29 _ => Err(MyOperandErr::InvalidToken(s))
30 }
31 }
32}
33
34#[derive(Debug, Copy, Clone)]
38enum MyEvaluator<T> {
39 Add,
40 Sub,
41 _Phantom(PhantomData<T>) }
44
45impl<'a, T> TryFromRef<&'a str> for MyEvaluator<T> {
46 type Err = MyOperandErr<&'a str>;
47 fn try_from_ref(s: &&'a str) -> Result<Self, Self::Err> {
48 match *s {
49 "+" => Ok(MyEvaluator::Add),
50 "-" => Ok(MyEvaluator::Sub),
51 _ => Err(MyOperandErr::InvalidToken(s))
52 }
53 }
54}
55
56#[derive(Debug)]
58enum MyOperandErr<T> {
59 InvalidToken(T),
60}
61
62#[derive(Debug)]
68enum MyEvalErr<T> {
69 CannotAddOperands(T, T),
70 CannotSubOperands(T, T),
71 NotEnoughOperands
72}
73
74impl Evaluate<MyOperand> for MyEvaluator<MyOperand> {
77 type Err = MyEvalErr<MyOperand>;
78
79 fn operands_needed(&self) -> usize {
80 match *self {
81 MyEvaluator::Add | MyEvaluator::Sub => 2,
82 _ => unreachable!(), }
84 }
85 fn operands_generated(&self) -> usize {
86 match *self {
87 MyEvaluator::Add | MyEvaluator::Sub => 1,
88 _ => unreachable!(), }
90 }
91
92 fn evaluate(self, stack: &mut Stack<MyOperand>) -> Result<(), Self::Err> {
93 let (a, b) = pop_two_operands(stack).ok_or(MyEvalErr::NotEnoughOperands)?;
94 match self {
95 MyEvaluator::Add => {
96 match (a, b) {
97 (MyOperand::Number1, MyOperand::Number1) => {
98 Ok(stack.push(MyOperand::Number2))
99 },
100 _ => Err(MyEvalErr::CannotAddOperands(a, b)),
101 }
102 },
103 MyEvaluator::Sub => {
104 match (a, b) {
105 (MyOperand::Number2, MyOperand::Number1) => {
106 Ok(stack.push(MyOperand::Number1))
107 },
108 _ => Err(MyEvalErr::CannotSubOperands(a, b)),
109 }
110 }
111 _ => unreachable!() }
113 }
114}
115
116type MyExpression = Expression<MyOperand, DummyVariable, MyEvaluator<MyOperand>>;
117
118fn main() {
121 let expr_str = env::args().nth(1).unwrap_or_else(|| {
122 println!("Give me an expression as first argument!");
123 "1 1 +".into()
124 });
125
126 let tokens = expr_str.split_whitespace();
127 match MyExpression::from_iter(tokens) {
128 Ok(expr) => println!("Evaluation of {:?} gives {:?}", expr_str, expr.evaluate()),
129 Err(err) => println!("Parsing results in {:?}", err),
130 }
131}