blob: 28345397ea1dc1f8e78021ce696c26e217ce8d23 [file] [log] [blame]
David Tolnay3cb23a92016-10-07 23:02:21 -07001use super::*;
2
3#[derive(Debug, Clone, Eq, PartialEq)]
4pub enum ConstExpr {
5 /// A function call
6 ///
7 /// The first field resolves to the function itself,
8 /// and the second field is the list of arguments
9 Call(Box<ConstExpr>, Vec<ConstExpr>),
10 /// A binary operation (For example: `a + b`, `a * b`)
11 Binary(BinOp, Box<ConstExpr>, Box<ConstExpr>),
12 /// A unary operation (For example: `!x`, `*x`)
13 Unary(UnOp, Box<ConstExpr>),
14 /// A literal (For example: `1`, `"foo"`)
15 Lit(Lit),
16 /// A cast (`foo as f64`)
17 Cast(Box<ConstExpr>, Box<Ty>),
18 /// Variable reference, possibly containing `::` and/or type
19 /// parameters, e.g. foo::bar::<baz>.
20 Path(Path),
21}
22
23#[cfg(feature = "parsing")]
24pub mod parsing {
25 use super::*;
26 use {BinOp, Ty};
27 use lit::parsing::lit;
28 use op::parsing::{binop, unop};
29 use ty::parsing::{path, ty};
30
31 named!(pub const_expr -> ConstExpr, do_parse!(
32 mut e: alt!(
33 expr_lit
34 |
35 expr_unary
36 |
37 path => { ConstExpr::Path }
38 ) >>
39 many0!(alt!(
40 tap!(args: and_call => {
41 e = ConstExpr::Call(Box::new(e), args);
42 })
43 |
44 tap!(more: and_binary => {
45 let (op, other) = more;
46 e = ConstExpr::Binary(op, Box::new(e), Box::new(other));
47 })
48 |
49 tap!(ty: and_cast => {
50 e = ConstExpr::Cast(Box::new(e), Box::new(ty));
51 })
52 )) >>
53 (e)
54 ));
55
56 named!(and_call -> Vec<ConstExpr>, do_parse!(
57 punct!("(") >>
58 args: separated_list!(punct!(","), const_expr) >>
59 punct!(")") >>
60 (args)
61 ));
62
63 named!(and_binary -> (BinOp, ConstExpr), tuple!(binop, const_expr));
64
65 named!(expr_unary -> ConstExpr, do_parse!(
66 operator: unop >>
67 operand: const_expr >>
68 (ConstExpr::Unary(operator, Box::new(operand)))
69 ));
70
71 named!(expr_lit -> ConstExpr, map!(lit, ConstExpr::Lit));
72
73 named!(and_cast -> Ty, do_parse!(
74 keyword!("as") >>
75 ty: ty >>
76 (ty)
77 ));
78}
79
80#[cfg(feature = "printing")]
81mod printing {
82 use super::*;
83 use quote::{Tokens, ToTokens};
84
85 impl ToTokens for ConstExpr {
86 fn to_tokens(&self, tokens: &mut Tokens) {
87 match *self {
88 ConstExpr::Call(ref func, ref args) => {
89 func.to_tokens(tokens);
90 tokens.append("(");
91 tokens.append_separated(args, ",");
92 tokens.append(")");
93 }
94 ConstExpr::Binary(op, ref left, ref right) => {
95 left.to_tokens(tokens);
96 op.to_tokens(tokens);
97 right.to_tokens(tokens);
98 }
99 ConstExpr::Unary(op, ref expr) => {
100 op.to_tokens(tokens);
101 expr.to_tokens(tokens);
102 }
103 ConstExpr::Lit(ref lit) => lit.to_tokens(tokens),
104 ConstExpr::Cast(ref expr, ref ty) => {
105 expr.to_tokens(tokens);
106 tokens.append("as");
107 ty.to_tokens(tokens);
108 }
109 ConstExpr::Path(ref path) => path.to_tokens(tokens),
110 }
111 }
112 }
113}