#![feature(plugin)]
#![plugin(peg_syntax_ext)]
use arithmetic::expression;

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Expression {
	Number(i64),
	Sum(Box<Expression>, Box<Expression>),
	Product(Box<Expression>, Box<Expression>),
}

peg! arithmetic(r#"
use super::Expression;

#[pub]
expression -> Expression
	= sum

sum -> Expression
	= l:product "+" r:product { Expression::Sum(Box::new(l), Box::new(r)) }
	/ product

product -> Expression
	= l:atom "*" r:atom { Expression::Product(Box::new(l), Box::new(r)) }
	/ atom

atom -> Expression
	= number
	/ "(" v:sum ")" { v }

number -> Expression
	= [0-9]+ { Expression::Number(match_str.parse().unwrap()) }
"#);

#[test]
fn main() {
	assert_eq!(expression("1+1"), Ok(Expression::Sum(
		Box::new(Expression::Number(1)),
		Box::new(Expression::Number(1)))
	));
	assert_eq!(expression("5*5"), Ok(Expression::Product(
		Box::new(Expression::Number(5)),
		Box::new(Expression::Number(5)))
	));
	assert_eq!(expression("2+3*4"), Ok(Expression::Sum(
		Box::new(Expression::Number(2)),
		Box::new(Expression::Product(
			Box::new(Expression::Number(3)),
			Box::new(Expression::Number(4))
		)),
	)));
	assert!(expression("(22+)+1").is_err());
	assert!(expression("1++1").is_err());
	assert!(expression("3)+1").is_err());
}

Add a version of the arithmetic example that returns an AST as an enum
Add a version of the arithmetic example that returns an AST as an enum

Closes #114
