ConstExpr type for discriminant and array len
diff --git a/src/expr.rs b/src/expr.rs
index f2f96d0..fa7cdf7 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -188,56 +188,6 @@
     pub attrs: Vec<Attribute>,
 }
 
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub enum BinOp {
-    /// The `+` operator (addition)
-    Add,
-    /// The `-` operator (subtraction)
-    Sub,
-    /// The `*` operator (multiplication)
-    Mul,
-    /// The `/` operator (division)
-    Div,
-    /// The `%` operator (modulus)
-    Rem,
-    /// The `&&` operator (logical and)
-    And,
-    /// The `||` operator (logical or)
-    Or,
-    /// The `^` operator (bitwise xor)
-    BitXor,
-    /// The `&` operator (bitwise and)
-    BitAnd,
-    /// The `|` operator (bitwise or)
-    BitOr,
-    /// The `<<` operator (shift left)
-    Shl,
-    /// The `>>` operator (shift right)
-    Shr,
-    /// The `==` operator (equality)
-    Eq,
-    /// The `<` operator (less than)
-    Lt,
-    /// The `<=` operator (less than or equal to)
-    Le,
-    /// The `!=` operator (not equal to)
-    Ne,
-    /// The `>=` operator (greater than or equal to)
-    Ge,
-    /// The `>` operator (greater than)
-    Gt,
-}
-
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub enum UnOp {
-    /// The `*` operator for dereferencing
-    Deref,
-    /// The `!` operator for logical inversion
-    Not,
-    /// The `-` operator for negation
-    Neg,
-}
-
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum Pat {
     /// Represents a wildcard pattern (`_`)
@@ -340,7 +290,7 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
-    use {Delimited, DelimToken, FnArg, FnDecl, FunctionRetTy, Ident, Lifetime, TokenTree, Ty};
+    use {BinOp, Delimited, DelimToken, FnArg, FnDecl, FunctionRetTy, Ident, Lifetime, TokenTree, Ty};
     use attr::parsing::outer_attr;
     use generics::parsing::lifetime;
     use ident::parsing::ident;
@@ -348,6 +298,7 @@
     use lit::parsing::lit;
     use mac::parsing::mac;
     use nom::IResult::Error;
+    use op::parsing::{binop, unop};
     use ty::parsing::{mutability, path, qpath, ty};
 
     named!(pub expr -> Expr, do_parse!(
@@ -482,55 +433,10 @@
         (Expr::Tup(elems))
     ));
 
-    named!(and_binary -> (BinOp, Expr), tuple!(
-        alt!(
-            punct!("&&") => { |_| BinOp::And }
-            |
-            punct!("||") => { |_| BinOp::Or }
-            |
-            punct!("<<") => { |_| BinOp::Shl }
-            |
-            punct!(">>") => { |_| BinOp::Shr }
-            |
-            punct!("==") => { |_| BinOp::Eq }
-            |
-            punct!("<=") => { |_| BinOp::Le }
-            |
-            punct!("!=") => { |_| BinOp::Ne }
-            |
-            punct!(">=") => { |_| BinOp::Ge }
-            |
-            punct!("+") => { |_| BinOp::Add }
-            |
-            punct!("-") => { |_| BinOp::Sub }
-            |
-            punct!("*") => { |_| BinOp::Mul }
-            |
-            punct!("/") => { |_| BinOp::Div }
-            |
-            punct!("%") => { |_| BinOp::Rem }
-            |
-            punct!("^") => { |_| BinOp::BitXor }
-            |
-            punct!("&") => { |_| BinOp::BitAnd }
-            |
-            punct!("|") => { |_| BinOp::BitOr }
-            |
-            punct!("<") => { |_| BinOp::Lt }
-            |
-            punct!(">") => { |_| BinOp::Gt }
-        ),
-        expr
-    ));
+    named!(and_binary -> (BinOp, Expr), tuple!(binop, expr));
 
     named!(expr_unary -> Expr, do_parse!(
-        operator: alt!(
-            punct!("*") => { |_| UnOp::Deref }
-            |
-            punct!("!") => { |_| UnOp::Not }
-            |
-            punct!("-") => { |_| UnOp::Neg }
-        ) >>
+        operator: unop >>
         operand: expr >>
         (Expr::Unary(operator, Box::new(operand)))
     ));
@@ -1206,7 +1112,7 @@
                 }
                 Expr::AssignOp(op, ref var, ref expr) => {
                     var.to_tokens(tokens);
-                    tokens.append(op.assign_op());
+                    tokens.append(op.assign_op().unwrap());
                     expr.to_tokens(tokens);
                 }
                 Expr::Field(ref expr, ref field) => {
@@ -1306,69 +1212,6 @@
         }
     }
 
-    impl BinOp {
-        fn op(&self) -> &'static str {
-            match *self {
-                BinOp::Add => "+",
-                BinOp::Sub => "-",
-                BinOp::Mul => "*",
-                BinOp::Div => "/",
-                BinOp::Rem => "%",
-                BinOp::And => "&&",
-                BinOp::Or => "||",
-                BinOp::BitXor => "^",
-                BinOp::BitAnd => "&",
-                BinOp::BitOr => "|",
-                BinOp::Shl => "<<",
-                BinOp::Shr => ">>",
-                BinOp::Eq => "==",
-                BinOp::Lt => "<",
-                BinOp::Le => "<=",
-                BinOp::Ne => "!=",
-                BinOp::Ge => ">=",
-                BinOp::Gt => ">",
-            }
-        }
-
-        fn assign_op(&self) -> &'static str {
-            match *self {
-                BinOp::Add => "+=",
-                BinOp::Sub => "-=",
-                BinOp::Mul => "*=",
-                BinOp::Div => "/=",
-                BinOp::Rem => "%=",
-                BinOp::BitXor => "^=",
-                BinOp::BitAnd => "&=",
-                BinOp::BitOr => "|=",
-                BinOp::Shl => "<<=",
-                BinOp::Shr => ">>=",
-                _ => panic!("bad assignment operator"),
-            }
-        }
-    }
-
-    impl ToTokens for BinOp {
-        fn to_tokens(&self, tokens: &mut Tokens) {
-            tokens.append(self.op());
-        }
-    }
-
-    impl UnOp {
-        fn op(&self) -> &'static str {
-            match *self {
-                UnOp::Deref => "*",
-                UnOp::Not => "!",
-                UnOp::Neg => "-",
-            }
-        }
-    }
-
-    impl ToTokens for UnOp {
-        fn to_tokens(&self, tokens: &mut Tokens) {
-            tokens.append(self.op());
-        }
-    }
-
     impl ToTokens for FieldValue {
         fn to_tokens(&self, tokens: &mut Tokens) {
             self.ident.to_tokens(tokens);