aboutsummaryrefslogtreecommitdiff
path: root/src/parser/grammar/items/structs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/grammar/items/structs.rs')
-rw-r--r--src/parser/grammar/items/structs.rs117
1 files changed, 117 insertions, 0 deletions
diff --git a/src/parser/grammar/items/structs.rs b/src/parser/grammar/items/structs.rs
new file mode 100644
index 000000000..69d95c698
--- /dev/null
+++ b/src/parser/grammar/items/structs.rs
@@ -0,0 +1,117 @@
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_params::list(p);
11 match p.current() {
12 WHERE_KW => {
13 type_params::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
43pub(super) fn enum_item(p: &mut Parser) {
44 assert!(p.at(ENUM_KW));
45 p.bump();
46 p.expect(IDENT);
47 type_params::list(p);
48 type_params::where_clause(p);
49 if p.expect(L_CURLY) {
50 while !p.at(EOF) && !p.at(R_CURLY) {
51 let var = p.start();
52 attributes::outer_attributes(p);
53 if p.at(IDENT) {
54 p.bump();
55 match p.current() {
56 L_CURLY => named_fields(p),
57 L_PAREN => pos_fields(p),
58 EQ => {
59 p.bump();
60 expressions::expr(p);
61 }
62 _ => (),
63 }
64 var.complete(p, ENUM_VARIANT);
65 } else {
66 var.abandon(p);
67 p.err_and_bump("expected enum variant");
68 }
69 if !p.at(R_CURLY) {
70 p.expect(COMMA);
71 }
72 }
73 p.expect(R_CURLY);
74 }
75}
76
77fn named_fields(p: &mut Parser) {
78 assert!(p.at(L_CURLY));
79 p.bump();
80 while !p.at(R_CURLY) && !p.at(EOF) {
81 named_field(p);
82 if !p.at(R_CURLY) {
83 p.expect(COMMA);
84 }
85 }
86 p.expect(R_CURLY);
87
88 fn named_field(p: &mut Parser) {
89 let field = p.start();
90 visibility(p);
91 if p.expect(IDENT) {
92 p.expect(COLON);
93 types::type_ref(p);
94 field.complete(p, NAMED_FIELD);
95 } else {
96 field.abandon(p);
97 p.err_and_bump("expected field declaration");
98 }
99 }
100}
101
102fn pos_fields(p: &mut Parser) {
103 if !p.expect(L_PAREN) {
104 return;
105 }
106 while !p.at(R_PAREN) && !p.at(EOF) {
107 let pos_field = p.start();
108 visibility(p);
109 types::type_ref(p);
110 pos_field.complete(p, POS_FIELD);
111
112 if !p.at(R_PAREN) {
113 p.expect(COMMA);
114 }
115 }
116 p.expect(R_PAREN);
117}