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")]