aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-01-28 18:21:35 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-01-28 18:21:35 +0000
commitab81e4c7b4383a153145752059be59e17571fad3 (patch)
tree131a740b555157b665f2094897697192e499af6e /src
parent08def60f16a222895b242d907163d914348894c7 (diff)
parentb9cbbfa4052a080d658ce32dedac03c4621ce5ed (diff)
Merge #29
29: Structs r=matklad a=matklad r? @CAD97
Diffstat (limited to 'src')
-rw-r--r--src/parser/event_parser/grammar/items/mod.rs (renamed from src/parser/event_parser/grammar/items.rs)108
-rw-r--r--src/parser/event_parser/grammar/items/structs.rs83
-rw-r--r--src/syntax_kinds.rs6
3 files changed, 124 insertions, 73 deletions
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items/mod.rs
index 56e3208ac..f10fb230b 100644
--- a/src/parser/event_parser/grammar/items.rs
+++ b/src/parser/event_parser/grammar/items/mod.rs
@@ -1,5 +1,7 @@
1use super::*; 1use super::*;
2 2
3mod structs;
4
3pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { 5pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
4 attributes::inner_attributes(p); 6 attributes::inner_attributes(p);
5 while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { 7 while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) {
@@ -29,7 +31,7 @@ fn item(p: &mut Parser) {
29 USE_ITEM 31 USE_ITEM
30 } 32 }
31 STRUCT_KW => { 33 STRUCT_KW => {
32 struct_item(p); 34 structs::struct_item(p);
33 STRUCT_ITEM 35 STRUCT_ITEM
34 } 36 }
35 FN_KW => { 37 FN_KW => {
@@ -57,90 +59,50 @@ fn item(p: &mut Parser) {
57 item.complete(p, item_kind); 59 item.complete(p, item_kind);
58} 60}
59 61
60fn struct_item(p: &mut Parser) { 62fn type_param_list(p: &mut Parser) {
61 assert!(p.at(STRUCT_KW)); 63 if !p.at(L_ANGLE) {
62 p.bump();
63
64 if !p.expect(IDENT) {
65 return; 64 return;
66 } 65 }
67 generic_parameters(p); 66 let m = p.start();
68 match p.current() {
69 WHERE_KW => {
70 where_clause(p);
71 match p.current() {
72 SEMI => {
73 p.bump();
74 return;
75 }
76 L_CURLY => named_fields(p),
77 _ => {
78 //TODO: special case `(` error message
79 p.error().message("expected `;` or `{`").emit();
80 return;
81 }
82 }
83 }
84 SEMI => {
85 p.bump();
86 return;
87 }
88 L_CURLY => named_fields(p),
89 L_PAREN => {
90 pos_fields(p);
91 p.expect(SEMI);
92 }
93 _ => {
94 p.error().message("expected `;`, `{`, or `(`").emit();
95 return;
96 }
97 }
98}
99
100fn named_fields(p: &mut Parser) {
101 assert!(p.at(L_CURLY));
102 p.bump(); 67 p.bump();
103 while !p.at(R_CURLY) && !p.at(EOF) {
104 named_field(p);
105 if !p.at(R_CURLY) {
106 p.expect(COMMA);
107 }
108 }
109 p.expect(R_CURLY);
110 68
111 fn named_field(p: &mut Parser) { 69 while !p.at(EOF) && !p.at(R_ANGLE) {
112 let field = p.start(); 70 match p.current() {
113 visibility(p); 71 LIFETIME => lifetime_param(p),
114 if p.expect(IDENT) { 72 IDENT => type_param(p),
115 p.expect(COLON); 73 _ => p.err_and_bump("expected type parameter"),
116 types::type_ref(p); 74 }
117 field.complete(p, NAMED_FIELD); 75 if !p.at(R_ANGLE) && !p.expect(COMMA) {
118 } else { 76 break;
119 field.abandon(p);
120 p.err_and_bump("expected field declaration");
121 } 77 }
122 } 78 }
123} 79 p.expect(R_ANGLE);
80 m.complete(p, TYPE_PARAM_LIST);
124 81
125fn pos_fields(p: &mut Parser) { 82 fn lifetime_param(p: &mut Parser) {
126 if !p.expect(L_PAREN) { 83 assert!(p.at(LIFETIME));
127 return; 84 let m = p.start();
85 p.bump();
86 if p.eat(COLON) {
87 while p.at(LIFETIME) {
88 p.bump();
89 if !p.eat(PLUS) {
90 break;
91 }
92 }
93 }
94 m.complete(p, LIFETIME_PARAM);
128 } 95 }
129 while !p.at(R_PAREN) && !p.at(EOF) {
130 let pos_field = p.start();
131 visibility(p);
132 types::type_ref(p);
133 pos_field.complete(p, POS_FIELD);
134 96
135 if !p.at(R_PAREN) { 97 fn type_param(p: &mut Parser) {
136 p.expect(COMMA); 98 assert!(p.at(IDENT));
137 } 99 let m = p.start();
100 p.bump();
101 m.complete(p, TYPE_PARAM);
102 //TODO: bounds
138 } 103 }
139 p.expect(R_PAREN);
140} 104}
141 105
142fn generic_parameters(_: &mut Parser) {}
143
144fn where_clause(_: &mut Parser) {} 106fn where_clause(_: &mut Parser) {}
145 107
146fn extern_crate_item(p: &mut Parser) { 108fn extern_crate_item(p: &mut Parser) {
diff --git a/src/parser/event_parser/grammar/items/structs.rs b/src/parser/event_parser/grammar/items/structs.rs
new file mode 100644
index 000000000..0934f3d28
--- /dev/null
+++ b/src/parser/event_parser/grammar/items/structs.rs
@@ -0,0 +1,83 @@
1use super::*;
2
3pub(super) fn struct_item(p: &mut Parser) {
4 assert!(p.at(STRUCT_KW));
5 p.bump();
6
7 if !p.expect(IDENT) {
8 return;
9 }
10 type_param_list(p);
11 match p.current() {
12 WHERE_KW => {
13 where_clause(p);
14 match p.current() {
15 SEMI => {
16 p.bump();
17 return;
18 }
19 L_CURLY => named_fields(p),
20 _ => {
21 //TODO: special case `(` error message
22 p.error().message("expected `;` or `{`").emit();
23 return;
24 }
25 }
26 }
27 SEMI => {
28 p.bump();
29 return;
30 }
31 L_CURLY => named_fields(p),
32 L_PAREN => {
33 pos_fields(p);
34 p.expect(SEMI);
35 }
36 _ => {
37 p.error().message("expected `;`, `{`, or `(`").emit();
38 return;
39 }
40 }
41}
42
43fn named_fields(p: &mut Parser) {
44 assert!(p.at(L_CURLY));
45 p.bump();
46 while !p.at(R_CURLY) && !p.at(EOF) {
47 named_field(p);
48 if !p.at(R_CURLY) {
49 p.expect(COMMA);
50 }
51 }
52 p.expect(R_CURLY);
53
54 fn named_field(p: &mut Parser) {
55 let field = p.start();
56 visibility(p);
57 if p.expect(IDENT) {
58 p.expect(COLON);
59 types::type_ref(p);
60 field.complete(p, NAMED_FIELD);
61 } else {
62 field.abandon(p);
63 p.err_and_bump("expected field declaration");
64 }
65 }
66}
67
68fn pos_fields(p: &mut Parser) {
69 if !p.expect(L_PAREN) {
70 return;
71 }
72 while !p.at(R_PAREN) && !p.at(EOF) {
73 let pos_field = p.start();
74 visibility(p);
75 types::type_ref(p);
76 pos_field.complete(p, POS_FIELD);
77
78 if !p.at(R_PAREN) {
79 p.expect(COMMA);
80 }
81 }
82 p.expect(R_PAREN);
83}
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs
index 23a0881b7..b6c281cd5 100644
--- a/src/syntax_kinds.rs
+++ b/src/syntax_kinds.rs
@@ -90,6 +90,9 @@ pub enum SyntaxKind {
90 LITERAL, 90 LITERAL,
91 ALIAS, 91 ALIAS,
92 VISIBILITY, 92 VISIBILITY,
93 TYPE_PARAM_LIST,
94 LIFETIME_PARAM,
95 TYPE_PARAM,
93 96
94 // Technical SyntaxKinds: they appear temporally during parsing, 97 // Technical SyntaxKinds: they appear temporally during parsing,
95 // but never end up in the final tree 98 // but never end up in the final tree
@@ -187,6 +190,9 @@ impl SyntaxKind {
187 LITERAL => &SyntaxInfo { name: "LITERAL" }, 190 LITERAL => &SyntaxInfo { name: "LITERAL" },
188 ALIAS => &SyntaxInfo { name: "ALIAS" }, 191 ALIAS => &SyntaxInfo { name: "ALIAS" },
189 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, 192 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
193 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
194 LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
195 TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
190 196
191 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, 197 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
192 EOF => &SyntaxInfo { name: "EOF" }, 198 EOF => &SyntaxInfo { name: "EOF" },