blob: f0ec2c5918edd1382402070d3cf42fc92979f43b [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),
David Tolnayf43ba802016-10-30 10:20:47 -070021 /// No-op: used solely so we can pretty-print faithfully
22 Paren(Box<ConstExpr>),
David Tolnay3cb23a92016-10-07 23:02:21 -070023}
24
25#[cfg(feature = "parsing")]
26pub mod parsing {
27 use super::*;
28 use {BinOp, Ty};
29 use lit::parsing::lit;
30 use op::parsing::{binop, unop};
31 use ty::parsing::{path, ty};
32
33 named!(pub const_expr -> ConstExpr, do_parse!(
34 mut e: alt!(
David Tolnay3cb23a92016-10-07 23:02:21 -070035 expr_unary
36 |
David Tolnayf43ba802016-10-30 10:20:47 -070037 expr_lit
38 |
39 expr_path
40 |
41 expr_paren
David Tolnay3cb23a92016-10-07 23:02:21 -070042 ) >>
43 many0!(alt!(
44 tap!(args: and_call => {
45 e = ConstExpr::Call(Box::new(e), args);
46 })
47 |
48 tap!(more: and_binary => {
49 let (op, other) = more;
50 e = ConstExpr::Binary(op, Box::new(e), Box::new(other));
51 })
52 |
53 tap!(ty: and_cast => {
54 e = ConstExpr::Cast(Box::new(e), Box::new(ty));
55 })
56 )) >>
57 (e)
58 ));
59
60 named!(and_call -> Vec<ConstExpr>, do_parse!(
61 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -070062 args: terminated_list!(punct!(","), const_expr) >>
David Tolnay3cb23a92016-10-07 23:02:21 -070063 punct!(")") >>
64 (args)
65 ));
66
67 named!(and_binary -> (BinOp, ConstExpr), tuple!(binop, const_expr));
68
69 named!(expr_unary -> ConstExpr, do_parse!(
70 operator: unop >>
71 operand: const_expr >>
72 (ConstExpr::Unary(operator, Box::new(operand)))
73 ));
74
75 named!(expr_lit -> ConstExpr, map!(lit, ConstExpr::Lit));
76
David Tolnayf43ba802016-10-30 10:20:47 -070077 named!(expr_path -> ConstExpr, map!(path, ConstExpr::Path));
78
79 named!(expr_paren -> ConstExpr, do_parse!(
80 punct!("(") >>
81 e: const_expr >>
82 punct!(")") >>
83 (ConstExpr::Paren(Box::new(e)))
84 ));
85
David Tolnay3cb23a92016-10-07 23:02:21 -070086 named!(and_cast -> Ty, do_parse!(
87 keyword!("as") >>
88 ty: ty >>
89 (ty)
90 ));
91}
92
93#[cfg(feature = "printing")]
94mod printing {
95 use super::*;
96 use quote::{Tokens, ToTokens};
97
98 impl ToTokens for ConstExpr {
99 fn to_tokens(&self, tokens: &mut Tokens) {
100 match *self {
101 ConstExpr::Call(ref func, ref args) => {
102 func.to_tokens(tokens);
103 tokens.append("(");
104 tokens.append_separated(args, ",");
105 tokens.append(")");
106 }
107 ConstExpr::Binary(op, ref left, ref right) => {
108 left.to_tokens(tokens);
109 op.to_tokens(tokens);
110 right.to_tokens(tokens);
111 }
112 ConstExpr::Unary(op, ref expr) => {
113 op.to_tokens(tokens);
114 expr.to_tokens(tokens);
115 }
116 ConstExpr::Lit(ref lit) => lit.to_tokens(tokens),
117 ConstExpr::Cast(ref expr, ref ty) => {
118 expr.to_tokens(tokens);
119 tokens.append("as");
120 ty.to_tokens(tokens);
121 }
122 ConstExpr::Path(ref path) => path.to_tokens(tokens),
David Tolnayf43ba802016-10-30 10:20:47 -0700123 ConstExpr::Paren(ref expr) => {
124 tokens.append("(");
125 expr.to_tokens(tokens);
126 tokens.append(")");
127 }
David Tolnay3cb23a92016-10-07 23:02:21 -0700128 }
129 }
130 }
131}