More expression parsing
diff --git a/src/expr.rs b/src/expr.rs
index 1026654..312027f 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -4,8 +4,6 @@
 pub enum Expr {
     /// A `box x` expression.
     Box(Box<Expr>),
-    /// First expr is the place; second expr is the value.
-    InPlace(Box<Expr>, Box<Expr>),
     /// An array (`[a, b, c, d]`)
     Vec(Vec<Expr>),
     /// A function call
@@ -337,18 +335,137 @@
 #[cfg(feature = "parsing")]
 pub mod parsing {
     use super::*;
+    use {Ident, Ty};
+    use ident::parsing::ident;
+    use lit::parsing::lit;
     use nom::multispace;
+    use ty::parsing::ty;
 
-    named!(pub expr -> Expr, alt!(
-        box_expr
+    named!(pub expr -> Expr, do_parse!(
+        mut e: alt!(
+            boxed
+            |
+            vec
+            |
+            tup
+            |
+            unary
+            |
+            map!(lit, Expr::Lit)
+        ) >>
+        many0!(alt!(
+            tap!(c: call => {
+                e = Expr::Call(Box::new(e), c);
+            })
+            |
+            tap!(c: method_call => {
+                let (method, ascript, mut args) = c;
+                args.insert(0, e);
+                e = Expr::MethodCall(method, ascript, args);
+            })
+            |
+            tap!(b: binary => {
+                let (op, other) = b;
+                e = Expr::Binary(op, Box::new(e), Box::new(other));
+            })
+        )) >>
+        (e)
     ));
 
-    named!(box_expr -> Expr, do_parse!(
+    named!(boxed -> Expr, do_parse!(
         punct!("box") >>
         multispace >>
         inner: expr >>
         (Expr::Box(Box::new(inner)))
     ));
+
+    named!(vec -> Expr, do_parse!(
+        punct!("[") >>
+        elems: separated_list!(punct!(","), expr) >>
+        punct!("]") >>
+        (Expr::Vec(elems))
+    ));
+
+    named!(call -> Vec<Expr>, do_parse!(
+        punct!("(") >>
+        args: separated_list!(punct!(","), expr) >>
+        punct!(")") >>
+        (args)
+    ));
+
+    named!(method_call -> (Ident, Vec<Ty>, Vec<Expr>), do_parse!(
+        punct!(".") >>
+        method: ident >>
+        ascript: opt_vec!(delimited!(
+            punct!("<"),
+            separated_list!(punct!(","), ty),
+            punct!(">")
+        )) >>
+        punct!("(") >>
+        args: separated_list!(punct!(","), expr) >>
+        punct!(")") >>
+        (method, ascript, args)
+    ));
+
+    named!(tup -> Expr, do_parse!(
+        punct!("(") >>
+        elems: separated_list!(punct!(","), expr) >>
+        punct!(")") >>
+        (Expr::Tup(elems))
+    ));
+
+    named!(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!(unary -> Expr, do_parse!(
+        operator: alt!(
+            punct!("*") => { |_| UnOp::Deref }
+            |
+            punct!("!") => { |_| UnOp::Not }
+            |
+            punct!("-") => { |_| UnOp::Neg }
+        ) >>
+        operand: expr >>
+        (Expr::Unary(operator, Box::new(operand)))
+    ));
 }
 
 #[cfg(feature = "printing")]
diff --git a/src/helper.rs b/src/helper.rs
index bccdd42..2a429e9 100644
--- a/src/helper.rs
+++ b/src/helper.rs
@@ -25,8 +25,8 @@
 macro_rules! option {
     ($i:expr, $submac:ident!( $($args:tt)* )) => {
         match $submac!($i, $($args)*) {
-            ::nom::IResult::Done(i, o) => ::nom::IResult::Done(i, Some(o)),
-            ::nom::IResult::Error => ::nom::IResult::Done($i, None),
+            $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, Some(o)),
+            $crate::nom::IResult::Error => $crate::nom::IResult::Done($i, None),
         }
     };
 
@@ -38,14 +38,31 @@
 macro_rules! opt_vec {
     ($i:expr, $submac:ident!( $($args:tt)* )) => {
         match $submac!($i, $($args)*) {
-            ::nom::IResult::Done(i, o) => ::nom::IResult::Done(i, o),
-            ::nom::IResult::Error => ::nom::IResult::Done($i, Vec::new()),
+            $crate::nom::IResult::Done(i, o) => $crate::nom::IResult::Done(i, o),
+            $crate::nom::IResult::Error => $crate::nom::IResult::Done($i, Vec::new()),
         }
     };
 }
 
 macro_rules! epsilon {
     ($i:expr,) => {
-        value!($i, ())
+        $crate::nom::IResult::Done($i, ())
+    };
+}
+
+macro_rules! tap {
+    ($i:expr, $name:ident : $submac:ident!( $($args:tt)* ) => $e:expr) => {
+        match $submac!($i, $($args)*) {
+            $crate::nom::IResult::Done(i, o) => {
+                let $name = o;
+                $e;
+                $crate::nom::IResult::Done(i, ())
+            }
+            $crate::nom::IResult::Error => $crate::nom::IResult::Error,
+        }
+    };
+
+    ($i:expr, $name:ident : $f:expr => $e:expr) => {
+        tap!($i, $name: call!($f) => $e);
     };
 }
diff --git a/src/lit.rs b/src/lit.rs
index 92d5339..7dcc8bc 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -118,16 +118,14 @@
                     bytes.next();
                     len += 1;
                 }
-                _ => {
-                    return if len > 0 {
-                        IResult::Done(&input[len..], value)
-                    } else {
-                        IResult::Error
-                    };
-                },
+                _ => break,
             }
         }
-        IResult::Error
+        if len > 0 {
+            IResult::Done(&input[len..], value)
+        } else {
+            IResult::Error
+        }
     }
 }
 
diff --git a/src/nom.rs b/src/nom.rs
index a899a20..5d9d00c 100644
--- a/src/nom.rs
+++ b/src/nom.rs
@@ -549,6 +549,20 @@
         }
     };
 
+    ($i:expr, mut $field:ident : $e:ident >> $($rest:tt)*) => {
+        do_parse!($i, $field: call!($e) >> $($rest)*);
+    };
+
+    ($i:expr, mut $field:ident : $submac:ident!( $($args:tt)* ) >> $($rest:tt)*) => {
+        match $submac!($i, $($args)*) {
+            $crate::nom::IResult::Error => $crate::nom::IResult::Error,
+            $crate::nom::IResult::Done(i,o) => {
+                let mut $field = o;
+                do_parse!(i, $($rest)*)
+            },
+        }
+    };
+
     // ending the chain
     ($i:expr, $e:ident >> ( $($rest:tt)* )) => {
         do_parse!($i, call!($e) >> ( $($rest)* ));