aboutsummaryrefslogtreecommitdiff
path: root/src/grammar/expressions/atom.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-04 14:58:22 +0100
committerAleksey Kladov <[email protected]>2018-08-04 14:58:22 +0100
commitc5483822520e9c754f3ec8b9eb8e68bd5ef7c373 (patch)
tree5c1b0cd74781a4289c3b6269d5e77e9fc69eadd1 /src/grammar/expressions/atom.rs
parent23cbe7fd4a048ba44aee647b3b7d5a7f3aa575da (diff)
move atoms to a separate file
Diffstat (limited to 'src/grammar/expressions/atom.rs')
-rw-r--r--src/grammar/expressions/atom.rs239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/grammar/expressions/atom.rs b/src/grammar/expressions/atom.rs
new file mode 100644
index 000000000..95c811730
--- /dev/null
+++ b/src/grammar/expressions/atom.rs
@@ -0,0 +1,239 @@
1use super::*;
2
3// test expr_literals
4// fn foo() {
5// let _ = true;
6// let _ = false;
7// let _ = 1;
8// let _ = 2.0;
9// let _ = b'a';
10// let _ = 'b';
11// let _ = "c";
12// let _ = r"d";
13// let _ = b"e";
14// let _ = br"f";
15// }
16const LITERAL_FIRST: TokenSet =
17 token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR,
18 STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING];
19
20pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
21 if !LITERAL_FIRST.contains(p.current()) {
22 return None;
23 }
24 let m = p.start();
25 p.bump();
26 Some(m.complete(p, LITERAL))
27}
28
29pub(super) const ATOM_EXPR_FIRST: TokenSet =
30 token_set_union![
31 LITERAL_FIRST,
32 token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, MATCH_KW, UNSAFE_KW, L_CURLY, RETURN_KW,
33 IDENT, SELF_KW, SUPER_KW, COLONCOLON ],
34 ];
35
36pub(super) fn atom_expr(p: &mut Parser) -> Option<CompletedMarker> {
37 match literal(p) {
38 Some(m) => return Some(m),
39 None => (),
40 }
41 if paths::is_path_start(p) {
42 return Some(path_expr(p));
43 }
44 let la = p.nth(1);
45 let done = match p.current() {
46 L_PAREN => tuple_expr(p),
47 PIPE => lambda_expr(p),
48 MOVE_KW if la == PIPE => lambda_expr(p),
49 IF_KW => if_expr(p),
50 MATCH_KW => match_expr(p),
51 UNSAFE_KW if la == L_CURLY => block_expr(p),
52 L_CURLY => block_expr(p),
53 RETURN_KW => return_expr(p),
54 _ => {
55 p.err_and_bump("expected expression");
56 return None;
57 }
58 };
59 Some(done)
60}
61
62fn tuple_expr(p: &mut Parser) -> CompletedMarker {
63 assert!(p.at(L_PAREN));
64 let m = p.start();
65 p.expect(L_PAREN);
66 p.expect(R_PAREN);
67 m.complete(p, TUPLE_EXPR)
68}
69
70// test lambda_expr
71// fn foo() {
72// || ();
73// || -> i32 { 92 };
74// |x| x;
75// move |x: i32,| x;
76// }
77fn lambda_expr(p: &mut Parser) -> CompletedMarker {
78 assert!(p.at(PIPE) || (p.at(MOVE_KW) && p.nth(1) == PIPE));
79 let m = p.start();
80 p.eat(MOVE_KW);
81 params::param_list_opt_types(p);
82 if fn_ret_type(p) {
83 block(p);
84 } else {
85 expr(p)
86 }
87 m.complete(p, LAMBDA_EXPR)
88}
89
90// test if_expr
91// fn foo() {
92// if true {};
93// if true {} else {};
94// if true {} else if false {} else {}
95// }
96fn if_expr(p: &mut Parser) -> CompletedMarker {
97 assert!(p.at(IF_KW));
98 let m = p.start();
99 if_head(p);
100 block(p);
101 if p.at(ELSE_KW) {
102 p.bump();
103 if p.at(IF_KW) {
104 if_expr(p);
105 } else {
106 block(p);
107 }
108 }
109 m.complete(p, IF_EXPR)
110}
111
112fn if_head(p: &mut Parser) {
113 assert!(p.at(IF_KW));
114 p.bump();
115 expr(p);
116}
117
118// test match_expr
119// fn foo() {
120// match () { };
121// }
122fn match_expr(p: &mut Parser) -> CompletedMarker {
123 assert!(p.at(MATCH_KW));
124 let m = p.start();
125 p.bump();
126 expr(p);
127 p.eat(L_CURLY);
128 while !p.at(EOF) && !p.at(R_CURLY) {
129 match_arm(p);
130 if !p.at(R_CURLY) {
131 p.expect(COMMA);
132 }
133 }
134 p.expect(R_CURLY);
135 m.complete(p, MATCH_EXPR)
136}
137
138// test match_arm
139// fn foo() {
140// match () {
141// _ => (),
142// X | Y if Z => (),
143// };
144// }
145fn match_arm(p: &mut Parser) {
146 let m = p.start();
147 loop {
148 patterns::pattern(p);
149 if !p.eat(PIPE) {
150 break;
151 }
152 }
153 if p.at(IF_KW) {
154 if_head(p)
155 }
156 p.expect(FAT_ARROW);
157 expr(p);
158 m.complete(p, MATCH_ARM);
159}
160
161// test block_expr
162// fn foo() {
163// {};
164// unsafe {};
165// }
166pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker {
167 assert!(p.at(L_CURLY) || p.at(UNSAFE_KW) && p.nth(1) == L_CURLY);
168 let m = p.start();
169 p.eat(UNSAFE_KW);
170 p.bump();
171 while !p.at(EOF) && !p.at(R_CURLY) {
172 match p.current() {
173 LET_KW => let_stmt(p),
174 _ => {
175 // test block_items
176 // fn a() { fn b() {} }
177 let m = p.start();
178 match items::maybe_item(p) {
179 items::MaybeItem::Item(kind) => {
180 m.complete(p, kind);
181 }
182 items::MaybeItem::Modifiers => {
183 m.abandon(p);
184 p.error("expected an item");
185 }
186 // test pub_expr
187 // fn foo() { pub 92; } //FIXME
188 items::MaybeItem::None => {
189 expressions::expr(p);
190 if p.eat(SEMI) {
191 m.complete(p, EXPR_STMT);
192 } else {
193 m.abandon(p);
194 }
195 }
196 }
197 }
198 }
199 }
200 p.expect(R_CURLY);
201 m.complete(p, BLOCK_EXPR)
202}
203
204// test let_stmt;
205// fn foo() {
206// let a;
207// let b: i32;
208// let c = 92;
209// let d: i32 = 92;
210// }
211fn let_stmt(p: &mut Parser) {
212 assert!(p.at(LET_KW));
213 let m = p.start();
214 p.bump();
215 patterns::pattern(p);
216 if p.at(COLON) {
217 types::ascription(p);
218 }
219 if p.eat(EQ) {
220 expressions::expr(p);
221 }
222 p.expect(SEMI);
223 m.complete(p, LET_STMT);
224}
225
226// test return_expr
227// fn foo() {
228// return;
229// return 92;
230// }
231fn return_expr(p: &mut Parser) -> CompletedMarker {
232 assert!(p.at(RETURN_KW));
233 let m = p.start();
234 p.bump();
235 if EXPR_FIRST.contains(p.current()) {
236 expr(p);
237 }
238 m.complete(p, RETURN_EXPR)
239}