aboutsummaryrefslogtreecommitdiff
path: root/src/grammar/expressions/mod.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-04 15:12:00 +0100
committerAleksey Kladov <[email protected]>2018-08-04 15:12:00 +0100
commit82efdff34bf24680bef58eca399ec3f20748a96a (patch)
treec7f5d7346b0e8eaf4d9df8d728c985db523f1938 /src/grammar/expressions/mod.rs
parentc5483822520e9c754f3ec8b9eb8e68bd5ef7c373 (diff)
no-struct-literal-restr
Diffstat (limited to 'src/grammar/expressions/mod.rs')
-rw-r--r--src/grammar/expressions/mod.rs110
1 files changed, 56 insertions, 54 deletions
diff --git a/src/grammar/expressions/mod.rs b/src/grammar/expressions/mod.rs
index f2b0c36f5..cedbc235f 100644
--- a/src/grammar/expressions/mod.rs
+++ b/src/grammar/expressions/mod.rs
@@ -6,7 +6,13 @@ pub(super) use self::atom::literal;
6const EXPR_FIRST: TokenSet = UNARY_EXPR_FIRST; 6const EXPR_FIRST: TokenSet = UNARY_EXPR_FIRST;
7 7
8pub(super) fn expr(p: &mut Parser) { 8pub(super) fn expr(p: &mut Parser) {
9 expr_bp(p, 1) 9 let r = Restrictions { forbid_structs: false };
10 expr_bp(p, r, 1)
11}
12
13fn expr_no_struct(p: &mut Parser) {
14 let r = Restrictions { forbid_structs: true };
15 expr_bp(p, r, 1)
10} 16}
11 17
12// test block 18// test block
@@ -22,6 +28,11 @@ pub(super) fn block(p: &mut Parser) {
22 atom::block_expr(p); 28 atom::block_expr(p);
23} 29}
24 30
31#[derive(Clone, Copy)]
32struct Restrictions {
33 forbid_structs: bool
34}
35
25// test expr_binding_power 36// test expr_binding_power
26// fn foo() { 37// fn foo() {
27// 1 + 2 * 3 == 1 * 2 + 3 38// 1 + 2 * 3 == 1 * 2 + 3
@@ -36,8 +47,8 @@ fn bp_of(op: SyntaxKind) -> u8 {
36} 47}
37 48
38// Parses expression with binding power of at least bp. 49// Parses expression with binding power of at least bp.
39fn expr_bp(p: &mut Parser, bp: u8) { 50fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) {
40 let mut lhs = match unary_expr(p) { 51 let mut lhs = match unary_expr(p, r) {
41 Some(lhs) => lhs, 52 Some(lhs) => lhs,
42 None => return, 53 None => return,
43 }; 54 };
@@ -47,7 +58,7 @@ fn expr_bp(p: &mut Parser, bp: u8) {
47 if op_bp < bp { 58 if op_bp < bp {
48 break; 59 break;
49 } 60 }
50 lhs = bin_expr(p, lhs, op_bp); 61 lhs = bin_expr(p, r, lhs, op_bp);
51 } 62 }
52} 63}
53 64
@@ -57,17 +68,46 @@ const UNARY_EXPR_FIRST: TokenSet =
57 atom::ATOM_EXPR_FIRST, 68 atom::ATOM_EXPR_FIRST,
58 ]; 69 ];
59 70
60fn unary_expr(p: &mut Parser) -> Option<CompletedMarker> { 71fn unary_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
61 let done = match p.current() { 72 let m;
62 AMPERSAND => ref_expr(p), 73 let kind = match p.current() {
63 STAR => deref_expr(p), 74 // test ref_expr
64 EXCL => not_expr(p), 75 // fn foo() {
76 // let _ = &1;
77 // let _ = &mut &f();
78 // }
79 AMPERSAND => {
80 m = p.start();
81 p.bump();
82 p.eat(MUT_KW);
83 REF_EXPR
84
85 },
86 // test deref_expr
87 // fn foo() {
88 // **&1;
89 // }
90 STAR => {
91 m = p.start();
92 p.bump();
93 DEREF_EXPR
94 },
95 // test not_expr
96 // fn foo() {
97 // !!true;
98 // }
99 EXCL => {
100 m = p.start();
101 p.bump();
102 NOT_EXPR
103 },
65 _ => { 104 _ => {
66 let lhs = atom::atom_expr(p)?; 105 let lhs = atom::atom_expr(p, r)?;
67 postfix_expr(p, lhs) 106 return Some(postfix_expr(p, lhs))
68 } 107 }
69 }; 108 };
70 Some(done) 109 expr(p);
110 Some(m.complete(p, kind))
71} 111}
72 112
73fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker { 113fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker {
@@ -87,44 +127,6 @@ fn postfix_expr(p: &mut Parser, mut lhs: CompletedMarker) -> CompletedMarker {
87 lhs 127 lhs
88} 128}
89 129
90// test ref_expr
91// fn foo() {
92// let _ = &1;
93// let _ = &mut &f();
94// }
95fn ref_expr(p: &mut Parser) -> CompletedMarker {
96 assert!(p.at(AMPERSAND));
97 let m = p.start();
98 p.bump();
99 p.eat(MUT_KW);
100 expr(p);
101 m.complete(p, REF_EXPR)
102}
103
104// test deref_expr
105// fn foo() {
106// **&1;
107// }
108fn deref_expr(p: &mut Parser) -> CompletedMarker {
109 assert!(p.at(STAR));
110 let m = p.start();
111 p.bump();
112 expr(p);
113 m.complete(p, DEREF_EXPR)
114}
115
116// test not_expr
117// fn foo() {
118// !!true;
119// }
120fn not_expr(p: &mut Parser) -> CompletedMarker {
121 assert!(p.at(EXCL));
122 let m = p.start();
123 p.bump();
124 expr(p);
125 m.complete(p, NOT_EXPR)
126}
127
128// test call_expr 130// test call_expr
129// fn foo() { 131// fn foo() {
130// let _ = f(); 132// let _ = f();
@@ -199,11 +201,11 @@ fn arg_list(p: &mut Parser) {
199// let _ = a::b; 201// let _ = a::b;
200// let _ = ::a::<b>; 202// let _ = ::a::<b>;
201// } 203// }
202fn path_expr(p: &mut Parser) -> CompletedMarker { 204fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
203 assert!(paths::is_path_start(p)); 205 assert!(paths::is_path_start(p));
204 let m = p.start(); 206 let m = p.start();
205 paths::expr_path(p); 207 paths::expr_path(p);
206 if p.at(L_CURLY) { 208 if p.at(L_CURLY) && !r.forbid_structs {
207 struct_lit(p); 209 struct_lit(p);
208 m.complete(p, STRUCT_LIT) 210 m.complete(p, STRUCT_LIT)
209 } else { 211 } else {
@@ -243,13 +245,13 @@ fn struct_lit(p: &mut Parser) {
243 p.expect(R_CURLY); 245 p.expect(R_CURLY);
244} 246}
245 247
246fn bin_expr(p: &mut Parser, lhs: CompletedMarker, bp: u8) -> CompletedMarker { 248fn bin_expr(p: &mut Parser, r: Restrictions, lhs: CompletedMarker, bp: u8) -> CompletedMarker {
247 assert!(match p.current() { 249 assert!(match p.current() {
248 MINUS | PLUS | STAR | SLASH | EQEQ | NEQ => true, 250 MINUS | PLUS | STAR | SLASH | EQEQ | NEQ => true,
249 _ => false, 251 _ => false,
250 }); 252 });
251 let m = lhs.precede(p); 253 let m = lhs.precede(p);
252 p.bump(); 254 p.bump();
253 expr_bp(p, bp); 255 expr_bp(p, r, bp);
254 m.complete(p, BIN_EXPR) 256 m.complete(p, BIN_EXPR)
255} 257}